aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Configure705
-rw-r--r--scripts/Menuconfig1285
-rwxr-xr-xscripts/depmod.pl227
-rw-r--r--scripts/inittab86
-rw-r--r--scripts/lxdialog/BIG.FAT.WARNING4
-rw-r--r--scripts/lxdialog/Makefile46
-rw-r--r--scripts/lxdialog/Makefile-2.571
-rw-r--r--scripts/lxdialog/checklist.c369
-rw-r--r--scripts/lxdialog/colors.h161
-rw-r--r--scripts/lxdialog/dialog.h184
-rw-r--r--scripts/lxdialog/inputbox.c240
-rw-r--r--scripts/lxdialog/lxdialog.c226
-rw-r--r--scripts/lxdialog/menubox.c443
-rw-r--r--scripts/lxdialog/msgbox.c85
-rw-r--r--scripts/lxdialog/textbox.c556
-rw-r--r--scripts/lxdialog/util.c359
-rw-r--r--scripts/lxdialog/yesno.c118
-rwxr-xr-xscripts/mk2knr.pl84
-rw-r--r--scripts/mkdep.c628
-rw-r--r--scripts/split-include.c226
-rw-r--r--scripts/undeb53
-rw-r--r--scripts/unrpm48
22 files changed, 5706 insertions, 498 deletions
diff --git a/scripts/Configure b/scripts/Configure
new file mode 100644
index 000000000..01637bdbe
--- /dev/null
+++ b/scripts/Configure
@@ -0,0 +1,705 @@
1#! /bin/sh
2#
3# This script is used to configure BusyBox.
4#
5# It was inspired by the challenge in the original Configure script
6# to ``do something better'', combined with the actual need to ``do
7# something better'' because the old configure script wasn't flexible
8# enough.
9#
10# Raymond Chen was the original author of Configure.
11# Michael Elizabeth Chastain (mec@shout.net) is the current maintainer.
12#
13# 050793 - use IFS='@' to get around a bug in a pre-version of bash-1.13
14# with an empty IFS.
15#
16# 030995 (storner@osiris.ping.dk) - added support for tri-state answers,
17# for selecting modules to compile.
18#
19# 180995 Bernhard Kaindl (bkaindl@ping.at) - added dummy functions for
20# use with a config.in modified for make menuconfig.
21#
22# 301195 (boldt@math.ucsb.edu) - added help text support
23#
24# 281295 Paul Gortmaker - make tri_state functions collapse to boolean
25# if module support is not enabled.
26#
27# 010296 Aaron Ucko (ucko@vax1.rockhurst.edu) - fix int and hex to accept
28# arbitrary ranges
29#
30# 150296 Dick Streefland (dicks@tasking.nl) - report new configuration
31# items and ask for a value even when doing a "make oldconfig"
32#
33# 200396 Tom Dyas (tdyas@eden.rutgers.edu) - when the module option is
34# chosen for an item, define the macro <option_name>_MODULE
35#
36# 090397 Axel Boldt (boldt@math.ucsb.edu) - avoid ? and + in regular
37# expressions for GNU expr since version 1.15 and up use \? and \+.
38#
39# 300397 Phil Blundell (pjb27@cam.ac.uk) - added support for min/max
40# arguments to "int", allow dep_tristate to take a list of dependencies
41# rather than just one.
42#
43# 090398 Axel Boldt (boldt@math.ucsb.edu) - allow for empty lines in help
44# texts.
45#
46# 102598 Michael Chastain (mec@shout.net) - put temporary files in
47# current directory, not in /tmp.
48#
49# 24 January 1999, Michael Elizabeth Chastain, <mec@shout.net>
50# - Improve the exit message (Jeff Ronne).
51#
52# 7 October 2000, Ghozlane Toumi, <gtoumi@messel.emse.fr>
53# added switches for "random" , "all yes" and "all modules"
54#
55
56#
57# Make sure we're really running bash.
58#
59# I would really have preferred to write this script in a language with
60# better string handling, but alas, bash is the only scripting language
61# that I can be reasonable sure everybody has on their linux machine.
62#
63[ -z "$BASH" ] && { echo "Configure requires bash" 1>&2; exit 1; }
64
65# Disable filename globbing once and for all.
66# Enable function cacheing.
67set -f -h
68
69#
70# Dummy functions for use with a config.in modified for menuconf
71#
72function mainmenu_option () {
73 :
74}
75function mainmenu_name () {
76 :
77}
78function endmenu () {
79 :
80}
81
82#
83# returns a random number between 1 and $1
84#
85function rnd () {
86 rnd=$[ $RANDOM % $1 + 1 ]
87}
88
89#
90# randomly chose a number in a config list (LIST_CONFIG_NAME)
91# or in a range ( MIN_CONFIG_NAME MAX_CONFIG_NAME )
92# ONLY if there is no forced default (and we are in an "auto" mode)
93# we are limited by the range of values taken by "$RANDOM"
94#
95# rndval CONFIG_NAME
96#
97
98function rndval () {
99 [ "$AUTO" != "yes" -o -n "$old" ] && return
100 def_list=$(eval echo "\${LIST_$1}")
101 def_min=$(eval echo "\${MIN_$1}")
102 def_max=$(eval echo "\${MAX_$1}")
103
104 if [ -n "$def_list" ]; then
105 set -- $(echo $def_list | sed 's/,/ /g')
106 rnd $#
107 while [ $rnd -le $# ] ; do
108 def=$1
109 shift
110 done
111 return
112 fi
113 if [ -n "$def_min" -a -n "$def_max" ]; then
114 rnd $[ $def_max - $def_min ]
115 def=$[ $def_min + $rnd ]
116 fi
117}
118
119#
120# help prints the corresponding help text from Configure.help to stdout
121#
122# help variable
123#
124function help () {
125 if [ -f Documentation/Configure.help ]
126 then
127 #first escape regexp special characters in the argument:
128 var=$(echo "$1"|sed 's/[][\/.^$*]/\\&/g')
129 #now pick out the right help text:
130 text=$(sed -n "/^$var[ ]*\$/,\${
131 /^$var[ ]*\$/c\\
132${var}:\\
133
134 /^#/b
135 /^[^ ]/q
136 /<file:\\([^>]*\\)>/s//\\1/g
137 p
138 }" Documentation/Configure.help)
139 if [ -z "$text" ]
140 then
141 echo; echo " Sorry, no help available for this option yet.";echo
142 else
143 (echo; echo "$text") | ${PAGER:-more}
144 fi
145 else
146 echo;
147 echo " Can't access the file Documentation/Configure.help which"
148 echo " should contain the help texts."
149 echo
150 fi
151}
152
153
154#
155# readln reads a line into $ans.
156#
157# readln prompt default oldval
158#
159function readln () {
160 if [ "$AUTO" = "yes" ]; then
161 echo -n "$1"
162 ans=$2
163 echo $ans
164 elif [ "$DEFAULT" = "-d" -a -n "$3" ]; then
165 echo "$1"
166 ans=$2
167 else
168 echo -n "$1"
169 [ -z "$3" ] && echo -n "(NEW) "
170 IFS='@' read ans || exit 1
171 [ -z "$ans" ] && ans=$2
172 fi
173}
174
175#
176# comment does some pretty-printing
177#
178# comment 'xxx'
179#
180function comment () {
181 echo "*"; echo "* $1" ; echo "*"
182 (echo "" ; echo "#"; echo "# $1" ; echo "#") >>$CONFIG
183 (echo "" ; echo "/*"; echo " * $1" ; echo " */") >>$CONFIG_H
184}
185
186#
187# define_bool sets the value of a boolean argument
188#
189# define_bool define value
190#
191function define_bool () {
192 define_tristate $1 $2
193}
194
195function define_tristate () {
196 case "$2" in
197 "y")
198 echo "$1=y" >>$CONFIG
199 echo "#define $1 1" >>$CONFIG_H
200 ;;
201
202 "m")
203 echo "$1=m" >>$CONFIG
204 echo "#undef $1" >>$CONFIG_H
205 echo "#define $1_MODULE 1" >>$CONFIG_H
206 ;;
207
208 "n")
209 echo "# $1 is not set" >>$CONFIG
210 echo "#undef $1" >>$CONFIG_H
211 ;;
212 esac
213 eval "$1=$2"
214}
215
216#
217# bool processes a boolean argument
218#
219# bool question define
220#
221function bool () {
222 old=$(eval echo "\${$2}")
223 def=${old:-'n'}
224 if [ "$AUTO" = "yes" -a -z "$old" ]; then
225 if [ "$RND" = "-r" ]; then
226 rnd 2
227 case $rnd in
228 "1") def="y" ;;
229 "2") def="n" ;;
230 esac
231 else
232 def=$DEF_ANS;
233 fi
234 fi
235 case "$def" in
236 "y" | "m") defprompt="Y/n/?"
237 def="y"
238 ;;
239 "n") defprompt="N/y/?"
240 ;;
241 esac
242 while :; do
243 readln "$1 ($2) [$defprompt] " "$def" "$old"
244 case "$ans" in
245 [yY] | [yY]es ) define_bool "$2" "y"
246 break;;
247 [nN] | [nN]o ) define_bool "$2" "n"
248 break;;
249 * ) help "$2"
250 ;;
251 esac
252 done
253}
254
255#
256# tristate processes a tristate argument
257#
258# tristate question define
259#
260function tristate () {
261 if [ "$CONFIG_MODULES" != "y" ]; then
262 bool "$1" "$2"
263 else
264 old=$(eval echo "\${$2}")
265 def=${old:-'n'}
266 if [ "$AUTO" = "yes" -a -z "$old" ]; then
267 if [ "$RND" = "-r" ]; then
268 rnd 3
269 case $rnd in
270 "1") def="y" ;;
271 "2") def="n" ;;
272 "3") def="m" ;;
273 esac
274 else
275 def=$DEF_ANS
276 fi
277 fi
278 case "$def" in
279 "y") defprompt="Y/m/n/?"
280 ;;
281 "m") defprompt="M/n/y/?"
282 ;;
283 "n") defprompt="N/y/m/?"
284 ;;
285 esac
286 while :; do
287 readln "$1 ($2) [$defprompt] " "$def" "$old"
288 case "$ans" in
289 [yY] | [yY]es ) define_tristate "$2" "y"
290 break ;;
291 [nN] | [nN]o ) define_tristate "$2" "n"
292 break ;;
293 [mM] ) define_tristate "$2" "m"
294 break ;;
295 * ) help "$2"
296 ;;
297 esac
298 done
299 fi
300}
301
302#
303# dep_tristate processes a tristate argument that depends upon
304# another option or options. If any of the options we depend upon is a
305# module, then the only allowable options are M or N. If all are Y, then
306# this is a normal tristate. This is used in cases where modules
307# are nested, and one module requires the presence of something
308# else in the kernel.
309#
310# dep_tristate question define default ...
311#
312function dep_tristate () {
313 old=$(eval echo "\${$2}")
314 def=${old:-'n'}
315 ques=$1
316 var=$2
317 need_module=0
318 shift 2
319 while [ $# -gt 0 ]; do
320 case "$1" in
321 n)
322 define_tristate "$var" "n"
323 return
324 ;;
325 m)
326 need_module=1
327 ;;
328 esac
329 shift
330 done
331
332 if [ $need_module = 1 ]; then
333 if [ "$CONFIG_MODULES" = "y" ]; then
334 if [ "$AUTO" = "yes" -a -z "$old" ]; then
335 if [ "$RND" = "-r" ]; then
336 rnd 2
337 case $rnd in
338 "1") def="m" ;;
339 "2") def="n" ;;
340 esac
341 else
342 def=$DEF_ANS
343 fi
344 fi
345 case "$def" in
346 "y" | "m") defprompt="M/n/?"
347 def="m"
348 ;;
349 "n") defprompt="N/m/?"
350 ;;
351 esac
352 while :; do
353 readln "$ques ($var) [$defprompt] " "$def" "$old"
354 case "$ans" in
355 [nN] | [nN]o ) define_tristate "$var" "n"
356 break ;;
357 [mM] ) define_tristate "$var" "m"
358 break ;;
359 [yY] | [yY]es ) echo
360 echo " This answer is not allowed, because it is not consistent with"
361 echo " your other choices."
362 echo " This driver depends on another one which you chose to compile"
363 echo " as a module. This means that you can either compile this one"
364 echo " as a module as well (with M) or leave it out altogether (N)."
365 echo
366 ;;
367 * ) help "$var"
368 ;;
369 esac
370 done
371 fi
372 else
373 tristate "$ques" "$var"
374 fi
375}
376
377function dep_bool () {
378 ques=$1
379 var=$2
380 shift 2
381 while [ $# -gt 0 ]; do
382 case "$1" in
383 m | n)
384 define_bool "$var" "n"
385 return
386 ;;
387 esac
388 shift
389 done
390
391 bool "$ques" "$var"
392}
393
394function dep_mbool () {
395 ques=$1
396 var=$2
397 shift 2
398 while [ $# -gt 0 ]; do
399 case "$1" in
400 n)
401 define_bool "$var" "n"
402 return
403 ;;
404 esac
405 shift
406 done
407
408 bool "$ques" "$var"
409}
410
411#
412# define_int sets the value of a integer argument
413#
414# define_int define value
415#
416function define_int () {
417 echo "$1=$2" >>$CONFIG
418 echo "#define $1 ($2)" >>$CONFIG_H
419 eval "$1=$2"
420}
421
422#
423# int processes an integer argument with optional limits
424#
425# int question define default [min max]
426#
427function int () {
428 old=$(eval echo "\${$2}")
429 def=${old:-$3}
430 if [ $# -gt 3 ]; then
431 min=$4
432 else
433 min=-10000000 # !!
434 fi
435 if [ $# -gt 4 ]; then
436 max=$5
437 else
438 max=10000000 # !!
439 fi
440 rndval $2
441 while :; do
442 readln "$1 ($2) [$def] " "$def" "$old"
443 if expr \( \( $ans + 0 \) \>= $min \) \& \( $ans \<= $max \) >/dev/null 2>&1 ; then
444 define_int "$2" "$ans"
445 break
446 else
447 help "$2"
448 fi
449 done
450}
451
452#
453# define_hex sets the value of a hexadecimal argument
454#
455# define_hex define value
456#
457function define_hex () {
458 echo "$1=$2" >>$CONFIG
459 echo "#define $1 0x${2#*[x,X]}" >>$CONFIG_H
460 eval "$1=$2"
461}
462
463#
464# hex processes an hexadecimal argument
465#
466# hex question define default
467#
468function hex () {
469 old=$(eval echo "\${$2}")
470 def=${old:-$3}
471 def=${def#*[x,X]}
472 rndval $2
473 while :; do
474 readln "$1 ($2) [$def] " "$def" "$old"
475 ans=${ans#*[x,X]}
476 if expr "$ans" : '[0-9a-fA-F][0-9a-fA-F]*$' > /dev/null; then
477 define_hex "$2" "$ans"
478 break
479 else
480 help "$2"
481 fi
482 done
483}
484
485#
486# define_string sets the value of a string argument
487#
488# define_string define value
489#
490function define_string () {
491 echo "$1=\"$2\"" >>$CONFIG
492 echo "#define $1 \"$2\"" >>$CONFIG_H
493 eval "$1=\"$2\""
494}
495
496#
497# string processes a string argument
498#
499# string question define default
500#
501function string () {
502 old=$(eval echo "\${$2}")
503 def=${old:-$3}
504 while :; do
505 if [ "$old" = "?" ]; then
506 readln "$1 ($2) [$def] " "$def" ""
507 else
508 readln "$1 ($2) [$def] " "$def" "$old"
509 fi
510 if [ "$ans" = "?" ]; then
511 help "$2"
512 else
513 break
514 fi
515 done
516 define_string "$2" "$ans"
517}
518#
519# choice processes a choice list (1-out-of-n)
520#
521# choice question choice-list default
522#
523# The choice list has a syntax of:
524# NAME WHITESPACE VALUE { WHITESPACE NAME WHITESPACE VALUE }
525# The user may enter any unique prefix of one of the NAMEs and
526# choice will define VALUE as if it were a boolean option.
527# VALUE must be in all uppercase. Normally, VALUE is of the
528# form CONFIG_<something>. Thus, if the user selects <something>,
529# the CPP symbol CONFIG_<something> will be defined and the
530# shell variable CONFIG_<something> will be set to "y".
531#
532function choice () {
533 question="$1"
534 choices="$2"
535 old=
536 def=$3
537
538 # determine default answer:
539 names=""
540 set -- $choices
541 firstvar=$2
542 while [ -n "$2" ]; do
543 if [ -n "$names" ]; then
544 names="$names, $1"
545 else
546 names="$1"
547 fi
548 if [ "$(eval echo \"\${$2}\")" = "y" ]; then
549 old=$1
550 def=$1
551 fi
552 shift; shift
553 done
554
555 if [ "$RND" = "-r" -a -z "$old" ] ; then
556 set -- $choices
557 rnd $#
558 while [ $rnd -le $# ] ; do
559 def=$1
560 shift ; shift
561 done
562 fi
563
564 val=""
565 while [ -z "$val" ]; do
566 ambg=n
567 readln "$question ($names) [$def] " "$def" "$old"
568 ans=$(echo $ans | tr a-z A-Z)
569 set -- $choices
570 while [ -n "$1" ]; do
571 name=$(echo $1 | tr a-z A-Z)
572 case "$name" in
573 "$ans"* | */"$ans"* )
574 case "$name" in
575 "$ans" | */"$ans"/* | \
576 "$ans"/* | */"$ans" )
577 val="$2"
578 break # exact match
579 ;;
580 esac
581 if [ -n "$val" ]; then
582 echo;echo \
583 " Sorry, \"$ans\" is ambiguous; please enter a longer string."
584 echo
585 val=""
586 ambg=y
587 break
588 else
589 val="$2"
590 fi;;
591 esac
592 shift; shift
593 done
594 if [ "$val" = "" -a "$ambg" = "n" ]; then
595 help "$firstvar"
596 fi
597 done
598 set -- $choices
599 while [ -n "$2" ]; do
600 if [ "$2" = "$val" ]; then
601 echo " defined $val"
602 define_bool "$2" "y"
603 else
604 define_bool "$2" "n"
605 fi
606 shift; shift
607 done
608}
609
610CONFIG=.tmpconfig
611CONFIG_H=.tmpconfig.h
612FORCE_DEFAULT=.force_default
613trap "rm -f $CONFIG $CONFIG_H ; exit 1" 1 2
614
615#
616# Make sure we start out with a clean slate.
617#
618echo "#" > $CONFIG
619echo "# Automatically generated make config: don't edit" >> $CONFIG
620echo "#" >> $CONFIG
621
622echo "/*" > $CONFIG_H
623echo " * Automatically generated C config: don't edit" >> $CONFIG_H
624echo " */" >> $CONFIG_H
625echo "#define AUTOCONF_INCLUDED" >> $CONFIG_H
626
627DEFAULT=""
628if [ "$1" = "-d" ] ; then
629 DEFAULT="-d"
630 shift
631fi
632
633RND=""
634DEF_ANS=""
635AUTO=""
636case "$1" in
637 -r) RND="-r" ; AUTO="yes" ; shift ;;
638 -y) DEF_ANS="y" ; AUTO="yes" ; shift ;;
639 -m) DEF_ANS="m" ; AUTO="yes" ; shift ;;
640 -n) DEF_ANS="n" ; AUTO="yes" ; shift ;;
641esac
642
643CONFIG_IN=./config.in
644if [ "$1" != "" ] ; then
645 CONFIG_IN=$1
646fi
647
648DEFAULTS=sysdeps/$TARGET_OS/defconfig
649if [ -f .config ]; then
650 DEFAULTS=.config
651fi
652
653if [ "$AUTO" != "yes" ]; then
654 if [ -f $DEFAULTS ]; then
655 echo "#"
656 echo "# Using defaults found in" $DEFAULTS
657 echo "#"
658 . $DEFAULTS
659 sed -e 's/# \(CONFIG_[^ ]*\) is not.*/\1=n/' <$DEFAULTS >.config-is-not.$$
660 . .config-is-not.$$
661 rm .config-is-not.$$
662 else
663 echo "#"
664 echo "# No defaults found"
665 echo "#"
666 fi
667else
668 if [ -f $FORCE_DEFAULT ]; then
669 echo "#"
670 echo "# Forcing defaults found in $FORCE_DEFAULT"
671 echo "#"
672 sed -e '
673s/# \(CONFIG_[^ ]*\) is not.*/\1=n/;
674s/# range \(CONFIG_[^ ]*\) \([^ ][^ ]*\) \([^ ][^ ]*\)/MIN_\1=\2; MAX_\1=\3/;
675s/# list \(CONFIG_[^ ]*\) \([^ ][^ ]*\)/LIST_\1=\2/
676' <$FORCE_DEFAULT >.default_val.$$
677 . .default_val.$$
678 rm .default_val.$$
679 else
680 echo "#"
681 echo "# No defaults found"
682 echo "#"
683 fi
684fi
685
686. $CONFIG_IN
687
688rm -f .config.old
689if [ -f .config ]; then
690 mv .config .config.old
691fi
692mv .tmpconfig .config
693mv .tmpconfig.h include/config.h
694
695echo
696echo "*** End of BusyBox configuration."
697echo "*** Check the top-level Makefile for additional configuration."
698if [ ! -f .hdepend -o "$CONFIG_MODVERSIONS" = "y" ] ; then
699 echo "*** Next, you must run 'make dep'."
700else
701 echo "*** Next, you may run 'make bzImage', 'make bzdisk', or 'make install'."
702fi
703echo
704
705exit 0
diff --git a/scripts/Menuconfig b/scripts/Menuconfig
new file mode 100644
index 000000000..5d4cdce6b
--- /dev/null
+++ b/scripts/Menuconfig
@@ -0,0 +1,1285 @@
1#! /bin/sh
2#
3# This script is used to configure BusyBox.
4#
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.
7#
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
11# radiolists.
12#
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.
18#
19# Portions of this script were borrowed from the original Configure
20# script.
21#
22# William Roadcap was the original author of Menuconfig.
23# Michael Elizabeth Chastain (mec@shout.net) is the current maintainer.
24#
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.
28#
29# 180697 Bernhard Kaindl (bkaindl@netway.at) - added the needed support
30# for string options. They are handled like the int and hex options.
31#
32# 081297 Pavel Machek (pavel@atrey.karlin.mff.cuni.cz) - better error
33# handling
34#
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
38# dependencies.
39#
40# 101297 Michael Chastain (mec@shout.net) - remove sound driver cruft.
41#
42# 221297 Michael Chastain (mec@shout.net) - make define_bool actually
43# define its arguments so that later tests on them work right.
44#
45# 160198 Michael Chastain (mec@shout.net) - fix bug with 'c' command
46# (complement existing value) when used on virgin uninitialized variables.
47#
48# 090398 Axel Boldt (boldt@math.ucsb.edu) - allow for empty lines in help
49# texts.
50#
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).
56#
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.
60#
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".
64#
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.
68#
69# 24 January 1999, Michael Elizabeth Chastain, <mec@shout.net>
70# - Improve the exit message (Jeff Ronne).
71#
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().
76#
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).
80
81
82#
83# Change this to TRUE if you prefer all options listed
84# in a single menu rather than the standard menu hierarchy.
85#
86single_menu_mode=
87
88#
89# Make sure we're really running bash.
90#
91[ -z "$BASH" ] && { echo "Menuconfig requires bash" 1>&2; exit 1; }
92
93#
94# Cache function definitions, turn off posix compliance
95#
96set -h +o posix
97
98
99
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
102# variable.
103#
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.
106
107function set_x_info () {
108 eval x=\$$1
109 if [ -z "$x" ]; then
110 eval `sed -n -e 's/# \(.*\) is not set.*/\1=n/' -e "/^$1=/p" sysdeps/$TARGET_OS/defconfig`
111 eval x=\${$1:-"$2"}
112 eval $1=$x
113 eval INFO_$1="' (NEW)'"
114 fi
115 eval info="\$INFO_$1"
116}
117
118#
119# Load the functions used by the config.in files.
120#
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.
124#
125# Thank the heavens bash supports nesting function definitions.
126#
127load_functions () {
128
129#
130# Additional comments
131#
132function comment () {
133 comment_ctr=$[ comment_ctr + 1 ]
134 echo -ne "': $comment_ctr' '--- $1' " >>MCmenu
135}
136
137#
138# Define a boolean to a specific value.
139#
140function define_bool () {
141 eval $1=$2
142}
143
144function define_hex () {
145 eval $1=$2
146}
147
148function define_int () {
149 eval $1=$2
150}
151
152function define_string () {
153 eval $1="$2"
154}
155
156#
157# Create a boolean (Yes/No) function for our current menu
158# which calls our local bool function.
159#
160function bool () {
161 set_x_info "$2" "n"
162
163 case $x in
164 y|m) flag="*" ;;
165 n) flag=" " ;;
166 esac
167
168 echo -ne "'$2' '[$flag] $1$info' " >>MCmenu
169
170 echo -e "function $2 () { l_bool '$2' \"\$1\" ;}\n" >>MCradiolists
171}
172
173#
174# Same as above, but now only Y and N are allowed as dependency
175# (i.e. third and next arguments).
176#
177function dep_bool () {
178 ques="$1"
179 var="$2"
180 dep=y
181 shift 2
182 while [ $# -gt 0 ]; do
183 if [ "$1" = y ]; then
184 shift
185 else
186 dep=n
187 shift $#
188 fi
189 done
190 if [ "$dep" = y ]; then
191 bool "$ques" "$var"
192 else
193 define_bool "$var" n
194 fi
195}
196
197function dep_mbool () {
198 ques="$1"
199 var="$2"
200 dep=y
201 shift 2
202 while [ $# -gt 0 ]; do
203 if [ "$1" = y -o "$1" = m ]; then
204 shift
205 else
206 dep=n
207 shift $#
208 fi
209 done
210 if [ "$dep" = y ]; then
211 bool "$ques" "$var"
212 else
213 define_bool "$var" n
214 fi
215}
216
217#
218# Add a menu item which will call our local int function.
219#
220function int () {
221 set_x_info "$2" "$3"
222
223 echo -ne "'$2' '($x) $1$info' " >>MCmenu
224
225 echo -e "function $2 () { l_int '$1' '$2' '$3' '$x' ;}" >>MCradiolists
226}
227
228#
229# Add a menu item which will call our local hex function.
230#
231function hex () {
232 set_x_info "$2" "$3"
233 x=${x##*[x,X]}
234
235 echo -ne "'$2' '($x) $1$info' " >>MCmenu
236
237 echo -e "function $2 () { l_hex '$1' '$2' '$3' '$x' ;}" >>MCradiolists
238}
239
240#
241# Add a menu item which will call our local string function.
242#
243function string () {
244 set_x_info "$2" "$3"
245
246 echo -ne "'$2' ' $1: \"$x\"$info' " >>MCmenu
247
248 echo -e "function $2 () { l_string '$1' '$2' '$3' '$x' ;}" >>MCradiolists
249}
250
251#
252# Add a menu item which will call our local One-of-Many choice list.
253#
254function choice () {
255 #
256 # Need to remember params cause they're gonna get reset.
257 #
258 title=$1
259 choices=$2
260 default=$3
261 current=
262
263 #
264 # Find out if one of the choices is already set.
265 # If it's not then make it the default.
266 #
267 set -- $choices
268 firstchoice=$2
269
270 while [ -n "$2" ]
271 do
272 if eval [ "_\$$2" = "_y" ]
273 then
274 current=$1
275 break
276 fi
277 shift ; shift
278 done
279
280 : ${current:=$default}
281
282 echo -ne "'$firstchoice' '($current) $title' " >>MCmenu
283
284 echo -e "
285 function $firstchoice () \
286 { l_choice '$title' \"$choices\" \"$current\" ;}" >>MCradiolists
287}
288
289} # END load_functions()
290
291
292
293
294
295#
296# Extract available help for an option from Configure.help
297# and send it to standard output.
298#
299# Most of this function was borrowed from the original kernel
300# Configure script.
301#
302function extract_help () {
303 if [ -f docs/Configure.help ]
304 then
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[ ]*\$/,\${
309 /^$var[ ]*\$/c\\
310${var}:\\
311
312 /^#/b
313 /^[^ ]/q
314 s/^ //
315 /<file:\\([^>]*\\)>/s//\\1/g
316 p
317 }" docs/Configure.help)
318
319 if [ -z "$text" ]
320 then
321 echo "There is no help available for this option."
322 return 1
323 else
324 echo "$text"
325 fi
326 else
327 echo "There is no help available for this option."
328 return 1
329 fi
330}
331
332#
333# Activate a help dialog.
334#
335function help () {
336 if extract_help $1 >help.out
337 then
338 $DIALOG --backtitle "$backtitle" --title "$2"\
339 --textbox help.out $ROWS $COLS
340 else
341 $DIALOG --backtitle "$backtitle" \
342 --textbox help.out $ROWS $COLS
343 fi
344 rm -f help.out
345}
346
347#
348# Show the README file.
349#
350function show_readme () {
351 $DIALOG --backtitle "$backtitle" \
352 --textbox scripts/README.Menuconfig $ROWS $COLS
353}
354
355#
356# Begin building the dialog menu command and Initialize the
357# Radiolist function file.
358#
359function menu_name () {
360 echo -ne "$DIALOG --title '$1'\
361 --backtitle '$backtitle' \
362 --menu '$menu_instructions' \
363 $ROWS $COLS $((ROWS-10)) \
364 '$default' " >MCmenu
365 >MCradiolists
366}
367
368#
369# Add a submenu option to the menu currently under construction.
370#
371function submenu () {
372 echo -ne "'activate_menu $2' '$1 --->' " >>MCmenu
373}
374
375#
376# Handle a boolean (Yes/No) option.
377#
378function l_bool () {
379 if [ -n "$2" ]
380 then
381 case "$2" in
382 y|m) eval $1=y ;;
383 c) eval x=\$$1
384 case $x in
385 y) eval $1=n ;;
386 n) eval $1=y ;;
387 *) eval $1=y ;;
388 esac ;;
389 *) eval $1=n ;;
390 esac
391 else
392 echo -ne "\007"
393 fi
394}
395
396#
397# Create a dialog for entering an integer into a option.
398#
399function l_int () {
400 while true
401 do
402 if $DIALOG --title "$1" \
403 --backtitle "$backtitle" \
404 --inputbox "$inputbox_instructions_int" \
405 10 75 "$4" 2>MCdialog.out
406 then
407 answer="`cat MCdialog.out`"
408 answer="${answer:-$3}"
409
410 # Semantics of + and ? in GNU expr changed, so
411 # we avoid them:
412 if expr "$answer" : '0$' '|' "$answer" : '[1-9][0-9]*$' '|' "$answer" : '-[1-9][0-9]*$' >/dev/null
413 then
414 eval $2="$answer"
415 else
416 eval $2="$3"
417 echo -en "\007"
418 ${DIALOG} --backtitle "$backtitle" \
419 --infobox "You have made an invalid entry." 3 43
420 sleep 2
421 fi
422
423 break
424 fi
425
426 help "$2" "$1"
427 done
428}
429
430#
431# Create a dialog for entering a hexadecimal into an option.
432#
433function l_hex () {
434 while true
435 do
436 if $DIALOG --title "$1" \
437 --backtitle "$backtitle" \
438 --inputbox "$inputbox_instructions_hex" \
439 10 75 "$4" 2>MCdialog.out
440 then
441 answer="`cat MCdialog.out`"
442 answer="${answer:-$3}"
443 answer="${answer##*[x,X]}"
444
445 if expr "$answer" : '[0-9a-fA-F][0-9a-fA-F]*$' >/dev/null
446 then
447 eval $2="$answer"
448 else
449 eval $2="$3"
450 echo -en "\007"
451 ${DIALOG} --backtitle "$backtitle" \
452 --infobox "You have made an invalid entry." 3 43
453 sleep 2
454 fi
455
456 break
457 fi
458
459 help "$2" "$1"
460 done
461}
462
463#
464# Create a dialog for entering a string into an option.
465#
466function l_string () {
467 while true
468 do
469 if $DIALOG --title "$1" \
470 --backtitle "$backtitle" \
471 --inputbox "$inputbox_instructions_string" \
472 10 75 "$4" 2>MCdialog.out
473 then
474 answer="`cat MCdialog.out`"
475 answer="${answer:-$3}"
476
477 #
478 # Someone may add a nice check for the entered
479 # string here...
480 #
481 eval $2=\"$answer\"
482
483 break
484 fi
485
486 help "$2" "$1"
487 done
488}
489
490
491#
492# Handle a one-of-many choice list.
493#
494function l_choice () {
495 #
496 # Need to remember params cause they're gonna get reset.
497 #
498 title="$1"
499 choices="$2"
500 current="$3"
501 chosen=
502
503 #
504 # Scan current value of choices and set radiolist switches.
505 #
506 list=
507 set -- $choices
508 firstchoice=$2
509 while [ -n "$2" ]
510 do
511 case "$1" in
512 "$current"*) if [ -z "$chosen" ]; then
513 list="$list $2 $1 ON "
514 chosen=1
515 else
516 list="$list $2 $1 OFF "
517 fi ;;
518 *) list="$list $2 $1 OFF " ;;
519 esac
520
521 shift ; shift
522 done
523
524 while true
525 do
526 if $DIALOG --title "$title" \
527 --backtitle "$backtitle" \
528 --radiolist "$radiolist_instructions" \
529 15 70 6 $list 2>MCdialog.out
530 then
531 choice=`cat MCdialog.out`
532 break
533 fi
534
535 help "$firstchoice" "$title"
536 done
537
538 #
539 # Now set the boolean value of each option based on
540 # the selection made from the radiolist.
541 #
542 set -- $choices
543 while [ -n "$2" ]
544 do
545 if [ "$2" = "$choice" ]
546 then
547 eval $2="y"
548 else
549 eval $2="n"
550 fi
551
552 shift ; shift
553 done
554}
555
556#
557# Call awk, and watch for error codes, etc.
558#
559function callawk () {
560awk "$1" || echo "Awk died with error code $?. Giving up." || exit 1
561}
562
563#
564# A faster awk based recursive parser. (I hope)
565#
566function parser1 () {
567callawk '
568BEGIN {
569 menu_no = 0
570 comment_is_option = 0
571 parser("'$CONFIG_IN'","MCmenu0")
572}
573
574function parser(ifile,menu) {
575
576 while (getline <ifile) {
577 if ($1 == "mainmenu_option") {
578 comment_is_option = "1"
579 }
580 else if ($1 == "comment" && comment_is_option == "1") {
581 comment_is_option= "0"
582 sub($1,"",$0)
583 ++menu_no
584
585 printf("submenu %s MCmenu%s\n", $0, menu_no) >>menu
586
587 newmenu = sprintf("MCmenu%d", menu_no);
588 printf( "function MCmenu%s () {\n"\
589 "default=$1\n"\
590 "menu_name %s\n",\
591 menu_no, $0) >newmenu
592
593 parser(ifile, newmenu)
594 }
595 else if ($0 ~ /^#|\$MAKE|mainmenu_name/) {
596 printf("") >>menu
597 }
598 else if ($1 ~ "endmenu") {
599 printf("}\n") >>menu
600 return
601 }
602 else if ($1 == "source") {
603 parser($2,menu)
604 }
605 else {
606 print >>menu
607 }
608 }
609}'
610}
611
612#
613# Secondary parser for single menu mode.
614#
615function parser2 () {
616callawk '
617BEGIN {
618 parser("'$CONFIG_IN'","MCmenu0")
619}
620
621function parser(ifile,menu) {
622
623 while (getline <ifile) {
624 if ($0 ~ /^#|$MAKE|mainmenu_name/) {
625 printf("") >>menu
626 }
627 else if ($1 ~ /mainmenu_option|endmenu/) {
628 printf("") >>menu
629 }
630 else if ($1 == "source") {
631 parser($2,menu)
632 }
633 else {
634 print >>menu
635 }
636 }
637}'
638}
639
640#
641# Parse all the config.in files into mini scripts.
642#
643function parse_config_files () {
644 rm -f MCmenu*
645
646 echo "function MCmenu0 () {" >MCmenu0
647 echo 'default=$1' >>MCmenu0
648 echo "menu_name 'Main Menu'" >>MCmenu0
649
650 if [ "_$single_menu_mode" = "_TRUE" ]
651 then
652 parser2
653 else
654 parser1
655 fi
656
657 echo "comment ''" >>MCmenu0
658 echo "g_alt_config" >>MCmenu0
659 echo "s_alt_config" >>MCmenu0
660
661 echo "}" >>MCmenu0
662
663 #
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.
669 #
670 for i in MCmenu*
671 do
672 echo -n "."
673 source ./$i
674 done
675 rm -f MCmenu*
676}
677
678#
679# This is the menu tree's bootstrap.
680#
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.
684#
685function activate_menu () {
686 rm -f lxdialog.scrltmp
687 while true
688 do
689 comment_ctr=0 #So comment lines get unique tags
690
691 $1 "$default" 2> MCerror #Create the lxdialog menu & functions
692
693 if [ "$?" != "0" ]
694 then
695 clear
696 cat <<EOM
697
698Menuconfig has encountered a possible error in one of BusyBox's
699configuration files and is unable to continue. Here is the error
700report:
701
702EOM
703 sed 's/^/ Q> /' MCerror
704 cat <<EOM
705
706Please report this to the maintainer <mec@shout.net>. You may also
707send a problem report to <busybox@oss.lineo.com>.
708
709Please indicate the BusyBox version you are trying to configure and
710which menu you were trying to enter when this error occurred.
711
712EOM
713 cleanup
714 exit 1
715 fi
716 rm -f MCerror
717
718 . ./MCradiolists #Source the menu's functions
719
720 . ./MCmenu 2>MCdialog.out #Activate the lxdialog menu
721 ret=$?
722
723 read selection <MCdialog.out
724
725 case "$ret" in
726 0|3|4|5|6)
727 defaults="$selection$defaults" #pseudo stack
728 case "$ret" in
729 0) eval $selection ;;
730 3) eval $selection y ;;
731 4) eval $selection n ;;
732 5) eval $selection m ;;
733 6) eval $selection c ;;
734 esac
735 default="${defaults%%*}" defaults="${defaults#*}"
736 ;;
737 2)
738 default="${selection%%\ *}"
739
740 case "$selection" in
741 *"-->"*|*"alt_config"*)
742 show_readme ;;
743 *)
744 eval help $selection ;;
745 esac
746 ;;
747 255|1)
748 break
749 ;;
750 139)
751 stty sane
752 clear
753 cat <<EOM
754
755There seems to be a problem with the lxdialog companion utility which is
756built prior to running Menuconfig. Usually this is an indicator that you
757have upgraded/downgraded your ncurses libraries and did not remove the
758old ncurses header file(s) in /usr/include or /usr/include/ncurses.
759
760It is VERY important that you have only one set of ncurses header files
761and that those files are properly version matched to the ncurses libraries
762installed on your machine.
763
764You may also need to rebuild lxdialog. This can be done by moving to
765the /usr/src/linux/scripts/lxdialog directory and issuing the
766"make clean all" command.
767
768If you have verified that your ncurses install is correct, you may email
769the maintainer <andersen@codepoet.org> or post a message to
770<busybox@oss.lineo.com> for additional assistance.
771
772EOM
773 cleanup
774 exit 139
775 ;;
776 esac
777 done
778}
779
780#
781# Create a menu item to load an alternate configuration file.
782#
783g_alt_config () {
784 echo -n "get_alt_config 'Load an Alternate Configuration File' "\
785 >>MCmenu
786}
787
788#
789# Get alternate config file name and load the
790# configuration from it.
791#
792get_alt_config () {
793 set -f ## Switch file expansion OFF
794
795 while true
796 do
797 ALT_CONFIG="${ALT_CONFIG:-$DEFAULTS}"
798
799 $DIALOG --backtitle "$backtitle" \
800 --inputbox "\
801Enter the name of the configuration file you wish to load. \
802Accept the name shown to restore the configuration you \
803last retrieved. Leave blank to abort."\
804 11 55 "$ALT_CONFIG" 2>MCdialog.out
805
806 if [ "$?" = "0" ]
807 then
808 ALT_CONFIG=`cat MCdialog.out`
809
810 [ "_" = "_$ALT_CONFIG" ] && break
811
812 if eval [ -r "$ALT_CONFIG" ]
813 then
814 eval load_config_file "$ALT_CONFIG"
815 break
816 else
817 echo -ne "\007"
818 $DIALOG --backtitle "$backtitle" \
819 --infobox "File does not exist!" 3 38
820 sleep 2
821 fi
822 else
823 cat <<EOM >help.out
824
825For various reasons, one may wish to keep several different BusyBox
826configurations available on a single machine.
827
828If you have saved a previous configuration in a file other than the
829busybox default, entering the name of the file here will allow you
830to modify that configuration.
831
832If you are uncertain, then you have probably never used alternate
833configuration files. You should therefor leave this blank to abort.
834
835EOM
836 $DIALOG --backtitle "$backtitle"\
837 --title "Load Alternate Configuration"\
838 --textbox help.out $ROWS $COLS
839 fi
840 done
841
842 set +f ## Switch file expansion ON
843 rm -f help.out MCdialog.out
844}
845
846#
847# Create a menu item to store an alternate config file.
848#
849s_alt_config () {
850 echo -n "save_alt_config 'Save Configuration to an Alternate File' "\
851 >>MCmenu
852}
853
854#
855# Get an alternate config file name and save the current
856# configuration to it.
857#
858save_alt_config () {
859 set -f ## Switch file expansion OFF
860
861 while true
862 do
863 $DIALOG --backtitle "$backtitle" \
864 --inputbox "\
865Enter a filename to which this configuration should be saved \
866as an alternate. Leave blank to abort."\
867 10 55 "$ALT_CONFIG" 2>MCdialog.out
868
869 if [ "$?" = "0" ]
870 then
871 ALT_CONFIG=`cat MCdialog.out`
872
873 [ "_" = "_$ALT_CONFIG" ] && break
874
875 if eval touch $ALT_CONFIG 2>/dev/null
876 then
877 eval save_configuration $ALT_CONFIG
878 load_functions ## RELOAD
879 break
880 else
881 echo -ne "\007"
882 $DIALOG --backtitle "$backtitle" \
883 --infobox "Can't create file! Probably a nonexistent directory." 3 60
884 sleep 2
885 fi
886 else
887 cat <<EOM >help.out
888
889For various reasons, one may wish to keep different BusyBox
890configurations available on a single machine.
891
892Entering a file name here will allow you to later retrieve, modify
893and use the current configuration as an alternate to whatever
894configuration options you have selected at that time.
895
896If you are uncertain what all this means then you should probably
897leave this blank.
898EOM
899 $DIALOG --backtitle "$backtitle"\
900 --title "Save Alternate Configuration"\
901 --textbox help.out $ROWS $COLS
902 fi
903 done
904
905 set +f ## Switch file expansion ON
906 rm -f help.out MCdialog.out
907}
908
909#
910# Load config options from a file.
911# Converts all "# OPTION is not set" lines to "OPTION=n" lines
912#
913function load_config_file () {
914 awk '
915 /# .* is not set.*/ { printf("%s=n\n", $2) }
916 ! /# .* is not set.*/ { print }
917 ' $1 >.tmpconfig
918
919 source ./.tmpconfig
920 rm -f .tmpconfig
921}
922
923#
924# Just what it says.
925#
926save_configuration () {
927 echo
928 echo -n "Saving your BusyBox configuration."
929
930 #
931 # Now, let's redefine the configuration functions for final
932 # output to the config files.
933 #
934 # Nested function definitions, YIPEE!
935 #
936 function bool () {
937 set_x_info "$2" "n"
938 eval define_bool "$2" "$x"
939 }
940
941 function dep_bool () {
942 set_x_info "$2" "n"
943 var="$2"
944 shift 2
945 while [ $# -gt 0 ]; do
946 if [ "$1" = y ]; then
947 shift
948 else
949 x=n; shift $#
950 fi
951 done
952 define_bool "$var" "$x"
953 }
954
955 function int () {
956 set_x_info "$2" "$3"
957 echo "$2=$x" >>$CONFIG
958 echo "#define $2 ($x)" >>$CONFIG_H
959 }
960
961 function hex () {
962 set_x_info "$2" "$3"
963 echo "$2=$x" >>$CONFIG
964 echo "#define $2 0x${x##*[x,X]}" >>$CONFIG_H
965 }
966
967 function string () {
968 set_x_info "$2" "$3"
969 echo "$2=\"$x\"" >>$CONFIG
970 echo "#define $2 \"$x\"" >>$CONFIG_H
971 }
972
973 function define_hex () {
974 eval $1="$2"
975 echo "$1=$2" >>$CONFIG
976 echo "#define $1 0x${2##*[x,X]}" >>$CONFIG_H
977 }
978
979 function define_int () {
980 eval $1="$2"
981 echo "$1=$2" >>$CONFIG
982 echo "#define $1 ($2)" >>$CONFIG_H
983 }
984
985 function define_string () {
986 eval $1="$2"
987 echo "$1=\"$2\"" >>$CONFIG
988 echo "#define $1 \"$2\"" >>$CONFIG_H
989 }
990
991 function define_bool () {
992 define_tristate "$1" "$2"
993 }
994
995 function define_tristate () {
996 eval $1="$2"
997
998 case "$2" in
999 y)
1000 echo "$1=y" >>$CONFIG
1001 echo "#define $1 1" >>$CONFIG_H
1002 ;;
1003
1004 n)
1005 echo "# $1 is not set" >>$CONFIG
1006 echo "#undef $1" >>$CONFIG_H
1007 ;;
1008 esac
1009 }
1010
1011 function choice () {
1012 #
1013 # Find the first choice that's already set to 'y'
1014 #
1015 choices="$2"
1016 default="$3"
1017 current=
1018 chosen=
1019
1020 set -- $choices
1021 while [ -n "$2" ]
1022 do
1023 if eval [ "_\$$2" = "_y" ]
1024 then
1025 current=$1
1026 break
1027 fi
1028 shift ; shift
1029 done
1030
1031 #
1032 # Use the default if none were set.
1033 #
1034 : ${current:=$default}
1035
1036 #
1037 # Output all choices (to be compatible with other configs).
1038 #
1039 set -- $choices
1040 while [ -n "$2" ]
1041 do
1042 case "$1" in
1043 "$current"*) if [ -z "$chosen" ]; then
1044 define_bool "$2" "y"
1045 chosen=1
1046 else
1047 define_bool "$2" "n"
1048 fi ;;
1049 *) define_bool "$2" "n" ;;
1050 esac
1051 shift ; shift
1052 done
1053 }
1054
1055 function mainmenu_name () {
1056 :
1057 }
1058
1059 function mainmenu_option () {
1060 comment_is_option=TRUE
1061 }
1062
1063 function endmenu () {
1064 :
1065 }
1066
1067 function comment () {
1068 if [ "$comment_is_option" ]
1069 then
1070 comment_is_option=
1071 echo >>$CONFIG
1072 echo "#" >>$CONFIG
1073 echo "# $1" >>$CONFIG
1074 echo "#" >>$CONFIG
1075
1076 echo >>$CONFIG_H
1077 echo "/*" >>$CONFIG_H
1078 echo " * $1" >>$CONFIG_H
1079 echo " */" >>$CONFIG_H
1080 fi
1081 }
1082
1083 echo -n "."
1084
1085 DEF_CONFIG="${1:-.config}"
1086 DEF_CONFIG_H="include/config.h"
1087
1088 CONFIG=.tmpconfig
1089 CONFIG_H=.tmpconfig.h
1090
1091 echo "#" >$CONFIG
1092 echo "# Automatically generated by make menuconfig: don't edit" >>$CONFIG
1093 echo "#" >>$CONFIG
1094
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
1099
1100 echo -n "."
1101 if . $CONFIG_IN >>.menuconfig.log 2>&1
1102 then
1103 if [ "$DEF_CONFIG" = ".config" ]
1104 then
1105 mv $CONFIG_H $DEF_CONFIG_H
1106 fi
1107
1108 if [ -f "$DEF_CONFIG" ]
1109 then
1110 rm -f ${DEF_CONFIG}.old
1111 mv $DEF_CONFIG ${DEF_CONFIG}.old
1112 fi
1113
1114 mv $CONFIG $DEF_CONFIG
1115
1116 return 0
1117 else
1118 return 1
1119 fi
1120}
1121
1122#
1123# Remove temporary files
1124#
1125cleanup () {
1126 cleanup1
1127 cleanup2
1128}
1129
1130cleanup1 () {
1131 rm -f MCmenu* MCradiolists MCdialog.out help.out
1132}
1133
1134cleanup2 () {
1135 rm -f .tmpconfig .tmpconfig.h
1136}
1137
1138set_geometry () {
1139 # Some distributions export these with incorrect values
1140 # which can really screw up some ncurses programs.
1141 LINES= COLUMNS=
1142
1143 ROWS=${1:-24} COLS=${2:-80}
1144
1145 # Just in case the nasty rlogin bug returns.
1146 #
1147 [ $ROWS = 0 ] && ROWS=24
1148 [ $COLS = 0 ] && COLS=80
1149
1150 if [ $ROWS -lt 19 -o $COLS -lt 80 ]
1151 then
1152 echo -e "\n\007Your display is too small to run Menuconfig!"
1153 echo "It must be at least 19 lines by 80 columns."
1154 exit 1
1155 fi
1156
1157 ROWS=$((ROWS-4)) COLS=$((COLS-5))
1158}
1159
1160
1161set_geometry `stty size 2>/dev/null`
1162
1163menu_instructions="\
1164Arrow keys navigate the menu. \
1165Pressing <Enter> selects submenus --->. \
1166Highlighted letters are hotkeys. \
1167Pressing <Y> includes, and <N> excludes. \
1168Press <Esc><Esc> to exit, <?> for Help. \
1169Legend: [*] built-in [ ] excluded "
1170
1171radiolist_instructions="\
1172Use the arrow keys to navigate this window or \
1173press the hotkey of the item you wish to select \
1174followed by the <SPACE BAR>.
1175Press <?> for additional information about this option."
1176
1177inputbox_instructions_int="\
1178Please enter a decimal value. \
1179Fractions will not be accepted. \
1180Use the <TAB> key to move from the input field to the buttons below it."
1181
1182inputbox_instructions_hex="\
1183Please enter a hexadecimal value. \
1184Use the <TAB> key to move from the input field to the buttons below it."
1185
1186inputbox_instructions_string="\
1187Please enter a string value. \
1188Use the <TAB> key to move from the input field to the buttons below it."
1189
1190DIALOG="./scripts/lxdialog/lxdialog"
1191
1192bb_version="${VERSION}"
1193backtitle="BusyBox v$bb_version Configuration"
1194
1195trap "cleanup ; exit 1" 1 2 15
1196
1197
1198#
1199# Locate default files.
1200#
1201CONFIG_IN=./config.in
1202if [ "$1" != "" ] ; then
1203 CONFIG_IN=$1
1204fi
1205
1206DEFAULTS=sysdeps/$TARGET_OS/defconfig
1207if [ -f .config ]; then
1208 DEFAULTS=.config
1209fi
1210
1211if [ -f $DEFAULTS ]
1212then
1213 echo "Using defaults found in" $DEFAULTS
1214 load_config_file $DEFAULTS
1215else
1216 echo "No defaults found"
1217fi
1218
1219
1220# Fresh new log.
1221>.menuconfig.log
1222
1223# Load the functions used by the config.in files.
1224echo -n "Preparing scripts: functions"
1225load_functions
1226
1227if [ ! -e $CONFIG_IN ]
1228then
1229 echo "Your main config.in file ($CONFIG_IN) does not exist"
1230 exit 1
1231fi
1232
1233if [ ! -x $DIALOG ]
1234then
1235 echo "Your lxdialog utility does not exist"
1236 exit 1
1237fi
1238
1239#
1240# Read config.in files and parse them into one shell function per menu.
1241#
1242echo -n ", parsing"
1243parse_config_files $CONFIG_IN
1244
1245echo "done."
1246#
1247# Start the ball rolling from the top.
1248#
1249activate_menu MCmenu0
1250
1251#
1252# All done!
1253#
1254cleanup1
1255
1256#
1257# Confirm and Save
1258#
1259if $DIALOG --backtitle "$backtitle" \
1260 --yesno "Do you wish to save your new BusyBox configuration?" 5 60
1261then
1262 save_configuration
1263 echo
1264 echo
1265 echo "*** End of BusyBox configuration."
1266 echo "*** Check the top-level Makefile for additional configuration."
1267 if [ ! -f .hdepend ] ; then
1268 echo "*** Next, you must run 'make dep'."
1269 else
1270 echo "*** Next, you should run 'make' or 'make install'."
1271 fi
1272 echo
1273else
1274 echo
1275 echo
1276 echo Your BusyBox configuration changes were NOT saved.
1277 echo
1278fi
1279
1280# Remove log if empty.
1281if [ ! -s .menuconfig.log ] ; then
1282 rm -f .menuconfig.log
1283fi
1284
1285exit 0
diff --git a/scripts/depmod.pl b/scripts/depmod.pl
deleted file mode 100755
index e65f07b68..000000000
--- a/scripts/depmod.pl
+++ /dev/null
@@ -1,227 +0,0 @@
1#!/usr/bin/perl -w
2# vi: set ts=4:
3# Copyright (c) 2001 David Schleef <ds@schleef.org>
4# Copyright (c) 2001 Erik Andersen <andersen@lineo.com>
5# Copyright (c) 2001 Stuart Hughes <stuarth@lineo.com>
6# This program is free software; you can redistribute it and/or modify it
7# under the same terms as Perl itself.
8
9# TODO -- use strict mode...
10#use strict;
11
12use Getopt::Long;
13use File::Find;
14
15
16# Set up some default values
17
18my $basedir="";
19my $kernel;
20my $kernelsyms;
21my $stdout=1;
22my $verbose=0;
23
24
25# get command-line options
26
27my %opt;
28
29GetOptions(
30 \%opt,
31 "help|h",
32 "basedir|b=s" => \$basedir,
33 "kernel|k=s" => \$kernel,
34 "kernelsyms|F=s" => \$kernelsyms,
35 "stdout|n" => \$stdout,
36 "verbose|v" => \$verbose,
37);
38
39if (defined $opt{help}) {
40 print
41 "$0 [OPTION]... [basedir]\n",
42 "\t-h --help\t\tShow this help screen\n",
43 "\t-b --basedir\t\tModules base directory (defaults to /lib/modules)\n",
44 "\t-k --kernel\t\tKernel binary for the target\n",
45 "\t-F --kernelsyms\t\tKernel symbol file\n",
46 "\t-n --stdout\t\tWrite to stdout instead of modules.dep\n",
47 "\t-v --verbose\t\tPrint out lots of debugging stuff\n",
48 ;
49 exit 1;
50}
51
52if($basedir !~ m-/lib/modules-) {
53 warn "WARNING: base directory does not match ..../lib/modules\n";
54}
55
56# Find the list of .o files living under $basedir
57#if ($verbose) { printf "Locating all modules\n"; }
58my($file) = "";
59my(@liblist) = ();
60find sub {
61 if ( -f $_ && ! -d $_ ) {
62 $file = $File::Find::name;
63 if ( $file =~ /.o$/ ) {
64 push(@liblist, $file);
65 if ($verbose) { printf "$file\n"; }
66 }
67 }
68}, $basedir;
69if ($verbose) { printf "Finished locating modules\n"; }
70
71foreach $obj ( @liblist, $kernel ){
72 # turn the input file name into a target tag name
73 # vmlinux is a special that is only used to resolve symbols
74 if($obj =~ /vmlinux/) {
75 $tgtname = "vmlinux";
76 } else {
77 ($tgtname) = $obj =~ m-(/lib/modules/.*)$-;
78 }
79
80 warn "MODULE = $tgtname\n" if $verbose;
81
82 # get a list of symbols
83 @output=`nm $obj`;
84 $ksymtab=grep m/ __ksymtab/, @output;
85
86 # gather the exported symbols
87 if($ksymtab){
88 # explicitly exported
89 foreach ( @output ) {
90 / __ksymtab_(.*)$/ and do {
91 warn "sym = $1\n" if $verbose;
92 $exp->{$1} = $tgtname;
93 };
94 }
95 } else {
96 # exporting all symbols
97 foreach ( @output) {
98 / [ABCDGRST] (.*)$/ and do {
99 warn "syma = $1\n" if $verbose;
100 $exp->{$1} = $tgtname;
101 };
102 }
103 }
104 # gather the unresolved symbols
105 foreach ( @output ) {
106 !/ __this_module/ && / U (.*)$/ and do {
107 warn "und = $1\n" if $verbose;
108 push @{$dep->{$tgtname}}, $1;
109 };
110 }
111}
112
113
114# reduce dependancies: remove unresolvable and resolved from vmlinux
115# remove duplicates
116foreach $module (keys %$dep) {
117 $mod->{$module} = {};
118 foreach (@{$dep->{$module}}) {
119 if( $exp->{$_} ) {
120 warn "resolved symbol $_ in file $exp->{$_}\n" if $verbose;
121 next if $exp->{$_} =~ /vmlinux/;
122 $mod->{$module}{$exp->{$_}} = 1;
123 } else {
124 warn "unresolved symbol $_ in file $module\n";
125 }
126 }
127}
128
129# resolve the dependancies for each module
130foreach $module ( keys %$mod ) {
131 print "$module:\t";
132 @sorted = sort bydep keys %{$mod->{$module}};
133 print join(" \\\n\t",@sorted);
134# foreach $m (@sorted ) {
135# print "\t$m\n";
136# }
137 print "\n\n";
138}
139
140sub bydep
141{
142 foreach my $f ( keys %{$mod->{$b}} ) {
143 if($f eq $a) {
144 return 1;
145 }
146 }
147 return -1;
148}
149
150
151
152__END__
153
154=head1 NAME
155
156depmod.pl - a cross platform script to generate kernel module dependency
157 lists which can then be used by modprobe.
158
159=head1 SYNOPSIS
160
161depmod.pl [OPTION]... [FILE]...
162
163Example:
164
165 depmod.pl -F linux/System.map target/lib/modules
166
167=head1 DESCRIPTION
168
169The purpose of this script is to automagically generate a list of of kernel
170module dependancies. This script produces dependancy lists that should be
171identical to the depmod program from the modutils package. Unlike the depmod
172binary, however, depmod.pl is designed to be run on your host system, not
173on your target system.
174
175This script was written by David Schleef <ds@schleef.org> to be used in
176conjunction with the BusyBox modprobe applet.
177
178=head1 OPTIONS
179
180=over 4
181
182=item B<-h --help>
183
184This displays the help message.
185
186=item B<-b --basedir>
187
188The base directory uner which the target's modules will be found. This
189defaults to the /lib/modules directory.
190
191=item B<-k --kernel>
192
193Kernel binary for the target. You must either supply a kernel binary
194or a kernel symbol file (using the -F option).
195
196=item B<-F --kernelsyms>
197
198Kernel symbol file for the target. You must supply either a kernel symbol file
199kernel binary for the target (using the -k option).
200
201=item B<-n --stdout>
202
203Write to stdout instead of modules.dep. This is currently hard coded...
204kernel binary for the target (using the -k option).
205
206=item B<--verbose>
207
208Be verbose (not implemented)
209
210=back
211
212=head1 COPYRIGHT
213
214Copyright (c) 2001 David Schleef <ds@schleef.org>
215Copyright (c) 2001 Erik Andersen <andersen@lineo.com>
216Copyright (c) 2001 Stuart Hughes <stuarth@lineo.com>
217This program is free software; you can redistribute it and/or modify it
218under the same terms as Perl itself.
219
220=head1 AUTHOR
221
222David Schleef <ds@schleef.org>
223
224=cut
225
226# $Id: depmod.pl,v 1.1 2001/07/30 19:32:03 andersen Exp $
227
diff --git a/scripts/inittab b/scripts/inittab
deleted file mode 100644
index 8e7e945b3..000000000
--- a/scripts/inittab
+++ /dev/null
@@ -1,86 +0,0 @@
1# /etc/inittab init(8) configuration for BusyBox
2#
3# Copyright (C) 1999 by Lineo, inc. Written by Erik Andersen
4# <andersen@lineo.com>, <andersee@debian.org>
5#
6#
7# Note, BusyBox init doesn't support runlevels. The runlevels field is
8# completely ignored by BusyBox init. If you want runlevels, use sysvinit.
9#
10#
11# Format for each entry: <id>:<runlevels>:<action>:<process>
12#
13# <id>: WARNING: This field has a non-traditional meaning for BusyBox init!
14#
15# The id field is used by BusyBox init to specify the controlling tty for
16# the specified process to run on. The contents of this field are
17# appended to "/dev/" and used as-is. There is no need for this field to
18# be unique, although if it isn't you may have strange results. If this
19# field is left blank, it is completely ignored. Also note that if
20# BusyBox detects that a serial console is in use, then all entries
21# containing non-empty id fields will _not_ be run. BusyBox init does
22# nothing with utmp. We don't need no stinkin' utmp.
23#
24# <runlevels>: The runlevels field is completely ignored.
25#
26# <action>: Valid actions include: sysinit, respawn, askfirst, wait, once,
27# ctrlaltdel, and shutdown.
28#
29# Note: askfirst acts just like respawn, but before running the specified
30# process it displays the line "Please press Enter to activate this
31# console." and then waits for the user to press enter before starting
32# the specified process.
33#
34# Note: unrecognised actions (like initdefault) will cause init to emit
35# an error message, and then go along with its business.
36#
37# <process>: Specifies the process to be executed and it's command line.
38#
39# Note: BusyBox init works just fine without an inittab. If no inittab is
40# found, it has the following default behavior:
41# ::sysinit:/etc/init.d/rcS
42# ::askfirst:/bin/sh
43# ::ctrlaltdel:/sbin/reboot
44# ::shutdown:/sbin/swapoff -a
45# ::shutdown:/bin/umount -a -r
46# if it detects that /dev/console is _not_ a serial console, it will
47# also run:
48# tty2::askfirst:/bin/sh
49# tty3::askfirst:/bin/sh
50# tty4::askfirst:/bin/sh
51#
52# Boot-time system configuration/initialization script.
53# This is run first except when booting in single-user mode.
54#
55::sysinit:/etc/init.d/rcS
56
57# /bin/sh invocations on selected ttys
58#
59# Note below that we prefix the shell commands with a "-" to indicate to the
60# shell that it is supposed to be a login shell. Normally this is handled by
61# login, but since we are bypassing login in this case, BusyBox lets you do
62# this yourself...
63#
64# Start an "askfirst" shell on the console (whatever that may be)
65::askfirst:-/bin/sh
66# Start an "askfirst" shell on /dev/tty2-4
67tty2::askfirst:-/bin/sh
68tty3::askfirst:-/bin/sh
69tty4::askfirst:-/bin/sh
70
71# /sbin/getty invocations for selected ttys
72tty4::respawn:/sbin/getty 38400 tty5
73tty5::respawn:/sbin/getty 38400 tty6
74
75# Example of how to put a getty on a serial line (for a terminal)
76#::respawn:/sbin/getty -L ttyS0 9600 vt100
77#::respawn:/sbin/getty -L ttyS1 9600 vt100
78#
79# Example how to put a getty on a modem line.
80#::respawn:/sbin/getty 57600 ttyS2
81
82# Stuff to do before rebooting
83::ctrlaltdel:/sbin/reboot
84::shutdown:/bin/umount -a -r
85::shutdown:/sbin/swapoff -a
86
diff --git a/scripts/lxdialog/BIG.FAT.WARNING b/scripts/lxdialog/BIG.FAT.WARNING
new file mode 100644
index 000000000..a8999d82b
--- /dev/null
+++ b/scripts/lxdialog/BIG.FAT.WARNING
@@ -0,0 +1,4 @@
1This is NOT the official version of dialog. This version has been
2significantly modified from the original. It is for use by the Linux
3kernel configuration script. Please do not bother Savio Lam with
4questions about this program.
diff --git a/scripts/lxdialog/Makefile b/scripts/lxdialog/Makefile
new file mode 100644
index 000000000..ed8d17c37
--- /dev/null
+++ b/scripts/lxdialog/Makefile
@@ -0,0 +1,46 @@
1HOSTCFLAGS += -DLOCALE
2LIBS = -lncurses
3
4ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h))
5 HOSTCFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"
6else
7ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h))
8 HOSTCFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"
9else
10ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h))
11 HOSTCFLAGS += -DCURSES_LOC="<ncurses.h>"
12else
13 HOSTCFLAGS += -DCURSES_LOC="<curses.h>"
14endif
15endif
16endif
17
18
19OBJS = checklist.o menubox.o textbox.o yesno.o inputbox.o \
20 util.o lxdialog.o msgbox.o
21
22%.o: %.c
23 $(HOSTCC) $(HOSTCFLAGS) -c -o $@ $<
24
25all: ncurses lxdialog
26
27lxdialog: $(OBJS)
28 $(HOSTCC) -o lxdialog $(OBJS) $(LIBS)
29
30ncurses:
31 @echo "main() {}" > lxtemp.c
32 @if $(HOSTCC) -lncurses lxtemp.c ; then \
33 rm -f lxtemp.c a.out; \
34 else \
35 rm -f lxtemp.c; \
36 echo -e "\007" ;\
37 echo ">> Unable to find the Ncurses libraries." ;\
38 echo ">>" ;\
39 echo ">> You must have Ncurses installed in order" ;\
40 echo ">> to use 'make menuconfig'" ;\
41 echo ;\
42 exit 1 ;\
43 fi
44
45clean:
46 rm -f core *.o *~ lxdialog
diff --git a/scripts/lxdialog/Makefile-2.5 b/scripts/lxdialog/Makefile-2.5
new file mode 100644
index 000000000..665205200
--- /dev/null
+++ b/scripts/lxdialog/Makefile-2.5
@@ -0,0 +1,71 @@
1lxdialog-hostcflags += -DLOCALE
2lxdialog-libs = -lncurses
3
4ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h))
5 lxdialog-hostcflags += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"
6else
7ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h))
8 lxdialog-hostcflags += -I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"
9else
10ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h))
11 lxdialog-hostcflags += -DCURSES_LOC="<ncurses.h>"
12else
13 lxdialog-hostcflags += -DCURSES_LOC="<curses.h>"
14endif
15endif
16endif
17
18$(tmp_config)lxdialog-ncurses:
19 @mkdir -p $(lxdialog-objtree)
20 @( \
21 cd $(lxdialog-objtree) && \
22 echo "main() {}" > lxtemp.c && \
23 if $(HOSTCC) -lncurses lxtemp.c ; then \
24 rm -f lxtemp.c a.out && \
25 mkdir -p $(@D) && \
26 touch $@; \
27 else \
28 rm -f lxtemp.c; \
29 echo -e "\007" ;\
30 echo ">> Unable to find the Ncurses libraries." ;\
31 echo ">>" ;\
32 echo ">> You must have Ncurses installed in order" ;\
33 echo ">> to use 'make menuconfig'" ;\
34 echo ;\
35 exit 1 ;\
36 fi ; \
37 )
38
39lxdialog-objs := $(lxdialog-objtree)checklist.o $(lxdialog-objtree)menubox.o \
40 $(lxdialog-objtree)textbox.o $(lxdialog-objtree)yesno.o \
41 $(lxdialog-objtree)inputbox.o $(lxdialog-objtree)util.o \
42 $(lxdialog-objtree)lxdialog.o $(lxdialog-objtree)msgbox.o
43
44$(lxdialog-objtree)checklist.o: $(lxdialog-srctree)checklist.c $(tmp_config)lxdialog-ncurses
45 $(HOSTCC) $(HOSTCFLAGS) $(lxdialog-hostcflags) -c -o $@ $<
46
47$(lxdialog-objtree)menubox.o: $(lxdialog-srctree)menubox.c $(tmp_config)lxdialog-ncurses
48 $(HOSTCC) $(HOSTCFLAGS) $(lxdialog-hostcflags) -c -o $@ $<
49
50$(lxdialog-objtree)textbox.o: $(lxdialog-srctree)textbox.c $(tmp_config)lxdialog-ncurses
51 $(HOSTCC) $(HOSTCFLAGS) $(lxdialog-hostcflags) -c -o $@ $<
52
53$(lxdialog-objtree)yesno.o: $(lxdialog-srctree)yesno.c $(tmp_config)lxdialog-ncurses
54 $(HOSTCC) $(HOSTCFLAGS) $(lxdialog-hostcflags) -c -o $@ $<
55
56$(lxdialog-objtree)inputbox.o: $(lxdialog-srctree)inputbox.c $(tmp_config)lxdialog-ncurses
57 $(HOSTCC) $(HOSTCFLAGS) $(lxdialog-hostcflags) -c -o $@ $<
58
59$(lxdialog-objtree)util.o: $(lxdialog-srctree)util.c $(tmp_config)lxdialog-ncurses
60 $(HOSTCC) $(HOSTCFLAGS) $(lxdialog-hostcflags) -c -o $@ $<
61
62$(lxdialog-objtree)lxdialog.o: $(lxdialog-srctree)lxdialog.c $(tmp_config)lxdialog-ncurses
63 $(HOSTCC) $(HOSTCFLAGS) $(lxdialog-hostcflags) -c -o $@ $<
64
65$(lxdialog-objtree)msgbox.o: $(lxdialog-srctree)msgbox.c $(tmp_config)lxdialog-ncurses
66 $(HOSTCC) $(HOSTCFLAGS) $(lxdialog-hostcflags) -c -o $@ $<
67
68$(lxdialog-objtree)lxdialog: $(lxdialog-objs)
69 $(HOSTCC) -o $@ $(lxdialog-objs) $(lxdialog-libs)
70
71MRPROPER += $(lxdialog-objtree)lxdialog
diff --git a/scripts/lxdialog/checklist.c b/scripts/lxdialog/checklist.c
new file mode 100644
index 000000000..4f78688ed
--- /dev/null
+++ b/scripts/lxdialog/checklist.c
@@ -0,0 +1,369 @@
1/*
2 * checklist.c -- implements the checklist box
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
6 * Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
7 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "dialog.h"
25
26static int list_width, check_x, item_x, checkflag;
27
28/*
29 * Print list item
30 */
31static void
32print_item (WINDOW * win, const char *item, int status,
33 int choice, int selected)
34{
35 int i;
36
37 /* Clear 'residue' of last item */
38 wattrset (win, menubox_attr);
39 wmove (win, choice, 0);
40 for (i = 0; i < list_width; i++)
41 waddch (win, ' ');
42
43 wmove (win, choice, check_x);
44 wattrset (win, selected ? check_selected_attr : check_attr);
45 if (checkflag == FLAG_CHECK)
46 wprintw (win, "[%c]", status ? 'X' : ' ');
47 else
48 wprintw (win, "(%c)", status ? 'X' : ' ');
49
50 wattrset (win, selected ? tag_selected_attr : tag_attr);
51 mvwaddch(win, choice, item_x, item[0]);
52 wattrset (win, selected ? item_selected_attr : item_attr);
53 waddstr (win, (char *)item+1);
54 if (selected) {
55 wmove (win, choice, check_x+1);
56 wrefresh (win);
57 }
58}
59
60/*
61 * Print the scroll indicators.
62 */
63static void
64print_arrows (WINDOW * win, int choice, int item_no, int scroll,
65 int y, int x, int height)
66{
67 wmove(win, y, x);
68
69 if (scroll > 0) {
70 wattrset (win, uarrow_attr);
71 waddch (win, ACS_UARROW);
72 waddstr (win, "(-)");
73 }
74 else {
75 wattrset (win, menubox_attr);
76 waddch (win, ACS_HLINE);
77 waddch (win, ACS_HLINE);
78 waddch (win, ACS_HLINE);
79 waddch (win, ACS_HLINE);
80 }
81
82 y = y + height + 1;
83 wmove(win, y, x);
84
85 if ((height < item_no) && (scroll + choice < item_no - 1)) {
86 wattrset (win, darrow_attr);
87 waddch (win, ACS_DARROW);
88 waddstr (win, "(+)");
89 }
90 else {
91 wattrset (win, menubox_border_attr);
92 waddch (win, ACS_HLINE);
93 waddch (win, ACS_HLINE);
94 waddch (win, ACS_HLINE);
95 waddch (win, ACS_HLINE);
96 }
97}
98
99/*
100 * Display the termination buttons
101 */
102static void
103print_buttons( WINDOW *dialog, int height, int width, int selected)
104{
105 int x = width / 2 - 11;
106 int y = height - 2;
107
108 print_button (dialog, "Select", y, x, selected == 0);
109 print_button (dialog, " Help ", y, x + 14, selected == 1);
110
111 wmove(dialog, y, x+1 + 14*selected);
112 wrefresh (dialog);
113}
114
115/*
116 * Display a dialog box with a list of options that can be turned on or off
117 * The `flag' parameter is used to select between radiolist and checklist.
118 */
119int
120dialog_checklist (const char *title, const char *prompt, int height, int width,
121 int list_height, int item_no, const char * const * items, int flag)
122
123{
124 int i, x, y, box_x, box_y;
125 int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
126 WINDOW *dialog, *list;
127
128 checkflag = flag;
129
130 /* Allocate space for storing item on/off status */
131 if ((status = malloc (sizeof (int) * item_no)) == NULL) {
132 endwin ();
133 fprintf (stderr,
134 "\nCan't allocate memory in dialog_checklist().\n");
135 exit (-1);
136 }
137
138 /* Initializes status */
139 for (i = 0; i < item_no; i++) {
140 status[i] = !strcasecmp (items[i * 3 + 2], "on");
141 if (!choice && status[i])
142 choice = i;
143 }
144
145 max_choice = MIN (list_height, item_no);
146
147 /* center dialog box on screen */
148 x = (COLS - width) / 2;
149 y = (LINES - height) / 2;
150
151 draw_shadow (stdscr, y, x, height, width);
152
153 dialog = newwin (height, width, y, x);
154 keypad (dialog, TRUE);
155
156 draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
157 wattrset (dialog, border_attr);
158 mvwaddch (dialog, height-3, 0, ACS_LTEE);
159 for (i = 0; i < width - 2; i++)
160 waddch (dialog, ACS_HLINE);
161 wattrset (dialog, dialog_attr);
162 waddch (dialog, ACS_RTEE);
163
164 if (title != NULL && strlen(title) >= width-2 ) {
165 /* truncate long title -- mec */
166 char * title2 = malloc(width-2+1);
167 memcpy( title2, title, width-2 );
168 title2[width-2] = '\0';
169 title = title2;
170 }
171
172 if (title != NULL) {
173 wattrset (dialog, title_attr);
174 mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
175 waddstr (dialog, (char *)title);
176 waddch (dialog, ' ');
177 }
178
179 wattrset (dialog, dialog_attr);
180 print_autowrap (dialog, prompt, width - 2, 1, 3);
181
182 list_width = width - 6;
183 box_y = height - list_height - 5;
184 box_x = (width - list_width) / 2 - 1;
185
186 /* create new window for the list */
187 list = subwin (dialog, list_height, list_width, y+box_y+1, x+box_x+1);
188
189 keypad (list, TRUE);
190
191 /* draw a box around the list items */
192 draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2,
193 menubox_border_attr, menubox_attr);
194
195 /* Find length of longest item in order to center checklist */
196 check_x = 0;
197 for (i = 0; i < item_no; i++)
198 check_x = MAX (check_x, + strlen (items[i * 3 + 1]) + 4);
199
200 check_x = (list_width - check_x) / 2;
201 item_x = check_x + 4;
202
203 if (choice >= list_height) {
204 scroll = choice - list_height + 1;
205 choice -= scroll;
206 }
207
208 /* Print the list */
209 for (i = 0; i < max_choice; i++) {
210 print_item (list, items[(scroll+i) * 3 + 1],
211 status[i+scroll], i, i == choice);
212 }
213
214 print_arrows(dialog, choice, item_no, scroll,
215 box_y, box_x + check_x + 5, list_height);
216
217 print_buttons(dialog, height, width, 0);
218
219 wnoutrefresh (list);
220 wnoutrefresh (dialog);
221 doupdate ();
222
223 while (key != ESC) {
224 key = wgetch (dialog);
225
226 for (i = 0; i < max_choice; i++)
227 if (toupper(key) == toupper(items[(scroll+i)*3+1][0]))
228 break;
229
230
231 if ( i < max_choice || key == KEY_UP || key == KEY_DOWN ||
232 key == '+' || key == '-' ) {
233 if (key == KEY_UP || key == '-') {
234 if (!choice) {
235 if (!scroll)
236 continue;
237 /* Scroll list down */
238 if (list_height > 1) {
239 /* De-highlight current first item */
240 print_item (list, items[scroll * 3 + 1],
241 status[scroll], 0, FALSE);
242 scrollok (list, TRUE);
243 wscrl (list, -1);
244 scrollok (list, FALSE);
245 }
246 scroll--;
247 print_item (list, items[scroll * 3 + 1],
248 status[scroll], 0, TRUE);
249 wnoutrefresh (list);
250
251 print_arrows(dialog, choice, item_no, scroll,
252 box_y, box_x + check_x + 5, list_height);
253
254 wrefresh (dialog);
255
256 continue; /* wait for another key press */
257 } else
258 i = choice - 1;
259 } else if (key == KEY_DOWN || key == '+') {
260 if (choice == max_choice - 1) {
261 if (scroll + choice >= item_no - 1)
262 continue;
263 /* Scroll list up */
264 if (list_height > 1) {
265 /* De-highlight current last item before scrolling up */
266 print_item (list, items[(scroll + max_choice - 1) * 3 + 1],
267 status[scroll + max_choice - 1],
268 max_choice - 1, FALSE);
269 scrollok (list, TRUE);
270 scroll (list);
271 scrollok (list, FALSE);
272 }
273 scroll++;
274 print_item (list, items[(scroll + max_choice - 1) * 3 + 1],
275 status[scroll + max_choice - 1],
276 max_choice - 1, TRUE);
277 wnoutrefresh (list);
278
279 print_arrows(dialog, choice, item_no, scroll,
280 box_y, box_x + check_x + 5, list_height);
281
282 wrefresh (dialog);
283
284 continue; /* wait for another key press */
285 } else
286 i = choice + 1;
287 }
288 if (i != choice) {
289 /* De-highlight current item */
290 print_item (list, items[(scroll + choice) * 3 + 1],
291 status[scroll + choice], choice, FALSE);
292 /* Highlight new item */
293 choice = i;
294 print_item (list, items[(scroll + choice) * 3 + 1],
295 status[scroll + choice], choice, TRUE);
296 wnoutrefresh (list);
297 wrefresh (dialog);
298 }
299 continue; /* wait for another key press */
300 }
301 switch (key) {
302 case 'H':
303 case 'h':
304 case '?':
305 delwin (dialog);
306 free (status);
307 return 1;
308 case TAB:
309 case KEY_LEFT:
310 case KEY_RIGHT:
311 button = ((key == KEY_LEFT ? --button : ++button) < 0)
312 ? 1 : (button > 1 ? 0 : button);
313
314 print_buttons(dialog, height, width, button);
315 wrefresh (dialog);
316 break;
317 case 'S':
318 case 's':
319 case ' ':
320 case '\n':
321 if (!button) {
322 if (flag == FLAG_CHECK) {
323 status[scroll + choice] = !status[scroll + choice];
324 wmove (list, choice, check_x);
325 wattrset (list, check_selected_attr);
326 wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' ');
327 } else {
328 if (!status[scroll + choice]) {
329 for (i = 0; i < item_no; i++)
330 status[i] = 0;
331 status[scroll + choice] = 1;
332 for (i = 0; i < max_choice; i++)
333 print_item (list, items[(scroll + i) * 3 + 1],
334 status[scroll + i], i, i == choice);
335 }
336 }
337 wnoutrefresh (list);
338 wrefresh (dialog);
339
340 for (i = 0; i < item_no; i++) {
341 if (status[i]) {
342 if (flag == FLAG_CHECK) {
343 fprintf (stderr, "\"%s\" ", items[i * 3]);
344 } else {
345 fprintf (stderr, "%s", items[i * 3]);
346 }
347
348 }
349 }
350 }
351 delwin (dialog);
352 free (status);
353 return button;
354 case 'X':
355 case 'x':
356 key = ESC;
357 case ESC:
358 break;
359 }
360
361 /* Now, update everything... */
362 doupdate ();
363 }
364
365
366 delwin (dialog);
367 free (status);
368 return -1; /* ESC pressed */
369}
diff --git a/scripts/lxdialog/colors.h b/scripts/lxdialog/colors.h
new file mode 100644
index 000000000..d34dd37c6
--- /dev/null
+++ b/scripts/lxdialog/colors.h
@@ -0,0 +1,161 @@
1/*
2 * colors.h -- color attribute definitions
3 *
4 * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
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.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21
22/*
23 * Default color definitions
24 *
25 * *_FG = foreground
26 * *_BG = background
27 * *_HL = highlight?
28 */
29#define SCREEN_FG COLOR_CYAN
30#define SCREEN_BG COLOR_BLUE
31#define SCREEN_HL TRUE
32
33#define SHADOW_FG COLOR_BLACK
34#define SHADOW_BG COLOR_BLACK
35#define SHADOW_HL TRUE
36
37#define DIALOG_FG COLOR_BLACK
38#define DIALOG_BG COLOR_WHITE
39#define DIALOG_HL FALSE
40
41#define TITLE_FG COLOR_YELLOW
42#define TITLE_BG COLOR_WHITE
43#define TITLE_HL TRUE
44
45#define BORDER_FG COLOR_WHITE
46#define BORDER_BG COLOR_WHITE
47#define BORDER_HL TRUE
48
49#define BUTTON_ACTIVE_FG COLOR_WHITE
50#define BUTTON_ACTIVE_BG COLOR_BLUE
51#define BUTTON_ACTIVE_HL TRUE
52
53#define BUTTON_INACTIVE_FG COLOR_BLACK
54#define BUTTON_INACTIVE_BG COLOR_WHITE
55#define BUTTON_INACTIVE_HL FALSE
56
57#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE
58#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE
59#define BUTTON_KEY_ACTIVE_HL TRUE
60
61#define BUTTON_KEY_INACTIVE_FG COLOR_RED
62#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE
63#define BUTTON_KEY_INACTIVE_HL FALSE
64
65#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW
66#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE
67#define BUTTON_LABEL_ACTIVE_HL TRUE
68
69#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK
70#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE
71#define BUTTON_LABEL_INACTIVE_HL TRUE
72
73#define INPUTBOX_FG COLOR_BLACK
74#define INPUTBOX_BG COLOR_WHITE
75#define INPUTBOX_HL FALSE
76
77#define INPUTBOX_BORDER_FG COLOR_BLACK
78#define INPUTBOX_BORDER_BG COLOR_WHITE
79#define INPUTBOX_BORDER_HL FALSE
80
81#define SEARCHBOX_FG COLOR_BLACK
82#define SEARCHBOX_BG COLOR_WHITE
83#define SEARCHBOX_HL FALSE
84
85#define SEARCHBOX_TITLE_FG COLOR_YELLOW
86#define SEARCHBOX_TITLE_BG COLOR_WHITE
87#define SEARCHBOX_TITLE_HL TRUE
88
89#define SEARCHBOX_BORDER_FG COLOR_WHITE
90#define SEARCHBOX_BORDER_BG COLOR_WHITE
91#define SEARCHBOX_BORDER_HL TRUE
92
93#define POSITION_INDICATOR_FG COLOR_YELLOW
94#define POSITION_INDICATOR_BG COLOR_WHITE
95#define POSITION_INDICATOR_HL TRUE
96
97#define MENUBOX_FG COLOR_BLACK
98#define MENUBOX_BG COLOR_WHITE
99#define MENUBOX_HL FALSE
100
101#define MENUBOX_BORDER_FG COLOR_WHITE
102#define MENUBOX_BORDER_BG COLOR_WHITE
103#define MENUBOX_BORDER_HL TRUE
104
105#define ITEM_FG COLOR_BLACK
106#define ITEM_BG COLOR_WHITE
107#define ITEM_HL FALSE
108
109#define ITEM_SELECTED_FG COLOR_WHITE
110#define ITEM_SELECTED_BG COLOR_BLUE
111#define ITEM_SELECTED_HL TRUE
112
113#define TAG_FG COLOR_YELLOW
114#define TAG_BG COLOR_WHITE
115#define TAG_HL TRUE
116
117#define TAG_SELECTED_FG COLOR_YELLOW
118#define TAG_SELECTED_BG COLOR_BLUE
119#define TAG_SELECTED_HL TRUE
120
121#define TAG_KEY_FG COLOR_YELLOW
122#define TAG_KEY_BG COLOR_WHITE
123#define TAG_KEY_HL TRUE
124
125#define TAG_KEY_SELECTED_FG COLOR_YELLOW
126#define TAG_KEY_SELECTED_BG COLOR_BLUE
127#define TAG_KEY_SELECTED_HL TRUE
128
129#define CHECK_FG COLOR_BLACK
130#define CHECK_BG COLOR_WHITE
131#define CHECK_HL FALSE
132
133#define CHECK_SELECTED_FG COLOR_WHITE
134#define CHECK_SELECTED_BG COLOR_BLUE
135#define CHECK_SELECTED_HL TRUE
136
137#define UARROW_FG COLOR_GREEN
138#define UARROW_BG COLOR_WHITE
139#define UARROW_HL TRUE
140
141#define DARROW_FG COLOR_GREEN
142#define DARROW_BG COLOR_WHITE
143#define DARROW_HL TRUE
144
145/* End of default color definitions */
146
147#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
148#define COLOR_NAME_LEN 10
149#define COLOR_COUNT 8
150
151/*
152 * Global variables
153 */
154
155typedef struct {
156 char name[COLOR_NAME_LEN];
157 int value;
158} color_names_st;
159
160extern color_names_st color_names[];
161extern int color_table[][3];
diff --git a/scripts/lxdialog/dialog.h b/scripts/lxdialog/dialog.h
new file mode 100644
index 000000000..0e30d00d0
--- /dev/null
+++ b/scripts/lxdialog/dialog.h
@@ -0,0 +1,184 @@
1
2/*
3 * dialog.h -- common declarations for all dialog modules
4 *
5 * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <sys/types.h>
23#include <fcntl.h>
24#include <unistd.h>
25#include <ctype.h>
26#include <stdlib.h>
27#include <string.h>
28
29#include CURSES_LOC
30
31/*
32 * Colors in ncurses 1.9.9e do not work properly since foreground and
33 * background colors are OR'd rather than separately masked. This version
34 * of dialog was hacked to work with ncurses 1.9.9e, making it incompatible
35 * with standard curses. The simplest fix (to make this work with standard
36 * curses) uses the wbkgdset() function, not used in the original hack.
37 * Turn it off if we're building with 1.9.9e, since it just confuses things.
38 */
39#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE)
40#define OLD_NCURSES 1
41#undef wbkgdset
42#define wbkgdset(w,p) /*nothing*/
43#else
44#define OLD_NCURSES 0
45#endif
46
47#define TR(params) _tracef params
48
49#define ESC 27
50#define TAB 9
51#define MAX_LEN 2048
52#define BUF_SIZE (10*1024)
53#define MIN(x,y) (x < y ? x : y)
54#define MAX(x,y) (x > y ? x : y)
55
56
57#ifndef ACS_ULCORNER
58#define ACS_ULCORNER '+'
59#endif
60#ifndef ACS_LLCORNER
61#define ACS_LLCORNER '+'
62#endif
63#ifndef ACS_URCORNER
64#define ACS_URCORNER '+'
65#endif
66#ifndef ACS_LRCORNER
67#define ACS_LRCORNER '+'
68#endif
69#ifndef ACS_HLINE
70#define ACS_HLINE '-'
71#endif
72#ifndef ACS_VLINE
73#define ACS_VLINE '|'
74#endif
75#ifndef ACS_LTEE
76#define ACS_LTEE '+'
77#endif
78#ifndef ACS_RTEE
79#define ACS_RTEE '+'
80#endif
81#ifndef ACS_UARROW
82#define ACS_UARROW '^'
83#endif
84#ifndef ACS_DARROW
85#define ACS_DARROW 'v'
86#endif
87
88/*
89 * Attribute names
90 */
91#define screen_attr attributes[0]
92#define shadow_attr attributes[1]
93#define dialog_attr attributes[2]
94#define title_attr attributes[3]
95#define border_attr attributes[4]
96#define button_active_attr attributes[5]
97#define button_inactive_attr attributes[6]
98#define button_key_active_attr attributes[7]
99#define button_key_inactive_attr attributes[8]
100#define button_label_active_attr attributes[9]
101#define button_label_inactive_attr attributes[10]
102#define inputbox_attr attributes[11]
103#define inputbox_border_attr attributes[12]
104#define searchbox_attr attributes[13]
105#define searchbox_title_attr attributes[14]
106#define searchbox_border_attr attributes[15]
107#define position_indicator_attr attributes[16]
108#define menubox_attr attributes[17]
109#define menubox_border_attr attributes[18]
110#define item_attr attributes[19]
111#define item_selected_attr attributes[20]
112#define tag_attr attributes[21]
113#define tag_selected_attr attributes[22]
114#define tag_key_attr attributes[23]
115#define tag_key_selected_attr attributes[24]
116#define check_attr attributes[25]
117#define check_selected_attr attributes[26]
118#define uarrow_attr attributes[27]
119#define darrow_attr attributes[28]
120
121/* number of attributes */
122#define ATTRIBUTE_COUNT 29
123
124/*
125 * Global variables
126 */
127extern bool use_colors;
128extern bool use_shadow;
129
130extern chtype attributes[];
131
132extern const char *backtitle;
133
134/*
135 * Function prototypes
136 */
137extern void create_rc (const char *filename);
138extern int parse_rc (void);
139
140
141void init_dialog (void);
142void end_dialog (void);
143void attr_clear (WINDOW * win, int height, int width, chtype attr);
144void dialog_clear (void);
145void color_setup (void);
146void print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x);
147void print_button (WINDOW * win, const char *label, int y, int x, int selected);
148void draw_box (WINDOW * win, int y, int x, int height, int width, chtype box,
149 chtype border);
150void draw_shadow (WINDOW * win, int y, int x, int height, int width);
151
152int first_alpha (const char *string, const char *exempt);
153int dialog_yesno (const char *title, const char *prompt, int height, int width);
154int dialog_msgbox (const char *title, const char *prompt, int height,
155 int width, int pause);
156int dialog_textbox (const char *title, const char *file, int height, int width);
157int dialog_menu (const char *title, const char *prompt, int height, int width,
158 int menu_height, const char *choice, int item_no,
159 const char * const * items);
160int dialog_checklist (const char *title, const char *prompt, int height,
161 int width, int list_height, int item_no,
162 const char * const * items, int flag);
163extern unsigned char dialog_input_result[];
164int dialog_inputbox (const char *title, const char *prompt, int height,
165 int width, const char *init);
166
167/*
168 * This is the base for fictitious keys, which activate
169 * the buttons.
170 *
171 * Mouse-generated keys are the following:
172 * -- the first 32 are used as numbers, in addition to '0'-'9'
173 * -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o')
174 * -- uppercase chars are used to invoke the button (M_EVENT + 'O')
175 */
176#define M_EVENT (KEY_MAX+1)
177
178
179/*
180 * The `flag' parameter in checklist is used to select between
181 * radiolist and checklist
182 */
183#define FLAG_CHECK 1
184#define FLAG_RADIO 0
diff --git a/scripts/lxdialog/inputbox.c b/scripts/lxdialog/inputbox.c
new file mode 100644
index 000000000..fa7bebc69
--- /dev/null
+++ b/scripts/lxdialog/inputbox.c
@@ -0,0 +1,240 @@
1/*
2 * inputbox.c -- implements the input box
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "dialog.h"
23
24unsigned char dialog_input_result[MAX_LEN + 1];
25
26/*
27 * Print the termination buttons
28 */
29static void
30print_buttons(WINDOW *dialog, int height, int width, int selected)
31{
32 int x = width / 2 - 11;
33 int y = height - 2;
34
35 print_button (dialog, " Ok ", y, x, selected==0);
36 print_button (dialog, " Help ", y, x + 14, selected==1);
37
38 wmove(dialog, y, x+1+14*selected);
39 wrefresh(dialog);
40}
41
42/*
43 * Display a dialog box for inputing a string
44 */
45int
46dialog_inputbox (const char *title, const char *prompt, int height, int width,
47 const char *init)
48{
49 int i, x, y, box_y, box_x, box_width;
50 int input_x = 0, scroll = 0, key = 0, button = -1;
51 unsigned char *instr = dialog_input_result;
52 WINDOW *dialog;
53
54 /* center dialog box on screen */
55 x = (COLS - width) / 2;
56 y = (LINES - height) / 2;
57
58
59 draw_shadow (stdscr, y, x, height, width);
60
61 dialog = newwin (height, width, y, x);
62 keypad (dialog, TRUE);
63
64 draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
65 wattrset (dialog, border_attr);
66 mvwaddch (dialog, height-3, 0, ACS_LTEE);
67 for (i = 0; i < width - 2; i++)
68 waddch (dialog, ACS_HLINE);
69 wattrset (dialog, dialog_attr);
70 waddch (dialog, ACS_RTEE);
71
72 if (title != NULL && strlen(title) >= width-2 ) {
73 /* truncate long title -- mec */
74 char * title2 = malloc(width-2+1);
75 memcpy( title2, title, width-2 );
76 title2[width-2] = '\0';
77 title = title2;
78 }
79
80 if (title != NULL) {
81 wattrset (dialog, title_attr);
82 mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
83 waddstr (dialog, (char *)title);
84 waddch (dialog, ' ');
85 }
86
87 wattrset (dialog, dialog_attr);
88 print_autowrap (dialog, prompt, width - 2, 1, 3);
89
90 /* Draw the input field box */
91 box_width = width - 6;
92 getyx (dialog, y, x);
93 box_y = y + 2;
94 box_x = (width - box_width) / 2;
95 draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2,
96 border_attr, dialog_attr);
97
98 print_buttons(dialog, height, width, 0);
99
100 /* Set up the initial value */
101 wmove (dialog, box_y, box_x);
102 wattrset (dialog, inputbox_attr);
103
104 if (!init)
105 instr[0] = '\0';
106 else
107 strcpy (instr, init);
108
109 input_x = strlen (instr);
110
111 if (input_x >= box_width) {
112 scroll = input_x - box_width + 1;
113 input_x = box_width - 1;
114 for (i = 0; i < box_width - 1; i++)
115 waddch (dialog, instr[scroll + i]);
116 } else
117 waddstr (dialog, instr);
118
119 wmove (dialog, box_y, box_x + input_x);
120
121 wrefresh (dialog);
122
123 while (key != ESC) {
124 key = wgetch (dialog);
125
126 if (button == -1) { /* Input box selected */
127 switch (key) {
128 case TAB:
129 case KEY_UP:
130 case KEY_DOWN:
131 break;
132 case KEY_LEFT:
133 continue;
134 case KEY_RIGHT:
135 continue;
136 case KEY_BACKSPACE:
137 case 127:
138 if (input_x || scroll) {
139 wattrset (dialog, inputbox_attr);
140 if (!input_x) {
141 scroll = scroll < box_width - 1 ?
142 0 : scroll - (box_width - 1);
143 wmove (dialog, box_y, box_x);
144 for (i = 0; i < box_width; i++)
145 waddch (dialog, instr[scroll + input_x + i] ?
146 instr[scroll + input_x + i] : ' ');
147 input_x = strlen (instr) - scroll;
148 } else
149 input_x--;
150 instr[scroll + input_x] = '\0';
151 mvwaddch (dialog, box_y, input_x + box_x, ' ');
152 wmove (dialog, box_y, input_x + box_x);
153 wrefresh (dialog);
154 }
155 continue;
156 default:
157 if (key < 0x100 && isprint (key)) {
158 if (scroll + input_x < MAX_LEN) {
159 wattrset (dialog, inputbox_attr);
160 instr[scroll + input_x] = key;
161 instr[scroll + input_x + 1] = '\0';
162 if (input_x == box_width - 1) {
163 scroll++;
164 wmove (dialog, box_y, box_x);
165 for (i = 0; i < box_width - 1; i++)
166 waddch (dialog, instr[scroll + i]);
167 } else {
168 wmove (dialog, box_y, input_x++ + box_x);
169 waddch (dialog, key);
170 }
171 wrefresh (dialog);
172 } else
173 flash (); /* Alarm user about overflow */
174 continue;
175 }
176 }
177 }
178 switch (key) {
179 case 'O':
180 case 'o':
181 delwin (dialog);
182 return 0;
183 case 'H':
184 case 'h':
185 delwin (dialog);
186 return 1;
187 case KEY_UP:
188 case KEY_LEFT:
189 switch (button) {
190 case -1:
191 button = 1; /* Indicates "Cancel" button is selected */
192 print_buttons(dialog, height, width, 1);
193 break;
194 case 0:
195 button = -1; /* Indicates input box is selected */
196 print_buttons(dialog, height, width, 0);
197 wmove (dialog, box_y, box_x + input_x);
198 wrefresh (dialog);
199 break;
200 case 1:
201 button = 0; /* Indicates "OK" button is selected */
202 print_buttons(dialog, height, width, 0);
203 break;
204 }
205 break;
206 case TAB:
207 case KEY_DOWN:
208 case KEY_RIGHT:
209 switch (button) {
210 case -1:
211 button = 0; /* Indicates "OK" button is selected */
212 print_buttons(dialog, height, width, 0);
213 break;
214 case 0:
215 button = 1; /* Indicates "Cancel" button is selected */
216 print_buttons(dialog, height, width, 1);
217 break;
218 case 1:
219 button = -1; /* Indicates input box is selected */
220 print_buttons(dialog, height, width, 0);
221 wmove (dialog, box_y, box_x + input_x);
222 wrefresh (dialog);
223 break;
224 }
225 break;
226 case ' ':
227 case '\n':
228 delwin (dialog);
229 return (button == -1 ? 0 : button);
230 case 'X':
231 case 'x':
232 key = ESC;
233 case ESC:
234 break;
235 }
236 }
237
238 delwin (dialog);
239 return -1; /* ESC pressed */
240}
diff --git a/scripts/lxdialog/lxdialog.c b/scripts/lxdialog/lxdialog.c
new file mode 100644
index 000000000..6f4c1fd4e
--- /dev/null
+++ b/scripts/lxdialog/lxdialog.c
@@ -0,0 +1,226 @@
1/*
2 * dialog - Display simple dialog boxes from shell scripts
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "dialog.h"
23
24static void Usage (const char *name);
25
26typedef int (jumperFn) (const char *title, int argc, const char * const * argv);
27
28struct Mode {
29 char *name;
30 int argmin, argmax, argmod;
31 jumperFn *jumper;
32};
33
34jumperFn j_menu, j_checklist, j_radiolist, j_yesno, j_textbox, j_inputbox;
35jumperFn j_msgbox, j_infobox;
36
37static struct Mode modes[] =
38{
39 {"--menu", 9, 0, 3, j_menu},
40 {"--checklist", 9, 0, 3, j_checklist},
41 {"--radiolist", 9, 0, 3, j_radiolist},
42 {"--yesno", 5,5,1, j_yesno},
43 {"--textbox", 5,5,1, j_textbox},
44 {"--inputbox", 5, 6, 1, j_inputbox},
45 {"--msgbox", 5, 5, 1, j_msgbox},
46 {"--infobox", 5, 5, 1, j_infobox},
47 {NULL, 0, 0, 0, NULL}
48};
49
50static struct Mode *modePtr;
51
52#ifdef LOCALE
53#include <locale.h>
54#endif
55
56int
57main (int argc, const char * const * argv)
58{
59 int offset = 0, clear_screen = 0, end_common_opts = 0, retval;
60 const char *title = NULL;
61
62#ifdef LOCALE
63 (void) setlocale (LC_ALL, "");
64#endif
65
66#ifdef TRACE
67 trace(TRACE_CALLS|TRACE_UPDATE);
68#endif
69 if (argc < 2) {
70 Usage (argv[0]);
71 exit (-1);
72 }
73
74 while (offset < argc - 1 && !end_common_opts) { /* Common options */
75 if (!strcmp (argv[offset + 1], "--title")) {
76 if (argc - offset < 3 || title != NULL) {
77 Usage (argv[0]);
78 exit (-1);
79 } else {
80 title = argv[offset + 2];
81 offset += 2;
82 }
83 } else if (!strcmp (argv[offset + 1], "--backtitle")) {
84 if (backtitle != NULL) {
85 Usage (argv[0]);
86 exit (-1);
87 } else {
88 backtitle = argv[offset + 2];
89 offset += 2;
90 }
91 } else if (!strcmp (argv[offset + 1], "--clear")) {
92 if (clear_screen) { /* Hey, "--clear" can't appear twice! */
93 Usage (argv[0]);
94 exit (-1);
95 } else if (argc == 2) { /* we only want to clear the screen */
96 init_dialog ();
97 refresh (); /* init_dialog() will clear the screen for us */
98 end_dialog ();
99 return 0;
100 } else {
101 clear_screen = 1;
102 offset++;
103 }
104 } else /* no more common options */
105 end_common_opts = 1;
106 }
107
108 if (argc - 1 == offset) { /* no more options */
109 Usage (argv[0]);
110 exit (-1);
111 }
112 /* use a table to look for the requested mode, to avoid code duplication */
113
114 for (modePtr = modes; modePtr->name; modePtr++) /* look for the mode */
115 if (!strcmp (argv[offset + 1], modePtr->name))
116 break;
117
118 if (!modePtr->name)
119 Usage (argv[0]);
120 if (argc - offset < modePtr->argmin)
121 Usage (argv[0]);
122 if (modePtr->argmax && argc - offset > modePtr->argmax)
123 Usage (argv[0]);
124
125
126
127 init_dialog ();
128 retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset);
129
130 if (clear_screen) { /* clear screen before exit */
131 attr_clear (stdscr, LINES, COLS, screen_attr);
132 refresh ();
133 }
134 end_dialog();
135
136 exit (retval);
137}
138
139/*
140 * Print program usage
141 */
142static void
143Usage (const char *name)
144{
145 fprintf (stderr, "\
146\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\
147\n patched by Stuart Herbert (S.Herbert@shef.ac.uk)\
148\n modified/gutted for use as a Linux kernel config tool by \
149\n William Roadcap (roadcapw@cfw.com)\
150\n\
151\n* Display dialog boxes from shell scripts *\
152\n\
153\nUsage: %s --clear\
154\n %s [--title <title>] [--backtitle <backtitle>] --clear <Box options>\
155\n\
156\nBox options:\
157\n\
158\n --menu <text> <height> <width> <menu height> <tag1> <item1>...\
159\n --checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
160\n --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
161\n --textbox <file> <height> <width>\
162\n --inputbox <text> <height> <width> [<init>]\
163\n --yesno <text> <height> <width>\
164\n", name, name);
165 exit (-1);
166}
167
168/*
169 * These are the program jumpers
170 */
171
172int
173j_menu (const char *t, int ac, const char * const * av)
174{
175 return dialog_menu (t, av[2], atoi (av[3]), atoi (av[4]),
176 atoi (av[5]), av[6], (ac - 6) / 2, av + 7);
177}
178
179int
180j_checklist (const char *t, int ac, const char * const * av)
181{
182 return dialog_checklist (t, av[2], atoi (av[3]), atoi (av[4]),
183 atoi (av[5]), (ac - 6) / 3, av + 6, FLAG_CHECK);
184}
185
186int
187j_radiolist (const char *t, int ac, const char * const * av)
188{
189 return dialog_checklist (t, av[2], atoi (av[3]), atoi (av[4]),
190 atoi (av[5]), (ac - 6) / 3, av + 6, FLAG_RADIO);
191}
192
193int
194j_textbox (const char *t, int ac, const char * const * av)
195{
196 return dialog_textbox (t, av[2], atoi (av[3]), atoi (av[4]));
197}
198
199int
200j_yesno (const char *t, int ac, const char * const * av)
201{
202 return dialog_yesno (t, av[2], atoi (av[3]), atoi (av[4]));
203}
204
205int
206j_inputbox (const char *t, int ac, const char * const * av)
207{
208 int ret = dialog_inputbox (t, av[2], atoi (av[3]), atoi (av[4]),
209 ac == 6 ? av[5] : (char *) NULL);
210 if (ret == 0)
211 fprintf(stderr, dialog_input_result);
212 return ret;
213}
214
215int
216j_msgbox (const char *t, int ac, const char * const * av)
217{
218 return dialog_msgbox (t, av[2], atoi (av[3]), atoi (av[4]), 1);
219}
220
221int
222j_infobox (const char *t, int ac, const char * const * av)
223{
224 return dialog_msgbox (t, av[2], atoi (av[3]), atoi (av[4]), 0);
225}
226
diff --git a/scripts/lxdialog/menubox.c b/scripts/lxdialog/menubox.c
new file mode 100644
index 000000000..a234e9f3b
--- /dev/null
+++ b/scripts/lxdialog/menubox.c
@@ -0,0 +1,443 @@
1/*
2 * menubox.c -- implements the menu box
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22/*
23 * Changes by Clifford Wolf (god@clifford.at)
24 *
25 * [ 1998-06-13 ]
26 *
27 * *) A bugfix for the Page-Down problem
28 *
29 * *) Formerly when I used Page Down and Page Up, the cursor would be set
30 * to the first position in the menu box. Now lxdialog is a bit
31 * smarter and works more like other menu systems (just have a look at
32 * it).
33 *
34 * *) Formerly if I selected something my scrolling would be broken because
35 * lxdialog is re-invoked by the Menuconfig shell script, can't
36 * remember the last scrolling position, and just sets it so that the
37 * cursor is at the bottom of the box. Now it writes the temporary file
38 * lxdialog.scrltmp which contains this information. The file is
39 * deleted by lxdialog if the user leaves a submenu or enters a new
40 * one, but it would be nice if Menuconfig could make another "rm -f"
41 * just to be sure. Just try it out - you will recognise a difference!
42 *
43 * [ 1998-06-14 ]
44 *
45 * *) Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
46 * and menus change their size on the fly.
47 *
48 * *) If for some reason the last scrolling position is not saved by
49 * lxdialog, it sets the scrolling so that the selected item is in the
50 * middle of the menu box, not at the bottom.
51 *
52 * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
53 * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
54 * This fixes a bug in Menuconfig where using ' ' to descend into menus
55 * would leave mis-synchronized lxdialog.scrltmp files lying around,
56 * fscanf would read in 'scroll', and eventually that value would get used.
57 */
58
59#include "dialog.h"
60
61static int menu_width, item_x;
62
63/*
64 * Print menu item
65 */
66static void
67print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey)
68{
69 int j;
70 char menu_item[menu_width+1];
71
72 strncpy(menu_item, item, menu_width);
73 menu_item[menu_width] = 0;
74 j = first_alpha(menu_item, "YyNnMm");
75
76 /* Clear 'residue' of last item */
77 wattrset (win, menubox_attr);
78 wmove (win, choice, 0);
79#if OLD_NCURSES
80 {
81 int i;
82 for (i = 0; i < menu_width; i++)
83 waddch (win, ' ');
84 }
85#else
86 wclrtoeol(win);
87#endif
88 wattrset (win, selected ? item_selected_attr : item_attr);
89 mvwaddstr (win, choice, item_x, menu_item);
90 if (hotkey) {
91 wattrset (win, selected ? tag_key_selected_attr : tag_key_attr);
92 mvwaddch(win, choice, item_x+j, menu_item[j]);
93 }
94 if (selected) {
95 wmove (win, choice, item_x+1);
96 wrefresh (win);
97 }
98}
99
100/*
101 * Print the scroll indicators.
102 */
103static void
104print_arrows (WINDOW * win, int item_no, int scroll,
105 int y, int x, int height)
106{
107 int cur_y, cur_x;
108
109 getyx(win, cur_y, cur_x);
110
111 wmove(win, y, x);
112
113 if (scroll > 0) {
114 wattrset (win, uarrow_attr);
115 waddch (win, ACS_UARROW);
116 waddstr (win, "(-)");
117 }
118 else {
119 wattrset (win, menubox_attr);
120 waddch (win, ACS_HLINE);
121 waddch (win, ACS_HLINE);
122 waddch (win, ACS_HLINE);
123 waddch (win, ACS_HLINE);
124 }
125
126 y = y + height + 1;
127 wmove(win, y, x);
128
129 if ((height < item_no) && (scroll + height < item_no)) {
130 wattrset (win, darrow_attr);
131 waddch (win, ACS_DARROW);
132 waddstr (win, "(+)");
133 }
134 else {
135 wattrset (win, menubox_border_attr);
136 waddch (win, ACS_HLINE);
137 waddch (win, ACS_HLINE);
138 waddch (win, ACS_HLINE);
139 waddch (win, ACS_HLINE);
140 }
141
142 wmove(win, cur_y, cur_x);
143}
144
145/*
146 * Display the termination buttons.
147 */
148static void
149print_buttons (WINDOW *win, int height, int width, int selected)
150{
151 int x = width / 2 - 16;
152 int y = height - 2;
153
154 print_button (win, "Select", y, x, selected == 0);
155 print_button (win, " Exit ", y, x + 12, selected == 1);
156 print_button (win, " Help ", y, x + 24, selected == 2);
157
158 wmove(win, y, x+1+12*selected);
159 wrefresh (win);
160}
161
162/*
163 * Display a menu for choosing among a number of options
164 */
165int
166dialog_menu (const char *title, const char *prompt, int height, int width,
167 int menu_height, const char *current, int item_no,
168 const char * const * items)
169
170{
171 int i, j, x, y, box_x, box_y;
172 int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice;
173 WINDOW *dialog, *menu;
174 FILE *f;
175
176 max_choice = MIN (menu_height, item_no);
177
178 /* center dialog box on screen */
179 x = (COLS - width) / 2;
180 y = (LINES - height) / 2;
181
182 draw_shadow (stdscr, y, x, height, width);
183
184 dialog = newwin (height, width, y, x);
185 keypad (dialog, TRUE);
186
187 draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
188 wattrset (dialog, border_attr);
189 mvwaddch (dialog, height - 3, 0, ACS_LTEE);
190 for (i = 0; i < width - 2; i++)
191 waddch (dialog, ACS_HLINE);
192 wattrset (dialog, dialog_attr);
193 wbkgdset (dialog, dialog_attr & A_COLOR);
194 waddch (dialog, ACS_RTEE);
195
196 if (title != NULL && strlen(title) >= width-2 ) {
197 /* truncate long title -- mec */
198 char * title2 = malloc(width-2+1);
199 memcpy( title2, title, width-2 );
200 title2[width-2] = '\0';
201 title = title2;
202 }
203
204 if (title != NULL) {
205 wattrset (dialog, title_attr);
206 mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
207 waddstr (dialog, (char *)title);
208 waddch (dialog, ' ');
209 }
210
211 wattrset (dialog, dialog_attr);
212 print_autowrap (dialog, prompt, width - 2, 1, 3);
213
214 menu_width = width - 6;
215 box_y = height - menu_height - 5;
216 box_x = (width - menu_width) / 2 - 1;
217
218 /* create new window for the menu */
219 menu = subwin (dialog, menu_height, menu_width,
220 y + box_y + 1, x + box_x + 1);
221 keypad (menu, TRUE);
222
223 /* draw a box around the menu items */
224 draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2,
225 menubox_border_attr, menubox_attr);
226
227 /*
228 * Find length of longest item in order to center menu.
229 * Set 'choice' to default item.
230 */
231 item_x = 0;
232 for (i = 0; i < item_no; i++) {
233 item_x = MAX (item_x, MIN(menu_width, strlen (items[i * 2 + 1]) + 2));
234 if (strcmp(current, items[i*2]) == 0) choice = i;
235 }
236
237 item_x = (menu_width - item_x) / 2;
238
239 /* get the scroll info from the temp file */
240 if ( (f=fopen("lxdialog.scrltmp","r")) != NULL ) {
241 if ( (fscanf(f,"%d\n",&scroll) == 1) && (scroll <= choice) &&
242 (scroll+max_choice > choice) && (scroll >= 0) &&
243 (scroll+max_choice <= item_no) ) {
244 first_item = scroll;
245 choice = choice - scroll;
246 fclose(f);
247 } else {
248 scroll=0;
249 remove("lxdialog.scrltmp");
250 fclose(f);
251 f=NULL;
252 }
253 }
254 if ( (choice >= max_choice) || (f==NULL && choice >= max_choice/2) ) {
255 if (choice >= item_no-max_choice/2)
256 scroll = first_item = item_no-max_choice;
257 else
258 scroll = first_item = choice - max_choice/2;
259 choice = choice - scroll;
260 }
261
262 /* Print the menu */
263 for (i=0; i < max_choice; i++) {
264 print_item (menu, items[(first_item + i) * 2 + 1], i, i == choice,
265 (items[(first_item + i)*2][0] != ':'));
266 }
267
268 wnoutrefresh (menu);
269
270 print_arrows(dialog, item_no, scroll,
271 box_y, box_x+item_x+1, menu_height);
272
273 print_buttons (dialog, height, width, 0);
274 wmove (menu, choice, item_x+1);
275 wrefresh (menu);
276
277 while (key != ESC) {
278 key = wgetch(menu);
279
280 if (key < 256 && isalpha(key)) key = tolower(key);
281
282 if (strchr("ynm", key))
283 i = max_choice;
284 else {
285 for (i = choice+1; i < max_choice; i++) {
286 j = first_alpha(items[(scroll+i)*2+1], "YyNnMm");
287 if (key == tolower(items[(scroll+i)*2+1][j]))
288 break;
289 }
290 if (i == max_choice)
291 for (i = 0; i < max_choice; i++) {
292 j = first_alpha(items[(scroll+i)*2+1], "YyNnMm");
293 if (key == tolower(items[(scroll+i)*2+1][j]))
294 break;
295 }
296 }
297
298 if (i < max_choice ||
299 key == KEY_UP || key == KEY_DOWN ||
300 key == '-' || key == '+' ||
301 key == KEY_PPAGE || key == KEY_NPAGE) {
302
303 print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
304 (items[(scroll+choice)*2][0] != ':'));
305
306 if (key == KEY_UP || key == '-') {
307 if (choice < 2 && scroll) {
308 /* Scroll menu down */
309 scrollok (menu, TRUE);
310 wscrl (menu, -1);
311 scrollok (menu, FALSE);
312
313 scroll--;
314
315 print_item (menu, items[scroll * 2 + 1], 0, FALSE,
316 (items[scroll*2][0] != ':'));
317 } else
318 choice = MAX(choice - 1, 0);
319
320 } else if (key == KEY_DOWN || key == '+') {
321
322 print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
323 (items[(scroll+choice)*2][0] != ':'));
324
325 if ((choice > max_choice-3) &&
326 (scroll + max_choice < item_no)
327 ) {
328 /* Scroll menu up */
329 scrollok (menu, TRUE);
330 scroll (menu);
331 scrollok (menu, FALSE);
332
333 scroll++;
334
335 print_item (menu, items[(scroll+max_choice-1)*2+1],
336 max_choice-1, FALSE,
337 (items[(scroll+max_choice-1)*2][0] != ':'));
338 } else
339 choice = MIN(choice+1, max_choice-1);
340
341 } else if (key == KEY_PPAGE) {
342 scrollok (menu, TRUE);
343 for (i=0; (i < max_choice); i++) {
344 if (scroll > 0) {
345 wscrl (menu, -1);
346 scroll--;
347 print_item (menu, items[scroll * 2 + 1], 0, FALSE,
348 (items[scroll*2][0] != ':'));
349 } else {
350 if (choice > 0)
351 choice--;
352 }
353 }
354 scrollok (menu, FALSE);
355
356 } else if (key == KEY_NPAGE) {
357 for (i=0; (i < max_choice); i++) {
358 if (scroll+max_choice < item_no) {
359 scrollok (menu, TRUE);
360 scroll(menu);
361 scrollok (menu, FALSE);
362 scroll++;
363 print_item (menu, items[(scroll+max_choice-1)*2+1],
364 max_choice-1, FALSE,
365 (items[(scroll+max_choice-1)*2][0] != ':'));
366 } else {
367 if (choice+1 < max_choice)
368 choice++;
369 }
370 }
371
372 } else
373 choice = i;
374
375 print_item (menu, items[(scroll+choice)*2+1], choice, TRUE,
376 (items[(scroll+choice)*2][0] != ':'));
377
378 print_arrows(dialog, item_no, scroll,
379 box_y, box_x+item_x+1, menu_height);
380
381 wnoutrefresh (dialog);
382 wrefresh (menu);
383
384 continue; /* wait for another key press */
385 }
386
387 switch (key) {
388 case KEY_LEFT:
389 case TAB:
390 case KEY_RIGHT:
391 button = ((key == KEY_LEFT ? --button : ++button) < 0)
392 ? 2 : (button > 2 ? 0 : button);
393
394 print_buttons(dialog, height, width, button);
395 wrefresh (menu);
396 break;
397 case ' ':
398 case 's':
399 case 'y':
400 case 'n':
401 case 'm':
402 /* save scroll info */
403 if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) {
404 fprintf(f,"%d\n",scroll);
405 fclose(f);
406 }
407 delwin (dialog);
408 fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
409 switch (key) {
410 case 's': return 3;
411 case 'y': return 3;
412 case 'n': return 4;
413 case 'm': return 5;
414 case ' ': return 6;
415 }
416 return 0;
417 case 'h':
418 case '?':
419 button = 2;
420 case '\n':
421 delwin (dialog);
422 if (button == 2)
423 fprintf(stderr, "%s \"%s\"\n",
424 items[(scroll + choice) * 2],
425 items[(scroll + choice) * 2 + 1] +
426 first_alpha(items[(scroll + choice) * 2 + 1],""));
427 else
428 fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
429
430 remove("lxdialog.scrltmp");
431 return button;
432 case 'e':
433 case 'x':
434 key = ESC;
435 case ESC:
436 break;
437 }
438 }
439
440 delwin (dialog);
441 remove("lxdialog.scrltmp");
442 return -1; /* ESC pressed */
443}
diff --git a/scripts/lxdialog/msgbox.c b/scripts/lxdialog/msgbox.c
new file mode 100644
index 000000000..93692e1fb
--- /dev/null
+++ b/scripts/lxdialog/msgbox.c
@@ -0,0 +1,85 @@
1/*
2 * msgbox.c -- implements the message box and info box
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "dialog.h"
23
24/*
25 * Display a message box. Program will pause and display an "OK" button
26 * if the parameter 'pause' is non-zero.
27 */
28int
29dialog_msgbox (const char *title, const char *prompt, int height, int width,
30 int pause)
31{
32 int i, x, y, key = 0;
33 WINDOW *dialog;
34
35 /* center dialog box on screen */
36 x = (COLS - width) / 2;
37 y = (LINES - height) / 2;
38
39 draw_shadow (stdscr, y, x, height, width);
40
41 dialog = newwin (height, width, y, x);
42 keypad (dialog, TRUE);
43
44 draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
45
46 if (title != NULL && strlen(title) >= width-2 ) {
47 /* truncate long title -- mec */
48 char * title2 = malloc(width-2+1);
49 memcpy( title2, title, width-2 );
50 title2[width-2] = '\0';
51 title = title2;
52 }
53
54 if (title != NULL) {
55 wattrset (dialog, title_attr);
56 mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
57 waddstr (dialog, (char *)title);
58 waddch (dialog, ' ');
59 }
60 wattrset (dialog, dialog_attr);
61 print_autowrap (dialog, prompt, width - 2, 1, 2);
62
63 if (pause) {
64 wattrset (dialog, border_attr);
65 mvwaddch (dialog, height - 3, 0, ACS_LTEE);
66 for (i = 0; i < width - 2; i++)
67 waddch (dialog, ACS_HLINE);
68 wattrset (dialog, dialog_attr);
69 waddch (dialog, ACS_RTEE);
70
71 print_button (dialog, " Ok ",
72 height - 2, width / 2 - 4, TRUE);
73
74 wrefresh (dialog);
75 while (key != ESC && key != '\n' && key != ' ' &&
76 key != 'O' && key != 'o' && key != 'X' && key != 'x')
77 key = wgetch (dialog);
78 } else {
79 key = '\n';
80 wrefresh (dialog);
81 }
82
83 delwin (dialog);
84 return key == ESC ? -1 : 0;
85}
diff --git a/scripts/lxdialog/textbox.c b/scripts/lxdialog/textbox.c
new file mode 100644
index 000000000..ecf55410e
--- /dev/null
+++ b/scripts/lxdialog/textbox.c
@@ -0,0 +1,556 @@
1/*
2 * textbox.c -- implements the text box
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "dialog.h"
23
24static void back_lines (int n);
25static void print_page (WINDOW * win, int height, int width);
26static void print_line (WINDOW * win, int row, int width);
27static char *get_line (void);
28static void print_position (WINDOW * win, int height, int width);
29
30static int hscroll = 0, fd, file_size, bytes_read;
31static int begin_reached = 1, end_reached = 0, page_length;
32static char *buf, *page;
33
34/*
35 * Display text from a file in a dialog box.
36 */
37int
38dialog_textbox (const char *title, const char *file, int height, int width)
39{
40 int i, x, y, cur_x, cur_y, fpos, key = 0;
41 int passed_end;
42 char search_term[MAX_LEN + 1];
43 WINDOW *dialog, *text;
44
45 search_term[0] = '\0'; /* no search term entered yet */
46
47 /* Open input file for reading */
48 if ((fd = open (file, O_RDONLY)) == -1) {
49 endwin ();
50 fprintf (stderr,
51 "\nCan't open input file in dialog_textbox().\n");
52 exit (-1);
53 }
54 /* Get file size. Actually, 'file_size' is the real file size - 1,
55 since it's only the last byte offset from the beginning */
56 if ((file_size = lseek (fd, 0, SEEK_END)) == -1) {
57 endwin ();
58 fprintf (stderr, "\nError getting file size in dialog_textbox().\n");
59 exit (-1);
60 }
61 /* Restore file pointer to beginning of file after getting file size */
62 if (lseek (fd, 0, SEEK_SET) == -1) {
63 endwin ();
64 fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n");
65 exit (-1);
66 }
67 /* Allocate space for read buffer */
68 if ((buf = malloc (BUF_SIZE + 1)) == NULL) {
69 endwin ();
70 fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n");
71 exit (-1);
72 }
73 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
74 endwin ();
75 fprintf (stderr, "\nError reading file in dialog_textbox().\n");
76 exit (-1);
77 }
78 buf[bytes_read] = '\0'; /* mark end of valid data */
79 page = buf; /* page is pointer to start of page to be displayed */
80
81 /* center dialog box on screen */
82 x = (COLS - width) / 2;
83 y = (LINES - height) / 2;
84
85
86 draw_shadow (stdscr, y, x, height, width);
87
88 dialog = newwin (height, width, y, x);
89 keypad (dialog, TRUE);
90
91 /* Create window for text region, used for scrolling text */
92 text = subwin (dialog, height - 4, width - 2, y + 1, x + 1);
93 wattrset (text, dialog_attr);
94 wbkgdset (text, dialog_attr & A_COLOR);
95
96 keypad (text, TRUE);
97
98 /* register the new window, along with its borders */
99 draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
100
101 wattrset (dialog, border_attr);
102 mvwaddch (dialog, height-3, 0, ACS_LTEE);
103 for (i = 0; i < width - 2; i++)
104 waddch (dialog, ACS_HLINE);
105 wattrset (dialog, dialog_attr);
106 wbkgdset (dialog, dialog_attr & A_COLOR);
107 waddch (dialog, ACS_RTEE);
108
109 if (title != NULL && strlen(title) >= width-2 ) {
110 /* truncate long title -- mec */
111 char * title2 = malloc(width-2+1);
112 memcpy( title2, title, width-2 );
113 title2[width-2] = '\0';
114 title = title2;
115 }
116
117 if (title != NULL) {
118 wattrset (dialog, title_attr);
119 mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
120 waddstr (dialog, (char *)title);
121 waddch (dialog, ' ');
122 }
123 print_button (dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
124 wnoutrefresh (dialog);
125 getyx (dialog, cur_y, cur_x); /* Save cursor position */
126
127 /* Print first page of text */
128 attr_clear (text, height - 4, width - 2, dialog_attr);
129 print_page (text, height - 4, width - 2);
130 print_position (dialog, height, width);
131 wmove (dialog, cur_y, cur_x); /* Restore cursor position */
132 wrefresh (dialog);
133
134 while ((key != ESC) && (key != '\n')) {
135 key = wgetch (dialog);
136 switch (key) {
137 case 'E': /* Exit */
138 case 'e':
139 case 'X':
140 case 'x':
141 delwin (dialog);
142 free (buf);
143 close (fd);
144 return 0;
145 case 'g': /* First page */
146 case KEY_HOME:
147 if (!begin_reached) {
148 begin_reached = 1;
149 /* First page not in buffer? */
150 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
151 endwin ();
152 fprintf (stderr,
153 "\nError moving file pointer in dialog_textbox().\n");
154 exit (-1);
155 }
156 if (fpos > bytes_read) { /* Yes, we have to read it in */
157 if (lseek (fd, 0, SEEK_SET) == -1) {
158 endwin ();
159 fprintf (stderr, "\nError moving file pointer in "
160 "dialog_textbox().\n");
161 exit (-1);
162 }
163 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
164 endwin ();
165 fprintf (stderr,
166 "\nError reading file in dialog_textbox().\n");
167 exit (-1);
168 }
169 buf[bytes_read] = '\0';
170 }
171 page = buf;
172 print_page (text, height - 4, width - 2);
173 print_position (dialog, height, width);
174 wmove (dialog, cur_y, cur_x); /* Restore cursor position */
175 wrefresh (dialog);
176 }
177 break;
178 case 'G': /* Last page */
179 case KEY_END:
180
181 end_reached = 1;
182 /* Last page not in buffer? */
183 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
184 endwin ();
185 fprintf (stderr,
186 "\nError moving file pointer in dialog_textbox().\n");
187 exit (-1);
188 }
189 if (fpos < file_size) { /* Yes, we have to read it in */
190 if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) {
191 endwin ();
192 fprintf (stderr,
193 "\nError moving file pointer in dialog_textbox().\n");
194 exit (-1);
195 }
196 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
197 endwin ();
198 fprintf (stderr,
199 "\nError reading file in dialog_textbox().\n");
200 exit (-1);
201 }
202 buf[bytes_read] = '\0';
203 }
204 page = buf + bytes_read;
205 back_lines (height - 4);
206 print_page (text, height - 4, width - 2);
207 print_position (dialog, height, width);
208 wmove (dialog, cur_y, cur_x); /* Restore cursor position */
209 wrefresh (dialog);
210 break;
211 case 'K': /* Previous line */
212 case 'k':
213 case KEY_UP:
214 if (!begin_reached) {
215 back_lines (page_length + 1);
216
217 /* We don't call print_page() here but use scrolling to ensure
218 faster screen update. However, 'end_reached' and
219 'page_length' should still be updated, and 'page' should
220 point to start of next page. This is done by calling
221 get_line() in the following 'for' loop. */
222 scrollok (text, TRUE);
223 wscrl (text, -1); /* Scroll text region down one line */
224 scrollok (text, FALSE);
225 page_length = 0;
226 passed_end = 0;
227 for (i = 0; i < height - 4; i++) {
228 if (!i) {
229 /* print first line of page */
230 print_line (text, 0, width - 2);
231 wnoutrefresh (text);
232 } else
233 /* Called to update 'end_reached' and 'page' */
234 get_line ();
235 if (!passed_end)
236 page_length++;
237 if (end_reached && !passed_end)
238 passed_end = 1;
239 }
240
241 print_position (dialog, height, width);
242 wmove (dialog, cur_y, cur_x); /* Restore cursor position */
243 wrefresh (dialog);
244 }
245 break;
246 case 'B': /* Previous page */
247 case 'b':
248 case KEY_PPAGE:
249 if (begin_reached)
250 break;
251 back_lines (page_length + height - 4);
252 print_page (text, height - 4, width - 2);
253 print_position (dialog, height, width);
254 wmove (dialog, cur_y, cur_x);
255 wrefresh (dialog);
256 break;
257 case 'J': /* Next line */
258 case 'j':
259 case KEY_DOWN:
260 if (!end_reached) {
261 begin_reached = 0;
262 scrollok (text, TRUE);
263 scroll (text); /* Scroll text region up one line */
264 scrollok (text, FALSE);
265 print_line (text, height - 5, width - 2);
266 wnoutrefresh (text);
267 print_position (dialog, height, width);
268 wmove (dialog, cur_y, cur_x); /* Restore cursor position */
269 wrefresh (dialog);
270 }
271 break;
272 case KEY_NPAGE: /* Next page */
273 case ' ':
274 if (end_reached)
275 break;
276
277 begin_reached = 0;
278 print_page (text, height - 4, width - 2);
279 print_position (dialog, height, width);
280 wmove (dialog, cur_y, cur_x);
281 wrefresh (dialog);
282 break;
283 case '0': /* Beginning of line */
284 case 'H': /* Scroll left */
285 case 'h':
286 case KEY_LEFT:
287 if (hscroll <= 0)
288 break;
289
290 if (key == '0')
291 hscroll = 0;
292 else
293 hscroll--;
294 /* Reprint current page to scroll horizontally */
295 back_lines (page_length);
296 print_page (text, height - 4, width - 2);
297 wmove (dialog, cur_y, cur_x);
298 wrefresh (dialog);
299 break;
300 case 'L': /* Scroll right */
301 case 'l':
302 case KEY_RIGHT:
303 if (hscroll >= MAX_LEN)
304 break;
305 hscroll++;
306 /* Reprint current page to scroll horizontally */
307 back_lines (page_length);
308 print_page (text, height - 4, width - 2);
309 wmove (dialog, cur_y, cur_x);
310 wrefresh (dialog);
311 break;
312 case ESC:
313 break;
314 }
315 }
316
317 delwin (dialog);
318 free (buf);
319 close (fd);
320 return -1; /* ESC pressed */
321}
322
323/*
324 * Go back 'n' lines in text file. Called by dialog_textbox().
325 * 'page' will be updated to point to the desired line in 'buf'.
326 */
327static void
328back_lines (int n)
329{
330 int i, fpos;
331
332 begin_reached = 0;
333 /* We have to distinguish between end_reached and !end_reached
334 since at end of file, the line is not ended by a '\n'.
335 The code inside 'if' basically does a '--page' to move one
336 character backward so as to skip '\n' of the previous line */
337 if (!end_reached) {
338 /* Either beginning of buffer or beginning of file reached? */
339 if (page == buf) {
340 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
341 endwin ();
342 fprintf (stderr, "\nError moving file pointer in "
343 "back_lines().\n");
344 exit (-1);
345 }
346 if (fpos > bytes_read) { /* Not beginning of file yet */
347 /* We've reached beginning of buffer, but not beginning of
348 file yet, so read previous part of file into buffer.
349 Note that we only move backward for BUF_SIZE/2 bytes,
350 but not BUF_SIZE bytes to avoid re-reading again in
351 print_page() later */
352 /* Really possible to move backward BUF_SIZE/2 bytes? */
353 if (fpos < BUF_SIZE / 2 + bytes_read) {
354 /* No, move less then */
355 if (lseek (fd, 0, SEEK_SET) == -1) {
356 endwin ();
357 fprintf (stderr, "\nError moving file pointer in "
358 "back_lines().\n");
359 exit (-1);
360 }
361 page = buf + fpos - bytes_read;
362 } else { /* Move backward BUF_SIZE/2 bytes */
363 if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR)
364 == -1) {
365 endwin ();
366 fprintf (stderr, "\nError moving file pointer "
367 "in back_lines().\n");
368 exit (-1);
369 }
370 page = buf + BUF_SIZE / 2;
371 }
372 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
373 endwin ();
374 fprintf (stderr, "\nError reading file in back_lines().\n");
375 exit (-1);
376 }
377 buf[bytes_read] = '\0';
378 } else { /* Beginning of file reached */
379 begin_reached = 1;
380 return;
381 }
382 }
383 if (*(--page) != '\n') { /* '--page' here */
384 /* Something's wrong... */
385 endwin ();
386 fprintf (stderr, "\nInternal error in back_lines().\n");
387 exit (-1);
388 }
389 }
390 /* Go back 'n' lines */
391 for (i = 0; i < n; i++)
392 do {
393 if (page == buf) {
394 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
395 endwin ();
396 fprintf (stderr,
397 "\nError moving file pointer in back_lines().\n");
398 exit (-1);
399 }
400 if (fpos > bytes_read) {
401 /* Really possible to move backward BUF_SIZE/2 bytes? */
402 if (fpos < BUF_SIZE / 2 + bytes_read) {
403 /* No, move less then */
404 if (lseek (fd, 0, SEEK_SET) == -1) {
405 endwin ();
406 fprintf (stderr, "\nError moving file pointer "
407 "in back_lines().\n");
408 exit (-1);
409 }
410 page = buf + fpos - bytes_read;
411 } else { /* Move backward BUF_SIZE/2 bytes */
412 if (lseek (fd, -(BUF_SIZE / 2 + bytes_read),
413 SEEK_CUR) == -1) {
414 endwin ();
415 fprintf (stderr, "\nError moving file pointer"
416 " in back_lines().\n");
417 exit (-1);
418 }
419 page = buf + BUF_SIZE / 2;
420 }
421 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
422 endwin ();
423 fprintf (stderr, "\nError reading file in "
424 "back_lines().\n");
425 exit (-1);
426 }
427 buf[bytes_read] = '\0';
428 } else { /* Beginning of file reached */
429 begin_reached = 1;
430 return;
431 }
432 }
433 } while (*(--page) != '\n');
434 page++;
435}
436
437/*
438 * Print a new page of text. Called by dialog_textbox().
439 */
440static void
441print_page (WINDOW * win, int height, int width)
442{
443 int i, passed_end = 0;
444
445 page_length = 0;
446 for (i = 0; i < height; i++) {
447 print_line (win, i, width);
448 if (!passed_end)
449 page_length++;
450 if (end_reached && !passed_end)
451 passed_end = 1;
452 }
453 wnoutrefresh (win);
454}
455
456/*
457 * Print a new line of text. Called by dialog_textbox() and print_page().
458 */
459static void
460print_line (WINDOW * win, int row, int width)
461{
462 int y, x;
463 char *line;
464
465 line = get_line ();
466 line += MIN (strlen (line), hscroll); /* Scroll horizontally */
467 wmove (win, row, 0); /* move cursor to correct line */
468 waddch (win, ' ');
469 waddnstr (win, line, MIN (strlen (line), width - 2));
470
471 getyx (win, y, x);
472 /* Clear 'residue' of previous line */
473#if OLD_NCURSES
474 {
475 int i;
476 for (i = 0; i < width - x; i++)
477 waddch (win, ' ');
478 }
479#else
480 wclrtoeol(win);
481#endif
482}
483
484/*
485 * Return current line of text. Called by dialog_textbox() and print_line().
486 * 'page' should point to start of current line before calling, and will be
487 * updated to point to start of next line.
488 */
489static char *
490get_line (void)
491{
492 int i = 0, fpos;
493 static char line[MAX_LEN + 1];
494
495 end_reached = 0;
496 while (*page != '\n') {
497 if (*page == '\0') {
498 /* Either end of file or end of buffer reached */
499 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
500 endwin ();
501 fprintf (stderr, "\nError moving file pointer in "
502 "get_line().\n");
503 exit (-1);
504 }
505 if (fpos < file_size) { /* Not end of file yet */
506 /* We've reached end of buffer, but not end of file yet,
507 so read next part of file into buffer */
508 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
509 endwin ();
510 fprintf (stderr, "\nError reading file in get_line().\n");
511 exit (-1);
512 }
513 buf[bytes_read] = '\0';
514 page = buf;
515 } else {
516 if (!end_reached)
517 end_reached = 1;
518 break;
519 }
520 } else if (i < MAX_LEN)
521 line[i++] = *(page++);
522 else {
523 /* Truncate lines longer than MAX_LEN characters */
524 if (i == MAX_LEN)
525 line[i++] = '\0';
526 page++;
527 }
528 }
529 if (i <= MAX_LEN)
530 line[i] = '\0';
531 if (!end_reached)
532 page++; /* move pass '\n' */
533
534 return line;
535}
536
537/*
538 * Print current position
539 */
540static void
541print_position (WINDOW * win, int height, int width)
542{
543 int fpos, percent;
544
545 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
546 endwin ();
547 fprintf (stderr, "\nError moving file pointer in print_position().\n");
548 exit (-1);
549 }
550 wattrset (win, position_indicator_attr);
551 wbkgdset (win, position_indicator_attr & A_COLOR);
552 percent = !file_size ?
553 100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
554 wmove (win, height - 3, width - 9);
555 wprintw (win, "(%3d%%)", percent);
556}
diff --git a/scripts/lxdialog/util.c b/scripts/lxdialog/util.c
new file mode 100644
index 000000000..b3a7af9d2
--- /dev/null
+++ b/scripts/lxdialog/util.c
@@ -0,0 +1,359 @@
1/*
2 * util.c
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "dialog.h"
23
24
25/* use colors by default? */
26bool use_colors = 1;
27
28const char *backtitle = NULL;
29
30const char *dialog_result;
31
32/*
33 * Attribute values, default is for mono display
34 */
35chtype attributes[] =
36{
37 A_NORMAL, /* screen_attr */
38 A_NORMAL, /* shadow_attr */
39 A_NORMAL, /* dialog_attr */
40 A_BOLD, /* title_attr */
41 A_NORMAL, /* border_attr */
42 A_REVERSE, /* button_active_attr */
43 A_DIM, /* button_inactive_attr */
44 A_REVERSE, /* button_key_active_attr */
45 A_BOLD, /* button_key_inactive_attr */
46 A_REVERSE, /* button_label_active_attr */
47 A_NORMAL, /* button_label_inactive_attr */
48 A_NORMAL, /* inputbox_attr */
49 A_NORMAL, /* inputbox_border_attr */
50 A_NORMAL, /* searchbox_attr */
51 A_BOLD, /* searchbox_title_attr */
52 A_NORMAL, /* searchbox_border_attr */
53 A_BOLD, /* position_indicator_attr */
54 A_NORMAL, /* menubox_attr */
55 A_NORMAL, /* menubox_border_attr */
56 A_NORMAL, /* item_attr */
57 A_REVERSE, /* item_selected_attr */
58 A_BOLD, /* tag_attr */
59 A_REVERSE, /* tag_selected_attr */
60 A_BOLD, /* tag_key_attr */
61 A_REVERSE, /* tag_key_selected_attr */
62 A_BOLD, /* check_attr */
63 A_REVERSE, /* check_selected_attr */
64 A_BOLD, /* uarrow_attr */
65 A_BOLD /* darrow_attr */
66};
67
68
69#include "colors.h"
70
71/*
72 * Table of color values
73 */
74int color_table[][3] =
75{
76 {SCREEN_FG, SCREEN_BG, SCREEN_HL},
77 {SHADOW_FG, SHADOW_BG, SHADOW_HL},
78 {DIALOG_FG, DIALOG_BG, DIALOG_HL},
79 {TITLE_FG, TITLE_BG, TITLE_HL},
80 {BORDER_FG, BORDER_BG, BORDER_HL},
81 {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
82 {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
83 {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
84 {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL},
85 {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL},
86 {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
87 BUTTON_LABEL_INACTIVE_HL},
88 {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
89 {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
90 {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
91 {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
92 {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
93 {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
94 {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
95 {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
96 {ITEM_FG, ITEM_BG, ITEM_HL},
97 {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
98 {TAG_FG, TAG_BG, TAG_HL},
99 {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
100 {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
101 {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
102 {CHECK_FG, CHECK_BG, CHECK_HL},
103 {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
104 {UARROW_FG, UARROW_BG, UARROW_HL},
105 {DARROW_FG, DARROW_BG, DARROW_HL},
106}; /* color_table */
107
108/*
109 * Set window to attribute 'attr'
110 */
111void
112attr_clear (WINDOW * win, int height, int width, chtype attr)
113{
114 int i, j;
115
116 wattrset (win, attr);
117 for (i = 0; i < height; i++) {
118 wmove (win, i, 0);
119 for (j = 0; j < width; j++)
120 waddch (win, ' ');
121 }
122 touchwin (win);
123}
124
125void dialog_clear (void)
126{
127 attr_clear (stdscr, LINES, COLS, screen_attr);
128 /* Display background title if it exists ... - SLH */
129 if (backtitle != NULL) {
130 int i;
131
132 wattrset (stdscr, screen_attr);
133 mvwaddstr (stdscr, 0, 1, (char *)backtitle);
134 wmove (stdscr, 1, 1);
135 for (i = 1; i < COLS - 1; i++)
136 waddch (stdscr, ACS_HLINE);
137 }
138 wnoutrefresh (stdscr);
139}
140
141/*
142 * Do some initialization for dialog
143 */
144void
145init_dialog (void)
146{
147 initscr (); /* Init curses */
148 keypad (stdscr, TRUE);
149 cbreak ();
150 noecho ();
151
152
153 if (use_colors) /* Set up colors */
154 color_setup ();
155
156
157 dialog_clear ();
158}
159
160/*
161 * Setup for color display
162 */
163void
164color_setup (void)
165{
166 int i;
167
168 if (has_colors ()) { /* Terminal supports color? */
169 start_color ();
170
171 /* Initialize color pairs */
172 for (i = 0; i < ATTRIBUTE_COUNT; i++)
173 init_pair (i + 1, color_table[i][0], color_table[i][1]);
174
175 /* Setup color attributes */
176 for (i = 0; i < ATTRIBUTE_COUNT; i++)
177 attributes[i] = C_ATTR (color_table[i][2], i + 1);
178 }
179}
180
181/*
182 * End using dialog functions.
183 */
184void
185end_dialog (void)
186{
187 endwin ();
188}
189
190
191/*
192 * Print a string of text in a window, automatically wrap around to the
193 * next line if the string is too long to fit on one line. Newline
194 * characters '\n' are replaced by spaces. We start on a new line
195 * if there is no room for at least 4 nonblanks following a double-space.
196 */
197void
198print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x)
199{
200 int newl, cur_x, cur_y;
201 int i, prompt_len, room, wlen;
202 char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
203
204 strcpy (tempstr, prompt);
205
206 prompt_len = strlen(tempstr);
207
208 /*
209 * Remove newlines
210 */
211 for(i=0; i<prompt_len; i++) {
212 if(tempstr[i] == '\n') tempstr[i] = ' ';
213 }
214
215 if (prompt_len <= width - x * 2) { /* If prompt is short */
216 wmove (win, y, (width - prompt_len) / 2);
217 waddstr (win, tempstr);
218 } else {
219 cur_x = x;
220 cur_y = y;
221 newl = 1;
222 word = tempstr;
223 while (word && *word) {
224 sp = index(word, ' ');
225 if (sp)
226 *sp++ = 0;
227
228 /* Wrap to next line if either the word does not fit,
229 or it is the first word of a new sentence, and it is
230 short, and the next word does not fit. */
231 room = width - cur_x;
232 wlen = strlen(word);
233 if (wlen > room ||
234 (newl && wlen < 4 && sp && wlen+1+strlen(sp) > room
235 && (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) {
236 cur_y++;
237 cur_x = x;
238 }
239 wmove (win, cur_y, cur_x);
240 waddstr (win, word);
241 getyx (win, cur_y, cur_x);
242 cur_x++;
243 if (sp && *sp == ' ') {
244 cur_x++; /* double space */
245 while (*++sp == ' ');
246 newl = 1;
247 } else
248 newl = 0;
249 word = sp;
250 }
251 }
252}
253
254/*
255 * Print a button
256 */
257void
258print_button (WINDOW * win, const char *label, int y, int x, int selected)
259{
260 int i, temp;
261
262 wmove (win, y, x);
263 wattrset (win, selected ? button_active_attr : button_inactive_attr);
264 waddstr (win, "<");
265 temp = strspn (label, " ");
266 label += temp;
267 wattrset (win, selected ? button_label_active_attr
268 : button_label_inactive_attr);
269 for (i = 0; i < temp; i++)
270 waddch (win, ' ');
271 wattrset (win, selected ? button_key_active_attr
272 : button_key_inactive_attr);
273 waddch (win, label[0]);
274 wattrset (win, selected ? button_label_active_attr
275 : button_label_inactive_attr);
276 waddstr (win, (char *)label + 1);
277 wattrset (win, selected ? button_active_attr : button_inactive_attr);
278 waddstr (win, ">");
279 wmove (win, y, x + temp + 1);
280}
281
282/*
283 * Draw a rectangular box with line drawing characters
284 */
285void
286draw_box (WINDOW * win, int y, int x, int height, int width,
287 chtype box, chtype border)
288{
289 int i, j;
290
291 wattrset (win, 0);
292 for (i = 0; i < height; i++) {
293 wmove (win, y + i, x);
294 for (j = 0; j < width; j++)
295 if (!i && !j)
296 waddch (win, border | ACS_ULCORNER);
297 else if (i == height - 1 && !j)
298 waddch (win, border | ACS_LLCORNER);
299 else if (!i && j == width - 1)
300 waddch (win, box | ACS_URCORNER);
301 else if (i == height - 1 && j == width - 1)
302 waddch (win, box | ACS_LRCORNER);
303 else if (!i)
304 waddch (win, border | ACS_HLINE);
305 else if (i == height - 1)
306 waddch (win, box | ACS_HLINE);
307 else if (!j)
308 waddch (win, border | ACS_VLINE);
309 else if (j == width - 1)
310 waddch (win, box | ACS_VLINE);
311 else
312 waddch (win, box | ' ');
313 }
314}
315
316/*
317 * Draw shadows along the right and bottom edge to give a more 3D look
318 * to the boxes
319 */
320void
321draw_shadow (WINDOW * win, int y, int x, int height, int width)
322{
323 int i;
324
325 if (has_colors ()) { /* Whether terminal supports color? */
326 wattrset (win, shadow_attr);
327 wmove (win, y + height, x + 2);
328 for (i = 0; i < width; i++)
329 waddch (win, winch (win) & A_CHARTEXT);
330 for (i = y + 1; i < y + height + 1; i++) {
331 wmove (win, i, x + width);
332 waddch (win, winch (win) & A_CHARTEXT);
333 waddch (win, winch (win) & A_CHARTEXT);
334 }
335 wnoutrefresh (win);
336 }
337}
338
339/*
340 * Return the position of the first alphabetic character in a string.
341 */
342int
343first_alpha(const char *string, const char *exempt)
344{
345 int i, in_paren=0, c;
346
347 for (i = 0; i < strlen(string); i++) {
348 c = tolower(string[i]);
349
350 if (strchr("<[(", c)) ++in_paren;
351 if (strchr(">])", c)) --in_paren;
352
353 if ((! in_paren) && isalpha(c) &&
354 strchr(exempt, c) == 0)
355 return i;
356 }
357
358 return 0;
359}
diff --git a/scripts/lxdialog/yesno.c b/scripts/lxdialog/yesno.c
new file mode 100644
index 000000000..11fcc25f5
--- /dev/null
+++ b/scripts/lxdialog/yesno.c
@@ -0,0 +1,118 @@
1/*
2 * yesno.c -- implements the yes/no box
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "dialog.h"
23
24/*
25 * Display termination buttons
26 */
27static void
28print_buttons(WINDOW *dialog, int height, int width, int selected)
29{
30 int x = width / 2 - 10;
31 int y = height - 2;
32
33 print_button (dialog, " Yes ", y, x, selected == 0);
34 print_button (dialog, " No ", y, x + 13, selected == 1);
35
36 wmove(dialog, y, x+1 + 13*selected );
37 wrefresh (dialog);
38}
39
40/*
41 * Display a dialog box with two buttons - Yes and No
42 */
43int
44dialog_yesno (const char *title, const char *prompt, int height, int width)
45{
46 int i, x, y, key = 0, button = 0;
47 WINDOW *dialog;
48
49 /* center dialog box on screen */
50 x = (COLS - width) / 2;
51 y = (LINES - height) / 2;
52
53 draw_shadow (stdscr, y, x, height, width);
54
55 dialog = newwin (height, width, y, x);
56 keypad (dialog, TRUE);
57
58 draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
59 wattrset (dialog, border_attr);
60 mvwaddch (dialog, height-3, 0, ACS_LTEE);
61 for (i = 0; i < width - 2; i++)
62 waddch (dialog, ACS_HLINE);
63 wattrset (dialog, dialog_attr);
64 waddch (dialog, ACS_RTEE);
65
66 if (title != NULL && strlen(title) >= width-2 ) {
67 /* truncate long title -- mec */
68 char * title2 = malloc(width-2+1);
69 memcpy( title2, title, width-2 );
70 title2[width-2] = '\0';
71 title = title2;
72 }
73
74 if (title != NULL) {
75 wattrset (dialog, title_attr);
76 mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
77 waddstr (dialog, (char *)title);
78 waddch (dialog, ' ');
79 }
80
81 wattrset (dialog, dialog_attr);
82 print_autowrap (dialog, prompt, width - 2, 1, 3);
83
84 print_buttons(dialog, height, width, 0);
85
86 while (key != ESC) {
87 key = wgetch (dialog);
88 switch (key) {
89 case 'Y':
90 case 'y':
91 delwin (dialog);
92 return 0;
93 case 'N':
94 case 'n':
95 delwin (dialog);
96 return 1;
97
98 case TAB:
99 case KEY_LEFT:
100 case KEY_RIGHT:
101 button = ((key == KEY_LEFT ? --button : ++button) < 0)
102 ? 1 : (button > 1 ? 0 : button);
103
104 print_buttons(dialog, height, width, button);
105 wrefresh (dialog);
106 break;
107 case ' ':
108 case '\n':
109 delwin (dialog);
110 return button;
111 case ESC:
112 break;
113 }
114 }
115
116 delwin (dialog);
117 return -1; /* ESC pressed */
118}
diff --git a/scripts/mk2knr.pl b/scripts/mk2knr.pl
deleted file mode 100755
index aaf4963b1..000000000
--- a/scripts/mk2knr.pl
+++ /dev/null
@@ -1,84 +0,0 @@
1#!/usr/bin/perl -w
2#
3# @(#) mk2knr.pl - generates a perl script that converts lexemes to K&R-style
4#
5# How to use this script:
6# - In the busybox directory type 'scripts/mk2knr.pl files-you-want-to-convert'
7# - Review the 'convertme.pl' script generated and remove / edit any of the
8# substitutions in there (please especially check for false positives)
9# - Type './convertme.pl same-files-as-before'
10# - Compile and see if it works
11#
12# BUGS: This script does not ignore strings inside comments or strings inside
13# quotes (it probably should).
14
15# set this to something else if you want
16$convertme = 'convertme.pl';
17
18# internal-use variables (don't touch)
19$convert = 0;
20%converted = ();
21
22# if no files were specified, print usage
23die "usage: $0 file.c | file.h\n" if scalar(@ARGV) == 0;
24
25# prepare the "convert me" file
26open(CM, ">$convertme") or die "convertme.pl $!";
27print CM "#!/usr/bin/perl -p -i\n\n";
28
29# process each file passed on the cmd line
30while (<>) {
31
32 # if the line says "getopt" in it anywhere, we don't want to muck with it
33 # because option lists tend to include strings like "cxtzvOf:" which get
34 # matched by the "check for mixed case" regexps below
35 next if /getopt/;
36
37 # tokenize the string into just the variables
38 while (/([a-zA-Z_][a-zA-Z0-9_]*)/g) {
39 $var = $1;
40
41 # ignore the word "BusyBox"
42 next if ($var =~ /BusyBox/);
43
44 # this checks for javaStyle or szHungarianNotation
45 $convert++ if ($var =~ /^[a-z]+[A-Z][a-z]+/);
46
47 # this checks for PascalStyle
48 $convert++ if ($var =~ /^[A-Z][a-z]+[A-Z][a-z]+/);
49
50 # if we want to add more checks, we can add 'em here, but the above
51 # checks catch "just enough" and not too much, so prolly not.
52
53 if ($convert) {
54 $convert = 0;
55
56 # skip ahead if we've already dealt with this one
57 next if ($converted{$var});
58
59 # record that we've dealt with this var
60 $converted{$var} = 1;
61
62 print CM "s/\\b$var\\b/"; # more to come in just a minute
63
64 # change the first letter to lower-case
65 $var = lcfirst($var);
66
67 # put underscores before all remaining upper-case letters
68 $var =~ s/([A-Z])/_$1/g;
69
70 # now change the remaining characters to lower-case
71 $var = lc($var);
72
73 print CM "$var/g;\n";
74 }
75 }
76}
77
78# tidy up and make the $convertme script executable
79close(CM);
80chmod 0755, $convertme;
81
82# print a helpful help message
83print "Done. Scheduled name changes are in $convertme.\n";
84print "Please review/modify it and then type ./$convertme to do the search & replace.\n";
diff --git a/scripts/mkdep.c b/scripts/mkdep.c
new file mode 100644
index 000000000..c3e94bfae
--- /dev/null
+++ b/scripts/mkdep.c
@@ -0,0 +1,628 @@
1/*
2 * Originally by Linus Torvalds.
3 * Smart CONFIG_* processing by Werner Almesberger, Michael Chastain.
4 *
5 * Usage: mkdep cflags -- file ...
6 *
7 * Read source files and output makefile dependency lines for them.
8 * I make simple dependency lines for #include <*.h> and #include "*.h".
9 * I also find instances of CONFIG_FOO and generate dependencies
10 * like include/config/foo.h.
11 *
12 * 1 August 1999, Michael Elizabeth Chastain, <mec@shout.net>
13 * - Keith Owens reported a bug in smart config processing. There used
14 * to be an optimization for "#define CONFIG_FOO ... #ifdef CONFIG_FOO",
15 * so that the file would not depend on CONFIG_FOO because the file defines
16 * this symbol itself. But this optimization is bogus! Consider this code:
17 * "#if 0 \n #define CONFIG_FOO \n #endif ... #ifdef CONFIG_FOO". Here
18 * the definition is inactivated, but I still used it. It turns out this
19 * actually happens a few times in the kernel source. The simple way to
20 * fix this problem is to remove this particular optimization.
21 *
22 * 2.3.99-pre1, Andrew Morton <andrewm@uow.edu.au>
23 * - Changed so that 'filename.o' depends upon 'filename.[cS]'. This is so that
24 * missing source files are noticed, rather than silently ignored.
25 *
26 * 2.4.2-pre3, Keith Owens <kaos@ocs.com.au>
27 * - Accept cflags followed by '--' followed by filenames. mkdep extracts -I
28 * options from cflags and looks in the specified directories as well as the
29 * defaults. Only -I is supported, no attempt is made to handle -idirafter,
30 * -isystem, -I- etc.
31 */
32
33#include <ctype.h>
34#include <fcntl.h>
35#include <limits.h>
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39#include <unistd.h>
40
41#include <sys/fcntl.h>
42#include <sys/mman.h>
43#include <sys/stat.h>
44#include <sys/types.h>
45
46
47
48char __depname[512] = "\n\t@touch ";
49#define depname (__depname+9)
50int hasdep;
51
52struct path_struct {
53 int len;
54 char *buffer;
55};
56struct path_struct *path_array;
57int paths;
58
59
60/* Current input file */
61static const char *g_filename;
62
63/*
64 * This records all the configuration options seen.
65 * In perl this would be a hash, but here it's a long string
66 * of values separated by newlines. This is simple and
67 * extremely fast.
68 */
69char * str_config = NULL;
70int size_config = 0;
71int len_config = 0;
72
73static void
74do_depname(void)
75{
76 if (!hasdep) {
77 hasdep = 1;
78 printf("%s:", depname);
79 if (g_filename)
80 printf(" %s", g_filename);
81 }
82}
83
84/*
85 * Grow the configuration string to a desired length.
86 * Usually the first growth is plenty.
87 */
88void grow_config(int len)
89{
90 while (len_config + len > size_config) {
91 if (size_config == 0)
92 size_config = 2048;
93 str_config = realloc(str_config, size_config *= 2);
94 if (str_config == NULL)
95 { perror("malloc config"); exit(1); }
96 }
97}
98
99
100
101/*
102 * Lookup a value in the configuration string.
103 */
104int is_defined_config(const char * name, int len)
105{
106 const char * pconfig;
107 const char * plast = str_config + len_config - len;
108 for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) {
109 if (pconfig[ -1] == '\n'
110 && pconfig[len] == '\n'
111 && !memcmp(pconfig, name, len))
112 return 1;
113 }
114 return 0;
115}
116
117
118
119/*
120 * Add a new value to the configuration string.
121 */
122void define_config(const char * name, int len)
123{
124 grow_config(len + 1);
125
126 memcpy(str_config+len_config, name, len);
127 len_config += len;
128 str_config[len_config++] = '\n';
129}
130
131
132
133/*
134 * Clear the set of configuration strings.
135 */
136void clear_config(void)
137{
138 len_config = 0;
139 define_config("", 0);
140}
141
142
143
144/*
145 * This records all the precious .h filenames. No need for a hash,
146 * it's a long string of values enclosed in tab and newline.
147 */
148char * str_precious = NULL;
149int size_precious = 0;
150int len_precious = 0;
151
152
153
154/*
155 * Grow the precious string to a desired length.
156 * Usually the first growth is plenty.
157 */
158void grow_precious(int len)
159{
160 while (len_precious + len > size_precious) {
161 if (size_precious == 0)
162 size_precious = 2048;
163 str_precious = realloc(str_precious, size_precious *= 2);
164 if (str_precious == NULL)
165 { perror("malloc"); exit(1); }
166 }
167}
168
169
170
171/*
172 * Add a new value to the precious string.
173 */
174void define_precious(const char * filename)
175{
176 int len = strlen(filename);
177 grow_precious(len + 4);
178 *(str_precious+len_precious++) = '\t';
179 memcpy(str_precious+len_precious, filename, len);
180 len_precious += len;
181 memcpy(str_precious+len_precious, " \\\n", 3);
182 len_precious += 3;
183}
184
185
186
187/*
188 * Handle an #include line.
189 */
190void handle_include(int start, const char * name, int len)
191{
192 struct path_struct *path;
193 int i;
194
195 if (len == 14 && !memcmp(name, "include/config.h", len))
196 return;
197
198 if (len >= 7 && !memcmp(name, "config/", 7))
199 define_config(name+7, len-7-2);
200
201 for (i = start, path = path_array+start; i < paths; ++i, ++path) {
202 memcpy(path->buffer+path->len, name, len);
203 path->buffer[path->len+len] = '\0';
204 if (access(path->buffer, F_OK) == 0) {
205 do_depname();
206 printf(" \\\n %s", path->buffer);
207 return;
208 }
209 }
210
211}
212
213
214
215/*
216 * Add a path to the list of include paths.
217 */
218void add_path(const char * name)
219{
220 struct path_struct *path;
221 char resolved_path[PATH_MAX+1];
222 const char *name2;
223
224 if (strcmp(name, ".")) {
225 name2 = realpath(name, resolved_path);
226 if (!name2) {
227 fprintf(stderr, "realpath(%s) failed, %m\n", name);
228 exit(1);
229 }
230 }
231 else {
232 name2 = "";
233 }
234
235 path_array = realloc(path_array, (++paths)*sizeof(*path_array));
236 if (!path_array) {
237 fprintf(stderr, "cannot expand path_arry\n");
238 exit(1);
239 }
240
241 path = path_array+paths-1;
242 path->len = strlen(name2);
243 path->buffer = malloc(path->len+1+256+1);
244 if (!path->buffer) {
245 fprintf(stderr, "cannot allocate path buffer\n");
246 exit(1);
247 }
248 strcpy(path->buffer, name2);
249 if (path->len && *(path->buffer+path->len-1) != '/') {
250 *(path->buffer+path->len) = '/';
251 *(path->buffer+(++(path->len))) = '\0';
252 }
253}
254
255
256
257/*
258 * Record the use of a CONFIG_* word.
259 */
260void use_config(const char * name, int len)
261{
262 char *pc;
263 int i;
264
265 pc = path_array[paths-1].buffer + path_array[paths-1].len;
266 memcpy(pc, "config/", 7);
267 pc += 7;
268
269 for (i = 0; i < len; i++) {
270 char c = name[i];
271 if (isupper(c)) c = tolower(c);
272 if (c == '_') c = '/';
273 pc[i] = c;
274 }
275 pc[len] = '\0';
276
277 if (is_defined_config(pc, len))
278 return;
279
280 define_config(pc, len);
281
282 do_depname();
283 printf(" \\\n $(wildcard %s.h)", path_array[paths-1].buffer);
284}
285
286
287
288/*
289 * Macros for stunningly fast map-based character access.
290 * __buf is a register which holds the current word of the input.
291 * Thus, there is one memory access per sizeof(unsigned long) characters.
292 */
293
294#if defined(__alpha__) || defined(__i386__) || defined(__ia64__) || defined(__x86_64__) || defined(__MIPSEL__) \
295 || defined(__arm__)
296#define LE_MACHINE
297#endif
298
299#ifdef LE_MACHINE
300#define next_byte(x) (x >>= 8)
301#define current ((unsigned char) __buf)
302#else
303#define next_byte(x) (x <<= 8)
304#define current (__buf >> 8*(sizeof(unsigned long)-1))
305#endif
306
307#define GETNEXT { \
308 next_byte(__buf); \
309 if ((unsigned long) next % sizeof(unsigned long) == 0) { \
310 if (next >= end) \
311 break; \
312 __buf = * (unsigned long *) next; \
313 } \
314 next++; \
315}
316
317/*
318 * State machine macros.
319 */
320#define CASE(c,label) if (current == c) goto label
321#define NOTCASE(c,label) if (current != c) goto label
322
323/*
324 * Yet another state machine speedup.
325 */
326#define MAX2(a,b) ((a)>(b)?(a):(b))
327#define MIN2(a,b) ((a)<(b)?(a):(b))
328#define MAX5(a,b,c,d,e) (MAX2(a,MAX2(b,MAX2(c,MAX2(d,e)))))
329#define MIN5(a,b,c,d,e) (MIN2(a,MIN2(b,MIN2(c,MIN2(d,e)))))
330
331
332
333/*
334 * The state machine looks for (approximately) these Perl regular expressions:
335 *
336 * m|\/\*.*?\*\/|
337 * m|\/\/.*|
338 * m|'.*?'|
339 * m|".*?"|
340 * m|#\s*include\s*"(.*?)"|
341 * m|#\s*include\s*<(.*?>"|
342 * m|#\s*(?define|undef)\s*CONFIG_(\w*)|
343 * m|(?!\w)CONFIG_|
344 *
345 * About 98% of the CPU time is spent here, and most of that is in
346 * the 'start' paragraph. Because the current characters are
347 * in a register, the start loop usually eats 4 or 8 characters
348 * per memory read. The MAX5 and MIN5 tests dispose of most
349 * input characters with 1 or 2 comparisons.
350 */
351void state_machine(const char * map, const char * end)
352{
353 const char * next = map;
354 const char * map_dot;
355 unsigned long __buf = 0;
356
357 for (;;) {
358start:
359 GETNEXT
360__start:
361 if (current > MAX5('/','\'','"','#','C')) goto start;
362 if (current < MIN5('/','\'','"','#','C')) goto start;
363 CASE('/', slash);
364 CASE('\'', squote);
365 CASE('"', dquote);
366 CASE('#', pound);
367 CASE('C', cee);
368 goto start;
369
370/* // */
371slash_slash:
372 GETNEXT
373 CASE('\n', start);
374 NOTCASE('\\', slash_slash);
375 GETNEXT
376 goto slash_slash;
377
378/* / */
379slash:
380 GETNEXT
381 CASE('/', slash_slash);
382 NOTCASE('*', __start);
383slash_star_dot_star:
384 GETNEXT
385__slash_star_dot_star:
386 NOTCASE('*', slash_star_dot_star);
387 GETNEXT
388 NOTCASE('/', __slash_star_dot_star);
389 goto start;
390
391/* '.*?' */
392squote:
393 GETNEXT
394 CASE('\'', start);
395 NOTCASE('\\', squote);
396 GETNEXT
397 goto squote;
398
399/* ".*?" */
400dquote:
401 GETNEXT
402 CASE('"', start);
403 NOTCASE('\\', dquote);
404 GETNEXT
405 goto dquote;
406
407/* #\s* */
408pound:
409 GETNEXT
410 CASE(' ', pound);
411 CASE('\t', pound);
412 CASE('i', pound_i);
413 CASE('d', pound_d);
414 CASE('u', pound_u);
415 goto __start;
416
417/* #\s*i */
418pound_i:
419 GETNEXT NOTCASE('n', __start);
420 GETNEXT NOTCASE('c', __start);
421 GETNEXT NOTCASE('l', __start);
422 GETNEXT NOTCASE('u', __start);
423 GETNEXT NOTCASE('d', __start);
424 GETNEXT NOTCASE('e', __start);
425 goto pound_include;
426
427/* #\s*include\s* */
428pound_include:
429 GETNEXT
430 CASE(' ', pound_include);
431 CASE('\t', pound_include);
432 map_dot = next;
433 CASE('"', pound_include_dquote);
434 CASE('<', pound_include_langle);
435 goto __start;
436
437/* #\s*include\s*"(.*)" */
438pound_include_dquote:
439 GETNEXT
440 CASE('\n', start);
441 NOTCASE('"', pound_include_dquote);
442 handle_include(0, map_dot, next - map_dot - 1);
443 goto start;
444
445/* #\s*include\s*<(.*)> */
446pound_include_langle:
447 GETNEXT
448 CASE('\n', start);
449 NOTCASE('>', pound_include_langle);
450 handle_include(1, map_dot, next - map_dot - 1);
451 goto start;
452
453/* #\s*d */
454pound_d:
455 GETNEXT NOTCASE('e', __start);
456 GETNEXT NOTCASE('f', __start);
457 GETNEXT NOTCASE('i', __start);
458 GETNEXT NOTCASE('n', __start);
459 GETNEXT NOTCASE('e', __start);
460 goto pound_define_undef;
461
462/* #\s*u */
463pound_u:
464 GETNEXT NOTCASE('n', __start);
465 GETNEXT NOTCASE('d', __start);
466 GETNEXT NOTCASE('e', __start);
467 GETNEXT NOTCASE('f', __start);
468 goto pound_define_undef;
469
470/*
471 * #\s*(define|undef)\s*CONFIG_(\w*)
472 *
473 * this does not define the word, because it could be inside another
474 * conditional (#if 0). But I do parse the word so that this instance
475 * does not count as a use. -- mec
476 */
477pound_define_undef:
478 GETNEXT
479 CASE(' ', pound_define_undef);
480 CASE('\t', pound_define_undef);
481
482 NOTCASE('C', __start);
483 GETNEXT NOTCASE('O', __start);
484 GETNEXT NOTCASE('N', __start);
485 GETNEXT NOTCASE('F', __start);
486 GETNEXT NOTCASE('I', __start);
487 GETNEXT NOTCASE('G', __start);
488 GETNEXT NOTCASE('_', __start);
489
490 map_dot = next;
491pound_define_undef_CONFIG_word:
492 GETNEXT
493 if (isalnum(current) || current == '_')
494 goto pound_define_undef_CONFIG_word;
495 goto __start;
496
497/* \<CONFIG_(\w*) */
498cee:
499 if (next >= map+2 && (isalnum(next[-2]) || next[-2] == '_'))
500 goto start;
501 GETNEXT NOTCASE('O', __start);
502 GETNEXT NOTCASE('N', __start);
503 GETNEXT NOTCASE('F', __start);
504 GETNEXT NOTCASE('I', __start);
505 GETNEXT NOTCASE('G', __start);
506 GETNEXT NOTCASE('_', __start);
507
508 map_dot = next;
509cee_CONFIG_word:
510 GETNEXT
511 if (isalnum(current) || current == '_')
512 goto cee_CONFIG_word;
513 use_config(map_dot, next - map_dot - 1);
514 goto __start;
515 }
516}
517
518
519
520/*
521 * Generate dependencies for one file.
522 */
523void do_depend(const char * filename, const char * command)
524{
525 int mapsize;
526 int pagesizem1 = getpagesize()-1;
527 int fd;
528 struct stat st;
529 char * map;
530
531 fd = open(filename, O_RDONLY);
532 if (fd < 0) {
533 perror(filename);
534 return;
535 }
536
537 fstat(fd, &st);
538 if (st.st_size == 0) {
539 fprintf(stderr,"%s is empty\n",filename);
540 close(fd);
541 return;
542 }
543
544 mapsize = st.st_size;
545 mapsize = (mapsize+pagesizem1) & ~pagesizem1;
546 map = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0);
547 if ((long) map == -1) {
548 perror("mkdep: mmap");
549 close(fd);
550 return;
551 }
552 if ((unsigned long) map % sizeof(unsigned long) != 0)
553 {
554 fprintf(stderr, "do_depend: map not aligned\n");
555 exit(1);
556 }
557
558 hasdep = 0;
559 clear_config();
560 state_machine(map, map+st.st_size);
561 if (hasdep) {
562 puts(command);
563 if (*command)
564 define_precious(filename);
565 }
566
567 munmap(map, mapsize);
568 close(fd);
569}
570
571
572
573/*
574 * Generate dependencies for all files.
575 */
576int main(int argc, char **argv)
577{
578 int len;
579 const char *hpath;
580
581 hpath = getenv("TOPDIR");
582 if (!hpath) {
583 fputs("mkdep: TOPDIR not set in environment. "
584 "Don't bypass the top level Makefile.\n", stderr);
585 return 1;
586 }
587
588 add_path("."); /* for #include "..." */
589
590 while (++argv, --argc > 0) {
591 if (strncmp(*argv, "-I", 2) == 0) {
592 if (*((*argv)+2)) {
593 add_path((*argv)+2);
594 }
595 else {
596 ++argv;
597 --argc;
598 add_path(*argv);
599 }
600 }
601 else if (strcmp(*argv, "--") == 0) {
602 break;
603 }
604 }
605
606 add_path(hpath); /* must be last entry, for config files */
607
608 while (--argc > 0) {
609 const char * filename = *++argv;
610 const char * command = __depname;
611 g_filename = 0;
612 len = strlen(filename);
613 memcpy(depname, filename, len+1);
614 if (len > 2 && filename[len-2] == '.') {
615 if (filename[len-1] == 'c' || filename[len-1] == 'S') {
616 depname[len-1] = 'o';
617 g_filename = filename;
618 command = "";
619 }
620 }
621 do_depend(filename, command);
622 }
623 if (len_precious) {
624 *(str_precious+len_precious) = '\0';
625 printf(".PRECIOUS:%s\n", str_precious);
626 }
627 return 0;
628}
diff --git a/scripts/split-include.c b/scripts/split-include.c
new file mode 100644
index 000000000..3ab9fed87
--- /dev/null
+++ b/scripts/split-include.c
@@ -0,0 +1,226 @@
1/*
2 * split-include.c
3 *
4 * Copyright abandoned, Michael Chastain, <mailto:mec@shout.net>.
5 * This is a C version of syncdep.pl by Werner Almesberger.
6 *
7 * This program takes autoconf.h as input and outputs a directory full
8 * of one-line include files, merging onto the old values.
9 *
10 * Think of the configuration options as key-value pairs. Then there
11 * are five cases:
12 *
13 * key old value new value action
14 *
15 * KEY-1 VALUE-1 VALUE-1 leave file alone
16 * KEY-2 VALUE-2A VALUE-2B write VALUE-2B into file
17 * KEY-3 - VALUE-3 write VALUE-3 into file
18 * KEY-4 VALUE-4 - write an empty file
19 * KEY-5 (empty) - leave old empty file alone
20 */
21
22#include <sys/stat.h>
23#include <sys/types.h>
24
25#include <ctype.h>
26#include <errno.h>
27#include <fcntl.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <unistd.h>
32
33#define ERROR_EXIT(strExit) \
34 { \
35 const int errnoSave = errno; \
36 fprintf(stderr, "%s: ", str_my_name); \
37 errno = errnoSave; \
38 perror((strExit)); \
39 exit(1); \
40 }
41
42
43
44int main(int argc, const char * argv [])
45{
46 const char * str_my_name;
47 const char * str_file_autoconf;
48 const char * str_dir_config;
49
50 FILE * fp_config;
51 FILE * fp_target;
52 FILE * fp_find;
53
54 int buffer_size;
55
56 char * line;
57 char * old_line;
58 char * list_target;
59 char * ptarget;
60
61 struct stat stat_buf;
62
63 /* Check arg count. */
64 if (argc != 3)
65 {
66 fprintf(stderr, "%s: wrong number of arguments.\n", argv[0]);
67 exit(1);
68 }
69
70 str_my_name = argv[0];
71 str_file_autoconf = argv[1];
72 str_dir_config = argv[2];
73
74 /* Find a buffer size. */
75 if (stat(str_file_autoconf, &stat_buf) != 0)
76 ERROR_EXIT(str_file_autoconf);
77 buffer_size = 2 * stat_buf.st_size + 4096;
78
79 /* Allocate buffers. */
80 if ( (line = malloc(buffer_size)) == NULL
81 || (old_line = malloc(buffer_size)) == NULL
82 || (list_target = malloc(buffer_size)) == NULL )
83 ERROR_EXIT(str_file_autoconf);
84
85 /* Open autoconfig file. */
86 if ((fp_config = fopen(str_file_autoconf, "r")) == NULL)
87 ERROR_EXIT(str_file_autoconf);
88
89 /* Make output directory if needed. */
90 if (stat(str_dir_config, &stat_buf) != 0)
91 {
92 if (mkdir(str_dir_config, 0755) != 0)
93 ERROR_EXIT(str_dir_config);
94 }
95
96 /* Change to output directory. */
97 if (chdir(str_dir_config) != 0)
98 ERROR_EXIT(str_dir_config);
99
100 /* Put initial separator into target list. */
101 ptarget = list_target;
102 *ptarget++ = '\n';
103
104 /* Read config lines. */
105 while (fgets(line, buffer_size, fp_config))
106 {
107 const char * str_config;
108 int is_same;
109 int itarget;
110
111 if (line[0] != '#')
112 continue;
113 if ((str_config = strstr(line, "CONFIG_")) == NULL)
114 continue;
115
116 /* Make the output file name. */
117 str_config += sizeof("CONFIG_") - 1;
118 for (itarget = 0; !isspace(str_config[itarget]); itarget++)
119 {
120 char c = str_config[itarget];
121 if (isupper(c)) c = tolower(c);
122 if (c == '_') c = '/';
123 ptarget[itarget] = c;
124 }
125 ptarget[itarget++] = '.';
126 ptarget[itarget++] = 'h';
127 ptarget[itarget++] = '\0';
128
129 /* Check for existing file. */
130 is_same = 0;
131 if ((fp_target = fopen(ptarget, "r")) != NULL)
132 {
133 fgets(old_line, buffer_size, fp_target);
134 if (fclose(fp_target) != 0)
135 ERROR_EXIT(ptarget);
136 if (!strcmp(line, old_line))
137 is_same = 1;
138 }
139
140 if (!is_same)
141 {
142 /* Auto-create directories. */
143 int islash;
144 for (islash = 0; islash < itarget; islash++)
145 {
146 if (ptarget[islash] == '/')
147 {
148 ptarget[islash] = '\0';
149 if (stat(ptarget, &stat_buf) != 0
150 && mkdir(ptarget, 0755) != 0)
151 ERROR_EXIT( ptarget );
152 ptarget[islash] = '/';
153 }
154 }
155
156 /* Write the file. */
157 if ((fp_target = fopen(ptarget, "w" )) == NULL)
158 ERROR_EXIT(ptarget);
159 fputs(line, fp_target);
160 if (ferror(fp_target) || fclose(fp_target) != 0)
161 ERROR_EXIT(ptarget);
162 }
163
164 /* Update target list */
165 ptarget += itarget;
166 *(ptarget-1) = '\n';
167 }
168
169 /*
170 * Close autoconfig file.
171 * Terminate the target list.
172 */
173 if (fclose(fp_config) != 0)
174 ERROR_EXIT(str_file_autoconf);
175 *ptarget = '\0';
176
177 /*
178 * Fix up existing files which have no new value.
179 * This is Case 4 and Case 5.
180 *
181 * I re-read the tree and filter it against list_target.
182 * This is crude. But it avoids data copies. Also, list_target
183 * is compact and contiguous, so it easily fits into cache.
184 *
185 * Notice that list_target contains strings separated by \n,
186 * with a \n before the first string and after the last.
187 * fgets gives the incoming names a terminating \n.
188 * So by having an initial \n, strstr will find exact matches.
189 */
190
191 fp_find = popen("find * -type f -name \"*.h\" -print", "r");
192 if (fp_find == 0)
193 ERROR_EXIT( "find" );
194
195 line[0] = '\n';
196 while (fgets(line+1, buffer_size, fp_find))
197 {
198 if (strstr(list_target, line) == NULL)
199 {
200 /*
201 * This is an old file with no CONFIG_* flag in autoconf.h.
202 */
203
204 /* First strip the \n. */
205 line[strlen(line)-1] = '\0';
206
207 /* Grab size. */
208 if (stat(line+1, &stat_buf) != 0)
209 ERROR_EXIT(line);
210
211 /* If file is not empty, make it empty and give it a fresh date. */
212 if (stat_buf.st_size != 0)
213 {
214 if ((fp_target = fopen(line+1, "w")) == NULL)
215 ERROR_EXIT(line);
216 if (fclose(fp_target) != 0)
217 ERROR_EXIT(line);
218 }
219 }
220 }
221
222 if (pclose(fp_find) != 0)
223 ERROR_EXIT("find");
224
225 return 0;
226}
diff --git a/scripts/undeb b/scripts/undeb
deleted file mode 100644
index a72e1e2ba..000000000
--- a/scripts/undeb
+++ /dev/null
@@ -1,53 +0,0 @@
1#!/bin/sh
2#
3# This should work with the GNU version of tar and gzip!
4# This should work with the bash or ash shell!
5# Requires the programs (ar, tar, gzip, and the pager more or less).
6#
7usage() {
8echo "Usage: undeb -c package.deb <Print control file info>"
9echo " undeb -l package.deb <List contents of deb package>"
10echo " undeb -x package.deb /foo/boo <Extract deb package to this directory,"
11echo " put . for current directory>"
12exit
13}
14
15deb=$2
16
17exist() {
18if [ "$deb" = "" ]; then
19usage
20elif [ ! -s "$deb" ]; then
21echo "Can't find $deb!"
22exit
23fi
24}
25
26if [ "$1" = "" ]; then
27usage
28elif [ "$1" = "-l" ]; then
29exist
30type more >/dev/null 2>&1 && pager=more
31type less >/dev/null 2>&1 && pager=less
32[ "$pager" = "" ] && echo "No pager found!" && exit
33(ar -p $deb control.tar.gz | tar -xzO *control ; echo -e "\nPress enter to scroll, q to Quit!\n" ; ar -p $deb data.tar.gz | tar -tzv) | $pager
34exit
35elif [ "$1" = "-c" ]; then
36exist
37ar -p $deb control.tar.gz | tar -xzO *control
38exit
39elif [ "$1" = "-x" ]; then
40exist
41if [ "$3" = "" ]; then
42usage
43elif [ ! -d "$3" ]; then
44echo "No such directory $3!"
45exit
46fi
47ar -p $deb data.tar.gz | tar -xzvpf - -C $3 || exit
48echo
49echo "Extracted $deb to $3!"
50exit
51else
52usage
53fi
diff --git a/scripts/unrpm b/scripts/unrpm
deleted file mode 100644
index 376286a6f..000000000
--- a/scripts/unrpm
+++ /dev/null
@@ -1,48 +0,0 @@
1#!/bin/sh
2#
3# This should work with the GNU version of cpio and gzip!
4# This should work with the bash or ash shell!
5# Requires the programs (cpio, gzip, and the pager more or less).
6#
7usage() {
8echo "Usage: unrpm -l package.rpm <List contents of rpm package>"
9echo " unrpm -x package.rpm /foo/boo <Extract rpm package to this directory,"
10echo " put . for current directory>"
11exit
12}
13
14rpm=$2
15
16exist() {
17if [ "$rpm" = "" ]; then
18usage
19elif [ ! -s "$rpm" ]; then
20echo "Can't find $rpm!"
21exit
22fi
23}
24
25if [ "$1" = "" ]; then
26usage
27elif [ "$1" = "-l" ]; then
28exist
29type more >/dev/null 2>&1 && pager=more
30type less >/dev/null 2>&1 && pager=less
31[ "$pager" = "" ] && echo "No pager found!" && exit
32(echo -e "\nPress enter to scroll, q to Quit!\n" ; rpm2cpio $rpm | cpio -tv --quiet) | $pager
33exit
34elif [ "$1" = "-x" ]; then
35exist
36if [ "$3" = "" ]; then
37usage
38elif [ ! -d "$3" ]; then
39echo "No such directory $3!"
40exit
41fi
42rpm2cpio $rpm | (umask 0 ; cd $3 ; cpio -idmuv) || exit
43echo
44echo "Extracted $rpm to $3!"
45exit
46else
47usage
48fi