From 444a86792471c0bef33dde15c7a4a33e16a951b4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 10 Dec 2004 20:07:04 +0000 Subject: r4132: - Bunch of rather large fixes in the registry - Added some README files Not everything works yet, e.g. the EnumValue test appears to be broken. (This used to be commit c169e86c1f52763b83e77e509f89cb91f9b69071) --- source4/lib/registry/tools/regdiff.c | 76 +++++++++++++----------------- source4/lib/registry/tools/regpatch.c | 25 ++++------ source4/lib/registry/tools/regshell.c | 87 ++++++++++++++++++++++++----------- source4/lib/registry/tools/regtree.c | 38 +++++++++++---- 4 files changed, 129 insertions(+), 97 deletions(-) (limited to 'source4/lib/registry/tools') diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 55c8f1e72f..fc2954b6af 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -113,21 +113,19 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, { int opt; poptContext pc; - const char *backend1 = NULL, *backend2 = NULL; - const char *location2; - const char *credentials1= NULL, *credentials2 = NULL; char *outputfile = NULL; FILE *fd = stdout; - struct registry_context *h1 = NULL, *h2; + struct registry_context *h1 = NULL, *h2 = NULL; int from_null = 0; int i; WERROR error, error2; struct poptOption long_options[] = { POPT_AUTOHELP - {"backend", 'b', POPT_ARG_STRING, NULL, 'b', "backend to use", NULL}, - {"credentials", 'c', POPT_ARG_STRING, NULL, 'c', "credentials", NULL}, + POPT_COMMON_CREDENTIALS {"output", 'o', POPT_ARG_STRING, &outputfile, 'o', "output file to use", NULL }, - {"null", 'n', POPT_ARG_NONE, &from_null, 'n', "Diff from NULL" }, + {"null", 'n', POPT_ARG_NONE, &from_null, 'n', "Diff from NULL", NULL }, + {"remote", 'R', POPT_ARG_STRING, NULL, 0, "Connect to remote server" , NULL }, + {"local", 'L', POPT_ARG_NONE, NULL, 0, "Open local registry", NULL }, POPT_TABLEEND }; @@ -141,49 +139,24 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); while((opt = poptGetNextOpt(pc)) != -1) { + error = WERR_OK; switch(opt) { - case 'c': - if(!credentials1 && !from_null) credentials1 = poptGetOptArg(pc); - else if(!credentials2) credentials2 = poptGetOptArg(pc); + case 'L': + if (!h1 && !from_null) error = reg_open_local(&h1); + else if (!h2) error = reg_open_local(&h2); break; - case 'b': - if(!backend1 && !from_null) backend1 = poptGetOptArg(pc); - else if(!backend2) backend2 = poptGetOptArg(pc); + case 'R': + if (!h1 && !from_null) error = reg_open_remote(&h1, cmdline_get_username(), cmdline_get_userpassword(), poptGetOptArg(pc)); + else if (!h2) error = reg_open_remote(&h2, cmdline_get_username(), cmdline_get_userpassword(), poptGetOptArg(pc)); break; } - } - setup_logging(argv[0], True); - if(!from_null) { - const char *location1; - location1 = poptGetArg(pc); - if(!location1) { - poptPrintUsage(pc, stderr, 0); + if (!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Error: %s\n", win_errstr(error)); return 1; } - - if(!backend1) backend1 = "rpc"; - - error = reg_open(&h1, backend1, location1, credentials1); - if(!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location1, backend1); - return 1; - } - } - - location2 = poptGetArg(pc); - if(!location2) { - poptPrintUsage(pc, stderr, 0); - return 2; - } - - if(!backend2) backend2 = "rpc"; - - error = reg_open(&h2, backend2, location2, credentials2); - if(!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location2, backend2); - return 1; } + setup_logging(argv[0], True); poptFreeContext(pc); @@ -196,12 +169,25 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, } fprintf(fd, "REGEDIT4\n\n"); - fprintf(fd, "; Generated using regdiff\n"); + fprintf(fd, "; Generated using regdiff, part of Samba\n"); error2 = error = WERR_OK; - for(i = 0; (!h1 || i < h1->num_hives) && i < h2->num_hives; i++) { - writediff(h1?h1->hives[i]->root:NULL, h2->hives[i]->root, fd); + for(i = HKEY_CLASSES_ROOT; i <= HKEY_PN; i++) { + struct registry_key *r1, *r2; + error = reg_get_hive(h1, i, &r1); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Unable to open hive %s for backend 1\n", reg_get_hkey_name(i))); + continue; + } + + error = reg_get_hive(h2, i, &r2); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Unable to open hive %s for backend 2\n", reg_get_hkey_name(i))); + continue; + } + + writediff(r1, r2, fd); } fclose(fd); diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index be60b96019..a4a4649c96 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -758,16 +758,14 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd { int opt; poptContext pc; - const char *location; - const char *credentials = NULL; const char *patch; - const char *backend = "rpc"; struct registry_context *h; + const char *remote = NULL; WERROR error; struct poptOption long_options[] = { POPT_AUTOHELP - {"backend", 'b', POPT_ARG_STRING, &backend, 'b', "backend to use", NULL}, - {"credentials", 'c', POPT_ARG_STRING, &credentials, 'c', "credentials (user%password", NULL}, + POPT_COMMON_CREDENTIALS + {"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL}, POPT_TABLEEND }; @@ -785,25 +783,22 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd setup_logging(argv[0], True); - location = poptGetArg(pc); - if(!location) { - poptPrintUsage(pc, stderr, 0); - return 1; + if (remote) { + error = reg_open_remote (&h, cmdline_get_username(), cmdline_get_userpassword(), remote); + } else { + error = reg_open_local (&h); } - error = reg_open(&h, backend, location, credentials); - if(!h) { - fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location, backend); + if (W_ERROR_IS_OK(error)) { + fprintf(stderr, "Error: %s\n", win_errstr(error)); return 1; } - + patch = poptGetArg(pc); if(!patch) patch = "/dev/stdin"; poptFreeContext(pc); nt_apply_reg_command_file(h, patch); - talloc_destroy(h->mem_ctx); - return 0; } diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index f18b012720..3fd9dab268 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -164,15 +164,23 @@ static struct registry_key *cmd_rmval(TALLOC_CTX *mem_ctx, struct registry_key * static struct registry_key *cmd_hive(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) { - int i; - for(i = 0; i < cur->hive->reg_ctx->num_hives; i++) { + if (!cur->hive->reg_ctx) { + fprintf(stderr, "Only one hive loaded\n"); + return cur; + } - if(argc == 1) { - printf("%s\n", cur->hive->reg_ctx->hives[i]->name); - } else if(!strcmp(cur->hive->reg_ctx->hives[i]->name, argv[1])) { - return cur->hive->reg_ctx->hives[i]->root; - } + if (argc == 1) { + printf("%s\n", cur->hive->root->name); + } else { + struct registry_key *newroot; + WERROR error = reg_get_hive_by_name(cur->hive->reg_ctx, argv[1], &newroot); + if (W_ERROR_IS_OK(error)) { + return newroot; + } else { + fprintf(stderr, "Can't switch to hive %s: %s\n", cur->hive->root->name, win_errstr(error)); + } } + return NULL; } @@ -274,11 +282,7 @@ static char **reg_complete_command(const char *text, int end) matches[0] = strdup(matches[1]); break; default: - matches[0] = malloc(samelen+1); - if (!matches[0]) - goto cleanup; - strncpy(matches[0], matches[1], samelen); - matches[0][samelen] = 0; + matches[0] = strndup(matches[1], samelen); } matches[count] = NULL; return matches; @@ -295,11 +299,11 @@ cleanup: static char **reg_complete_key(const char *text, int end) { struct registry_key *subkey; - int i, j = 0; + int i, j = 1; + int samelen = 0; int len; char **matches; TALLOC_CTX *mem_ctx; - /* Complete argument */ matches = malloc_array_p(char *, MAX_COMPLETIONS); if (!matches) return NULL; @@ -313,6 +317,12 @@ static char **reg_complete_key(const char *text, int end) if(!strncmp(text, subkey->name, len)) { matches[j] = strdup(subkey->name); j++; + + if (j == 1) + samelen = strlen(matches[j]); + else + while (strncmp(matches[j], matches[j-1], samelen) != 0) + samelen--; } } else if(W_ERROR_EQUAL(status, WERR_NO_MORE_ITEMS)) { break; @@ -322,8 +332,20 @@ static char **reg_complete_key(const char *text, int end) return NULL; } } - matches[j] = NULL; talloc_destroy(mem_ctx); + + if (j == 1) { /* No matches at all */ + SAFE_FREE(matches); + return NULL; + } + + if (j == 2) { /* Exact match */ + matches[0] = strdup(matches[1]); + } else { + matches[0] = strndup(matches[1], samelen); + } + + matches[j] = NULL; return matches; } @@ -341,18 +363,18 @@ static char **reg_completion(const char *text, int start, int end) int main(int argc, char **argv) { int opt; - const char *backend = "rpc"; - const char *credentials = NULL; + const char *backend = NULL; struct registry_key *curkey = NULL; poptContext pc; WERROR error; TALLOC_CTX *mem_ctx = talloc_init("cmd"); - struct registry_context *h; + const char *remote = NULL; + struct registry_context *h = NULL; struct poptOption long_options[] = { POPT_AUTOHELP - POPT_COMMON_SAMBA + POPT_COMMON_CREDENTIALS {"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL}, - {"credentials", 'c', POPT_ARG_STRING, &credentials, 0, "credentials", NULL}, + {"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL}, POPT_TABLEEND }; @@ -370,20 +392,31 @@ static char **reg_completion(const char *text, int start, int end) setup_logging("regtree", True); - error = reg_open(&h, backend, poptPeekArg(pc), credentials); + if (remote) { + error = reg_open_remote (&h, cmdline_get_username(), cmdline_get_userpassword(), remote); + } else if (backend) { + error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, &curkey); + } else { + error = reg_open_local(&h); + } + if(!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Unable to open '%s' with backend '%s'\n", poptGetArg(pc), backend); + fprintf(stderr, "Unable to open registry\n"); return 1; } - poptFreeContext(pc); - - curkey = h->hives[0]->root; + if (h) { + /*FIXME: What if HKEY_CLASSES_ROOT is not present ? */ + reg_get_hive(h, HKEY_CLASSES_ROOT, &curkey); + } + + poptFreeContext(pc); + while(True) { char *line, *prompt; - if(curkey->hive->name) { - asprintf(&prompt, "%s:%s> ", curkey->hive->name, curkey->path); + if(curkey->hive->root->name) { + asprintf(&prompt, "%s:%s> ", curkey->hive->root->name, curkey->path); } else { asprintf(&prompt, "%s> ", curkey->path); } diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index ced7a00f94..8ff68229eb 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -36,7 +36,7 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) /* Hive name */ if(p->hive->root == p) { - if(p->hive->name) printf("%s\n", p->hive->name); else printf("\n"); + if(p->hive->root->name) printf("%s\n", p->hive->root->name); else printf("\n"); } else { if(!p->name) printf("\n"); if(fullpath) printf("%s\n", p->path); @@ -73,17 +73,19 @@ 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 = "rpc"; - const char *credentials = NULL; + const char *backend = NULL; + const char *remote = NULL; poptContext pc; - struct registry_context *h; + struct registry_context *h = NULL; + struct registry_key *root = NULL; WERROR error; int fullpath = 0, no_values = 0; struct poptOption long_options[] = { POPT_AUTOHELP + POPT_COMMON_CREDENTIALS {"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL}, {"fullpath", 'f', POPT_ARG_NONE, &fullpath, 0, "show full paths", NULL}, - {"credentials", 'c', POPT_ARG_STRING, &credentials, 0, "credentials (user%password)", NULL}, + {"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL }, {"no-values", 'V', POPT_ARG_NONE, &no_values, 0, "don't show values", NULL}, POPT_TABLEEND }; @@ -102,7 +104,14 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) setup_logging("regtree", True); - error = reg_open(&h, backend, poptPeekArg(pc), credentials); + if (remote) { + error = reg_open_remote(&h, cmdline_get_username(), cmdline_get_userpassword(), remote); + } else if (backend) { + error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, &root); + } else { + error = reg_open_local (&h); + } + if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open '%s' with backend '%s':%s \n", poptGetArg(pc), backend, win_errstr(error)); return 1; @@ -110,10 +119,19 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) poptFreeContext(pc); error = WERR_OK; - - for(i = 0; i < h->num_hives; i++) { - print_tree(0, h->hives[i]->root, fullpath, no_values); - } + if (!h) { + print_tree(0, root, fullpath, no_values); + } else { + for(i = HKEY_CLASSES_ROOT; i < HKEY_PN; i++) { + error = reg_get_hive(h, i, &root); + if (!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Skipping %s\n", reg_get_hkey_name(i)); + continue; + } + print_tree(0, root, fullpath, no_values); + } + } + return 0; } -- cgit