-rw-r--r-- | scripts/kconfig/mconf.c | 711 |
1 files changed, 711 insertions, 0 deletions
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c new file mode 100644 index 0000000..84699be --- a/dev/null +++ b/scripts/kconfig/mconf.c | |||
@@ -0,0 +1,711 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||
3 | * Released under the terms of the GNU GPL v2.0. | ||
4 | */ | ||
5 | |||
6 | #include <sys/ioctl.h> | ||
7 | #include <sys/wait.h> | ||
8 | #include <ctype.h> | ||
9 | #include <errno.h> | ||
10 | #include <fcntl.h> | ||
11 | #include <signal.h> | ||
12 | #include <stdarg.h> | ||
13 | #include <stdlib.h> | ||
14 | #include <string.h> | ||
15 | #include <unistd.h> | ||
16 | |||
17 | #define LKC_DIRECT_LINK | ||
18 | #include "lkc.h" | ||
19 | |||
20 | static char menu_backtitle[128]; | ||
21 | static const char menu_instructions[] = | ||
22 | "Arrow keys navigate the menu. " | ||
23 | "<Enter> selects submenus --->. " | ||
24 | "Highlighted letters are hotkeys. " | ||
25 | "Pressing <Y> includes, <N> excludes, <M> modularizes features. " | ||
26 | "Press <Esc><Esc> to exit, <?> for Help. " | ||
27 | "Legend: [*] built-in [ ] excluded <M> module < > module capable", | ||
28 | radiolist_instructions[] = | ||
29 | "Use the arrow keys to navigate this window or " | ||
30 | "press the hotkey of the item you wish to select " | ||
31 | "followed by the <SPACE BAR>. " | ||
32 | "Press <?> for additional information about this option.", | ||
33 | inputbox_instructions_int[] = | ||
34 | "Please enter a decimal value. " | ||
35 | "Fractions will not be accepted. " | ||
36 | "Use the <TAB> key to move from the input field to the buttons below it.", | ||
37 | inputbox_instructions_hex[] = | ||
38 | "Please enter a hexadecimal value. " | ||
39 | "Use the <TAB> key to move from the input field to the buttons below it.", | ||
40 | inputbox_instructions_string[] = | ||
41 | "Please enter a string value. " | ||
42 | "Use the <TAB> key to move from the input field to the buttons below it.", | ||
43 | setmod_text[] = | ||
44 | "This feature depends on another which has been configured as a module.\n" | ||
45 | "As a result, this feature will be built as a module.", | ||
46 | nohelp_text[] = | ||
47 | "There is no help available for this kernel option.\n", | ||
48 | load_config_text[] = | ||
49 | "Enter the name of the configuration file you wish to load. " | ||
50 | "Accept the name shown to restore the configuration you " | ||
51 | "last retrieved. Leave blank to abort.", | ||
52 | load_config_help[] = | ||
53 | "\n" | ||
54 | "For various reasons, one may wish to keep several different kernel\n" | ||
55 | "configurations available on a single machine.\n" | ||
56 | "\n" | ||
57 | "If you have saved a previous configuration in a file other than the\n" | ||
58 | "kernel's default, entering the name of the file here will allow you\n" | ||
59 | "to modify that configuration.\n" | ||
60 | "\n" | ||
61 | "If you are uncertain, then you have probably never used alternate\n" | ||
62 | "configuration files. You should therefor leave this blank to abort.\n", | ||
63 | save_config_text[] = | ||
64 | "Enter a filename to which this configuration should be saved " | ||
65 | "as an alternate. Leave blank to abort.", | ||
66 | save_config_help[] = | ||
67 | "\n" | ||
68 | "For various reasons, one may wish to keep different kernel\n" | ||
69 | "configurations available on a single machine.\n" | ||
70 | "\n" | ||
71 | "Entering a file name here will allow you to later retrieve, modify\n" | ||
72 | "and use the current configuration as an alternate to whatever\n" | ||
73 | "configuration options you have selected at that time.\n" | ||
74 | "\n" | ||
75 | "If you are uncertain what all this means then you should probably\n" | ||
76 | "leave this blank.\n" | ||
77 | ; | ||
78 | |||
79 | static char buf[4096], *bufptr = buf; | ||
80 | static char input_buf[4096]; | ||
81 | static char *args[1024], **argptr = args; | ||
82 | static int indent = 0; | ||
83 | static int rows, cols; | ||
84 | static struct menu *current_menu; | ||
85 | static int child_count; | ||
86 | static int do_resize; | ||
87 | |||
88 | static void conf(struct menu *menu); | ||
89 | static void conf_choice(struct menu *menu); | ||
90 | static void conf_string(struct menu *menu); | ||
91 | static void conf_load(void); | ||
92 | static void conf_save(void); | ||
93 | static void show_textbox(const char *title, const char *text, int r, int c); | ||
94 | static void show_helptext(const char *title, const char *text); | ||
95 | static void show_help(struct menu *menu); | ||
96 | static void show_readme(void); | ||
97 | |||
98 | static void cprint_init(void); | ||
99 | static int cprint1(const char *fmt, ...); | ||
100 | static void cprint_done(void); | ||
101 | static int cprint(const char *fmt, ...); | ||
102 | |||
103 | static void init_wsize(void) | ||
104 | { | ||
105 | struct winsize ws; | ||
106 | |||
107 | if (ioctl(1, TIOCGWINSZ, &ws) == -1) { | ||
108 | rows = 24; | ||
109 | cols = 80; | ||
110 | } else { | ||
111 | rows = ws.ws_row; | ||
112 | cols = ws.ws_col; | ||
113 | } | ||
114 | |||
115 | if (rows < 19 || cols < 80) { | ||
116 | fprintf(stderr, "Your display is too small to run Menuconfig!\n"); | ||
117 | fprintf(stderr, "It must be at least 19 lines by 80 columns.\n"); | ||
118 | exit(1); | ||
119 | } | ||
120 | |||
121 | rows -= 4; | ||
122 | cols -= 5; | ||
123 | } | ||
124 | |||
125 | static void cprint_init(void) | ||
126 | { | ||
127 | bufptr = buf; | ||
128 | argptr = args; | ||
129 | memset(args, 0, sizeof(args)); | ||
130 | indent = 0; | ||
131 | child_count = 0; | ||
132 | cprint("./scripts/lxdialog/lxdialog"); | ||
133 | cprint("--backtitle"); | ||
134 | cprint(menu_backtitle); | ||
135 | } | ||
136 | |||
137 | static int cprint1(const char *fmt, ...) | ||
138 | { | ||
139 | va_list ap; | ||
140 | int res; | ||
141 | |||
142 | if (!*argptr) | ||
143 | *argptr = bufptr; | ||
144 | va_start(ap, fmt); | ||
145 | res = vsprintf(bufptr, fmt, ap); | ||
146 | va_end(ap); | ||
147 | bufptr += res; | ||
148 | |||
149 | return res; | ||
150 | } | ||
151 | |||
152 | static void cprint_done(void) | ||
153 | { | ||
154 | *bufptr++ = 0; | ||
155 | argptr++; | ||
156 | } | ||
157 | |||
158 | static int cprint(const char *fmt, ...) | ||
159 | { | ||
160 | va_list ap; | ||
161 | int res; | ||
162 | |||
163 | *argptr++ = bufptr; | ||
164 | va_start(ap, fmt); | ||
165 | res = vsprintf(bufptr, fmt, ap); | ||
166 | va_end(ap); | ||
167 | bufptr += res; | ||
168 | *bufptr++ = 0; | ||
169 | |||
170 | return res; | ||
171 | } | ||
172 | |||
173 | pid_t pid; | ||
174 | |||
175 | static void winch_handler(int sig) | ||
176 | { | ||
177 | if (!do_resize) { | ||
178 | kill(pid, SIGINT); | ||
179 | do_resize = 1; | ||
180 | } | ||
181 | } | ||
182 | |||
183 | static int exec_conf(void) | ||
184 | { | ||
185 | int pipefd[2], stat, size; | ||
186 | struct sigaction sa; | ||
187 | sigset_t sset, osset; | ||
188 | |||
189 | sigemptyset(&sset); | ||
190 | sigaddset(&sset, SIGINT); | ||
191 | sigprocmask(SIG_BLOCK, &sset, &osset); | ||
192 | |||
193 | signal(SIGINT, SIG_DFL); | ||
194 | |||
195 | sa.sa_handler = winch_handler; | ||
196 | sigemptyset(&sa.sa_mask); | ||
197 | sa.sa_flags = SA_RESTART; | ||
198 | sigaction(SIGWINCH, &sa, NULL); | ||
199 | |||
200 | *argptr++ = NULL; | ||
201 | |||
202 | pipe(pipefd); | ||
203 | pid = fork(); | ||
204 | if (pid == 0) { | ||
205 | sigprocmask(SIG_SETMASK, &osset, NULL); | ||
206 | dup2(pipefd[1], 2); | ||
207 | close(pipefd[0]); | ||
208 | close(pipefd[1]); | ||
209 | execv(args[0], args); | ||
210 | _exit(EXIT_FAILURE); | ||
211 | } | ||
212 | |||
213 | close(pipefd[1]); | ||
214 | bufptr = input_buf; | ||
215 | while (1) { | ||
216 | size = input_buf + sizeof(input_buf) - bufptr; | ||
217 | size = read(pipefd[0], bufptr, size); | ||
218 | if (size <= 0) { | ||
219 | if (size < 0) { | ||
220 | if (errno == EINTR || errno == EAGAIN) | ||
221 | continue; | ||
222 | perror("read"); | ||
223 | } | ||
224 | break; | ||
225 | } | ||
226 | bufptr += size; | ||
227 | } | ||
228 | *bufptr++ = 0; | ||
229 | close(pipefd[0]); | ||
230 | waitpid(pid, &stat, 0); | ||
231 | |||
232 | if (do_resize) { | ||
233 | init_wsize(); | ||
234 | do_resize = 0; | ||
235 | sigprocmask(SIG_SETMASK, &osset, NULL); | ||
236 | return -1; | ||
237 | } | ||
238 | if (WIFSIGNALED(stat)) { | ||
239 | printf("\finterrupted(%d)\n", WTERMSIG(stat)); | ||
240 | exit(1); | ||
241 | } | ||
242 | #if 0 | ||
243 | printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat), input_buf); | ||
244 | sleep(1); | ||
245 | #endif | ||
246 | sigpending(&sset); | ||
247 | if (sigismember(&sset, SIGINT)) { | ||
248 | printf("\finterrupted\n"); | ||
249 | exit(1); | ||
250 | } | ||
251 | sigprocmask(SIG_SETMASK, &osset, NULL); | ||
252 | |||
253 | return WEXITSTATUS(stat); | ||
254 | } | ||
255 | |||
256 | static void build_conf(struct menu *menu) | ||
257 | { | ||
258 | struct symbol *sym; | ||
259 | struct property *prop; | ||
260 | struct menu *child; | ||
261 | int type, tmp, doint = 2; | ||
262 | tristate val; | ||
263 | char ch; | ||
264 | |||
265 | if (!menu_is_visible(menu)) | ||
266 | return; | ||
267 | |||
268 | sym = menu->sym; | ||
269 | prop = menu->prompt; | ||
270 | if (!sym) { | ||
271 | if (prop && menu != current_menu) { | ||
272 | const char *prompt = menu_get_prompt(menu); | ||
273 | switch (prop->type) { | ||
274 | case P_MENU: | ||
275 | child_count++; | ||
276 | cprint("m%p", menu); | ||
277 | if (menu->parent != &rootmenu) | ||
278 | cprint1(" %*c", indent + 1, ' '); | ||
279 | cprint1("%s --->", prompt); | ||
280 | cprint_done(); | ||
281 | return; | ||
282 | default: | ||
283 | if (prompt) { | ||
284 | child_count++; | ||
285 | cprint(":%p", menu); | ||
286 | cprint("---%*c%s", indent + 1, ' ', prompt); | ||
287 | } | ||
288 | } | ||
289 | } else | ||
290 | doint = 0; | ||
291 | goto conf_childs; | ||
292 | } | ||
293 | |||
294 | type = sym_get_type(sym); | ||
295 | if (sym_is_choice(sym)) { | ||
296 | struct symbol *def_sym = sym_get_choice_value(sym); | ||
297 | struct menu *def_menu = NULL; | ||
298 | |||
299 | child_count++; | ||
300 | for (child = menu->list; child; child = child->next) { | ||
301 | if (menu_is_visible(child) && child->sym == def_sym) | ||
302 | def_menu = child; | ||
303 | } | ||
304 | |||
305 | val = sym_get_tristate_value(sym); | ||
306 | if (sym_is_changable(sym)) { | ||
307 | cprint("t%p", menu); | ||
308 | switch (type) { | ||
309 | case S_BOOLEAN: | ||
310 | cprint1("[%c]", val == no ? ' ' : '*'); | ||
311 | break; | ||
312 | case S_TRISTATE: | ||
313 | switch (val) { | ||
314 | case yes: ch = '*'; break; | ||
315 | case mod: ch = 'M'; break; | ||
316 | default: ch = ' '; break; | ||
317 | } | ||
318 | cprint1("<%c>", ch); | ||
319 | break; | ||
320 | } | ||
321 | } else { | ||
322 | cprint("%c%p", def_menu ? 't' : ':', menu); | ||
323 | cprint1(" "); | ||
324 | } | ||
325 | |||
326 | cprint1("%*c%s", indent + 1, ' ', menu_get_prompt(menu)); | ||
327 | if (val == yes) { | ||
328 | if (def_menu) { | ||
329 | cprint1(" (%s)", menu_get_prompt(def_menu)); | ||
330 | cprint1(" --->"); | ||
331 | cprint_done(); | ||
332 | if (def_menu->list) { | ||
333 | indent += 2; | ||
334 | build_conf(def_menu); | ||
335 | indent -= 2; | ||
336 | } | ||
337 | } else | ||
338 | cprint_done(); | ||
339 | return; | ||
340 | } | ||
341 | cprint_done(); | ||
342 | } else { | ||
343 | child_count++; | ||
344 | val = sym_get_tristate_value(sym); | ||
345 | if (sym_is_choice_value(sym) && val == yes) { | ||
346 | cprint(":%p", menu); | ||
347 | cprint1(" "); | ||
348 | } else { | ||
349 | switch (type) { | ||
350 | case S_BOOLEAN: | ||
351 | cprint("t%p", menu); | ||
352 | cprint1("[%c]", val == no ? ' ' : '*'); | ||
353 | break; | ||
354 | case S_TRISTATE: | ||
355 | cprint("t%p", menu); | ||
356 | switch (val) { | ||
357 | case yes: ch = '*'; break; | ||
358 | case mod: ch = 'M'; break; | ||
359 | default: ch = ' '; break; | ||
360 | } | ||
361 | cprint1("<%c>", ch); | ||
362 | break; | ||
363 | default: | ||
364 | cprint("s%p", menu); | ||
365 | tmp = cprint1("(%s)", sym_get_string_value(sym)); | ||
366 | tmp = indent - tmp + 4; | ||
367 | if (tmp < 0) | ||
368 | tmp = 0; | ||
369 | cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu), | ||
370 | sym_has_value(sym) ? "" : " (NEW)"); | ||
371 | cprint_done(); | ||
372 | goto conf_childs; | ||
373 | } | ||
374 | } | ||
375 | cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), | ||
376 | sym_has_value(sym) ? "" : " (NEW)"); | ||
377 | cprint_done(); | ||
378 | } | ||
379 | |||
380 | conf_childs: | ||
381 | indent += doint; | ||
382 | for (child = menu->list; child; child = child->next) | ||
383 | build_conf(child); | ||
384 | indent -= doint; | ||
385 | } | ||
386 | |||
387 | static void conf(struct menu *menu) | ||
388 | { | ||
389 | struct menu *submenu; | ||
390 | const char *prompt = menu_get_prompt(menu); | ||
391 | struct symbol *sym; | ||
392 | char active_entry[40]; | ||
393 | int stat, type, i; | ||
394 | |||
395 | active_entry[0] = 0; | ||
396 | while (1) { | ||
397 | cprint_init(); | ||
398 | cprint("--title"); | ||
399 | cprint("%s", prompt ? prompt : "Main Menu"); | ||
400 | cprint("--menu"); | ||
401 | cprint(menu_instructions); | ||
402 | cprint("%d", rows); | ||
403 | cprint("%d", cols); | ||
404 | cprint("%d", rows - 10); | ||
405 | cprint("%s", active_entry); | ||
406 | current_menu = menu; | ||
407 | build_conf(menu); | ||
408 | if (!child_count) | ||
409 | break; | ||
410 | if (menu == &rootmenu) { | ||
411 | cprint(":"); | ||
412 | cprint("--- "); | ||
413 | cprint("L"); | ||
414 | cprint("Load an Alternate Configuration File"); | ||
415 | cprint("S"); | ||
416 | cprint("Save Configuration to an Alternate File"); | ||
417 | } | ||
418 | stat = exec_conf(); | ||
419 | if (stat < 0) | ||
420 | continue; | ||
421 | |||
422 | if (stat == 1 || stat == 255) | ||
423 | break; | ||
424 | |||
425 | type = input_buf[0]; | ||
426 | if (!type) | ||
427 | continue; | ||
428 | |||
429 | for (i = 0; input_buf[i] && !isspace(input_buf[i]); i++) | ||
430 | ; | ||
431 | if (i >= sizeof(active_entry)) | ||
432 | i = sizeof(active_entry) - 1; | ||
433 | input_buf[i] = 0; | ||
434 | strcpy(active_entry, input_buf); | ||
435 | |||
436 | sym = NULL; | ||
437 | submenu = NULL; | ||
438 | if (sscanf(input_buf + 1, "%p", &submenu) == 1) | ||
439 | sym = submenu->sym; | ||
440 | |||
441 | switch (stat) { | ||
442 | case 0: | ||
443 | switch (type) { | ||
444 | case 'm': | ||
445 | conf(submenu); | ||
446 | break; | ||
447 | case 't': | ||
448 | if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes) | ||
449 | conf_choice(submenu); | ||
450 | break; | ||
451 | case 's': | ||
452 | conf_string(submenu); | ||
453 | break; | ||
454 | case 'L': | ||
455 | conf_load(); | ||
456 | break; | ||
457 | case 'S': | ||
458 | conf_save(); | ||
459 | break; | ||
460 | } | ||
461 | break; | ||
462 | case 2: | ||
463 | if (sym) | ||
464 | show_help(submenu); | ||
465 | else | ||
466 | show_readme(); | ||
467 | break; | ||
468 | case 3: | ||
469 | if (type == 't') { | ||
470 | if (sym_set_tristate_value(sym, yes)) | ||
471 | break; | ||
472 | if (sym_set_tristate_value(sym, mod)) | ||
473 | show_textbox(NULL, setmod_text, 6, 74); | ||
474 | } | ||
475 | break; | ||
476 | case 4: | ||
477 | if (type == 't') | ||
478 | sym_set_tristate_value(sym, no); | ||
479 | break; | ||
480 | case 5: | ||
481 | if (type == 't') | ||
482 | sym_set_tristate_value(sym, mod); | ||
483 | break; | ||
484 | case 6: | ||
485 | if (type == 't') | ||
486 | sym_toggle_tristate_value(sym); | ||
487 | break; | ||
488 | } | ||
489 | } | ||
490 | } | ||
491 | |||
492 | static void show_textbox(const char *title, const char *text, int r, int c) | ||
493 | { | ||
494 | int fd; | ||
495 | |||
496 | fd = creat(".help.tmp", 0777); | ||
497 | write(fd, text, strlen(text)); | ||
498 | close(fd); | ||
499 | do { | ||
500 | cprint_init(); | ||
501 | if (title) { | ||
502 | cprint("--title"); | ||
503 | cprint("%s", title); | ||
504 | } | ||
505 | cprint("--textbox"); | ||
506 | cprint(".help.tmp"); | ||
507 | cprint("%d", r); | ||
508 | cprint("%d", c); | ||
509 | } while (exec_conf() < 0); | ||
510 | unlink(".help.tmp"); | ||
511 | } | ||
512 | |||
513 | static void show_helptext(const char *title, const char *text) | ||
514 | { | ||
515 | show_textbox(title, text, rows, cols); | ||
516 | } | ||
517 | |||
518 | static void show_help(struct menu *menu) | ||
519 | { | ||
520 | const char *help; | ||
521 | |||
522 | help = menu->sym->help; | ||
523 | if (!help) | ||
524 | help = nohelp_text; | ||
525 | show_helptext(menu_get_prompt(menu), help); | ||
526 | } | ||
527 | |||
528 | static void show_readme(void) | ||
529 | { | ||
530 | do { | ||
531 | cprint_init(); | ||
532 | cprint("--textbox"); | ||
533 | cprint("scripts/README.Menuconfig"); | ||
534 | cprint("%d", rows); | ||
535 | cprint("%d", cols); | ||
536 | } while (exec_conf() == -1); | ||
537 | } | ||
538 | |||
539 | static void conf_choice(struct menu *menu) | ||
540 | { | ||
541 | const char *prompt = menu_get_prompt(menu); | ||
542 | struct menu *child; | ||
543 | struct symbol *active; | ||
544 | int stat; | ||
545 | |||
546 | while (1) { | ||
547 | cprint_init(); | ||
548 | cprint("--title"); | ||
549 | cprint("%s", prompt ? prompt : "Main Menu"); | ||
550 | cprint("--radiolist"); | ||
551 | cprint(radiolist_instructions); | ||
552 | cprint("15"); | ||
553 | cprint("70"); | ||
554 | cprint("6"); | ||
555 | |||
556 | current_menu = menu; | ||
557 | active = sym_get_choice_value(menu->sym); | ||
558 | for (child = menu->list; child; child = child->next) { | ||
559 | if (!menu_is_visible(child)) | ||
560 | continue; | ||
561 | cprint("%p", child); | ||
562 | cprint("%s", menu_get_prompt(child)); | ||
563 | cprint(child->sym == active ? "ON" : "OFF"); | ||
564 | } | ||
565 | |||
566 | stat = exec_conf(); | ||
567 | switch (stat) { | ||
568 | case 0: | ||
569 | if (sscanf(input_buf, "%p", &menu) != 1) | ||
570 | break; | ||
571 | sym_set_tristate_value(menu->sym, yes); | ||
572 | return; | ||
573 | case 1: | ||
574 | show_help(menu); | ||
575 | break; | ||
576 | case 255: | ||
577 | return; | ||
578 | } | ||
579 | } | ||
580 | } | ||
581 | |||
582 | static void conf_string(struct menu *menu) | ||
583 | { | ||
584 | const char *prompt = menu_get_prompt(menu); | ||
585 | int stat; | ||
586 | |||
587 | while (1) { | ||
588 | cprint_init(); | ||
589 | cprint("--title"); | ||
590 | cprint("%s", prompt ? prompt : "Main Menu"); | ||
591 | cprint("--inputbox"); | ||
592 | switch (sym_get_type(menu->sym)) { | ||
593 | case S_INT: | ||
594 | cprint(inputbox_instructions_int); | ||
595 | break; | ||
596 | case S_HEX: | ||
597 | cprint(inputbox_instructions_hex); | ||
598 | break; | ||
599 | case S_STRING: | ||
600 | cprint(inputbox_instructions_string); | ||
601 | break; | ||
602 | default: | ||
603 | /* panic? */; | ||
604 | } | ||
605 | cprint("10"); | ||
606 | cprint("75"); | ||
607 | cprint("%s", sym_get_string_value(menu->sym)); | ||
608 | stat = exec_conf(); | ||
609 | switch (stat) { | ||
610 | case 0: | ||
611 | if (sym_set_string_value(menu->sym, input_buf)) | ||
612 | return; | ||
613 | show_textbox(NULL, "You have made an invalid entry.", 5, 43); | ||
614 | break; | ||
615 | case 1: | ||
616 | show_help(menu); | ||
617 | break; | ||
618 | case 255: | ||
619 | return; | ||
620 | } | ||
621 | } | ||
622 | } | ||
623 | |||
624 | static void conf_load(void) | ||
625 | { | ||
626 | int stat; | ||
627 | |||
628 | while (1) { | ||
629 | cprint_init(); | ||
630 | cprint("--inputbox"); | ||
631 | cprint(load_config_text); | ||
632 | cprint("11"); | ||
633 | cprint("55"); | ||
634 | cprint("%s", conf_filename); | ||
635 | stat = exec_conf(); | ||
636 | switch(stat) { | ||
637 | case 0: | ||
638 | if (!input_buf[0]) | ||
639 | return; | ||
640 | if (!conf_read(input_buf)) | ||
641 | return; | ||
642 | show_textbox(NULL, "File does not exist!", 5, 38); | ||
643 | break; | ||
644 | case 1: | ||
645 | show_helptext("Load Alternate Configuration", load_config_help); | ||
646 | break; | ||
647 | case 255: | ||
648 | return; | ||
649 | } | ||
650 | } | ||
651 | } | ||
652 | |||
653 | static void conf_save(void) | ||
654 | { | ||
655 | int stat; | ||
656 | |||
657 | while (1) { | ||
658 | cprint_init(); | ||
659 | cprint("--inputbox"); | ||
660 | cprint(save_config_text); | ||
661 | cprint("11"); | ||
662 | cprint("55"); | ||
663 | cprint("%s", conf_filename); | ||
664 | stat = exec_conf(); | ||
665 | switch(stat) { | ||
666 | case 0: | ||
667 | if (!input_buf[0]) | ||
668 | return; | ||
669 | if (!conf_write(input_buf)) | ||
670 | return; | ||
671 | show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60); | ||
672 | break; | ||
673 | case 1: | ||
674 | show_helptext("Save Alternate Configuration", save_config_help); | ||
675 | break; | ||
676 | case 255: | ||
677 | return; | ||
678 | } | ||
679 | } | ||
680 | } | ||
681 | |||
682 | int main(int ac, char **av) | ||
683 | { | ||
684 | int stat; | ||
685 | conf_parse(av[1]); | ||
686 | conf_read(NULL); | ||
687 | |||
688 | sprintf(menu_backtitle, "Configuration"); | ||
689 | |||
690 | init_wsize(); | ||
691 | conf(&rootmenu); | ||
692 | |||
693 | do { | ||
694 | cprint_init(); | ||
695 | cprint("--yesno"); | ||
696 | cprint("Do you wish to save your new configuration?"); | ||
697 | cprint("5"); | ||
698 | cprint("60"); | ||
699 | stat = exec_conf(); | ||
700 | } while (stat < 0); | ||
701 | |||
702 | if (stat == 0) { | ||
703 | conf_write(NULL); | ||
704 | printf("\n\n" | ||
705 | "*** End of configuration.\n" | ||
706 | "*** Check the top-level Makefile for additional configuration.\n"); | ||
707 | } else | ||
708 | printf("\n\nYour configuration changes were NOT saved.\n\n"); | ||
709 | |||
710 | return 0; | ||
711 | } | ||