regedit: add a refresh command to clear cache and reload current path
authorChris Davis <cd.rattan@gmail.com>
Tue, 1 Jul 2014 06:14:20 +0000 (23:14 -0700)
committerMichael Adam <obnox@samba.org>
Wed, 1 Oct 2014 12:32:09 +0000 (14:32 +0200)
This is needed to view changes made externally

Signed-off-by: Chris Davis <cd.rattan@gmail.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
source3/utils/regedit.c
source3/utils/regedit_treeview.c
source3/utils/regedit_treeview.h

index 9b8a7ddfc2c9e5c5345f68ecd9b7a47f52969465..c0dbf9069ea90678020c56079442ba87660c6f2c 100644 (file)
@@ -52,6 +52,7 @@
 #define PATH_WIDTH_MAX 1024
 
 struct regedit {
+       struct registry_context *registry_context;
        WINDOW *main_window;
        WINDOW *path_label;
        size_t path_len;
@@ -86,8 +87,7 @@ static void print_path(struct regedit *regedit, struct tree_node *node)
 }
 
 /* load all available hives */
-static struct tree_node *load_hives(TALLOC_CTX *mem_ctx,
-                                   struct registry_context *ctx)
+static struct tree_node *load_hives(struct regedit *regedit)
 {
        const char *hives[] = {
                "HKEY_CLASSES_ROOT",
@@ -110,12 +110,13 @@ static struct tree_node *load_hives(TALLOC_CTX *mem_ctx,
        prev = NULL;
 
        for (i = 0; hives[i] != NULL; ++i) {
-               rv = reg_get_predefined_key_by_name(ctx, hives[i], &key);
+               rv = reg_get_predefined_key_by_name(regedit->registry_context,
+                                                   hives[i], &key);
                if (!W_ERROR_IS_OK(rv)) {
                        continue;
                }
 
-               node = tree_node_new(mem_ctx, NULL, hives[i], key);
+               node = tree_node_new(regedit, NULL, hives[i], key);
                if (node == NULL) {
                        return NULL;
                }
@@ -426,7 +427,7 @@ static void handle_tree_input(struct regedit *regedit, int c)
                                tree_node_reopen_key(parent);
                                tree_view_clear(regedit->keys);
                                pop = tree_node_pop(&node);
-                               tree_node_free_recursive(pop);
+                               talloc_free(pop);
                                node = parent->child_head;
                                if (node == NULL) {
                                        node = tree_node_first(parent);
@@ -530,6 +531,24 @@ static bool find_substring_nocase(const char *haystack, const char *needle)
 static void handle_main_input(struct regedit *regedit, int c)
 {
        switch (c) {
+       case 18: { /* CTRL-R */
+               struct tree_node *root, *node;
+               const char **path;
+
+               node = tree_view_get_current_node(regedit->keys);
+               path = tree_node_get_path(regedit, node);
+
+               root = load_hives(regedit);
+               tree_view_set_root(regedit->keys, root);
+               tree_view_set_path(regedit->keys, path);
+               node = tree_view_get_current_node(regedit->keys);
+               value_list_load(regedit->vl, node->key);
+               tree_view_show(regedit->keys);
+               value_list_show(regedit->vl);
+               print_path(regedit, node);
+               talloc_free(discard_const(path));
+               break;
+       }
        case 'f':
        case 'F':
        case '/': {
@@ -618,6 +637,7 @@ static void display_window(TALLOC_CTX *mem_ctx, struct registry_context *ctx)
        SMB_ASSERT(regedit != NULL);
        regedit_main = regedit;
 
+       regedit->registry_context = ctx;
        regedit->main_window = stdscr;
        keypad(regedit->main_window, TRUE);
 
@@ -627,7 +647,7 @@ static void display_window(TALLOC_CTX *mem_ctx, struct registry_context *ctx)
        wprintw(regedit->path_label, "/");
        show_path(regedit_main);
 
-       root = load_hives(regedit, ctx);
+       root = load_hives(regedit);
        SMB_ASSERT(root != NULL);
 
        regedit->keys = tree_view_new(regedit, root, KEY_HEIGHT, KEY_WIDTH,
index 3af3c8b59cee7d1d7cb6f025a567fc56a11f612d..2f44613e8df9ba3e17738080f0400d123b50df86 100644 (file)
@@ -272,6 +272,44 @@ void tree_view_clear(struct tree_view *view)
        multilist_set_data(view->list, NULL);
 }
 
+WERROR tree_view_set_root(struct tree_view *view, struct tree_node *root)
+{
+       multilist_set_data(view->list, NULL);
+       talloc_free(view->root);
+       view->root = root;
+       return tree_view_update(view, root);
+}
+
+WERROR tree_view_set_path(struct tree_view *view, const char **path)
+{
+       struct tree_node *top, *node;
+       WERROR rv;
+
+       top = view->root;
+       while (*path) {
+               for (node = top; node != NULL; node = node->next) {
+                       if (strcmp(*path, node->name) == 0) {
+                               if (path[1] && tree_node_has_children(node)) {
+                                       rv = tree_node_load_children(node);
+                                       if (!W_ERROR_IS_OK(rv)) {
+                                               return rv;
+                                       }
+                                       SMB_ASSERT(node->child_head);
+                                       top = node->child_head;
+                                       break;
+                               } else {
+                                       tree_view_update(view, top);
+                                       tree_view_set_current_node(view, node);
+                                       return WERR_OK;
+                               }
+                       }
+               }
+               ++path;
+       }
+
+       return WERR_OK;
+}
+
 WERROR tree_view_update(struct tree_view *view, struct tree_node *list)
 {
        WERROR rv;
@@ -476,20 +514,38 @@ void tree_view_resize(struct tree_view *view, int nlines, int ncols,
        tree_view_show(view);
 }
 
-static void print_path_recursive(WINDOW *label, struct tree_node *node,
-                                size_t *len)
+const char **tree_node_get_path(TALLOC_CTX *ctx, struct tree_node *node)
 {
-       if (node->parent)
-               print_path_recursive(label, node->parent, len);
+       const char **array;
+       size_t nitems, index;
+       struct tree_node *p;
 
-       wprintw(label, "%s/", node->name);
-       *len += 1 + strlen(node->name);
+       for (nitems = 0, p = node; p != NULL; p = p->parent) {
+               ++nitems;
+       }
+
+       array = talloc_zero_array(ctx, const char *, nitems + 1);
+       if (array == NULL) {
+               return NULL;
+       }
+
+       for (index = nitems - 1, p = node; p != NULL; p = p->parent, --index) {
+               array[index] = talloc_strdup(array, p->name);
+               if (array[index] == NULL) {
+                       talloc_free(discard_const(array));
+                       return NULL;
+               }
+       }
+
+       return array;
 }
 
 /* print the path of node to label */
 size_t tree_node_print_path(WINDOW *label, struct tree_node *node)
 {
        size_t len = 1;
+       const char **path;
+       TALLOC_CTX *frame;
 
        if (node == NULL)
                return 0;
@@ -497,8 +553,19 @@ size_t tree_node_print_path(WINDOW *label, struct tree_node *node)
        werase(label);
        wprintw(label, "/");
 
-       if (node->parent)
-               print_path_recursive(label, node->parent, &len);
+       if (node->parent == NULL)
+               return 0;
+
+       frame = talloc_stackframe();
+       path = tree_node_get_path(frame, node->parent);
+
+       while (*path) {
+               len += strlen(*path) + 1;
+               wprintw(label, "%s/", *path);
+               ++path;
+       }
+
+       talloc_free(frame);
 
        return len;
 }
index 954bae5ec7a277e3687220f759c85c62e04aa41c..29c5fe2e6552b4f0183e2738e68c4ca48d7823a9 100644 (file)
@@ -55,8 +55,8 @@ struct tree_node *tree_node_pop(struct tree_node **plist);
 struct tree_node *tree_node_first(struct tree_node *list);
 struct tree_node *tree_node_last(struct tree_node *list);
 void tree_node_append_last(struct tree_node *list, struct tree_node *node);
-void tree_node_free_recursive(struct tree_node *list);
 size_t tree_node_print_path(WINDOW *label, struct tree_node *node);
+const char **tree_node_get_path(TALLOC_CTX *ctx, struct tree_node *node);
 struct tree_view *tree_view_new(TALLOC_CTX *ctx, struct tree_node *root,
                                int nlines, int ncols,
                                int begin_y, int begin_x);
@@ -65,6 +65,8 @@ void tree_view_resize(struct tree_view *view, int nlines, int ncols,
                             int begin_y, int begin_x);
 void tree_view_show(struct tree_view *view);
 void tree_view_clear(struct tree_view *view);
+WERROR tree_view_set_root(struct tree_view *view, struct tree_node *root);
+WERROR tree_view_set_path(struct tree_view *view, const char **path);
 WERROR tree_view_update(struct tree_view *view, struct tree_node *list);
 WERROR tree_node_reopen_key(struct tree_node *node);
 bool tree_node_has_children(struct tree_node *node);