s4:libregistry - change counters to be "unsigned"
[Samba/nascimento.git] / source4 / lib / registry / dir.c
blob4380dce74e98ba88c8b27be755dad59f10b53474
1 /*
2 Unix SMB/CIFS implementation.
3 Registry interface
4 Copyright (C) Jelmer Vernooij 2004-2007.
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 3 of the License, or
9 (at your option) any later version.
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.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "registry.h"
22 #include "system/dir.h"
23 #include "system/filesys.h"
25 struct dir_key {
26 struct hive_key key;
27 const char *path;
30 static struct hive_operations reg_backend_dir;
32 static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx,
33 const struct hive_key *parent,
34 const char *name, const char *classname,
35 struct security_descriptor *desc,
36 struct hive_key **result)
38 struct dir_key *dk = talloc_get_type(parent, struct dir_key);
39 char *path;
40 int ret;
42 path = talloc_asprintf(mem_ctx, "%s/%s", dk->path, name);
43 ret = mkdir(path, 0700);
44 if (ret == 0) {
45 struct dir_key *key = talloc(mem_ctx, struct dir_key);
46 key->key.ops = &reg_backend_dir;
47 key->path = talloc_steal(key, path);
48 *result = (struct hive_key *)key;
49 return WERR_OK;
52 if (errno == EEXIST)
53 return WERR_ALREADY_EXISTS;
54 printf("FAILED %s BECAUSE: %s\n", path, strerror(errno));
55 return WERR_GENERAL_FAILURE;
58 static WERROR reg_dir_delete_recursive(const char *name)
60 DIR *d;
61 struct dirent *e;
62 WERROR werr;
64 d = opendir(name);
65 if (d == NULL) {
66 DEBUG(3,("Unable to open '%s': %s\n", name,
67 strerror(errno)));
68 return WERR_BADFILE;
71 while((e = readdir(d))) {
72 char *path;
73 struct stat stbuf;
75 if (ISDOT(e->d_name) || ISDOTDOT(e->d_name))
76 continue;
78 path = talloc_asprintf(name, "%s/%s", name, e->d_name);
79 if (!path)
80 return WERR_NOMEM;
82 stat(path, &stbuf);
84 if (!S_ISDIR(stbuf.st_mode)) {
85 if (unlink(path) < 0) {
86 talloc_free(path);
87 closedir(d);
88 return WERR_GENERAL_FAILURE;
90 } else {
91 werr = reg_dir_delete_recursive(path);
92 if (!W_ERROR_IS_OK(werr)) {
93 talloc_free(path);
94 closedir(d);
95 return werr;
99 talloc_free(path);
101 closedir(d);
103 if (rmdir(name) == 0)
104 return WERR_OK;
105 else if (errno == ENOENT)
106 return WERR_BADFILE;
107 else
108 return WERR_GENERAL_FAILURE;
111 static WERROR reg_dir_del_key(const struct hive_key *k, const char *name)
113 struct dir_key *dk = talloc_get_type(k, struct dir_key);
114 char *child = talloc_asprintf(NULL, "%s/%s", dk->path, name);
115 WERROR ret;
117 ret = reg_dir_delete_recursive(child);
119 talloc_free(child);
121 return ret;
124 static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx,
125 const struct hive_key *parent,
126 const char *name, struct hive_key **subkey)
128 DIR *d;
129 char *fullpath;
130 const struct dir_key *p = talloc_get_type(parent, struct dir_key);
131 struct dir_key *ret;
133 if (name == NULL) {
134 DEBUG(0, ("NULL pointer passed as directory name!"));
135 return WERR_INVALID_PARAM;
138 fullpath = talloc_asprintf(mem_ctx, "%s/%s", p->path, name);
140 d = opendir(fullpath);
141 if (d == NULL) {
142 DEBUG(3,("Unable to open '%s': %s\n", fullpath,
143 strerror(errno)));
144 return WERR_BADFILE;
146 closedir(d);
147 ret = talloc(mem_ctx, struct dir_key);
148 ret->key.ops = &reg_backend_dir;
149 ret->path = talloc_steal(ret, fullpath);
150 *subkey = (struct hive_key *)ret;
151 return WERR_OK;
154 static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx,
155 const struct hive_key *k, uint32_t idx,
156 const char **name,
157 const char **classname,
158 NTTIME *last_mod_time)
160 struct dirent *e;
161 const struct dir_key *dk = talloc_get_type(k, struct dir_key);
162 unsigned int i = 0;
163 DIR *d;
165 d = opendir(dk->path);
167 if (d == NULL)
168 return WERR_INVALID_PARAM;
170 while((e = readdir(d))) {
171 if(!ISDOT(e->d_name) && !ISDOTDOT(e->d_name)) {
172 struct stat stbuf;
173 char *thispath;
175 /* Check if file is a directory */
176 asprintf(&thispath, "%s/%s", dk->path, e->d_name);
177 stat(thispath, &stbuf);
179 if (!S_ISDIR(stbuf.st_mode)) {
180 SAFE_FREE(thispath);
181 continue;
184 if (i == idx) {
185 struct stat st;
186 *name = talloc_strdup(mem_ctx, e->d_name);
187 *classname = NULL;
188 stat(thispath, &st);
189 unix_to_nt_time(last_mod_time, st.st_mtime);
190 SAFE_FREE(thispath);
191 closedir(d);
192 return WERR_OK;
194 i++;
196 SAFE_FREE(thispath);
200 closedir(d);
202 return WERR_NO_MORE_ITEMS;
205 WERROR reg_open_directory(TALLOC_CTX *parent_ctx,
206 const char *location, struct hive_key **key)
208 struct dir_key *dk;
210 if (location == NULL)
211 return WERR_INVALID_PARAM;
213 dk = talloc(parent_ctx, struct dir_key);
214 dk->key.ops = &reg_backend_dir;
215 dk->path = talloc_strdup(dk, location);
216 *key = (struct hive_key *)dk;
217 return WERR_OK;
220 WERROR reg_create_directory(TALLOC_CTX *parent_ctx,
221 const char *location, struct hive_key **key)
223 if (mkdir(location, 0700) != 0) {
224 *key = NULL;
225 return WERR_GENERAL_FAILURE;
228 return reg_open_directory(parent_ctx, location, key);
231 static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key,
232 const char **classname,
233 uint32_t *num_subkeys,
234 uint32_t *num_values,
235 NTTIME *lastmod,
236 uint32_t *max_subkeynamelen,
237 uint32_t *max_valnamelen,
238 uint32_t *max_valbufsize)
240 DIR *d;
241 const struct dir_key *dk = talloc_get_type(key, struct dir_key);
242 struct dirent *e;
243 struct stat st;
245 SMB_ASSERT(key != NULL);
247 if (classname != NULL)
248 *classname = NULL;
250 d = opendir(dk->path);
251 if (d == NULL)
252 return WERR_INVALID_PARAM;
254 if (num_subkeys != NULL)
255 *num_subkeys = 0;
257 if (num_values != NULL)
258 *num_values = 0;
260 if (max_subkeynamelen != NULL)
261 *max_subkeynamelen = 0;
263 if (max_valnamelen != NULL)
264 *max_valnamelen = 0;
266 if (max_valbufsize != NULL)
267 *max_valbufsize = 0;
269 while((e = readdir(d))) {
270 if(!ISDOT(e->d_name) && !ISDOTDOT(e->d_name)) {
271 char *path = talloc_asprintf(ctx, "%s/%s",
272 dk->path, e->d_name);
274 if (stat(path, &st) < 0) {
275 DEBUG(0, ("Error statting %s: %s\n", path,
276 strerror(errno)));
277 continue;
280 if (S_ISDIR(st.st_mode)) {
281 if (num_subkeys != NULL)
282 (*num_subkeys)++;
283 if (max_subkeynamelen != NULL)
284 *max_subkeynamelen = MAX(*max_subkeynamelen, strlen(e->d_name));
287 if (!S_ISDIR(st.st_mode)) {
288 if (num_values != NULL)
289 (*num_values)++;
290 if (max_valnamelen != NULL)
291 *max_valnamelen = MAX(*max_valnamelen, strlen(e->d_name));
292 if (max_valbufsize != NULL)
293 *max_valbufsize = MAX(*max_valbufsize, st.st_size);
296 talloc_free(path);
300 closedir(d);
302 if (lastmod != NULL)
303 *lastmod = 0;
304 return WERR_OK;
307 static WERROR reg_dir_set_value(struct hive_key *key, const char *name,
308 uint32_t type, const DATA_BLOB data)
310 const struct dir_key *dk = talloc_get_type(key, struct dir_key);
311 char *path = talloc_asprintf(dk, "%s/%s", dk->path, name);
313 if (!file_save(path, data.data, data.length))
314 return WERR_GENERAL_FAILURE;
316 /* FIXME: Type */
318 return WERR_OK;
321 static WERROR reg_dir_get_value(TALLOC_CTX *mem_ctx,
322 struct hive_key *key, const char *name,
323 uint32_t *type, DATA_BLOB *data)
325 const struct dir_key *dk = talloc_get_type(key, struct dir_key);
326 char *path = talloc_asprintf(mem_ctx, "%s/%s", dk->path, name);
327 size_t size;
328 char *contents;
330 contents = file_load(path, &size, 0, mem_ctx);
331 talloc_free(path);
332 if (contents == NULL)
333 return WERR_BADFILE;
335 if (type != NULL)
336 *type = 4; /* FIXME */
338 data->data = (uint8_t *)contents;
339 data->length = size;
341 return WERR_OK;
344 static WERROR reg_dir_enum_value(TALLOC_CTX *mem_ctx,
345 struct hive_key *key, uint32_t idx,
346 const char **name,
347 uint32_t *type, DATA_BLOB *data)
349 const struct dir_key *dk = talloc_get_type(key, struct dir_key);
350 DIR *d;
351 struct dirent *e;
352 unsigned int i;
354 d = opendir(dk->path);
355 if (d == NULL) {
356 DEBUG(3,("Unable to open '%s': %s\n", dk->path,
357 strerror(errno)));
358 return WERR_BADFILE;
361 i = 0;
362 while((e = readdir(d))) {
363 if (ISDOT(e->d_name) || ISDOTDOT(e->d_name))
364 continue;
366 if (i == idx) {
367 if (name != NULL)
368 *name = talloc_strdup(mem_ctx, e->d_name);
369 W_ERROR_NOT_OK_RETURN(reg_dir_get_value(mem_ctx, key,
370 *name, type,
371 data));
372 return WERR_OK;
375 i++;
377 closedir(d);
379 return WERR_NO_MORE_ITEMS;
383 static WERROR reg_dir_del_value (struct hive_key *key, const char *name)
385 const struct dir_key *dk = talloc_get_type(key, struct dir_key);
386 char *path = talloc_asprintf(key, "%s/%s", dk->path, name);
387 if (unlink(path) < 0) {
388 talloc_free(path);
389 if (errno == ENOENT)
390 return WERR_BADFILE;
391 return WERR_GENERAL_FAILURE;
393 talloc_free(path);
395 return WERR_OK;
398 static struct hive_operations reg_backend_dir = {
399 .name = "dir",
400 .get_key_by_name = reg_dir_open_key,
401 .get_key_info = reg_dir_get_info,
402 .add_key = reg_dir_add_key,
403 .del_key = reg_dir_del_key,
404 .enum_key = reg_dir_key_by_index,
405 .set_value = reg_dir_set_value,
406 .get_value_by_name = reg_dir_get_value,
407 .enum_value = reg_dir_enum_value,
408 .delete_value = reg_dir_del_value,