r24667: Finally merge the registry improvements that Wilco Baan Hofman and I have
[sfrench/samba-autobuild/.git] / source4 / lib / registry / tools / regtree.c
index 548a702d48d44d16111c50c1ac277c5a7b026294..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 "lib/registry/registry.h"
+#include "lib/registry/tools/common.h"
+#include "lib/events/events.h"
+#include "lib/cmdline/popt_common.h"
 
-void print_tree(int l, REG_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)
 {
-       REG_KEY *subkey;
-       REG_VAL *value;
+       struct registry_key *subkey;
+       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(' ');
-       if(fullpath) printf("%s\n", reg_key_get_path(p));
-       else printf("%s\n", reg_key_name(p));
+       for(i = 0; i < level; i++) putchar(' '); puts(name);
 
-       for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(p, i, &subkey)); i++) {
-               print_tree(l+1, subkey, fullpath, novals);
-               reg_key_free(subkey);
+       mem_ctx = talloc_init("print_tree");
+       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'\n", reg_key_get_path(p)));
+               DEBUG(0, ("Error occured while fetching subkeys for '%s': %s\n", 
+                                 name, win_errstr(error)));
        }
 
-       if(!novals) {
-               for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(p, i, &value)); i++) {
+       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, &valuename, &value_type, &value_data)); i++) {
                        int j;
                        char *desc;
-                       for(j = 0; j < l+1; j++) putchar(' ');
-                       desc = reg_val_description(value);
+                       for(j = 0; j < level+1; j++) putchar(' ');
+                       desc = reg_val_description(mem_ctx, valuename, value_type, 
+                                                                          value_data);
                        printf("%s\n", desc);
-                       free(desc);
-                       reg_val_free(value);
                }
+               talloc_free(mem_ctx);
 
                if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) {
-                       DEBUG(0, ("Error occured while fetching subkeys for '%s'\n", reg_key_get_path(p)));
+                       DEBUG(0, ("Error occured while fetching values for '%s': %s\n", 
+                                         name, win_errstr(error)));
                }
        }
+
+       mem_ctx = talloc_init("sec_desc");
+       if (NT_STATUS_IS_ERR(reg_get_sec_desc(mem_ctx, p, &sec_desc))) {
+               DEBUG(0, ("Error getting security descriptor\n"));
+       }
+       talloc_free(mem_ctx);
 }
 
-int main (int argc, char **argv)
+int main(int argc, char **argv)
 {
-       uint32  setparms, checkparms;
-       int opt;
-       char *backend = "dir", *credentials = NULL;
+       int opt, i;
+       const char *file = NULL;
+       const char *remote = NULL;
        poptContext pc;
-       REG_KEY *root;
-       REG_HANDLE *h;
+       struct registry_context *h = 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},
+               {"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},
-               {"credentials", 'c', POPT_ARG_NONE, &credentials, 0, "credentials (user%password)", NULL},
                {"no-values", 'V', POPT_ARG_NONE, &no_values, 0, "don't show values", NULL},
-               POPT_TABLEEND
+               POPT_COMMON_SAMBA       
+               POPT_COMMON_CREDENTIALS 
+               POPT_COMMON_VERSION
+               { NULL }
        };
 
        pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0);
@@ -82,19 +117,37 @@ int main (int argc, char **argv)
        while((opt = poptGetNextOpt(pc)) != -1) {
        }
 
-       setup_logging("regtree", True);
+       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 {
+               h = reg_common_open_local(cmdline_credentials);
+       }
 
-       error = reg_open(backend, poptPeekArg(pc), credentials, &h);
-       if(!W_ERROR_IS_OK(error)) {
-               fprintf(stderr, "Unable to open '%s' with backend '%s'\n", poptGetArg(pc), backend);
+       if (h == NULL && start_key == NULL)
                return 1;
-       }
-       poptFreeContext(pc);
 
-       error = reg_get_root(h, &root);
-       if(!W_ERROR_IS_OK(error)) return 1;
+       poptFreeContext(pc);
 
-       print_tree(0, root, fullpath, no_values);
+       error = WERR_OK;
        
+       if (start_key != NULL) {
+               print_tree(0, start_key, "", fullpath, no_values);
+       } else {
+               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: %s\n", reg_predefined_keys[i].name, 
+                                               win_errstr(error));
+                               continue;
+                       }
+                       SMB_ASSERT(start_key != NULL);
+                       print_tree(0, start_key, reg_predefined_keys[i].name, fullpath, 
+                                          no_values);
+               }
+       }
+
        return 0;
 }