sync'ing up for 3.0alpha20 release
[tprouty/samba.git] / source / registry / reg_frontend.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Gerald Carter                     2002.
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *  
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *  
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20
21 /* Implementation of registry frontend view functions. */
22
23 #include "includes.h"
24
25 #undef DBGC_CLASS
26 #define DBGC_CLASS DBGC_RPC_SRV
27
28 extern REGISTRY_OPS printing_ops;
29 extern REGISTRY_OPS regdb_ops;          /* these are the default */
30
31 /* array of REGISTRY_HOOK's which are read into a tree for easy access */
32
33
34 REGISTRY_HOOK reg_hooks[] = {
35   { KEY_PRINTING,   &printing_ops },
36   { NULL, NULL }
37 };
38
39
40 /***********************************************************************
41  Open the registry database and initialize the REGISTRY_HOOK cache
42  ***********************************************************************/
43  
44 BOOL init_registry( void )
45 {
46         int i;
47         
48         if ( !init_registry_db() ) {
49                 DEBUG(0,("init_registry: failed to initialize the registry tdb!\n"));
50                 return False;
51         }
52                 
53         /* build the cache tree of registry hooks */
54         
55         reghook_cache_init();
56         
57         for ( i=0; reg_hooks[i].keyname; i++ ) {
58                 if ( !reghook_cache_add(&reg_hooks[i]) )
59                         return False;
60         }
61
62         if ( DEBUGLEVEL >= 20 )
63                 reghook_dump_cache(20);
64
65         return True;
66 }
67
68
69
70
71 /***********************************************************************
72  High level wrapper function for storing registry subkeys
73  ***********************************************************************/
74  
75 BOOL store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys )
76 {
77         if ( key->hook && key->hook->ops && key->hook->ops->store_subkeys_fn )
78                 return key->hook->ops->store_subkeys_fn( key->name, subkeys );
79         else
80                 return False;
81
82 }
83
84 /***********************************************************************
85  High level wrapper function for storing registry values
86  ***********************************************************************/
87  
88 BOOL store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
89 {
90         if ( key->hook && key->hook->ops && key->hook->ops->store_values_fn )
91                 return key->hook->ops->store_values_fn( key->name, val );
92         else
93                 return False;
94 }
95
96
97 /***********************************************************************
98  High level wrapper function for enumerating registry subkeys
99  Initialize the TALLOC_CTX if necessary
100  ***********************************************************************/
101
102 int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
103 {
104         int result = -1;
105         
106         if ( key->hook && key->hook->ops && key->hook->ops->subkey_fn )
107                 result = key->hook->ops->subkey_fn( key->name, subkey_ctr );
108
109         return result;
110 }
111
112 /***********************************************************************
113  retreive a specific subkey specified by index.  Caller is 
114  responsible for freeing memory
115  ***********************************************************************/
116
117 BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index )
118 {
119         static REGSUBKEY_CTR ctr;
120         static pstring save_path;
121         static BOOL ctr_init = False;
122         char *s;
123         
124         *subkey = NULL;
125         
126         /* simple caching for performance; very basic heuristic */
127         
128         if ( !ctr_init ) {
129                 DEBUG(8,("fetch_reg_keys_specific: Initializing cache of subkeys for [%s]\n", key->name));
130                 ZERO_STRUCTP( &ctr );   
131                 regsubkey_ctr_init( &ctr );
132                 
133                 pstrcpy( save_path, key->name );
134                 
135                 if ( fetch_reg_keys( key, &ctr) == -1 )
136                         return False;
137                         
138                 ctr_init = True;
139         }
140         /* clear the cache when key_index == 0 or the path has changed */
141         else if ( !key_index || StrCaseCmp( save_path, key->name) ) {
142
143                 DEBUG(8,("fetch_reg_keys_specific: Updating cache of subkeys for [%s]\n", key->name));
144                 
145                 regsubkey_ctr_destroy( &ctr );  
146                 regsubkey_ctr_init( &ctr );
147                 
148                 pstrcpy( save_path, key->name );
149                 
150                 if ( fetch_reg_keys( key, &ctr) == -1 )
151                         return False;
152         }
153         
154         if ( !(s = regsubkey_ctr_specific_key( &ctr, key_index )) )
155                 return False;
156
157         *subkey = strdup( s );
158
159         return True;
160 }
161
162
163 /***********************************************************************
164  High level wrapper function for enumerating registry values
165  Initialize the TALLOC_CTX if necessary
166  ***********************************************************************/
167
168 int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
169 {
170         int result = -1;
171         
172         if ( key->hook && key->hook->ops && key->hook->ops->value_fn )
173                 result = key->hook->ops->value_fn( key->name, val );
174
175         return result;
176 }
177
178
179 /***********************************************************************
180  retreive a specific subkey specified by index.  Caller is 
181  responsible for freeing memory
182  ***********************************************************************/
183
184 BOOL fetch_reg_values_specific( REGISTRY_KEY *key, REGISTRY_VALUE **val, uint32 val_index )
185 {
186         static REGVAL_CTR       ctr;
187         static pstring          save_path;
188         static BOOL             ctr_init = False;
189         REGISTRY_VALUE          *v;
190         
191         *val = NULL;
192         
193         /* simple caching for performance; very basic heuristic */
194         
195         if ( !ctr_init ) {
196                 DEBUG(8,("fetch_reg_values_specific: Initializing cache of values for [%s]\n", key->name));
197
198                 ZERO_STRUCTP( &ctr );   
199                 regval_ctr_init( &ctr );
200                 
201                 pstrcpy( save_path, key->name );
202                 
203                 if ( fetch_reg_values( key, &ctr) == -1 )
204                         return False;
205                         
206                 ctr_init = True;
207         }
208         /* clear the cache when val_index == 0 or the path has changed */
209         else if ( !val_index || StrCaseCmp(save_path, key->name) ) {
210
211                 DEBUG(8,("fetch_reg_values_specific: Updating cache of values for [%s]\n", key->name));         
212                 
213                 regval_ctr_destroy( &ctr );     
214                 regval_ctr_init( &ctr );
215                 
216                 pstrcpy( save_path, key->name );
217                 
218                 if ( fetch_reg_values( key, &ctr) == -1 )
219                         return False;
220         }
221         
222         if ( !(v = regval_ctr_specific_value( &ctr, val_index )) )
223                 return False;
224
225         *val = dup_registry_value( v );
226
227         return True;
228 }
229
230 /***********************************************************************
231  Utility function for splitting the base path of a registry path off
232  by setting base and new_path to the apprapriate offsets withing the
233  path.
234  
235  WARNING!!  Does modify the original string!
236  ***********************************************************************/
237
238 BOOL reg_split_path( char *path, char **base, char **new_path )
239 {
240         char *p;
241         
242         *new_path = *base = NULL;
243         
244         if ( !path)
245                 return False;
246         
247         *base = path;
248         
249         p = strchr( path, '\\' );
250         
251         if ( p ) {
252                 *p = '\0';
253                 *new_path = p+1;
254         }
255         
256         return True;
257 }
258
259
260