*/
#include "includes.h"
-#include "popt_common.h"
+#include "popt_common_cmdline.h"
#include "lib/util/data_blob.h"
#include "lib/registry/registry.h"
#include "regedit.h"
if (subkey) {
msg = "Enter name of new subkey";
}
- dialog_input(regedit, &name, "New Key", msg);
+ dialog_input(regedit, &name, "New Key", "%s", msg);
if (name) {
WERROR rv;
struct registry_key *new_key;
- struct tree_node *new_node;
+ struct tree_node *new_node = NULL;
struct tree_node *list;
struct tree_node *parent;
} else {
/* Reopen the parent key to make sure the
new subkey will be noticed. */
- tree_node_reopen_key(parent);
+ tree_node_reopen_key(regedit->registry_context,
+ parent);
}
list = tree_node_first(node);
node = new_node;
}
tree_view_set_current_node(regedit->keys, node);
+ load_values(regedit);
} else {
msg = get_friendly_werror_msg(rv);
dialog_notice(regedit, DIA_ALERT, "New Key",
}
}
-static WERROR next_depth_first(struct tree_node **node)
-{
- WERROR rv = WERR_OK;
-
- SMB_ASSERT(node != NULL && *node != NULL);
-
- if (tree_node_has_children(*node)) {
- /* 1. If the node has children, go to the first one. */
- rv = tree_node_load_children(*node);
- if (W_ERROR_IS_OK(rv)) {
- SMB_ASSERT((*node)->child_head != NULL);
- *node = (*node)->child_head;
- }
- } else if ((*node)->next) {
- /* 2. If there's a node directly after this one, go there */
- *node = (*node)->next;
- } else {
- /* 3. Otherwise, go up the hierarchy to find the next one */
- do {
- *node = (*node)->parent;
- if (*node && (*node)->next) {
- *node = (*node)->next;
- break;
- }
- } while (*node);
- }
-
- return rv;
-}
-
-static WERROR regedit_search_next(struct regedit *regedit)
-{
- WERROR rv;
- struct regedit_search_opts *opts = ®edit->active_search;
-
- if (opts->search_recursive) {
- rv = next_depth_first(&opts->node);
- if (!W_ERROR_IS_OK(rv)) {
- return rv;
- }
- } else {
- opts->node = opts->node->next;
- }
-
- return WERR_OK;
-}
-
-static WERROR regedit_search(struct regedit *regedit)
+enum search_flags {
+ SEARCH_NEXT = (1<<0),
+ SEARCH_PREV = (1<<1),
+ SEARCH_REPEAT = (1<<2)
+};
+static WERROR regedit_search(struct regedit *regedit, struct tree_node *node,
+ struct value_item *vitem, unsigned flags)
{
struct regedit_search_opts *opts;
struct tree_node *found;
+ struct value_item *found_value;
+ bool search_key, need_sync;
+ char *save_value_name;
WERROR rv;
+ bool (*iterate)(struct tree_node **, bool, WERROR *);
+ struct value_item *(*find_item)(struct value_list *,
+ struct value_item *,
+ const char *,
+ regedit_search_match_fn_t);
opts = ®edit->active_search;
SMB_ASSERT(opts->search_key || opts->search_value);
- for (found = NULL; opts->node && !found; ) {
- if (opts->search_key &&
- opts->match(opts->node->name, opts->query)) {
- found = opts->node;
+ rv = WERR_OK;
+ found = NULL;
+ found_value = NULL;
+ save_value_name = NULL;
+ search_key = opts->search_key;
+ need_sync = false;
+ iterate = tree_node_next;
+ find_item = value_list_find_next_item;
+
+ if (flags & SEARCH_PREV) {
+ iterate = tree_node_prev;
+ find_item = value_list_find_prev_item;
+ }
+
+ if (opts->search_value) {
+ struct value_item *it;
+
+ it = value_list_get_current_item(regedit->vl);
+ if (it) {
+ save_value_name = talloc_strdup(regedit,
+ it->value_name);
+ if (save_value_name == NULL) {
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+ }
+
+ if (vitem) {
+ search_key = false;
}
+ }
+
+ if (!vitem && (flags & SEARCH_REPEAT)) {
if (opts->search_value) {
- /* TODO
- rv = regedit_search_value(regedit);
- if (W_ERROR_IS_OK(rv)) {
- found = opts->node;
- } else if (!W_ERROR_EQUAL(rv, WERR_NO_MORE_ITEMS)) {
- return rv;
+ search_key = false;
+ } else if (!iterate(&node, opts->search_recursive, &rv)) {
+ beep();
+ return rv;
+ }
+ }
+
+ do {
+ if (search_key) {
+ SMB_ASSERT(opts->search_key == true);
+ if (opts->match(node->name, opts->query)) {
+ found = node;
+ } else if (opts->search_value) {
+ search_key = false;
}
- */
}
- rv = regedit_search_next(regedit);
- if (!W_ERROR_IS_OK(rv)) {
- return rv;
+ if (!search_key) {
+ SMB_ASSERT(opts->search_value == true);
+ if (!vitem) {
+ rv = value_list_load_quick(regedit->vl,
+ node->key);
+ if (!W_ERROR_IS_OK(rv)) {
+ goto out;
+ }
+ need_sync = true;
+ }
+ found_value = find_item(regedit->vl, vitem, opts->query,
+ opts->match);
+ if (found_value) {
+ found = node;
+ } else {
+ vitem = NULL;
+ search_key = opts->search_key;
+ }
}
+ } while (!found && iterate(&node, opts->search_recursive, &rv));
+
+ if (!W_ERROR_IS_OK(rv)) {
+ goto out;
}
if (found) {
print_path(regedit, found);
}
tree_view_set_current_node(regedit->keys, found);
- load_values(regedit);
+ if (found_value) {
+ if (need_sync) {
+ value_list_sync(regedit->vl);
+ }
+ value_list_set_current_item(regedit->vl, found_value);
+ regedit->tree_input = false;
+ } else {
+ load_values(regedit);
+ regedit->tree_input = true;
+ }
tree_view_show(regedit->keys);
value_list_show(regedit->vl);
+ print_heading(regedit);
} else {
+ if (need_sync) {
+ load_values(regedit);
+ value_list_set_current_item_by_name(regedit->vl,
+ save_value_name);
+ }
beep();
}
- return WERR_OK;
+out:
+ talloc_free(save_value_name);
+
+ return rv;
+}
+
+static void regedit_search_repeat(struct regedit *regedit, unsigned flags)
+{
+ struct tree_node *node;
+ struct value_item *vitem;
+ struct regedit_search_opts *opts;
+
+ opts = ®edit->active_search;
+ if (opts->query == NULL) {
+ return;
+ }
+
+ node = tree_view_get_current_node(regedit->keys);
+ vitem = NULL;
+ if (opts->search_value && !regedit->tree_input) {
+ vitem = value_list_get_current_item(regedit->vl);
+ }
+ regedit_search(regedit, node, vitem, flags | SEARCH_REPEAT);
}
static void handle_tree_input(struct regedit *regedit, int c)
tree_view_driver(regedit->keys, ML_CURSOR_UP);
load_values(regedit);
break;
+ case KEY_NPAGE:
+ tree_view_driver(regedit->keys, ML_CURSOR_PGDN);
+ load_values(regedit);
+ break;
+ case KEY_PPAGE:
+ tree_view_driver(regedit->keys, ML_CURSOR_PGUP);
+ load_values(regedit);
+ break;
+ case KEY_HOME:
+ tree_view_driver(regedit->keys, ML_CURSOR_HOME);
+ load_values(regedit);
+ break;
+ case KEY_END:
+ tree_view_driver(regedit->keys, ML_CURSOR_END);
+ load_values(regedit);
+ break;
case '\n':
case KEY_ENTER:
case KEY_RIGHT:
rv = reg_key_del(node, parent->key, node->name);
if (W_ERROR_IS_OK(rv)) {
- tree_node_reopen_key(parent);
+ tree_node_reopen_key(regedit->registry_context,
+ parent);
tree_view_clear(regedit->keys);
pop = tree_node_pop(&node);
talloc_free(pop);
{
struct value_item *vitem;
bool binmode = false;
+ WERROR err;
+ int sel;
switch (c) {
case KEY_DOWN:
case KEY_UP:
value_list_driver(regedit->vl, ML_CURSOR_UP);
break;
+ case KEY_NPAGE:
+ value_list_driver(regedit->vl, ML_CURSOR_PGDN);
+ break;
+ case KEY_PPAGE:
+ value_list_driver(regedit->vl, ML_CURSOR_PGUP);
+ break;
+ case KEY_HOME:
+ value_list_driver(regedit->vl, ML_CURSOR_HOME);
+ break;
+ case KEY_END:
+ value_list_driver(regedit->vl, ML_CURSOR_END);
+ break;
case 'b':
case 'B':
binmode = true;
- /* Falthrough... */
+
+ FALL_THROUGH;
case '\n':
case KEY_ENTER:
vitem = value_list_get_current_item(regedit->vl);
if (vitem) {
struct tree_node *node;
+ const char *name = NULL;
node = tree_view_get_current_node(regedit->keys);
- dialog_edit_value(regedit, node->key, vitem->type,
- vitem, binmode);
- tree_node_reopen_key(node);
- value_list_load(regedit->vl, node->key);
+ sel = dialog_edit_value(regedit, node->key, vitem->type,
+ vitem, binmode, &err, &name);
+ if (!W_ERROR_IS_OK(err)) {
+ const char *msg = get_friendly_werror_msg(err);
+ dialog_notice(regedit, DIA_ALERT, "Error",
+ "Error editing value:\n%s", msg);
+ } else if (sel == DIALOG_OK) {
+ tree_node_reopen_key(regedit->registry_context,
+ node);
+ value_list_load(regedit->vl, node->key);
+ value_list_set_current_item_by_name(regedit->vl,
+ name);
+ talloc_free(discard_const(name));
+ }
}
break;
case 'n':
case 'N': {
int new_type;
- int sel;
sel = dialog_select_type(regedit, &new_type);
if (sel == DIALOG_OK) {
struct tree_node *node;
+ const char *name = NULL;
node = tree_view_get_current_node(regedit->keys);
- dialog_edit_value(regedit, node->key, new_type, NULL,
- false);
- tree_node_reopen_key(node);
- value_list_load(regedit->vl, node->key);
+ sel = dialog_edit_value(regedit, node->key, new_type,
+ NULL, false, &err, &name);
+ if (!W_ERROR_IS_OK(err)) {
+ const char *msg = get_friendly_werror_msg(err);
+ dialog_notice(regedit, DIA_ALERT, "Error",
+ "Error creating value:\n%s", msg);
+ } else if (sel == DIALOG_OK) {
+ tree_node_reopen_key(regedit->registry_context,
+ node);
+ value_list_load(regedit->vl, node->key);
+ value_list_set_current_item_by_name(regedit->vl,
+ name);
+ talloc_free(discard_const(name));
+ }
}
break;
}
case 'D':
vitem = value_list_get_current_item(regedit->vl);
if (vitem) {
- int sel;
-
sel = dialog_notice(regedit, DIA_CONFIRM,
"Delete Value",
"Really delete value \"%s\"?",
node = tree_view_get_current_node(regedit->keys);
reg_del_value(regedit, node->key,
vitem->value_name);
- tree_node_reopen_key(node);
+ tree_node_reopen_key(regedit->registry_context,
+ node);
value_list_load(regedit->vl, node->key);
}
}
case '/': {
int rv;
struct regedit_search_opts *opts;
+ struct tree_node *node;
opts = ®edit->active_search;
- if (opts->query) {
- talloc_free(discard_const(opts->query));
- }
rv = dialog_search_input(regedit, opts);
if (rv == DIALOG_OK) {
SMB_ASSERT(opts->query != NULL);
- opts->match = find_substring;
- opts->node = regedit->keys->root;
- if (opts->search_nocase) {
- opts->match = find_substring_nocase;
+ opts->match = find_substring_nocase;
+ node = regedit->keys->root->child_head;
+ if (opts->search_case) {
+ opts->match = find_substring;
}
- if (opts->search_relative) {
- opts->node =
- tree_view_get_current_node(regedit->keys);
+ if (!opts->search_recursive) {
+ node = tree_view_get_current_node(regedit->keys);
+ node = tree_node_first(node);
}
- regedit_search(regedit);
+ regedit_search(regedit, node, NULL, SEARCH_NEXT);
}
break;
}
case 'x':
+ regedit_search_repeat(regedit, SEARCH_NEXT);
+ break;
case 'X':
- regedit_search(regedit);
+ regedit_search_repeat(regedit, SEARCH_PREV);
break;
case '\t':
regedit->tree_input = !regedit->tree_input;
static void regedit_panic_handler(const char *msg)
{
endwin();
+ smb_panic_log(msg);
smb_panic_s3(msg);
}
handle_main_input(regedit, key);
update_panels();
doupdate();
- } while (key != 'q' || key == 'Q');
+ } while (key != 'q' && key != 'Q');
endwin();
}
};
int opt;
poptContext pc;
- struct user_auth_info *auth_info;
TALLOC_CTX *frame;
struct registry_context *ctx;
WERROR rv;
lp_set_cmdline("log level", "0");
/* process options */
- auth_info = user_auth_info_init(frame);
- if (auth_info == NULL) {
- exit(1);
- }
- popt_common_set_auth_info(auth_info);
pc = poptGetContext("regedit", argc, argv, long_options, 0);
while ((opt = poptGetNextOpt(pc)) != -1) {
/* TODO */
}
- if (!lp_load_global(get_dyn_CONFIGFILE())) {
- DEBUG(0, ("ERROR loading config file...\n"));
- exit(1);
- }
-
- /* some simple tests */
-
rv = reg_open_samba3(frame, &ctx);
if (!W_ERROR_IS_OK(rv)) {
+ fprintf(stderr, "Unable to open registry: %s\n",
+ win_errstr(rv));
TALLOC_FREE(frame);
+ poptFreeContext(pc);
return 1;
}
display_window(frame, ctx);
TALLOC_FREE(frame);
+ poptFreeContext(pc);
return 0;
}