3 # This script is used to configure BusyBox.
5 # It was inspired by a desire to not have to hit <enter> 9 million times
6 # or startup the X server just to change a single kernel parameter.
8 # This script attempts to parse the configuration files, which are
9 # scattered throughout the kernel source tree, and creates a temporary
10 # set of mini scripts which are in turn used to create nested menus and
13 # It uses a very modified/mutilated version of the "dialog" utility
14 # written by Savio Lam (lam836@cs.cuhk.hk). Savio is not responsible
15 # for this script or the version of dialog used by this script.
16 # Please do not contact him with questions. The official version of
17 # dialog is available at sunsite.unc.edu or a sunsite mirror.
19 # Portions of this script were borrowed from the original Configure
22 # William Roadcap was the original author of Menuconfig.
23 # Michael Elizabeth Chastain (mec@shout.net) is the current maintainer.
25 # 070497 Bernhard Kaindl (bkaindl@netway.at) - get default values for
26 # new bool, tristate and dep_tristate parameters from the defconfig file.
27 # new configuration parameters are marked with '(NEW)' as in make config.
29 # 180697 Bernhard Kaindl (bkaindl@netway.at) - added the needed support
30 # for string options. They are handled like the int and hex options.
32 # 081297 Pavel Machek (pavel@atrey.karlin.mff.cuni.cz) - better error
35 # 131197 Michael Chastain (mec@shout.net) - output all lines for a
36 # choice list, not just the selected one. This makes the output
37 # the same as Configure output, which is important for smart config
40 # 101297 Michael Chastain (mec@shout.net) - remove sound driver cruft.
42 # 221297 Michael Chastain (mec@shout.net) - make define_bool actually
43 # define its arguments so that later tests on them work right.
45 # 160198 Michael Chastain (mec@shout.net) - fix bug with 'c' command
46 # (complement existing value) when used on virgin uninitialized variables.
48 # 090398 Axel Boldt (boldt@math.ucsb.edu) - allow for empty lines in help
51 # 12 Dec 1998, Michael Elizabeth Chastain (mec@shout.net)
52 # Remove a /tmp security hole in get_def (also makes it faster).
53 # Give uninitialized variables canonical values rather than null value.
54 # Change a lot of places to call set_x_info uniformly.
55 # Take out message about preparing version (old sound driver cruft).
57 # 13 Dec 1998, Riley H Williams <rhw@memalpha.cx>
58 # When an error occurs, actually display the error message as well as
59 # our comments thereon.
61 # 31 Dec 1998, Michael Elizabeth Chastain (mec@shout.net)
62 # Fix mod_bool to honor $CONFIG_MODULES.
63 # Fix dep_tristate to call define_bool when dependency is "n".
65 # 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
66 # Blow away lxdialog.scrltmp on entry to activate_menu. This protects
67 # against people who use commands like ' ' to select menus.
69 # 24 January 1999, Michael Elizabeth Chastain, <mec@shout.net>
70 # - Improve the exit message (Jeff Ronne).
72 # 06 July 1999, Andrzej M. Krzysztofowicz, <ankry@mif.pg.gda.pl>
73 # - Support for multiple conditions in dep_tristate().
74 # - Implemented new functions: define_tristate(), define_int(), define_hex(),
75 # define_string(), dep_bool().
77 # 22 October 2001, Erik Andersen <andersee@debian.org>
78 # - Adjusted for busybox (modified hard coded kernel specific paths,
79 # and everything to do with modules (tristates, modbools, etc).
83 # Change this to TRUE if you prefer all options listed
84 # in a single menu rather than the standard menu hierarchy.
89 # Make sure we're really running bash.
91 [ -z "$BASH" ] && { echo "Menuconfig requires bash" 1>&2; exit 1; }
94 # Cache function definitions, turn off posix compliance
100 # Given a configuration variable, set the global variable $x to its value,
101 # and the global variable $info to the string " (NEW)" if this is a new
104 # This function looks for: (1) the current value, or (2) the default value
105 # from the arch-dependent defconfig file, or (3) a default passed by the caller.
107 function set_x_info () {
110 eval `sed -n -e 's/# \(.*\) is not set.*/\1=n/' -e "/^$1=/p" sysdeps/$TARGET_OS/defconfig`
113 eval INFO_$1="' (NEW)'"
115 eval info="\$INFO_$1"
119 # Load the functions used by the config.in files.
121 # I do this because these functions must be redefined depending
122 # on whether they are being called for interactive use or for
123 # saving a configuration to a file.
125 # Thank the heavens bash supports nesting function definitions.
130 # Additional comments
132 function comment () {
133 comment_ctr=$[ comment_ctr + 1 ]
134 echo -ne "': $comment_ctr' '--- $1' " >>MCmenu
138 # Define a boolean to a specific value.
140 function define_bool () {
144 function define_hex () {
148 function define_int () {
152 function define_string () {
157 # Create a boolean (Yes/No) function for our current menu
158 # which calls our local bool function.
168 echo -ne "'$2' '[$flag] $1$info' " >>MCmenu
170 echo -e "function $2 () { l_bool '$2' \"\$1\" ;}\n" >>MCradiolists
174 # Same as above, but now only Y and N are allowed as dependency
175 # (i.e. third and next arguments).
177 function dep_bool () {
182 while [ $# -gt 0 ]; do
183 if [ "$1" = y ]; then
190 if [ "$dep" = y ]; then
197 function dep_mbool () {
202 while [ $# -gt 0 ]; do
203 if [ "$1" = y -o "$1" = m ]; then
210 if [ "$dep" = y ]; then
218 # Add a menu item which will call our local int function.
223 echo -ne "'$2' '($x) $1$info' " >>MCmenu
225 echo -e "function $2 () { l_int '$1' '$2' '$3' '$x' ;}" >>MCradiolists
229 # Add a menu item which will call our local hex function.
235 echo -ne "'$2' '($x) $1$info' " >>MCmenu
237 echo -e "function $2 () { l_hex '$1' '$2' '$3' '$x' ;}" >>MCradiolists
241 # Add a menu item which will call our local string function.
246 echo -ne "'$2' ' $1: \"$x\"$info' " >>MCmenu
248 echo -e "function $2 () { l_string '$1' '$2' '$3' '$x' ;}" >>MCradiolists
252 # Add a menu item which will call our local One-of-Many choice list.
256 # Need to remember params cause they're gonna get reset.
264 # Find out if one of the choices is already set.
265 # If it's not then make it the default.
272 if eval [ "_\$$2" = "_y" ]
280 : ${current:=$default}
282 echo -ne "'$firstchoice' '($current) $title' " >>MCmenu
285 function $firstchoice () \
286 { l_choice '$title' \"$choices\" \"$current\" ;}" >>MCradiolists
289 } # END load_functions()
296 # Extract available help for an option from Configure.help
297 # and send it to standard output.
299 # Most of this function was borrowed from the original kernel
302 function extract_help () {
303 if [ -f docs/Configure.help ]
305 #first escape regexp special characters in the argument:
306 var=$(echo "$1"|sed 's/[][\/.^$*]/\\&/g')
307 #now pick out the right help text:
308 text=$(sed -n "/^$var[ ]*\$/,\${
315 /<file:\\([^>]*\\)>/s//\\1/g
317 }" docs/Configure.help)
321 echo "There is no help available for this option."
327 echo "There is no help available for this option."
333 # Activate a help dialog.
336 if extract_help $1 >help.out
338 $DIALOG --backtitle "$backtitle" --title "$2"\
339 --textbox help.out $ROWS $COLS
341 $DIALOG --backtitle "$backtitle" \
342 --textbox help.out $ROWS $COLS
348 # Show the README file.
350 function show_readme () {
351 $DIALOG --backtitle "$backtitle" \
352 --textbox scripts/README.Menuconfig $ROWS $COLS
356 # Begin building the dialog menu command and Initialize the
357 # Radiolist function file.
359 function menu_name () {
360 echo -ne "$DIALOG --title '$1'\
361 --backtitle '$backtitle' \
362 --menu '$menu_instructions' \
363 $ROWS $COLS $((ROWS-10)) \
369 # Add a submenu option to the menu currently under construction.
371 function submenu () {
372 echo -ne "'activate_menu $2' '$1 --->' " >>MCmenu
376 # Handle a boolean (Yes/No) option.
397 # Create a dialog for entering an integer into a option.
402 if $DIALOG --title "$1" \
403 --backtitle "$backtitle" \
404 --inputbox "$inputbox_instructions_int" \
405 10 75 "$4" 2>MCdialog.out
407 answer="`cat MCdialog.out`"
408 answer="${answer:-$3}"
410 # Semantics of + and ? in GNU expr changed, so
412 if expr "$answer" : '0$' '|' "$answer" : '[1-9][0-9]*$' '|' "$answer" : '-[1-9][0-9]*$' >/dev/null
418 ${DIALOG} --backtitle "$backtitle" \
419 --infobox "You have made an invalid entry." 3 43
431 # Create a dialog for entering a hexadecimal into an option.
436 if $DIALOG --title "$1" \
437 --backtitle "$backtitle" \
438 --inputbox "$inputbox_instructions_hex" \
439 10 75 "$4" 2>MCdialog.out
441 answer="`cat MCdialog.out`"
442 answer="${answer:-$3}"
443 answer="${answer##*[x,X]}"
445 if expr "$answer" : '[0-9a-fA-F][0-9a-fA-F]*$' >/dev/null
451 ${DIALOG} --backtitle "$backtitle" \
452 --infobox "You have made an invalid entry." 3 43
464 # Create a dialog for entering a string into an option.
466 function l_string () {
469 if $DIALOG --title "$1" \
470 --backtitle "$backtitle" \
471 --inputbox "$inputbox_instructions_string" \
472 10 75 "$4" 2>MCdialog.out
474 answer="`cat MCdialog.out`"
475 answer="${answer:-$3}"
478 # Someone may add a nice check for the entered
492 # Handle a one-of-many choice list.
494 function l_choice () {
496 # Need to remember params cause they're gonna get reset.
504 # Scan current value of choices and set radiolist switches.
512 "$current"*) if [ -z "$chosen" ]; then
513 list="$list $2 $1 ON "
516 list="$list $2 $1 OFF "
518 *) list="$list $2 $1 OFF " ;;
526 if $DIALOG --title "$title" \
527 --backtitle "$backtitle" \
528 --radiolist "$radiolist_instructions" \
529 15 70 6 $list 2>MCdialog.out
531 choice=`cat MCdialog.out`
535 help "$firstchoice" "$title"
539 # Now set the boolean value of each option based on
540 # the selection made from the radiolist.
545 if [ "$2" = "$choice" ]
557 # Call awk, and watch for error codes, etc.
559 function callawk () {
560 awk "$1" || echo "Awk died with error code $?. Giving up." || exit 1
564 # A faster awk based recursive parser. (I hope)
566 function parser1 () {
570 comment_is_option = 0
571 parser("'$CONFIG_IN'","MCmenu0")
574 function parser(ifile,menu) {
576 while (getline <ifile) {
577 if ($1 == "mainmenu_option") {
578 comment_is_option = "1"
580 else if ($1 == "comment" && comment_is_option == "1") {
581 comment_is_option= "0"
585 printf("submenu %s MCmenu%s\n", $0, menu_no) >>menu
587 newmenu = sprintf("MCmenu%d", menu_no);
588 printf( "function MCmenu%s () {\n"\
591 menu_no, $0) >newmenu
593 parser(ifile, newmenu)
595 else if ($0 ~ /^#|\$MAKE|mainmenu_name/) {
598 else if ($1 ~ "endmenu") {
602 else if ($1 == "source") {
613 # Secondary parser for single menu mode.
615 function parser2 () {
618 parser("'$CONFIG_IN'","MCmenu0")
621 function parser(ifile,menu) {
623 while (getline <ifile) {
624 if ($0 ~ /^#|$MAKE|mainmenu_name/) {
627 else if ($1 ~ /mainmenu_option|endmenu/) {
630 else if ($1 == "source") {
641 # Parse all the config.in files into mini scripts.
643 function parse_config_files () {
646 echo "function MCmenu0 () {" >MCmenu0
647 echo 'default=$1' >>MCmenu0
648 echo "menu_name 'Main Menu'" >>MCmenu0
650 if [ "_$single_menu_mode" = "_TRUE" ]
657 echo "comment ''" >>MCmenu0
658 echo "g_alt_config" >>MCmenu0
659 echo "s_alt_config" >>MCmenu0
664 # These mini scripts must be sourced into the current
665 # environment in order for all of this to work. Leaving
666 # them on the disk as executables screws up the recursion
667 # in activate_menu(), among other things. Once they are
668 # sourced we can discard them.
679 # This is the menu tree's bootstrap.
681 # Executes the parsed menus on demand and creates a set of functions,
682 # one per configuration option. These functions will in turn execute
683 # dialog commands or recursively call other menus.
685 function activate_menu () {
686 rm -f lxdialog.scrltmp
689 comment_ctr=0 #So comment lines get unique tags
691 $1 "$default" 2> MCerror #Create the lxdialog menu & functions
698 Menuconfig has encountered a possible error in one of BusyBox's
699 configuration files and is unable to continue. Here is the error
703 sed 's/^/ Q> /' MCerror
706 Please report this to the maintainer <mec@shout.net>. You may also
707 send a problem report to <busybox@oss.lineo.com>.
709 Please indicate the BusyBox version you are trying to configure and
710 which menu you were trying to enter when this error occurred.
718 . ./MCradiolists #Source the menu's functions
720 . ./MCmenu 2>MCdialog.out #Activate the lxdialog menu
723 read selection <MCdialog.out
727 defaults="$selection
\12$defaults" #pseudo stack
729 0) eval $selection ;;
730 3) eval $selection y ;;
731 4) eval $selection n ;;
732 5) eval $selection m ;;
733 6) eval $selection c ;;
735 default="${defaults%%
\12*}" defaults="${defaults#*
\12}"
738 default="${selection%%\ *}"
741 *"-->"*|*"alt_config"*)
744 eval help $selection ;;
755 There seems to be a problem with the lxdialog companion utility which is
756 built prior to running Menuconfig. Usually this is an indicator that you
757 have upgraded/downgraded your ncurses libraries and did not remove the
758 old ncurses header file(s) in /usr/include or /usr/include/ncurses.
760 It is VERY important that you have only one set of ncurses header files
761 and that those files are properly version matched to the ncurses libraries
762 installed on your machine.
764 You may also need to rebuild lxdialog. This can be done by moving to
765 the /usr/src/linux/scripts/lxdialog directory and issuing the
766 "make clean all" command.
768 If you have verified that your ncurses install is correct, you may email
769 the maintainer <andersen@codepoet.org> or post a message to
770 <busybox@oss.lineo.com> for additional assistance.
781 # Create a menu item to load an alternate configuration file.
784 echo -n "get_alt_config 'Load an Alternate Configuration File' "\
789 # Get alternate config file name and load the
790 # configuration from it.
793 set -f ## Switch file expansion OFF
797 ALT_CONFIG="${ALT_CONFIG:-$DEFAULTS}"
799 $DIALOG --backtitle "$backtitle" \
801 Enter the name of the configuration file you wish to load. \
802 Accept the name shown to restore the configuration you \
803 last retrieved. Leave blank to abort."\
804 11 55 "$ALT_CONFIG" 2>MCdialog.out
808 ALT_CONFIG=`cat MCdialog.out`
810 [ "_" = "_$ALT_CONFIG" ] && break
812 if eval [ -r "$ALT_CONFIG" ]
814 eval load_config_file "$ALT_CONFIG"
818 $DIALOG --backtitle "$backtitle" \
819 --infobox "File does not exist!" 3 38
825 For various reasons, one may wish to keep several different BusyBox
826 configurations available on a single machine.
828 If you have saved a previous configuration in a file other than the
829 busybox default, entering the name of the file here will allow you
830 to modify that configuration.
832 If you are uncertain, then you have probably never used alternate
833 configuration files. You should therefor leave this blank to abort.
836 $DIALOG --backtitle "$backtitle"\
837 --title "Load Alternate Configuration"\
838 --textbox help.out $ROWS $COLS
842 set +f ## Switch file expansion ON
843 rm -f help.out MCdialog.out
847 # Create a menu item to store an alternate config file.
850 echo -n "save_alt_config 'Save Configuration to an Alternate File' "\
855 # Get an alternate config file name and save the current
856 # configuration to it.
859 set -f ## Switch file expansion OFF
863 $DIALOG --backtitle "$backtitle" \
865 Enter a filename to which this configuration should be saved \
866 as an alternate. Leave blank to abort."\
867 10 55 "$ALT_CONFIG" 2>MCdialog.out
871 ALT_CONFIG=`cat MCdialog.out`
873 [ "_" = "_$ALT_CONFIG" ] && break
875 if eval touch $ALT_CONFIG 2>/dev/null
877 eval save_configuration $ALT_CONFIG
878 load_functions ## RELOAD
882 $DIALOG --backtitle "$backtitle" \
883 --infobox "Can't create file! Probably a nonexistent directory." 3 60
889 For various reasons, one may wish to keep different BusyBox
890 configurations available on a single machine.
892 Entering a file name here will allow you to later retrieve, modify
893 and use the current configuration as an alternate to whatever
894 configuration options you have selected at that time.
896 If you are uncertain what all this means then you should probably
899 $DIALOG --backtitle "$backtitle"\
900 --title "Save Alternate Configuration"\
901 --textbox help.out $ROWS $COLS
905 set +f ## Switch file expansion ON
906 rm -f help.out MCdialog.out
910 # Load config options from a file.
911 # Converts all "# OPTION is not set" lines to "OPTION=n" lines
913 function load_config_file () {
915 /# .* is not set.*/ { printf("%s=n\n", $2) }
916 ! /# .* is not set.*/ { print }
926 save_configuration () {
928 echo -n "Saving your BusyBox configuration."
931 # Now, let's redefine the configuration functions for final
932 # output to the config files.
934 # Nested function definitions, YIPEE!
938 eval define_bool "$2" "$x"
941 function dep_bool () {
945 while [ $# -gt 0 ]; do
946 if [ "$1" = y ]; then
952 define_bool "$var" "$x"
957 echo "$2=$x" >>$CONFIG
958 echo "#define $2 ($x)" >>$CONFIG_H
963 echo "$2=$x" >>$CONFIG
964 echo "#define $2 0x${x##*[x,X]}" >>$CONFIG_H
969 echo "$2=\"$x\"" >>$CONFIG
970 echo "#define $2 \"$x\"" >>$CONFIG_H
973 function define_hex () {
975 echo "$1=$2" >>$CONFIG
976 echo "#define $1 0x${2##*[x,X]}" >>$CONFIG_H
979 function define_int () {
981 echo "$1=$2" >>$CONFIG
982 echo "#define $1 ($2)" >>$CONFIG_H
985 function define_string () {
987 echo "$1=\"$2\"" >>$CONFIG
988 echo "#define $1 \"$2\"" >>$CONFIG_H
991 function define_bool () {
992 define_tristate "$1" "$2"
995 function define_tristate () {
1000 echo "$1=y" >>$CONFIG
1001 echo "#define $1 1" >>$CONFIG_H
1005 echo "# $1 is not set" >>$CONFIG
1006 echo "#undef $1" >>$CONFIG_H
1011 function choice () {
1013 # Find the first choice that's already set to 'y'
1023 if eval [ "_\$$2" = "_y" ]
1032 # Use the default if none were set.
1034 : ${current:=$default}
1037 # Output all choices (to be compatible with other configs).
1043 "$current"*) if [ -z "$chosen" ]; then
1044 define_bool "$2" "y"
1047 define_bool "$2" "n"
1049 *) define_bool "$2" "n" ;;
1055 function mainmenu_name () {
1059 function mainmenu_option () {
1060 comment_is_option=TRUE
1063 function endmenu () {
1067 function comment () {
1068 if [ "$comment_is_option" ]
1073 echo "# $1" >>$CONFIG
1077 echo "/*" >>$CONFIG_H
1078 echo " * $1" >>$CONFIG_H
1079 echo " */" >>$CONFIG_H
1085 DEF_CONFIG="${1:-.config}"
1086 DEF_CONFIG_H="include/config.h"
1089 CONFIG_H=.tmpconfig.h
1092 echo "# Automatically generated by make menuconfig: don't edit" >>$CONFIG
1095 echo "/*" >$CONFIG_H
1096 echo " * Automatically generated by make menuconfig: don't edit" >>$CONFIG_H
1097 echo " */" >>$CONFIG_H
1098 echo "#define AUTOCONF_INCLUDED" >> $CONFIG_H
1101 if . $CONFIG_IN >>.menuconfig.log 2>&1
1103 if [ "$DEF_CONFIG" = ".config" ]
1105 mv $CONFIG_H $DEF_CONFIG_H
1108 if [ -f "$DEF_CONFIG" ]
1110 rm -f ${DEF_CONFIG}.old
1111 mv $DEF_CONFIG ${DEF_CONFIG}.old
1114 mv $CONFIG $DEF_CONFIG
1123 # Remove temporary files
1131 rm -f MCmenu* MCradiolists MCdialog.out help.out
1135 rm -f .tmpconfig .tmpconfig.h
1139 # Some distributions export these with incorrect values
1140 # which can really screw up some ncurses programs.
1143 ROWS=${1:-24} COLS=${2:-80}
1145 # Just in case the nasty rlogin bug returns.
1147 [ $ROWS = 0 ] && ROWS=24
1148 [ $COLS = 0 ] && COLS=80
1150 if [ $ROWS -lt 19 -o $COLS -lt 80 ]
1152 echo -e "\n\007Your display is too small to run Menuconfig!"
1153 echo "It must be at least 19 lines by 80 columns."
1157 ROWS=$((ROWS-4)) COLS=$((COLS-5))
1161 set_geometry `stty size 2>/dev/null`
1163 menu_instructions="\
1164 Enabling options will increase the size of busybox. \
1165 Arrow keys navigate the menu. \
1166 Pressing <Enter> selects submenus --->. \
1167 Highlighted letters are hotkeys. \
1168 Pressing <Y> includes, and <N> excludes. \
1169 Press <Esc><Esc> to exit, <?> for Help. \
1170 Legend: [*] built-in [ ] excluded"
1173 radiolist_instructions="\
1174 Use the arrow keys to navigate this window or \
1175 press the hotkey of the item you wish to select \
1176 followed by the <SPACE BAR>.
1177 Press <?> for additional information about this option."
1179 inputbox_instructions_int="\
1180 Please enter a decimal value. \
1181 Fractions will not be accepted. \
1182 Use the <TAB> key to move from the input field to the buttons below it."
1184 inputbox_instructions_hex="\
1185 Please enter a hexadecimal value. \
1186 Use the <TAB> key to move from the input field to the buttons below it."
1188 inputbox_instructions_string="\
1189 Please enter a string value. \
1190 Use the <TAB> key to move from the input field to the buttons below it."
1192 DIALOG="./scripts/lxdialog/lxdialog"
1194 bb_version="${VERSION}"
1195 backtitle="BusyBox v$bb_version Configuration"
1197 trap "cleanup ; exit 1" 1 2 15
1201 # Locate default files.
1203 CONFIG_IN=./config.in
1204 if [ "$1" != "" ] ; then
1208 DEFAULTS=sysdeps/$TARGET_OS/defconfig
1209 if [ -f .config ]; then
1215 echo "Using defaults found in" $DEFAULTS
1216 load_config_file $DEFAULTS
1218 echo "No defaults found"
1225 # Load the functions used by the config.in files.
1226 echo -n "Preparing scripts: functions"
1229 if [ ! -e $CONFIG_IN ]
1231 echo "Your main config.in file ($CONFIG_IN) does not exist"
1237 echo "Your lxdialog utility does not exist"
1242 # Read config.in files and parse them into one shell function per menu.
1245 parse_config_files $CONFIG_IN
1249 # Start the ball rolling from the top.
1251 activate_menu MCmenu0
1261 if $DIALOG --backtitle "$backtitle" \
1262 --yesno "Do you wish to save your new BusyBox configuration?" 5 60
1267 echo "*** End of BusyBox configuration."
1268 echo "*** Check the top-level Makefile for additional configuration."
1269 if [ ! -f .hdepend ] ; then
1270 echo "*** Next, you must run 'make dep'."
1272 echo "*** Next, you should run 'make' or 'make install'."
1278 echo Your BusyBox configuration changes were NOT saved.
1282 # Remove log if empty.
1283 if [ ! -s .menuconfig.log ] ; then
1284 rm -f .menuconfig.log