r24667: Finally merge the registry improvements that Wilco Baan Hofman and I have
[sfrench/samba-autobuild/.git] / source4 / lib / registry / tools / regtree.c
index c24e66412f4ddb9c7b22970b99a51e310d54d16a..8d2460a93efd9f0300ec96c5a45e8c385fb83270 100644 (file)
@@ -2,11 +2,11 @@
    Unix SMB/CIFS implementation.
    simple registry frontend
    
-   Copyright (C) Jelmer Vernooij 2004
+   Copyright (C) Jelmer Vernooij 2004-2007
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
-#include "dynconfig.h"
 #include "lib/registry/registry.h"
+#include "lib/registry/tools/common.h"
+#include "lib/events/events.h"
 #include "lib/cmdline/popt_common.h"
 
-static void print_tree(int l, struct registry_key *p, int fullpath, int novals)
+/**
+ * Print a registry key recursively 
+ * 
+ * @param level Level at which to print
+ * @param p Key to print
+ * @param fullpath Whether the full pat hshould be printed or just the last bit
+ * @param novals Whether values should not be printed
+ */
+static void print_tree(int level, struct registry_key *p, 
+                                          const char *name,
+                                          bool fullpath, bool novals)
 {
        struct registry_key *subkey;
-       struct registry_value *value;
+       const char *valuename;
+       const char *keyname;
+       uint32_t value_type;
+       DATA_BLOB value_data;
        struct security_descriptor *sec_desc;
        WERROR error;
        int i;
        TALLOC_CTX *mem_ctx;
 
-       for(i = 0; i < l; i++) putchar(' ');
-       
-       /* Hive name */
-       if(p->hive->root == p) {
-               if(p->hive->root->name) printf("%s\n", p->hive->root->name); else printf("<No Name>\n");
-       } else {
-               if(!p->name) printf("<No Name>\n");
-               if(fullpath) printf("%s\n", p->path);
-               else printf("%s\n", p->name);
-       }
+       for(i = 0; i < level; i++) putchar(' '); puts(name);
 
        mem_ctx = talloc_init("print_tree");
-       for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(mem_ctx, p, i, &subkey)); i++) {
-               print_tree(l+1, subkey, fullpath, novals);
+       for (i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(mem_ctx, p, i, &keyname, NULL, NULL)); i++) {
+               SMB_ASSERT(strlen(keyname) > 0);
+               if (!W_ERROR_IS_OK(reg_open_key(mem_ctx, p, keyname, &subkey))) 
+                       continue;
+               print_tree(level+1, subkey, (fullpath && strlen(name))?
+                                               talloc_asprintf(mem_ctx, "%s\\%s", name, keyname):
+                                               keyname, fullpath, novals);
        }
        talloc_free(mem_ctx);
 
        if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) {
-               DEBUG(0, ("Error occured while fetching subkeys for '%s': %s\n", p->path, win_errstr(error)));
+               DEBUG(0, ("Error occured while fetching subkeys for '%s': %s\n", 
+                                 name, win_errstr(error)));
        }
 
-       if(!novals) {
+       if (!novals) {
                mem_ctx = talloc_init("print_tree");
-               for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(mem_ctx, p, i, &value)); i++) {
+               for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(mem_ctx, 
+                                               p, i, &valuename, &value_type, &value_data)); i++) {
                        int j;
                        char *desc;
-                       for(j = 0; j < l+1; j++) putchar(' ');
-                       desc = reg_val_description(mem_ctx, value);
+                       for(j = 0; j < level+1; j++) putchar(' ');
+                       desc = reg_val_description(mem_ctx, valuename, value_type, 
+                                                                          value_data);
                        printf("%s\n", desc);
                }
                talloc_free(mem_ctx);
 
                if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) {
-                       DEBUG(0, ("Error occured while fetching values for '%s': %s\n", p->path, win_errstr(error)));
+                       DEBUG(0, ("Error occured while fetching values for '%s': %s\n", 
+                                         name, win_errstr(error)));
                }
        }
 
@@ -80,57 +93,59 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals)
 int main(int argc, char **argv)
 {
        int opt, i;
-       const char *backend = NULL;
+       const char *file = NULL;
        const char *remote = NULL;
        poptContext pc;
        struct registry_context *h = NULL;
-       struct registry_key *root = NULL;
+       struct registry_key *start_key = NULL;
        WERROR error;
-       int fullpath = 0, no_values = 0;
+       bool fullpath = false, no_values = false;
        struct poptOption long_options[] = {
                POPT_AUTOHELP
-               {"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL},
-               {"fullpath", 'f', POPT_ARG_NONE, &fullpath, 0, "show full paths", NULL},
+               {"file", 'F', POPT_ARG_STRING, &file, 0, "file path", NULL },
                {"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL },
+               {"fullpath", 'f', POPT_ARG_NONE, &fullpath, 0, "show full paths", NULL},
                {"no-values", 'V', POPT_ARG_NONE, &no_values, 0, "don't show values", NULL},
                POPT_COMMON_SAMBA       
                POPT_COMMON_CREDENTIALS 
-               POPT_TABLEEND
+               POPT_COMMON_VERSION
+               { NULL }
        };
 
-       regtree_init_subsystems;
-
        pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0);
        
        while((opt = poptGetNextOpt(pc)) != -1) {
        }
 
-       if (remote) {
-               error = reg_open_remote(&h, cmdline_credentials, remote, NULL);
-       } else if (backend) {
-           error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, &root);
+       if (remote != NULL) {
+               h = reg_common_open_remote(remote, cmdline_credentials);
+       } else if (file != NULL) {
+               start_key = reg_common_open_file(file, cmdline_credentials);
        } else {
-               error = reg_open_local (&h);
+               h = reg_common_open_local(cmdline_credentials);
        }
 
-       if(!W_ERROR_IS_OK(error)) {
-               fprintf(stderr, "Unable to open '%s' with backend '%s':%s \n", poptGetArg(pc), backend, win_errstr(error));
+       if (h == NULL && start_key == NULL)
                return 1;
-       }
+
        poptFreeContext(pc);
 
        error = WERR_OK;
        
-       if (!h) {
-               print_tree(0, root, fullpath, no_values);
+       if (start_key != NULL) {
+               print_tree(0, start_key, "", fullpath, no_values);
        } else {
-               for(i = HKEY_CLASSES_ROOT; i < HKEY_PERFORMANCE_NLSTEXT; i++) {
-                       error = reg_get_predefined_key(h, i, &root);
+               for(i = 0; reg_predefined_keys[i].handle; i++) {
+                       error = reg_get_predefined_key(h, reg_predefined_keys[i].handle, 
+                                                                                  &start_key);
                        if (!W_ERROR_IS_OK(error)) {
-                               fprintf(stderr, "Skipping %s\n", reg_get_predef_name(i));
+                               fprintf(stderr, "Skipping %s: %s\n", reg_predefined_keys[i].name, 
+                                               win_errstr(error));
                                continue;
                        }
-                       print_tree(0, root, fullpath, no_values);
+                       SMB_ASSERT(start_key != NULL);
+                       print_tree(0, start_key, reg_predefined_keys[i].name, fullpath, 
+                                          no_values);
                }
        }