regedit: Simplify notice dialogs, don't overwrite existing values.
[Samba/bjacke.git] / source3 / utils / regedit.c
blob7db0cbfe17b2776db319a33d0fbb7a348c09fb0e
1 /*
2 * Samba Unix/Linux SMB client library
3 * Registry Editor
4 * Copyright (C) Christopher Davis 2012
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "popt_common.h"
22 #include "lib/util/data_blob.h"
23 #include "lib/registry/registry.h"
24 #include "regedit.h"
25 #include "regedit_treeview.h"
26 #include "regedit_valuelist.h"
27 #include "regedit_dialog.h"
28 #include <ncurses.h>
29 #include <menu.h>
30 #include <panel.h>
32 struct regedit {
33 WINDOW *main_window;
34 PANEL *main_panel;
35 WINDOW *path_label;
36 WINDOW *key_label;
37 WINDOW *value_label;
38 struct value_list *vl;
39 struct tree_view *keys;
40 bool tree_input;
43 /* load all available hives */
44 static struct tree_node *load_hives(TALLOC_CTX *mem_ctx,
45 struct registry_context *ctx)
47 const char *hives[] = {
48 "HKEY_CLASSES_ROOT",
49 "HKEY_CURRENT_USER",
50 "HKEY_LOCAL_MACHINE",
51 "HKEY_PERFORMANCE_DATA",
52 "HKEY_USERS",
53 "HKEY_CURRENT_CONFIG",
54 "HKEY_DYN_DATA",
55 "HKEY_PERFORMANCE_TEXT",
56 "HKEY_PERFORMANCE_NLSTEXT",
57 NULL
59 struct tree_node *root, *prev, *node;
60 struct registry_key *key;
61 WERROR rv;
62 size_t i;
64 root = NULL;
65 prev = NULL;
67 for (i = 0; hives[i] != NULL; ++i) {
68 rv = reg_get_predefined_key_by_name(ctx, hives[i], &key);
69 if (!W_ERROR_IS_OK(rv)) {
70 continue;
73 node = tree_node_new(mem_ctx, NULL, hives[i], key);
74 if (node == NULL) {
75 return NULL;
78 if (root == NULL) {
79 root = node;
81 if (prev) {
82 tree_node_append(prev, node);
84 prev = node;
87 return root;
90 static void print_heading(WINDOW *win, bool selected, const char *str)
92 if (selected) {
93 wattron(win, A_REVERSE);
94 } else {
95 wattroff(win, A_REVERSE);
97 wmove(win, 0, 0);
98 wclrtoeol(win);
99 waddstr(win, str);
100 wnoutrefresh(win);
101 wrefresh(win);
104 static void handle_tree_input(struct regedit *regedit, int c)
106 struct tree_node *node;
108 switch (c) {
109 case KEY_DOWN:
110 menu_driver(regedit->keys->menu, REQ_DOWN_ITEM);
111 node = item_userptr(current_item(regedit->keys->menu));
112 value_list_load(regedit->vl, node->key);
113 break;
114 case KEY_UP:
115 menu_driver(regedit->keys->menu, REQ_UP_ITEM);
116 node = item_userptr(current_item(regedit->keys->menu));
117 value_list_load(regedit->vl, node->key);
118 break;
119 case '\n':
120 case KEY_ENTER:
121 case KEY_RIGHT:
122 node = item_userptr(current_item(regedit->keys->menu));
123 if (node && tree_node_has_children(node)) {
124 tree_node_load_children(node);
125 tree_node_print_path(regedit->path_label,
126 node->child_head);
127 tree_view_update(regedit->keys, node->child_head);
128 value_list_load(regedit->vl, node->child_head->key);
130 break;
131 case KEY_LEFT:
132 node = item_userptr(current_item(regedit->keys->menu));
133 if (node && node->parent) {
134 tree_node_print_path(regedit->path_label, node->parent);
135 node = tree_node_first(node->parent);
136 tree_view_update(regedit->keys, node);
137 value_list_load(regedit->vl, node->key);
139 break;
140 case 'd':
141 case 'D': {
142 int sel;
144 node = item_userptr(current_item(regedit->keys->menu));
145 sel = dialog_notice(regedit, DIA_CONFIRM,
146 "Delete Key",
147 regedit->main_window,
148 "Really delete key \"%s\"?",
149 node->name);
150 mvwprintw(regedit->main_window, 1, 0, "Sel: %d", sel);
151 /* TODO */
152 break;
156 tree_view_show(regedit->keys);
157 value_list_show(regedit->vl);
160 static void handle_value_input(struct regedit *regedit, int c)
162 struct value_item *vitem;
164 switch (c) {
165 case KEY_DOWN:
166 menu_driver(regedit->vl->menu, REQ_DOWN_ITEM);
167 break;
168 case KEY_UP:
169 menu_driver(regedit->vl->menu, REQ_UP_ITEM);
170 break;
171 case '\n':
172 case KEY_ENTER:
173 vitem = item_userptr(current_item(regedit->vl->menu));
174 if (vitem) {
175 struct tree_node *node;
176 node = item_userptr(current_item(regedit->keys->menu));
177 dialog_edit_value(regedit, node->key, vitem->type,
178 vitem, regedit->main_window);
179 value_list_load(regedit->vl, node->key);
181 break;
182 case 'n':
183 case 'N': {
184 int new_type;
185 int sel;
187 sel = dialog_select_type(regedit, &new_type,
188 regedit->main_window);
189 if (sel == DIALOG_OK) {
190 struct tree_node *node;
191 node = item_userptr(current_item(regedit->keys->menu));
192 dialog_edit_value(regedit, node->key, new_type, NULL,
193 regedit->main_window);
194 value_list_load(regedit->vl, node->key);
196 break;
198 case 'd':
199 case 'D':
200 vitem = item_userptr(current_item(regedit->vl->menu));
201 if (vitem) {
202 int sel;
204 sel = dialog_notice(regedit, DIA_CONFIRM,
205 "Delete Value",
206 regedit->main_window,
207 "Really delete value \"%s\"?",
208 vitem->value_name);
209 if (sel == DIALOG_OK) {
210 ITEM *it = current_item(regedit->keys->menu);
211 struct tree_node *node = item_userptr(it);
212 reg_del_value(regedit, node->key,
213 vitem->value_name);
214 value_list_load(regedit->vl, node->key);
219 break;
222 value_list_show(regedit->vl);
225 static void handle_main_input(struct regedit *regedit, int c)
227 switch (c) {
228 case '\t':
229 regedit->tree_input = !regedit->tree_input;
230 print_heading(regedit->key_label, regedit->tree_input == true,
231 "Keys");
232 print_heading(regedit->value_label, regedit->tree_input == false,
233 "Values");
234 break;
235 default:
236 if (regedit->tree_input) {
237 handle_tree_input(regedit, c);
238 } else {
239 handle_value_input(regedit, c);
244 /* test navigating available hives */
245 static void display_test_window(TALLOC_CTX *mem_ctx,
246 struct registry_context *ctx)
248 struct regedit *regedit;
249 struct tree_node *root;
250 int c;
252 initscr();
253 start_color();
254 cbreak();
255 noecho();
256 keypad(stdscr, TRUE);
258 regedit = talloc_zero(mem_ctx, struct regedit);
259 SMB_ASSERT(regedit != NULL);
261 regedit->main_window = newwin(25, 80, 0, 0);
262 SMB_ASSERT(regedit->main_window != NULL);
264 keypad(regedit->main_window, TRUE);
266 mvwprintw(regedit->main_window, 0, 0, "Path: ");
267 regedit->path_label = derwin(regedit->main_window, 1, 65, 0, 6);
268 wprintw(regedit->path_label, "/");
270 root = load_hives(regedit, ctx);
271 SMB_ASSERT(root != NULL);
273 regedit->key_label = derwin(regedit->main_window, 1, 10, 2, 0);
274 regedit->value_label = derwin(regedit->main_window, 1, 10, 2, 25);
276 print_heading(regedit->key_label, true, "Keys");
277 regedit->keys = tree_view_new(regedit, root, regedit->main_window,
278 15, 24, 3, 0);
279 SMB_ASSERT(regedit->keys != NULL);
281 print_heading(regedit->value_label, false, "Values");
282 regedit->vl = value_list_new(regedit, regedit->main_window,
283 15, 40, 3, 25);
284 SMB_ASSERT(regedit->vl != NULL);
286 regedit->tree_input = true;
288 tree_view_show(regedit->keys);
289 value_list_show(regedit->vl);
291 regedit->main_panel = new_panel(regedit->main_window);
292 SMB_ASSERT(regedit->main_panel != NULL);
294 update_panels();
295 doupdate();
296 while ((c = wgetch(regedit->main_window)) != 'q') {
297 handle_main_input(regedit, c);
298 update_panels();
299 doupdate();
302 endwin();
305 int main(int argc, char **argv)
307 struct poptOption long_options[] = {
308 POPT_AUTOHELP
309 /* ... */
310 POPT_COMMON_SAMBA
311 POPT_COMMON_CONNECTION
312 POPT_COMMON_CREDENTIALS
313 POPT_TABLEEND
315 int opt;
316 poptContext pc;
317 struct user_auth_info *auth_info;
318 TALLOC_CTX *frame;
319 struct registry_context *ctx;
320 WERROR rv;
322 talloc_enable_leak_report_full();
324 frame = talloc_stackframe();
326 setup_logging("regedit", DEBUG_DEFAULT_STDERR);
327 lp_set_cmdline("log level", "0");
329 /* process options */
330 auth_info = user_auth_info_init(frame);
331 if (auth_info == NULL) {
332 exit(1);
334 popt_common_set_auth_info(auth_info);
335 pc = poptGetContext("regedit", argc, (const char **)argv, long_options, 0);
337 while ((opt = poptGetNextOpt(pc)) != -1) {
338 /* TODO */
341 if (!lp_load_global(get_dyn_CONFIGFILE())) {
342 DEBUG(0, ("ERROR loading config file...\n"));
343 exit(1);
346 /* some simple tests */
348 rv = reg_open_samba3(frame, &ctx);
349 if (!W_ERROR_IS_OK(rv)) {
350 TALLOC_FREE(frame);
352 return 1;
355 display_test_window(frame, ctx);
357 //talloc_report_full(frame, stdout);
359 TALLOC_FREE(frame);
361 return 0;