2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
5 * Introduced single menu mode (show all sub-menus in one large tree).
6 * 2002-11-06 Petr Baudis <pasky@ucw.cz>
8 * i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br>
11 #include <sys/ioctl.h>
25 #define LKC_DIRECT_LINK
28 static char menu_backtitle
[128];
29 static const char mconf_readme
[] = N_(
32 "Some kernel features may be built directly into the kernel.\n"
33 "Some may be made into loadable runtime modules. Some features\n"
34 "may be completely removed altogether. There are also certain\n"
35 "kernel parameters which are not really features, but must be\n"
36 "entered in as decimal or hexadecimal numbers or possibly text.\n"
38 "Menu items beginning with [*], <M> or [ ] represent features\n"
39 "configured to be built in, modularized or removed respectively.\n"
40 "Pointed brackets <> represent module capable features.\n"
42 "To change any of these features, highlight it with the cursor\n"
43 "keys and press <Y> to build it in, <M> to make it a module or\n"
44 "<N> to removed it. You may also press the <Space Bar> to cycle\n"
45 "through the available options (ie. Y->N->M->Y).\n"
47 "Some additional keyboard hints:\n"
51 "o Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
52 " you wish to change or submenu wish to select and press <Enter>.\n"
53 " Submenus are designated by \"--->\".\n"
55 " Shortcut: Press the option's highlighted letter (hotkey).\n"
56 " Pressing a hotkey more than once will sequence\n"
57 " through all visible items which use that hotkey.\n"
59 " You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
60 " unseen options into view.\n"
62 "o To exit a menu use the cursor keys to highlight the <Exit> button\n"
63 " and press <ENTER>.\n"
65 " Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey\n"
66 " using those letters. You may press a single <ESC>, but\n"
67 " there is a delayed response which you may find annoying.\n"
69 " Also, the <TAB> and cursor keys will cycle between <Select>,\n"
70 " <Exit> and <Help>\n"
72 "o To get help with an item, use the cursor keys to highlight <Help>\n"
73 " and Press <ENTER>.\n"
75 " Shortcut: Press <H> or <?>.\n"
78 "Radiolists (Choice lists)\n"
80 "o Use the cursor keys to select the option you wish to set and press\n"
81 " <S> or the <SPACE BAR>.\n"
83 " Shortcut: Press the first letter of the option you wish to set then\n"
84 " press <S> or <SPACE BAR>.\n"
86 "o To see available help for the item, use the cursor keys to highlight\n"
87 " <Help> and Press <ENTER>.\n"
89 " Shortcut: Press <H> or <?>.\n"
91 " Also, the <TAB> and cursor keys will cycle between <Select> and\n"
97 "o Enter the requested information and press <ENTER>\n"
98 " If you are entering hexadecimal values, it is not necessary to\n"
99 " add the '0x' prefix to the entry.\n"
101 "o For help, use the <TAB> or cursor keys to highlight the help option\n"
102 " and press <ENTER>. You can try <TAB><H> as well.\n"
105 "Text Box (Help Window)\n"
107 "o Use the cursor keys to scroll up/down/left/right. The VI editor\n"
108 " keys h,j,k,l function here as do <SPACE BAR> and <B> for those\n"
109 " who are familiar with less and lynx.\n"
111 "o Press <E>, <X>, <Enter> or <Esc><Esc> to exit.\n"
114 "Alternate Configuration Files\n"
115 "-----------------------------\n"
116 "Menuconfig supports the use of alternate configuration files for\n"
117 "those who, for various reasons, find it necessary to switch\n"
118 "between different kernel configurations.\n"
120 "At the end of the main menu you will find two options. One is\n"
121 "for saving the current configuration to a file of your choosing.\n"
122 "The other option is for loading a previously saved alternate\n"
125 "Even if you don't use alternate configuration files, but you\n"
126 "find during a Menuconfig session that you have completely messed\n"
127 "up your settings, you may use the \"Load Alternate...\" option to\n"
128 "restore your previously saved settings from \".config\" without\n"
129 "restarting Menuconfig.\n"
131 "Other information\n"
132 "-----------------\n"
133 "If you use Menuconfig in an XTERM window make sure you have your\n"
134 "$TERM variable set to point to a xterm definition which supports color.\n"
135 "Otherwise, Menuconfig will look rather bad. Menuconfig will not\n"
136 "display correctly in a RXVT window because rxvt displays only one\n"
137 "intensity of color, bright.\n"
139 "Menuconfig will display larger menus on screens or xterms which are\n"
140 "set to display more than the standard 25 row by 80 column geometry.\n"
141 "In order for this to work, the \"stty size\" command must be able to\n"
142 "display the screen's current row and column geometry. I STRONGLY\n"
143 "RECOMMEND that you make sure you do NOT have the shell variables\n"
144 "LINES and COLUMNS exported into your environment. Some distributions\n"
145 "export those variables via /etc/profile. Some ncurses programs can\n"
146 "become confused when those variables (LINES & COLUMNS) don't reflect\n"
147 "the true screen size.\n"
149 "Optional personality available\n"
150 "------------------------------\n"
151 "If you prefer to have all of the kernel options listed in a single\n"
152 "menu, rather than the default multimenu hierarchy, run the menuconfig\n"
153 "with MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
155 "make MENUCONFIG_MODE=single_menu menuconfig\n"
157 "<Enter> will then unroll the appropriate category, or enfold it if it\n"
158 "is already unrolled.\n"
160 "Note that this mode can eventually be a little more CPU expensive\n"
161 "(especially with a larger number of unrolled categories) than the\n"
164 "Different color themes available\n"
165 "--------------------------------\n"
166 "It is possible to select different color themes using the variable\n"
167 "MENUCONFIG_COLOR. To select a theme use:\n"
169 "make MENUCONFIG_COLOR=<theme> menuconfig\n"
171 "Available themes are\n"
172 " mono => selects colors suitable for monochrome displays\n"
173 " blackbg => selects a color scheme with black background\n"
174 " classic => theme with blue background. The classic look\n"
175 " bluetitle => a LCD friendly version of classic. (default)\n"
177 menu_instructions
[] = N_(
178 "Arrow keys navigate the menu. "
179 "<Enter> selects submenus --->. "
180 "Highlighted letters are hotkeys. "
181 "Pressing <Y> includes, <N> excludes, <M> modularizes features. "
182 "Press <Esc><Esc> to exit, <?> for Help, </> for Search. "
183 "Legend: [*] built-in [ ] excluded <M> module < > module capable"),
184 radiolist_instructions
[] = N_(
185 "Use the arrow keys to navigate this window or "
186 "press the hotkey of the item you wish to select "
187 "followed by the <SPACE BAR>. "
188 "Press <?> for additional information about this option."),
189 inputbox_instructions_int
[] = N_(
190 "Please enter a decimal value. "
191 "Fractions will not be accepted. "
192 "Use the <TAB> key to move from the input field to the buttons below it."),
193 inputbox_instructions_hex
[] = N_(
194 "Please enter a hexadecimal value. "
195 "Use the <TAB> key to move from the input field to the buttons below it."),
196 inputbox_instructions_string
[] = N_(
197 "Please enter a string value. "
198 "Use the <TAB> key to move from the input field to the buttons below it."),
200 "This feature depends on another which has been configured as a module.\n"
201 "As a result, this feature will be built as a module."),
203 "There is no help available for this kernel option.\n"),
204 load_config_text
[] = N_(
205 "Enter the name of the configuration file you wish to load. "
206 "Accept the name shown to restore the configuration you "
207 "last retrieved. Leave blank to abort."),
208 load_config_help
[] = N_(
210 "For various reasons, one may wish to keep several different kernel\n"
211 "configurations available on a single machine.\n"
213 "If you have saved a previous configuration in a file other than the\n"
214 "kernel's default, entering the name of the file here will allow you\n"
215 "to modify that configuration.\n"
217 "If you are uncertain, then you have probably never used alternate\n"
218 "configuration files. You should therefor leave this blank to abort.\n"),
219 save_config_text
[] = N_(
220 "Enter a filename to which this configuration should be saved "
221 "as an alternate. Leave blank to abort."),
222 save_config_help
[] = N_(
224 "For various reasons, one may wish to keep different kernel\n"
225 "configurations available on a single machine.\n"
227 "Entering a file name here will allow you to later retrieve, modify\n"
228 "and use the current configuration as an alternate to whatever\n"
229 "configuration options you have selected at that time.\n"
231 "If you are uncertain what all this means then you should probably\n"
232 "leave this blank.\n"),
235 "Search for CONFIG_ symbols and display their relations.\n"
236 "Regular expressions are allowed.\n"
237 "Example: search for \"^FOO\"\n"
239 "-----------------------------------------------------------------\n"
241 "Prompt: Foo bus is used to drive the bar HW\n"
242 "Defined at drivers/pci/Kconfig:47\n"
243 "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
245 " -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
246 " -> PCI support (PCI [=y])\n"
247 " -> PCI access mode (<choice> [=y])\n"
248 "Selects: LIBCRC32\n"
250 "-----------------------------------------------------------------\n"
251 "o The line 'Prompt:' shows the text used in the menu structure for\n"
252 " this CONFIG_ symbol\n"
253 "o The 'Defined at' line tell at what file / line number the symbol\n"
255 "o The 'Depends on:' line tell what symbols needs to be defined for\n"
256 " this symbol to be visible in the menu (selectable)\n"
257 "o The 'Location:' lines tell where in the menu structure this symbol\n"
259 " A location followed by a [=y] indicate that this is a selectable\n"
260 " menu item - and current value is displayed inside brackets.\n"
261 "o The 'Selects:' line tell what symbol will be automatically\n"
262 " selected if this symbol is selected (y or m)\n"
263 "o The 'Selected by' line tell what symbol has selected this symbol\n"
265 "Only relevant lines are shown.\n"
268 "Examples: USB => find all CONFIG_ symbols containing USB\n"
269 " ^USB => find all CONFIG_ symbols starting with USB\n"
270 " USB$ => find all CONFIG_ symbols ending with USB\n"
273 static char buf
[4096], *bufptr
= buf
;
274 static char input_buf
[4096];
275 static char filename
[PATH_MAX
+1] = ".config";
276 static char *args
[1024], **argptr
= args
;
278 static struct termios ios_org
;
279 static int rows
= 0, cols
= 0;
280 static struct menu
*current_menu
;
281 static int child_count
;
282 static int do_resize
;
283 static int single_menu_mode
;
285 static void conf(struct menu
*menu
);
286 static void conf_choice(struct menu
*menu
);
287 static void conf_string(struct menu
*menu
);
288 static void conf_load(void);
289 static void conf_save(void);
290 static void show_textbox(const char *title
, const char *text
, int r
, int c
);
291 static void show_helptext(const char *title
, const char *text
);
292 static void show_help(struct menu
*menu
);
293 static void show_file(const char *filename
, const char *title
, int r
, int c
);
295 static void cprint_init(void);
296 static int cprint1(const char *fmt
, ...);
297 static void cprint_done(void);
298 static int cprint(const char *fmt
, ...);
300 static void init_wsize(void)
305 if (!ioctl(STDIN_FILENO
, TIOCGWINSZ
, &ws
)) {
311 env
= getenv("LINES");
318 env
= getenv("COLUMNS");
325 if (rows
< 19 || cols
< 80) {
326 fprintf(stderr
, N_("Your display is too small to run Menuconfig!\n"));
327 fprintf(stderr
, N_("It must be at least 19 lines by 80 columns.\n"));
335 static void cprint_init(void)
339 memset(args
, 0, sizeof(args
));
342 cprint("./scripts/kconfig/lxdialog/lxdialog");
343 cprint("--backtitle");
344 cprint(menu_backtitle
);
347 static int cprint1(const char *fmt
, ...)
355 res
= vsprintf(bufptr
, fmt
, ap
);
362 static void cprint_done(void)
368 static int cprint(const char *fmt
, ...)
375 res
= vsprintf(bufptr
, fmt
, ap
);
383 static void get_prompt_str(struct gstr
*r
, struct property
*prop
)
386 struct menu
*submenu
[8], *menu
;
388 str_printf(r
, "Prompt: %s\n", prop
->text
);
389 str_printf(r
, " Defined at %s:%d\n", prop
->menu
->file
->name
,
391 if (!expr_is_yes(prop
->visible
.expr
)) {
392 str_append(r
, " Depends on: ");
393 expr_gstr_print(prop
->visible
.expr
, r
);
396 menu
= prop
->menu
->parent
;
397 for (i
= 0; menu
!= &rootmenu
&& i
< 8; menu
= menu
->parent
)
400 str_printf(r
, " Location:\n");
401 for (j
= 4; --i
>= 0; j
+= 2) {
403 str_printf(r
, "%*c-> %s", j
, ' ', menu_get_prompt(menu
));
405 str_printf(r
, " (%s [=%s])", menu
->sym
->name
?
406 menu
->sym
->name
: "<choice>",
407 sym_get_string_value(menu
->sym
));
414 static void get_symbol_str(struct gstr
*r
, struct symbol
*sym
)
417 struct property
*prop
;
419 str_printf(r
, "Symbol: %s [=%s]\n", sym
->name
,
420 sym_get_string_value(sym
));
421 for_all_prompts(sym
, prop
)
422 get_prompt_str(r
, prop
);
424 for_all_properties(sym
, prop
, P_SELECT
) {
426 str_append(r
, " Selects: ");
429 str_printf(r
, " && ");
430 expr_gstr_print(prop
->expr
, r
);
434 if (sym
->rev_dep
.expr
) {
435 str_append(r
, " Selected by: ");
436 expr_gstr_print(sym
->rev_dep
.expr
, r
);
439 str_append(r
, "\n\n");
442 static struct gstr
get_relations_str(struct symbol
**sym_arr
)
445 struct gstr res
= str_new();
448 for (i
= 0; sym_arr
&& (sym
= sym_arr
[i
]); i
++)
449 get_symbol_str(&res
, sym
);
451 str_append(&res
, "No matches found.\n");
457 static void winch_handler(int sig
)
465 static int exec_conf(void)
467 int pipefd
[2], stat
, size
;
469 sigset_t sset
, osset
;
472 sigaddset(&sset
, SIGINT
);
473 sigprocmask(SIG_BLOCK
, &sset
, &osset
);
475 signal(SIGINT
, SIG_DFL
);
477 sa
.sa_handler
= winch_handler
;
478 sigemptyset(&sa
.sa_mask
);
479 sa
.sa_flags
= SA_RESTART
;
480 sigaction(SIGWINCH
, &sa
, NULL
);
487 sigprocmask(SIG_SETMASK
, &osset
, NULL
);
491 execv(args
[0], args
);
498 size
= input_buf
+ sizeof(input_buf
) - bufptr
;
499 size
= read(pipefd
[0], bufptr
, size
);
502 if (errno
== EINTR
|| errno
== EAGAIN
)
512 waitpid(pid
, &stat
, 0);
517 sigprocmask(SIG_SETMASK
, &osset
, NULL
);
520 if (WIFSIGNALED(stat
)) {
521 printf("\finterrupted(%d)\n", WTERMSIG(stat
));
525 printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat
), input_buf
);
529 if (sigismember(&sset
, SIGINT
)) {
530 printf("\finterrupted\n");
533 sigprocmask(SIG_SETMASK
, &osset
, NULL
);
535 return WEXITSTATUS(stat
);
538 static void search_conf(void)
540 struct symbol
**sym_arr
;
547 cprint(_("Search Configuration Parameter"));
548 cprint("--inputbox");
549 cprint(_("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"));
560 show_helptext(_("Search Configuration"), search_help
);
566 sym_arr
= sym_re_search(input_buf
);
567 res
= get_relations_str(sym_arr
);
569 show_textbox(_("Search Results"), str_get(&res
), 0, 0);
573 static void build_conf(struct menu
*menu
)
576 struct property
*prop
;
578 int type
, tmp
, doint
= 2;
582 if (!menu_is_visible(menu
))
588 if (prop
&& menu
!= current_menu
) {
589 const char *prompt
= menu_get_prompt(menu
);
590 switch (prop
->type
) {
595 if (single_menu_mode
) {
597 menu
->data
? "-->" : "++>",
598 indent
+ 1, ' ', prompt
);
600 cprint1(" %*c%s --->", indent
+ 1, ' ', prompt
);
603 if (single_menu_mode
&& menu
->data
)
610 cprint("---%*c%s", indent
+ 1, ' ', prompt
);
618 type
= sym_get_type(sym
);
619 if (sym_is_choice(sym
)) {
620 struct symbol
*def_sym
= sym_get_choice_value(sym
);
621 struct menu
*def_menu
= NULL
;
624 for (child
= menu
->list
; child
; child
= child
->next
) {
625 if (menu_is_visible(child
) && child
->sym
== def_sym
)
629 val
= sym_get_tristate_value(sym
);
630 if (sym_is_changable(sym
)) {
634 cprint1("[%c]", val
== no
? ' ' : '*');
638 case yes
: ch
= '*'; break;
639 case mod
: ch
= 'M'; break;
640 default: ch
= ' '; break;
646 cprint("%c%p", def_menu
? 't' : ':', menu
);
650 cprint1("%*c%s", indent
+ 1, ' ', menu_get_prompt(menu
));
653 cprint1(" (%s)", menu_get_prompt(def_menu
));
656 if (def_menu
->list
) {
658 build_conf(def_menu
);
667 if (menu
== current_menu
) {
669 cprint("---%*c%s", indent
+ 1, ' ', menu_get_prompt(menu
));
673 val
= sym_get_tristate_value(sym
);
674 if (sym_is_choice_value(sym
) && val
== yes
) {
681 if (sym_is_changable(sym
))
682 cprint1("[%c]", val
== no
? ' ' : '*');
689 case yes
: ch
= '*'; break;
690 case mod
: ch
= 'M'; break;
691 default: ch
= ' '; break;
693 if (sym_is_changable(sym
))
700 tmp
= cprint1("(%s)", sym_get_string_value(sym
));
701 tmp
= indent
- tmp
+ 4;
704 cprint1("%*c%s%s", tmp
, ' ', menu_get_prompt(menu
),
705 (sym_has_value(sym
) || !sym_is_changable(sym
)) ?
711 cprint1("%*c%s%s", indent
+ 1, ' ', menu_get_prompt(menu
),
712 (sym_has_value(sym
) || !sym_is_changable(sym
)) ?
714 if (menu
->prompt
->type
== P_MENU
) {
724 for (child
= menu
->list
; child
; child
= child
->next
)
729 static void conf(struct menu
*menu
)
731 struct menu
*submenu
;
732 const char *prompt
= menu_get_prompt(menu
);
734 char active_entry
[40];
737 unlink("lxdialog.scrltmp");
742 cprint("%s", prompt
? prompt
: _("Main Menu"));
744 cprint(_(menu_instructions
));
747 cprint("%d", rows
- 10);
748 cprint("%s", active_entry
);
753 if (menu
== &rootmenu
) {
757 cprint(_(" Load an Alternate Configuration File"));
759 cprint(_(" Save Configuration to an Alternate File"));
765 if (stat
== 1 || stat
== 255)
772 for (i
= 0; input_buf
[i
] && !isspace(input_buf
[i
]); i
++)
774 if (i
>= sizeof(active_entry
))
775 i
= sizeof(active_entry
) - 1;
777 strcpy(active_entry
, input_buf
);
781 if (sscanf(input_buf
+ 1, "%p", &submenu
) == 1)
788 if (single_menu_mode
)
789 submenu
->data
= (void *) (long) !submenu
->data
;
794 if (sym_is_choice(sym
) && sym_get_tristate_value(sym
) == yes
)
795 conf_choice(submenu
);
796 else if (submenu
->prompt
->type
== P_MENU
)
800 conf_string(submenu
);
814 show_helptext("README", _(mconf_readme
));
818 if (sym_set_tristate_value(sym
, yes
))
820 if (sym_set_tristate_value(sym
, mod
))
821 show_textbox(NULL
, setmod_text
, 6, 74);
826 sym_set_tristate_value(sym
, no
);
830 sym_set_tristate_value(sym
, mod
);
834 sym_toggle_tristate_value(sym
);
835 else if (type
== 'm')
845 static void show_textbox(const char *title
, const char *text
, int r
, int c
)
849 fd
= creat(".help.tmp", 0777);
850 write(fd
, text
, strlen(text
));
852 show_file(".help.tmp", title
, r
, c
);
856 static void show_helptext(const char *title
, const char *text
)
858 show_textbox(title
, text
, 0, 0);
861 static void show_help(struct menu
*menu
)
863 struct gstr help
= str_new();
864 struct symbol
*sym
= menu
->sym
;
869 str_printf(&help
, "CONFIG_%s:\n\n", sym
->name
);
870 str_append(&help
, _(sym
->help
));
871 str_append(&help
, "\n");
874 str_append(&help
, nohelp_text
);
876 get_symbol_str(&help
, sym
);
877 show_helptext(menu_get_prompt(menu
), str_get(&help
));
881 static void show_file(const char *filename
, const char *title
, int r
, int c
)
890 cprint("%s", filename
);
891 cprint("%d", r
? r
: rows
);
892 cprint("%d", c
? c
: cols
);
893 } while (exec_conf() < 0);
896 static void conf_choice(struct menu
*menu
)
898 const char *prompt
= menu_get_prompt(menu
);
900 struct symbol
*active
;
903 active
= sym_get_choice_value(menu
->sym
);
907 cprint("%s", prompt
? prompt
: _("Main Menu"));
908 cprint("--radiolist");
909 cprint(_(radiolist_instructions
));
915 for (child
= menu
->list
; child
; child
= child
->next
) {
916 if (!menu_is_visible(child
))
919 cprint("%s", menu_get_prompt(child
));
920 if (child
->sym
== sym_get_choice_value(menu
->sym
))
922 else if (child
->sym
== active
)
931 if (sscanf(input_buf
, "%p", &child
) != 1)
933 sym_set_tristate_value(child
->sym
, yes
);
936 if (sscanf(input_buf
, "%p", &child
) == 1) {
948 static void conf_string(struct menu
*menu
)
950 const char *prompt
= menu_get_prompt(menu
);
956 cprint("%s", prompt
? prompt
: _("Main Menu"));
957 cprint("--inputbox");
958 switch (sym_get_type(menu
->sym
)) {
960 cprint(_(inputbox_instructions_int
));
963 cprint(_(inputbox_instructions_hex
));
966 cprint(_(inputbox_instructions_string
));
973 cprint("%s", sym_get_string_value(menu
->sym
));
977 if (sym_set_string_value(menu
->sym
, input_buf
))
979 show_textbox(NULL
, _("You have made an invalid entry."), 5, 43);
990 static void conf_load(void)
996 cprint("--inputbox");
997 cprint(load_config_text
);
1000 cprint("%s", filename
);
1006 if (!conf_read(input_buf
))
1008 show_textbox(NULL
, _("File does not exist!"), 5, 38);
1011 show_helptext(_("Load Alternate Configuration"), load_config_help
);
1019 static void conf_save(void)
1025 cprint("--inputbox");
1026 cprint(save_config_text
);
1029 cprint("%s", filename
);
1035 if (!conf_write(input_buf
))
1037 show_textbox(NULL
, _("Can't create file! Probably a nonexistent directory."), 5, 60);
1040 show_helptext(_("Save Alternate Configuration"), save_config_help
);
1048 static void conf_cleanup(void)
1050 tcsetattr(1, TCSAFLUSH
, &ios_org
);
1051 unlink(".help.tmp");
1052 unlink("lxdialog.scrltmp");
1055 int main(int ac
, char **av
)
1061 setlocale(LC_ALL
, "");
1062 bindtextdomain(PACKAGE
, LOCALEDIR
);
1063 textdomain(PACKAGE
);
1068 sym
= sym_lookup("KERNELVERSION", 0);
1069 sym_calc_value(sym
);
1070 sprintf(menu_backtitle
, _("Linux Kernel v%s Configuration"),
1071 sym_get_string_value(sym
));
1073 mode
= getenv("MENUCONFIG_MODE");
1075 if (!strcasecmp(mode
, "single_menu"))
1076 single_menu_mode
= 1;
1079 tcgetattr(1, &ios_org
);
1080 atexit(conf_cleanup
);
1087 cprint(_("Do you wish to save your new kernel configuration?"));
1094 if (conf_write(NULL
)) {
1095 fprintf(stderr
, _("\n\n"
1096 "Error during writing of the kernel configuration.\n"
1097 "Your kernel configuration changes were NOT saved."
1102 "*** End of Linux kernel configuration.\n"
1103 "*** Execute 'make' to build the kernel or try 'make help'."
1106 fprintf(stderr
, _("\n\n"
1107 "Your kernel configuration changes were NOT saved."