source: MondoRescue/branches/stable/mindi-busybox/scripts/config/conf.c @ 821

Last change on this file since 821 was 821, checked in by Bruno Cornec, 13 years ago

Addition of busybox 1.2.1 as a mindi-busybox new package
This should avoid delivering binary files in mindi not built there (Fedora and Debian are quite serious about that)

File size: 10.5 KB
Line 
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 <ctype.h>
7#include <stdlib.h>
8#include <string.h>
9#include <unistd.h>
10#include <time.h>
11#include <sys/stat.h>
12
13#define LKC_DIRECT_LINK
14#include "lkc.h"
15
16static void conf(struct menu *menu);
17static void check_conf(struct menu *menu);
18
19enum {
20    ask_all,
21    ask_new,
22    ask_silent,
23    set_default,
24    set_yes,
25    set_mod,
26    set_no,
27    set_random
28} input_mode = ask_all;
29char *defconfig_file;
30
31static int indent = 1;
32static int valid_stdin = 1;
33static int conf_cnt;
34static char line[128];
35static struct menu *rootEntry;
36
37static char nohelp_text[] = "Sorry, no help available for this option yet.\n";
38
39static void strip(char *str)
40{
41    char *p = str;
42    int l;
43
44    while ((isspace(*p)))
45        p++;
46    l = strlen(p);
47    if (p != str)
48        memmove(str, p, l + 1);
49    if (!l)
50        return;
51    p = str + l - 1;
52    while ((isspace(*p)))
53        *p-- = 0;
54}
55
56static void check_stdin(void)
57{
58    if (!valid_stdin && input_mode == ask_silent) {
59        printf("aborted!\n\n");
60        printf("Console input/output is redirected. ");
61        printf("Run 'make oldconfig' to update configuration.\n\n");
62        exit(1);
63    }
64}
65
66static void conf_askvalue(struct symbol *sym, const char *def)
67{
68    enum symbol_type type = sym_get_type(sym);
69    tristate val;
70
71    if (!sym_has_value(sym))
72        printf("(NEW) ");
73
74    line[0] = '\n';
75    line[1] = 0;
76
77    if (!sym_is_changable(sym)) {
78        printf("%s\n", def);
79        line[0] = '\n';
80        line[1] = 0;
81        return;
82    }
83
84    switch (input_mode) {
85    case ask_new:
86    case ask_silent:
87        if (sym_has_value(sym)) {
88            printf("%s\n", def);
89            return;
90        }
91        check_stdin();
92    case ask_all:
93        fflush(stdout);
94        fgets(line, 128, stdin);
95        return;
96    case set_default:
97        printf("%s\n", def);
98        return;
99    default:
100        break;
101    }
102
103    switch (type) {
104    case S_INT:
105    case S_HEX:
106    case S_STRING:
107        printf("%s\n", def);
108        return;
109    default:
110        ;
111    }
112    switch (input_mode) {
113    case set_yes:
114        if (sym_tristate_within_range(sym, yes)) {
115            line[0] = 'y';
116            line[1] = '\n';
117            line[2] = 0;
118            break;
119        }
120    case set_mod:
121        if (type == S_TRISTATE) {
122            if (sym_tristate_within_range(sym, mod)) {
123                line[0] = 'm';
124                line[1] = '\n';
125                line[2] = 0;
126                break;
127            }
128        } else {
129            if (sym_tristate_within_range(sym, yes)) {
130                line[0] = 'y';
131                line[1] = '\n';
132                line[2] = 0;
133                break;
134            }
135        }
136    case set_no:
137        if (sym_tristate_within_range(sym, no)) {
138            line[0] = 'n';
139            line[1] = '\n';
140            line[2] = 0;
141            break;
142        }
143    case set_random:
144        do {
145            val = (tristate)(random() % 3);
146        } while (!sym_tristate_within_range(sym, val));
147        switch (val) {
148        case no: line[0] = 'n'; break;
149        case mod: line[0] = 'm'; break;
150        case yes: line[0] = 'y'; break;
151        }
152        line[1] = '\n';
153        line[2] = 0;
154        break;
155    default:
156        break;
157    }
158    printf("%s", line);
159}
160
161int conf_string(struct menu *menu)
162{
163    struct symbol *sym = menu->sym;
164    const char *def, *help;
165
166    while (1) {
167        printf("%*s%s ", indent - 1, "", menu->prompt->text);
168        printf("(%s) ", sym->name);
169        def = sym_get_string_value(sym);
170        if (sym_get_string_value(sym))
171            printf("[%s] ", def);
172        conf_askvalue(sym, def);
173        switch (line[0]) {
174        case '\n':
175            break;
176        case '?':
177            /* print help */
178            if (line[1] == '\n') {
179                help = nohelp_text;
180                if (menu->sym->help)
181                    help = menu->sym->help;
182                printf("\n%s\n", menu->sym->help);
183                def = NULL;
184                break;
185            }
186        default:
187            line[strlen(line)-1] = 0;
188            def = line;
189        }
190        if (def && sym_set_string_value(sym, def))
191            return 0;
192    }
193}
194
195static int conf_sym(struct menu *menu)
196{
197    struct symbol *sym = menu->sym;
198    int type;
199    tristate oldval, newval;
200    const char *help;
201
202    while (1) {
203        printf("%*s%s ", indent - 1, "", menu->prompt->text);
204        if (sym->name)
205            printf("(%s) ", sym->name);
206        type = sym_get_type(sym);
207        putchar('[');
208        oldval = sym_get_tristate_value(sym);
209        switch (oldval) {
210        case no:
211            putchar('N');
212            break;
213        case mod:
214            putchar('M');
215            break;
216        case yes:
217            putchar('Y');
218            break;
219        }
220        if (oldval != no && sym_tristate_within_range(sym, no))
221            printf("/n");
222        if (oldval != mod && sym_tristate_within_range(sym, mod))
223            printf("/m");
224        if (oldval != yes && sym_tristate_within_range(sym, yes))
225            printf("/y");
226        if (sym->help)
227            printf("/?");
228        printf("] ");
229        conf_askvalue(sym, sym_get_string_value(sym));
230        strip(line);
231
232        switch (line[0]) {
233        case 'n':
234        case 'N':
235            newval = no;
236            if (!line[1] || !strcmp(&line[1], "o"))
237                break;
238            continue;
239        case 'm':
240        case 'M':
241            newval = mod;
242            if (!line[1])
243                break;
244            continue;
245        case 'y':
246        case 'Y':
247            newval = yes;
248            if (!line[1] || !strcmp(&line[1], "es"))
249                break;
250            continue;
251        case 0:
252            newval = oldval;
253            break;
254        case '?':
255            goto help;
256        default:
257            continue;
258        }
259        if (sym_set_tristate_value(sym, newval))
260            return 0;
261help:
262        help = nohelp_text;
263        if (sym->help)
264            help = sym->help;
265        printf("\n%s\n", help);
266    }
267}
268
269static int conf_choice(struct menu *menu)
270{
271    struct symbol *sym, *def_sym;
272    struct menu *child;
273    int type;
274    bool is_new;
275
276    sym = menu->sym;
277    type = sym_get_type(sym);
278    is_new = !sym_has_value(sym);
279    if (sym_is_changable(sym)) {
280        conf_sym(menu);
281        sym_calc_value(sym);
282        switch (sym_get_tristate_value(sym)) {
283        case no:
284            return 1;
285        case mod:
286            return 0;
287        case yes:
288            break;
289        }
290    } else {
291        switch (sym_get_tristate_value(sym)) {
292        case no:
293            return 1;
294        case mod:
295            printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
296            return 0;
297        case yes:
298            break;
299        }
300    }
301
302    while (1) {
303        int cnt, def;
304
305        printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
306        def_sym = sym_get_choice_value(sym);
307        cnt = def = 0;
308        line[0] = '0';
309        line[1] = 0;
310        for (child = menu->list; child; child = child->next) {
311            if (!menu_is_visible(child))
312                continue;
313            if (!child->sym) {
314                printf("%*c %s\n", indent, '*', menu_get_prompt(child));
315                continue;
316            }
317            cnt++;
318            if (child->sym == def_sym) {
319                def = cnt;
320                printf("%*c", indent, '>');
321            } else
322                printf("%*c", indent, ' ');
323            printf(" %d. %s", cnt, menu_get_prompt(child));
324            if (child->sym->name)
325                printf(" (%s)", child->sym->name);
326            if (!sym_has_value(child->sym))
327                printf(" (NEW)");
328            printf("\n");
329        }
330        printf("%*schoice", indent - 1, "");
331        if (cnt == 1) {
332            printf("[1]: 1\n");
333            goto conf_childs;
334        }
335        printf("[1-%d", cnt);
336        if (sym->help)
337            printf("?");
338        printf("]: ");
339        switch (input_mode) {
340        case ask_new:
341        case ask_silent:
342            if (!is_new) {
343                cnt = def;
344                printf("%d\n", cnt);
345                break;
346            }
347            check_stdin();
348        case ask_all:
349            fflush(stdout);
350            fgets(line, 128, stdin);
351            strip(line);
352            if (line[0] == '?') {
353                printf("\n%s\n", menu->sym->help ?
354                    menu->sym->help : nohelp_text);
355                continue;
356            }
357            if (!line[0])
358                cnt = def;
359            else if (isdigit(line[0]))
360                cnt = atoi(line);
361            else
362                continue;
363            break;
364        case set_random:
365            def = (random() % cnt) + 1;
366        case set_default:
367        case set_yes:
368        case set_mod:
369        case set_no:
370            cnt = def;
371            printf("%d\n", cnt);
372            break;
373        }
374
375    conf_childs:
376        for (child = menu->list; child; child = child->next) {
377            if (!child->sym || !menu_is_visible(child))
378                continue;
379            if (!--cnt)
380                break;
381        }
382        if (!child)
383            continue;
384        if (line[strlen(line) - 1] == '?') {
385            printf("\n%s\n", child->sym->help ?
386                child->sym->help : nohelp_text);
387            continue;
388        }
389        sym_set_choice_value(sym, child->sym);
390        if (child->list) {
391            indent += 2;
392            conf(child->list);
393            indent -= 2;
394        }
395        return 1;
396    }
397}
398
399static void conf(struct menu *menu)
400{
401    struct symbol *sym;
402    struct property *prop;
403    struct menu *child;
404
405    if (!menu_is_visible(menu))
406        return;
407
408    sym = menu->sym;
409    prop = menu->prompt;
410    if (prop) {
411        const char *prompt;
412
413        switch (prop->type) {
414        case P_MENU:
415            if (input_mode == ask_silent && rootEntry != menu) {
416                check_conf(menu);
417                return;
418            }
419        case P_COMMENT:
420            prompt = menu_get_prompt(menu);
421            if (prompt)
422                printf("%*c\n%*c %s\n%*c\n",
423                    indent, '*',
424                    indent, '*', prompt,
425                    indent, '*');
426        default:
427            ;
428        }
429    }
430
431    if (!sym)
432        goto conf_childs;
433
434    if (sym_is_choice(sym)) {
435        conf_choice(menu);
436        if (sym->curr.tri != mod)
437            return;
438        goto conf_childs;
439    }
440
441    switch (sym->type) {
442    case S_INT:
443    case S_HEX:
444    case S_STRING:
445        conf_string(menu);
446        break;
447    default:
448        conf_sym(menu);
449        break;
450    }
451
452conf_childs:
453    if (sym)
454        indent += 2;
455    for (child = menu->list; child; child = child->next)
456        conf(child);
457    if (sym)
458        indent -= 2;
459}
460
461static void check_conf(struct menu *menu)
462{
463    struct symbol *sym;
464    struct menu *child;
465
466    if (!menu_is_visible(menu))
467        return;
468
469    sym = menu->sym;
470    if (sym) {
471        if (sym_is_changable(sym) && !sym_has_value(sym)) {
472            if (!conf_cnt++)
473                printf("*\n* Restart config...\n*\n");
474            rootEntry = menu_get_parent_menu(menu);
475            conf(rootEntry);
476        }
477        if (sym_is_choice(sym) && sym_get_tristate_value(sym) != mod)
478            return;
479    }
480
481    for (child = menu->list; child; child = child->next)
482        check_conf(child);
483}
484
485int main(int ac, char **av)
486{
487    int i = 1;
488    const char *name;
489    struct stat tmpstat;
490
491    if (ac > i && av[i][0] == '-') {
492        switch (av[i++][1]) {
493        case 'o':
494            input_mode = ask_new;
495            break;
496        case 's':
497            input_mode = ask_silent;
498            valid_stdin = isatty(0) && isatty(1) && isatty(2);
499            break;
500        case 'd':
501            input_mode = set_default;
502            break;
503        case 'D':
504            input_mode = set_default;
505            defconfig_file = av[i++];
506            if (!defconfig_file) {
507                printf("%s: No default config file specified\n",
508                    av[0]);
509                exit(1);
510            }
511            break;
512        case 'n':
513            input_mode = set_no;
514            break;
515        case 'm':
516            input_mode = set_mod;
517            break;
518        case 'y':
519            input_mode = set_yes;
520            break;
521        case 'r':
522            input_mode = set_random;
523            srandom(time(NULL));
524            break;
525        case 'h':
526        case '?':
527            printf("%s [-o|-s] config\n", av[0]);
528            exit(0);
529        }
530    }
531    name = av[i];
532    if (!name) {
533        printf("%s: configuration file missing\n", av[0]);
534    }
535    conf_parse(name);
536    //zconfdump(stdout);
537    switch (input_mode) {
538    case set_default:
539        if (!defconfig_file)
540            defconfig_file = conf_get_default_confname();
541        if (conf_read(defconfig_file)) {
542            printf("***\n"
543                "*** Can't find default configuration \"%s\"!\n"
544                "***\n", defconfig_file);
545            exit(1);
546        }
547        break;
548    case ask_silent:
549        if (stat(".config", &tmpstat)) {
550            printf("***\n"
551                "*** You have not yet configured BusyBox!\n"
552                "***\n"
553                "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
554                "*** \"make menuconfig\" or \"make config\").\n"
555                "***\n");
556            exit(1);
557        }
558    case ask_all:
559    case ask_new:
560        conf_read(NULL);
561        break;
562    default:
563        break;
564    }
565
566    if (input_mode != ask_silent) {
567        rootEntry = &rootmenu;
568        conf(&rootmenu);
569        if (input_mode == ask_all) {
570            input_mode = ask_silent;
571            valid_stdin = 1;
572        }
573    }
574    do {
575        conf_cnt = 0;
576        check_conf(&rootmenu);
577    } while (conf_cnt);
578    if (conf_write(NULL)) {
579        fprintf(stderr, "\n*** Error during writing of the BusyBox configuration.\n\n");
580        return 1;
581    }
582    return 0;
583}
Note: See TracBrowser for help on using the repository browser.