diff options
| author | Eric Andersen <andersen@codepoet.org> | 2001-10-24 05:00:29 +0000 |
|---|---|---|
| committer | Eric Andersen <andersen@codepoet.org> | 2001-10-24 05:00:29 +0000 |
| commit | bdfd0d78bc44e73d693510e70087857785b3b521 (patch) | |
| tree | 153a573095afac8d8d0ea857759ecabd77fb28b7 /scripts | |
| parent | 9260fc5552a3ee52eb95823aa6689d52a1ffd33c (diff) | |
| download | busybox-w32-bdfd0d78bc44e73d693510e70087857785b3b521.tar.gz busybox-w32-bdfd0d78bc44e73d693510e70087857785b3b521.tar.bz2 busybox-w32-bdfd0d78bc44e73d693510e70087857785b3b521.zip | |
Major rework of the directory structure and the entire build system.
-Erik
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/Configure | 705 | ||||
| -rw-r--r-- | scripts/Menuconfig | 1285 | ||||
| -rwxr-xr-x | scripts/depmod.pl | 227 | ||||
| -rw-r--r-- | scripts/inittab | 86 | ||||
| -rw-r--r-- | scripts/lxdialog/BIG.FAT.WARNING | 4 | ||||
| -rw-r--r-- | scripts/lxdialog/Makefile | 46 | ||||
| -rw-r--r-- | scripts/lxdialog/Makefile-2.5 | 71 | ||||
| -rw-r--r-- | scripts/lxdialog/checklist.c | 369 | ||||
| -rw-r--r-- | scripts/lxdialog/colors.h | 161 | ||||
| -rw-r--r-- | scripts/lxdialog/dialog.h | 184 | ||||
| -rw-r--r-- | scripts/lxdialog/inputbox.c | 240 | ||||
| -rw-r--r-- | scripts/lxdialog/lxdialog.c | 226 | ||||
| -rw-r--r-- | scripts/lxdialog/menubox.c | 443 | ||||
| -rw-r--r-- | scripts/lxdialog/msgbox.c | 85 | ||||
| -rw-r--r-- | scripts/lxdialog/textbox.c | 556 | ||||
| -rw-r--r-- | scripts/lxdialog/util.c | 359 | ||||
| -rw-r--r-- | scripts/lxdialog/yesno.c | 118 | ||||
| -rwxr-xr-x | scripts/mk2knr.pl | 84 | ||||
| -rw-r--r-- | scripts/mkdep.c | 628 | ||||
| -rw-r--r-- | scripts/split-include.c | 226 | ||||
| -rw-r--r-- | scripts/undeb | 53 | ||||
| -rw-r--r-- | scripts/unrpm | 48 |
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. | ||
| 67 | set -f -h | ||
| 68 | |||
| 69 | # | ||
| 70 | # Dummy functions for use with a config.in modified for menuconf | ||
| 71 | # | ||
| 72 | function mainmenu_option () { | ||
| 73 | : | ||
| 74 | } | ||
| 75 | function mainmenu_name () { | ||
| 76 | : | ||
| 77 | } | ||
| 78 | function endmenu () { | ||
| 79 | : | ||
| 80 | } | ||
| 81 | |||
| 82 | # | ||
| 83 | # returns a random number between 1 and $1 | ||
| 84 | # | ||
| 85 | function 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 | |||
| 98 | function 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 | # | ||
| 124 | function 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 | # | ||
| 159 | function 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 | # | ||
| 180 | function 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 | # | ||
| 191 | function define_bool () { | ||
| 192 | define_tristate $1 $2 | ||
| 193 | } | ||
| 194 | |||
| 195 | function 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 | # | ||
| 221 | function 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 | # | ||
| 260 | function 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 | # | ||
| 312 | function 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 | |||
| 377 | function 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 | |||
| 394 | function 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 | # | ||
| 416 | function 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 | # | ||
| 427 | function 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 | # | ||
| 457 | function 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 | # | ||
| 468 | function 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 | # | ||
| 490 | function 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 | # | ||
| 501 | function 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 | # | ||
| 532 | function 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 | |||
| 610 | CONFIG=.tmpconfig | ||
| 611 | CONFIG_H=.tmpconfig.h | ||
| 612 | FORCE_DEFAULT=.force_default | ||
| 613 | trap "rm -f $CONFIG $CONFIG_H ; exit 1" 1 2 | ||
| 614 | |||
| 615 | # | ||
| 616 | # Make sure we start out with a clean slate. | ||
| 617 | # | ||
| 618 | echo "#" > $CONFIG | ||
| 619 | echo "# Automatically generated make config: don't edit" >> $CONFIG | ||
| 620 | echo "#" >> $CONFIG | ||
| 621 | |||
| 622 | echo "/*" > $CONFIG_H | ||
| 623 | echo " * Automatically generated C config: don't edit" >> $CONFIG_H | ||
| 624 | echo " */" >> $CONFIG_H | ||
| 625 | echo "#define AUTOCONF_INCLUDED" >> $CONFIG_H | ||
| 626 | |||
| 627 | DEFAULT="" | ||
| 628 | if [ "$1" = "-d" ] ; then | ||
| 629 | DEFAULT="-d" | ||
| 630 | shift | ||
| 631 | fi | ||
| 632 | |||
| 633 | RND="" | ||
| 634 | DEF_ANS="" | ||
| 635 | AUTO="" | ||
| 636 | case "$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 ;; | ||
| 641 | esac | ||
| 642 | |||
| 643 | CONFIG_IN=./config.in | ||
| 644 | if [ "$1" != "" ] ; then | ||
| 645 | CONFIG_IN=$1 | ||
| 646 | fi | ||
| 647 | |||
| 648 | DEFAULTS=sysdeps/$TARGET_OS/defconfig | ||
| 649 | if [ -f .config ]; then | ||
| 650 | DEFAULTS=.config | ||
| 651 | fi | ||
| 652 | |||
| 653 | if [ "$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 | ||
| 667 | else | ||
| 668 | if [ -f $FORCE_DEFAULT ]; then | ||
| 669 | echo "#" | ||
| 670 | echo "# Forcing defaults found in $FORCE_DEFAULT" | ||
| 671 | echo "#" | ||
| 672 | sed -e ' | ||
| 673 | s/# \(CONFIG_[^ ]*\) is not.*/\1=n/; | ||
| 674 | s/# range \(CONFIG_[^ ]*\) \([^ ][^ ]*\) \([^ ][^ ]*\)/MIN_\1=\2; MAX_\1=\3/; | ||
| 675 | s/# 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 | ||
| 684 | fi | ||
| 685 | |||
| 686 | . $CONFIG_IN | ||
| 687 | |||
| 688 | rm -f .config.old | ||
| 689 | if [ -f .config ]; then | ||
| 690 | mv .config .config.old | ||
| 691 | fi | ||
| 692 | mv .tmpconfig .config | ||
| 693 | mv .tmpconfig.h include/config.h | ||
| 694 | |||
| 695 | echo | ||
| 696 | echo "*** End of BusyBox configuration." | ||
| 697 | echo "*** Check the top-level Makefile for additional configuration." | ||
| 698 | if [ ! -f .hdepend -o "$CONFIG_MODVERSIONS" = "y" ] ; then | ||
| 699 | echo "*** Next, you must run 'make dep'." | ||
| 700 | else | ||
| 701 | echo "*** Next, you may run 'make bzImage', 'make bzdisk', or 'make install'." | ||
| 702 | fi | ||
| 703 | echo | ||
| 704 | |||
| 705 | exit 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 | # | ||
| 86 | single_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 | # | ||
| 96 | set -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 | |||
| 107 | function 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 | # | ||
| 127 | load_functions () { | ||
| 128 | |||
| 129 | # | ||
| 130 | # Additional comments | ||
| 131 | # | ||
| 132 | function 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 | # | ||
| 140 | function define_bool () { | ||
| 141 | eval $1=$2 | ||
| 142 | } | ||
| 143 | |||
| 144 | function define_hex () { | ||
| 145 | eval $1=$2 | ||
| 146 | } | ||
| 147 | |||
| 148 | function define_int () { | ||
| 149 | eval $1=$2 | ||
| 150 | } | ||
| 151 | |||
| 152 | function 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 | # | ||
| 160 | function 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 | # | ||
| 177 | function 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 | |||
| 197 | function 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 | # | ||
| 220 | function 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 | # | ||
| 231 | function 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 | # | ||
| 243 | function 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 | # | ||
| 254 | function 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 | # | ||
| 302 | function 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 | # | ||
| 335 | function 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 | # | ||
| 350 | function 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 | # | ||
| 359 | function 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 | # | ||
| 371 | function submenu () { | ||
| 372 | echo -ne "'activate_menu $2' '$1 --->' " >>MCmenu | ||
| 373 | } | ||
| 374 | |||
| 375 | # | ||
| 376 | # Handle a boolean (Yes/No) option. | ||
| 377 | # | ||
| 378 | function 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 | # | ||
| 399 | function 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 | # | ||
| 433 | function 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 | # | ||
| 466 | function 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 | # | ||
| 494 | function 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 | # | ||
| 559 | function callawk () { | ||
| 560 | awk "$1" || echo "Awk died with error code $?. Giving up." || exit 1 | ||
| 561 | } | ||
| 562 | |||
| 563 | # | ||
| 564 | # A faster awk based recursive parser. (I hope) | ||
| 565 | # | ||
| 566 | function parser1 () { | ||
| 567 | callawk ' | ||
| 568 | BEGIN { | ||
| 569 | menu_no = 0 | ||
| 570 | comment_is_option = 0 | ||
| 571 | parser("'$CONFIG_IN'","MCmenu0") | ||
| 572 | } | ||
| 573 | |||
| 574 | function 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 | # | ||
| 615 | function parser2 () { | ||
| 616 | callawk ' | ||
| 617 | BEGIN { | ||
| 618 | parser("'$CONFIG_IN'","MCmenu0") | ||
| 619 | } | ||
| 620 | |||
| 621 | function 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 | # | ||
| 643 | function 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 | # | ||
| 685 | function 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 | |||
| 698 | Menuconfig has encountered a possible error in one of BusyBox's | ||
| 699 | configuration files and is unable to continue. Here is the error | ||
| 700 | report: | ||
| 701 | |||
| 702 | EOM | ||
| 703 | sed 's/^/ Q> /' MCerror | ||
| 704 | cat <<EOM | ||
| 705 | |||
| 706 | Please report this to the maintainer <mec@shout.net>. You may also | ||
| 707 | send a problem report to <busybox@oss.lineo.com>. | ||
| 708 | |||
| 709 | Please indicate the BusyBox version you are trying to configure and | ||
| 710 | which menu you were trying to enter when this error occurred. | ||
| 711 | |||
| 712 | EOM | ||
| 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 | |||
| 755 | There seems to be a problem with the lxdialog companion utility which is | ||
| 756 | built prior to running Menuconfig. Usually this is an indicator that you | ||
| 757 | have upgraded/downgraded your ncurses libraries and did not remove the | ||
| 758 | old ncurses header file(s) in /usr/include or /usr/include/ncurses. | ||
| 759 | |||
| 760 | It is VERY important that you have only one set of ncurses header files | ||
| 761 | and that those files are properly version matched to the ncurses libraries | ||
| 762 | installed on your machine. | ||
| 763 | |||
| 764 | You may also need to rebuild lxdialog. This can be done by moving to | ||
| 765 | the /usr/src/linux/scripts/lxdialog directory and issuing the | ||
| 766 | "make clean all" command. | ||
| 767 | |||
| 768 | If you have verified that your ncurses install is correct, you may email | ||
| 769 | the maintainer <andersen@codepoet.org> or post a message to | ||
| 770 | <busybox@oss.lineo.com> for additional assistance. | ||
| 771 | |||
| 772 | EOM | ||
| 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 | # | ||
| 783 | g_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 | # | ||
| 792 | get_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 "\ | ||
| 801 | Enter the name of the configuration file you wish to load. \ | ||
| 802 | Accept the name shown to restore the configuration you \ | ||
| 803 | last retrieved. Leave blank to abort."\ | ||
| 804 | 11 55 "$ALT_CONFIG" 2>MCdialog.out | ||
| 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 | |||
| 825 | For various reasons, one may wish to keep several different BusyBox | ||
| 826 | configurations available on a single machine. | ||
| 827 | |||
| 828 | If you have saved a previous configuration in a file other than the | ||
| 829 | busybox default, entering the name of the file here will allow you | ||
| 830 | to modify that configuration. | ||
| 831 | |||
| 832 | If you are uncertain, then you have probably never used alternate | ||
| 833 | configuration files. You should therefor leave this blank to abort. | ||
| 834 | |||
| 835 | EOM | ||
| 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 | # | ||
| 849 | s_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 | # | ||
| 858 | save_alt_config () { | ||
| 859 | set -f ## Switch file expansion OFF | ||
| 860 | |||
| 861 | while true | ||
| 862 | do | ||
| 863 | $DIALOG --backtitle "$backtitle" \ | ||
| 864 | --inputbox "\ | ||
| 865 | Enter a filename to which this configuration should be saved \ | ||
| 866 | as an alternate. Leave blank to abort."\ | ||
| 867 | 10 55 "$ALT_CONFIG" 2>MCdialog.out | ||
| 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 | |||
| 889 | For various reasons, one may wish to keep different BusyBox | ||
| 890 | configurations available on a single machine. | ||
| 891 | |||
| 892 | Entering a file name here will allow you to later retrieve, modify | ||
| 893 | and use the current configuration as an alternate to whatever | ||
| 894 | configuration options you have selected at that time. | ||
| 895 | |||
| 896 | If you are uncertain what all this means then you should probably | ||
| 897 | leave this blank. | ||
| 898 | EOM | ||
| 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 | # | ||
| 913 | function 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 | # | ||
| 926 | save_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 | # | ||
| 1125 | cleanup () { | ||
| 1126 | cleanup1 | ||
| 1127 | cleanup2 | ||
| 1128 | } | ||
| 1129 | |||
| 1130 | cleanup1 () { | ||
| 1131 | rm -f MCmenu* MCradiolists MCdialog.out help.out | ||
| 1132 | } | ||
| 1133 | |||
| 1134 | cleanup2 () { | ||
| 1135 | rm -f .tmpconfig .tmpconfig.h | ||
| 1136 | } | ||
| 1137 | |||
| 1138 | set_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 | |||
| 1161 | set_geometry `stty size 2>/dev/null` | ||
| 1162 | |||
| 1163 | menu_instructions="\ | ||
| 1164 | Arrow keys navigate the menu. \ | ||
| 1165 | Pressing <Enter> selects submenus --->. \ | ||
| 1166 | Highlighted letters are hotkeys. \ | ||
| 1167 | Pressing <Y> includes, and <N> excludes. \ | ||
| 1168 | Press <Esc><Esc> to exit, <?> for Help. \ | ||
| 1169 | Legend: [*] built-in [ ] excluded " | ||
| 1170 | |||
| 1171 | radiolist_instructions="\ | ||
| 1172 | Use the arrow keys to navigate this window or \ | ||
| 1173 | press the hotkey of the item you wish to select \ | ||
| 1174 | followed by the <SPACE BAR>. | ||
| 1175 | Press <?> for additional information about this option." | ||
| 1176 | |||
| 1177 | inputbox_instructions_int="\ | ||
| 1178 | Please enter a decimal value. \ | ||
| 1179 | Fractions will not be accepted. \ | ||
| 1180 | Use the <TAB> key to move from the input field to the buttons below it." | ||
| 1181 | |||
| 1182 | inputbox_instructions_hex="\ | ||
| 1183 | Please enter a hexadecimal value. \ | ||
| 1184 | Use the <TAB> key to move from the input field to the buttons below it." | ||
| 1185 | |||
| 1186 | inputbox_instructions_string="\ | ||
| 1187 | Please enter a string value. \ | ||
| 1188 | Use the <TAB> key to move from the input field to the buttons below it." | ||
| 1189 | |||
| 1190 | DIALOG="./scripts/lxdialog/lxdialog" | ||
| 1191 | |||
| 1192 | bb_version="${VERSION}" | ||
| 1193 | backtitle="BusyBox v$bb_version Configuration" | ||
| 1194 | |||
| 1195 | trap "cleanup ; exit 1" 1 2 15 | ||
| 1196 | |||
| 1197 | |||
| 1198 | # | ||
| 1199 | # Locate default files. | ||
| 1200 | # | ||
| 1201 | CONFIG_IN=./config.in | ||
| 1202 | if [ "$1" != "" ] ; then | ||
| 1203 | CONFIG_IN=$1 | ||
| 1204 | fi | ||
| 1205 | |||
| 1206 | DEFAULTS=sysdeps/$TARGET_OS/defconfig | ||
| 1207 | if [ -f .config ]; then | ||
| 1208 | DEFAULTS=.config | ||
| 1209 | fi | ||
| 1210 | |||
| 1211 | if [ -f $DEFAULTS ] | ||
| 1212 | then | ||
| 1213 | echo "Using defaults found in" $DEFAULTS | ||
| 1214 | load_config_file $DEFAULTS | ||
| 1215 | else | ||
| 1216 | echo "No defaults found" | ||
| 1217 | fi | ||
| 1218 | |||
| 1219 | |||
| 1220 | # Fresh new log. | ||
| 1221 | >.menuconfig.log | ||
| 1222 | |||
| 1223 | # Load the functions used by the config.in files. | ||
| 1224 | echo -n "Preparing scripts: functions" | ||
| 1225 | load_functions | ||
| 1226 | |||
| 1227 | if [ ! -e $CONFIG_IN ] | ||
| 1228 | then | ||
| 1229 | echo "Your main config.in file ($CONFIG_IN) does not exist" | ||
| 1230 | exit 1 | ||
| 1231 | fi | ||
| 1232 | |||
| 1233 | if [ ! -x $DIALOG ] | ||
| 1234 | then | ||
| 1235 | echo "Your lxdialog utility does not exist" | ||
| 1236 | exit 1 | ||
| 1237 | fi | ||
| 1238 | |||
| 1239 | # | ||
| 1240 | # Read config.in files and parse them into one shell function per menu. | ||
| 1241 | # | ||
| 1242 | echo -n ", parsing" | ||
| 1243 | parse_config_files $CONFIG_IN | ||
| 1244 | |||
| 1245 | echo "done." | ||
| 1246 | # | ||
| 1247 | # Start the ball rolling from the top. | ||
| 1248 | # | ||
| 1249 | activate_menu MCmenu0 | ||
| 1250 | |||
| 1251 | # | ||
| 1252 | # All done! | ||
| 1253 | # | ||
| 1254 | cleanup1 | ||
| 1255 | |||
| 1256 | # | ||
| 1257 | # Confirm and Save | ||
| 1258 | # | ||
| 1259 | if $DIALOG --backtitle "$backtitle" \ | ||
| 1260 | --yesno "Do you wish to save your new BusyBox configuration?" 5 60 | ||
| 1261 | then | ||
| 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 | ||
| 1273 | else | ||
| 1274 | echo | ||
| 1275 | echo | ||
| 1276 | echo Your BusyBox configuration changes were NOT saved. | ||
| 1277 | echo | ||
| 1278 | fi | ||
| 1279 | |||
| 1280 | # Remove log if empty. | ||
| 1281 | if [ ! -s .menuconfig.log ] ; then | ||
| 1282 | rm -f .menuconfig.log | ||
| 1283 | fi | ||
| 1284 | |||
| 1285 | exit 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 | |||
| 12 | use Getopt::Long; | ||
| 13 | use File::Find; | ||
| 14 | |||
| 15 | |||
| 16 | # Set up some default values | ||
| 17 | |||
| 18 | my $basedir=""; | ||
| 19 | my $kernel; | ||
| 20 | my $kernelsyms; | ||
| 21 | my $stdout=1; | ||
| 22 | my $verbose=0; | ||
| 23 | |||
| 24 | |||
| 25 | # get command-line options | ||
| 26 | |||
| 27 | my %opt; | ||
| 28 | |||
| 29 | GetOptions( | ||
| 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 | |||
| 39 | if (defined $opt{help}) { | ||
| 40 | |||
| 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 | |||
| 52 | if($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"; } | ||
| 58 | my($file) = ""; | ||
| 59 | my(@liblist) = (); | ||
| 60 | find 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; | ||
| 69 | if ($verbose) { printf "Finished locating modules\n"; } | ||
| 70 | |||
| 71 | foreach $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 | ||
| 116 | foreach $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 | ||
| 130 | foreach $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 | |||
| 140 | sub 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 | |||
| 156 | depmod.pl - a cross platform script to generate kernel module dependency | ||
| 157 | lists which can then be used by modprobe. | ||
| 158 | |||
| 159 | =head1 SYNOPSIS | ||
| 160 | |||
| 161 | depmod.pl [OPTION]... [FILE]... | ||
| 162 | |||
| 163 | Example: | ||
| 164 | |||
| 165 | depmod.pl -F linux/System.map target/lib/modules | ||
| 166 | |||
| 167 | =head1 DESCRIPTION | ||
| 168 | |||
| 169 | The purpose of this script is to automagically generate a list of of kernel | ||
| 170 | module dependancies. This script produces dependancy lists that should be | ||
| 171 | identical to the depmod program from the modutils package. Unlike the depmod | ||
| 172 | binary, however, depmod.pl is designed to be run on your host system, not | ||
| 173 | on your target system. | ||
| 174 | |||
| 175 | This script was written by David Schleef <ds@schleef.org> to be used in | ||
| 176 | conjunction with the BusyBox modprobe applet. | ||
| 177 | |||
| 178 | =head1 OPTIONS | ||
| 179 | |||
| 180 | =over 4 | ||
| 181 | |||
| 182 | =item B<-h --help> | ||
| 183 | |||
| 184 | This displays the help message. | ||
| 185 | |||
| 186 | =item B<-b --basedir> | ||
| 187 | |||
| 188 | The base directory uner which the target's modules will be found. This | ||
| 189 | defaults to the /lib/modules directory. | ||
| 190 | |||
| 191 | =item B<-k --kernel> | ||
| 192 | |||
| 193 | Kernel binary for the target. You must either supply a kernel binary | ||
| 194 | or a kernel symbol file (using the -F option). | ||
| 195 | |||
| 196 | =item B<-F --kernelsyms> | ||
| 197 | |||
| 198 | Kernel symbol file for the target. You must supply either a kernel symbol file | ||
| 199 | kernel binary for the target (using the -k option). | ||
| 200 | |||
| 201 | =item B<-n --stdout> | ||
| 202 | |||
| 203 | Write to stdout instead of modules.dep. This is currently hard coded... | ||
| 204 | kernel binary for the target (using the -k option). | ||
| 205 | |||
| 206 | =item B<--verbose> | ||
| 207 | |||
| 208 | Be verbose (not implemented) | ||
| 209 | |||
| 210 | =back | ||
| 211 | |||
| 212 | =head1 COPYRIGHT | ||
| 213 | |||
| 214 | Copyright (c) 2001 David Schleef <ds@schleef.org> | ||
| 215 | Copyright (c) 2001 Erik Andersen <andersen@lineo.com> | ||
| 216 | Copyright (c) 2001 Stuart Hughes <stuarth@lineo.com> | ||
| 217 | This program is free software; you can redistribute it and/or modify it | ||
| 218 | under the same terms as Perl itself. | ||
| 219 | |||
| 220 | =head1 AUTHOR | ||
| 221 | |||
| 222 | David 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 | ||
| 67 | tty2::askfirst:-/bin/sh | ||
| 68 | tty3::askfirst:-/bin/sh | ||
| 69 | tty4::askfirst:-/bin/sh | ||
| 70 | |||
| 71 | # /sbin/getty invocations for selected ttys | ||
| 72 | tty4::respawn:/sbin/getty 38400 tty5 | ||
| 73 | tty5::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 @@ | |||
| 1 | This is NOT the official version of dialog. This version has been | ||
| 2 | significantly modified from the original. It is for use by the Linux | ||
| 3 | kernel configuration script. Please do not bother Savio Lam with | ||
| 4 | questions 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 @@ | |||
| 1 | HOSTCFLAGS += -DLOCALE | ||
| 2 | LIBS = -lncurses | ||
| 3 | |||
| 4 | ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h)) | ||
| 5 | HOSTCFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>" | ||
| 6 | else | ||
| 7 | ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h)) | ||
| 8 | HOSTCFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>" | ||
| 9 | else | ||
| 10 | ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h)) | ||
| 11 | HOSTCFLAGS += -DCURSES_LOC="<ncurses.h>" | ||
| 12 | else | ||
| 13 | HOSTCFLAGS += -DCURSES_LOC="<curses.h>" | ||
| 14 | endif | ||
| 15 | endif | ||
| 16 | endif | ||
| 17 | |||
| 18 | |||
| 19 | OBJS = 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 | |||
| 25 | all: ncurses lxdialog | ||
| 26 | |||
| 27 | lxdialog: $(OBJS) | ||
| 28 | $(HOSTCC) -o lxdialog $(OBJS) $(LIBS) | ||
| 29 | |||
| 30 | ncurses: | ||
| 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 | |||
| 45 | clean: | ||
| 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 @@ | |||
| 1 | lxdialog-hostcflags += -DLOCALE | ||
| 2 | lxdialog-libs = -lncurses | ||
| 3 | |||
| 4 | ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h)) | ||
| 5 | lxdialog-hostcflags += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>" | ||
| 6 | else | ||
| 7 | ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h)) | ||
| 8 | lxdialog-hostcflags += -I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>" | ||
| 9 | else | ||
| 10 | ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h)) | ||
| 11 | lxdialog-hostcflags += -DCURSES_LOC="<ncurses.h>" | ||
| 12 | else | ||
| 13 | lxdialog-hostcflags += -DCURSES_LOC="<curses.h>" | ||
| 14 | endif | ||
| 15 | endif | ||
| 16 | endif | ||
| 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 | |||
| 39 | lxdialog-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 | |||
| 71 | MRPROPER += $(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 | |||
| 26 | static int list_width, check_x, item_x, checkflag; | ||
| 27 | |||
| 28 | /* | ||
| 29 | * Print list item | ||
| 30 | */ | ||
| 31 | static void | ||
| 32 | print_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 | */ | ||
| 63 | static void | ||
| 64 | print_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 | */ | ||
| 102 | static void | ||
| 103 | print_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 | */ | ||
| 119 | int | ||
| 120 | dialog_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 | |||
| 155 | typedef struct { | ||
| 156 | char name[COLOR_NAME_LEN]; | ||
| 157 | int value; | ||
| 158 | } color_names_st; | ||
| 159 | |||
| 160 | extern color_names_st color_names[]; | ||
| 161 | extern 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 | */ | ||
| 127 | extern bool use_colors; | ||
| 128 | extern bool use_shadow; | ||
| 129 | |||
| 130 | extern chtype attributes[]; | ||
| 131 | |||
| 132 | extern const char *backtitle; | ||
| 133 | |||
| 134 | /* | ||
| 135 | * Function prototypes | ||
| 136 | */ | ||
| 137 | extern void create_rc (const char *filename); | ||
| 138 | extern int parse_rc (void); | ||
| 139 | |||
| 140 | |||
| 141 | void init_dialog (void); | ||
| 142 | void end_dialog (void); | ||
| 143 | void attr_clear (WINDOW * win, int height, int width, chtype attr); | ||
| 144 | void dialog_clear (void); | ||
| 145 | void color_setup (void); | ||
| 146 | void print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x); | ||
| 147 | void print_button (WINDOW * win, const char *label, int y, int x, int selected); | ||
| 148 | void draw_box (WINDOW * win, int y, int x, int height, int width, chtype box, | ||
| 149 | chtype border); | ||
| 150 | void draw_shadow (WINDOW * win, int y, int x, int height, int width); | ||
| 151 | |||
| 152 | int first_alpha (const char *string, const char *exempt); | ||
| 153 | int dialog_yesno (const char *title, const char *prompt, int height, int width); | ||
| 154 | int dialog_msgbox (const char *title, const char *prompt, int height, | ||
| 155 | int width, int pause); | ||
| 156 | int dialog_textbox (const char *title, const char *file, int height, int width); | ||
| 157 | int 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); | ||
| 160 | int 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); | ||
| 163 | extern unsigned char dialog_input_result[]; | ||
| 164 | int 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 | |||
| 24 | unsigned char dialog_input_result[MAX_LEN + 1]; | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Print the termination buttons | ||
| 28 | */ | ||
| 29 | static void | ||
| 30 | print_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 | */ | ||
| 45 | int | ||
| 46 | dialog_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 | |||
| 24 | static void Usage (const char *name); | ||
| 25 | |||
| 26 | typedef int (jumperFn) (const char *title, int argc, const char * const * argv); | ||
| 27 | |||
| 28 | struct Mode { | ||
| 29 | char *name; | ||
| 30 | int argmin, argmax, argmod; | ||
| 31 | jumperFn *jumper; | ||
| 32 | }; | ||
| 33 | |||
| 34 | jumperFn j_menu, j_checklist, j_radiolist, j_yesno, j_textbox, j_inputbox; | ||
| 35 | jumperFn j_msgbox, j_infobox; | ||
| 36 | |||
| 37 | static 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 | |||
| 50 | static struct Mode *modePtr; | ||
| 51 | |||
| 52 | #ifdef LOCALE | ||
| 53 | #include <locale.h> | ||
| 54 | #endif | ||
| 55 | |||
| 56 | int | ||
| 57 | main (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 | */ | ||
| 142 | static void | ||
| 143 | Usage (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 | |||
| 172 | int | ||
| 173 | j_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 | |||
| 179 | int | ||
| 180 | j_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 | |||
| 186 | int | ||
| 187 | j_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 | |||
| 193 | int | ||
| 194 | j_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 | |||
| 199 | int | ||
| 200 | j_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 | |||
| 205 | int | ||
| 206 | j_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 | |||
| 215 | int | ||
| 216 | j_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 | |||
| 221 | int | ||
| 222 | j_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 | |||
| 61 | static int menu_width, item_x; | ||
| 62 | |||
| 63 | /* | ||
| 64 | * Print menu item | ||
| 65 | */ | ||
| 66 | static void | ||
| 67 | print_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 | */ | ||
| 103 | static void | ||
| 104 | print_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 | */ | ||
| 148 | static void | ||
| 149 | print_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 | */ | ||
| 165 | int | ||
| 166 | dialog_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 | */ | ||
| 28 | int | ||
| 29 | dialog_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 | |||
| 24 | static void back_lines (int n); | ||
| 25 | static void print_page (WINDOW * win, int height, int width); | ||
| 26 | static void print_line (WINDOW * win, int row, int width); | ||
| 27 | static char *get_line (void); | ||
| 28 | static void print_position (WINDOW * win, int height, int width); | ||
| 29 | |||
| 30 | static int hscroll = 0, fd, file_size, bytes_read; | ||
| 31 | static int begin_reached = 1, end_reached = 0, page_length; | ||
| 32 | static char *buf, *page; | ||
| 33 | |||
| 34 | /* | ||
| 35 | * Display text from a file in a dialog box. | ||
| 36 | */ | ||
| 37 | int | ||
| 38 | dialog_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 | */ | ||
| 327 | static void | ||
| 328 | back_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 | */ | ||
| 440 | static void | ||
| 441 | print_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 | */ | ||
| 459 | static void | ||
| 460 | print_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 | */ | ||
| 489 | static char * | ||
| 490 | get_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 | */ | ||
| 540 | static void | ||
| 541 | print_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? */ | ||
| 26 | bool use_colors = 1; | ||
| 27 | |||
| 28 | const char *backtitle = NULL; | ||
| 29 | |||
| 30 | const char *dialog_result; | ||
| 31 | |||
| 32 | /* | ||
| 33 | * Attribute values, default is for mono display | ||
| 34 | */ | ||
| 35 | chtype 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 | */ | ||
| 74 | int 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 | */ | ||
| 111 | void | ||
| 112 | attr_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 | |||
| 125 | void 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 | */ | ||
| 144 | void | ||
| 145 | init_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 | */ | ||
| 163 | void | ||
| 164 | color_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 | */ | ||
| 184 | void | ||
| 185 | end_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 | */ | ||
| 197 | void | ||
| 198 | print_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 | */ | ||
| 257 | void | ||
| 258 | print_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 | */ | ||
| 285 | void | ||
| 286 | draw_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 | */ | ||
| 320 | void | ||
| 321 | draw_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 | */ | ||
| 342 | int | ||
| 343 | first_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 | */ | ||
| 27 | static void | ||
| 28 | print_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 | */ | ||
| 43 | int | ||
| 44 | dialog_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 | ||
| 23 | die "usage: $0 file.c | file.h\n" if scalar(@ARGV) == 0; | ||
| 24 | |||
| 25 | # prepare the "convert me" file | ||
| 26 | open(CM, ">$convertme") or die "convertme.pl $!"; | ||
| 27 | print CM "#!/usr/bin/perl -p -i\n\n"; | ||
| 28 | |||
| 29 | # process each file passed on the cmd line | ||
| 30 | while (<>) { | ||
| 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 | ||
| 79 | close(CM); | ||
| 80 | chmod 0755, $convertme; | ||
| 81 | |||
| 82 | # print a helpful help message | ||
| 83 | print "Done. Scheduled name changes are in $convertme.\n"; | ||
| 84 | print "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 | |||
| 48 | char __depname[512] = "\n\t@touch "; | ||
| 49 | #define depname (__depname+9) | ||
| 50 | int hasdep; | ||
| 51 | |||
| 52 | struct path_struct { | ||
| 53 | int len; | ||
| 54 | char *buffer; | ||
| 55 | }; | ||
| 56 | struct path_struct *path_array; | ||
| 57 | int paths; | ||
| 58 | |||
| 59 | |||
| 60 | /* Current input file */ | ||
| 61 | static 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 | */ | ||
| 69 | char * str_config = NULL; | ||
| 70 | int size_config = 0; | ||
| 71 | int len_config = 0; | ||
| 72 | |||
| 73 | static void | ||
| 74 | do_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 | */ | ||
| 88 | void 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 | */ | ||
| 104 | int 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 | */ | ||
| 122 | void 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 | */ | ||
| 136 | void 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 | */ | ||
| 148 | char * str_precious = NULL; | ||
| 149 | int size_precious = 0; | ||
| 150 | int len_precious = 0; | ||
| 151 | |||
| 152 | |||
| 153 | |||
| 154 | /* | ||
| 155 | * Grow the precious string to a desired length. | ||
| 156 | * Usually the first growth is plenty. | ||
| 157 | */ | ||
| 158 | void 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 | */ | ||
| 174 | void 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 | */ | ||
| 190 | void 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 | */ | ||
| 218 | void 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 | */ | ||
| 260 | void 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 | */ | ||
| 351 | void 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 (;;) { | ||
| 358 | start: | ||
| 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 | /* // */ | ||
| 371 | slash_slash: | ||
| 372 | GETNEXT | ||
| 373 | CASE('\n', start); | ||
| 374 | NOTCASE('\\', slash_slash); | ||
| 375 | GETNEXT | ||
| 376 | goto slash_slash; | ||
| 377 | |||
| 378 | /* / */ | ||
| 379 | slash: | ||
| 380 | GETNEXT | ||
| 381 | CASE('/', slash_slash); | ||
| 382 | NOTCASE('*', __start); | ||
| 383 | slash_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 | /* '.*?' */ | ||
| 392 | squote: | ||
| 393 | GETNEXT | ||
| 394 | CASE('\'', start); | ||
| 395 | NOTCASE('\\', squote); | ||
| 396 | GETNEXT | ||
| 397 | goto squote; | ||
| 398 | |||
| 399 | /* ".*?" */ | ||
| 400 | dquote: | ||
| 401 | GETNEXT | ||
| 402 | CASE('"', start); | ||
| 403 | NOTCASE('\\', dquote); | ||
| 404 | GETNEXT | ||
| 405 | goto dquote; | ||
| 406 | |||
| 407 | /* #\s* */ | ||
| 408 | pound: | ||
| 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 */ | ||
| 418 | pound_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* */ | ||
| 428 | pound_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*"(.*)" */ | ||
| 438 | pound_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*<(.*)> */ | ||
| 446 | pound_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 */ | ||
| 454 | pound_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 */ | ||
| 463 | pound_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 | */ | ||
| 477 | pound_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; | ||
| 491 | pound_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*) */ | ||
| 498 | cee: | ||
| 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; | ||
| 509 | cee_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 | */ | ||
| 523 | void 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 | */ | ||
| 576 | int 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 | |||
| 44 | int 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 | # | ||
| 7 | usage() { | ||
| 8 | echo "Usage: undeb -c package.deb <Print control file info>" | ||
| 9 | echo " undeb -l package.deb <List contents of deb package>" | ||
| 10 | echo " undeb -x package.deb /foo/boo <Extract deb package to this directory," | ||
| 11 | echo " put . for current directory>" | ||
| 12 | exit | ||
| 13 | } | ||
| 14 | |||
| 15 | deb=$2 | ||
| 16 | |||
| 17 | exist() { | ||
| 18 | if [ "$deb" = "" ]; then | ||
| 19 | usage | ||
| 20 | elif [ ! -s "$deb" ]; then | ||
| 21 | echo "Can't find $deb!" | ||
| 22 | exit | ||
| 23 | fi | ||
| 24 | } | ||
| 25 | |||
| 26 | if [ "$1" = "" ]; then | ||
| 27 | usage | ||
| 28 | elif [ "$1" = "-l" ]; then | ||
| 29 | exist | ||
| 30 | type more >/dev/null 2>&1 && pager=more | ||
| 31 | type 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 | ||
| 34 | exit | ||
| 35 | elif [ "$1" = "-c" ]; then | ||
| 36 | exist | ||
| 37 | ar -p $deb control.tar.gz | tar -xzO *control | ||
| 38 | exit | ||
| 39 | elif [ "$1" = "-x" ]; then | ||
| 40 | exist | ||
| 41 | if [ "$3" = "" ]; then | ||
| 42 | usage | ||
| 43 | elif [ ! -d "$3" ]; then | ||
| 44 | echo "No such directory $3!" | ||
| 45 | exit | ||
| 46 | fi | ||
| 47 | ar -p $deb data.tar.gz | tar -xzvpf - -C $3 || exit | ||
| 48 | echo | ||
| 49 | echo "Extracted $deb to $3!" | ||
| 50 | exit | ||
| 51 | else | ||
| 52 | usage | ||
| 53 | fi | ||
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 | # | ||
| 7 | usage() { | ||
| 8 | echo "Usage: unrpm -l package.rpm <List contents of rpm package>" | ||
| 9 | echo " unrpm -x package.rpm /foo/boo <Extract rpm package to this directory," | ||
| 10 | echo " put . for current directory>" | ||
| 11 | exit | ||
| 12 | } | ||
| 13 | |||
| 14 | rpm=$2 | ||
| 15 | |||
| 16 | exist() { | ||
| 17 | if [ "$rpm" = "" ]; then | ||
| 18 | usage | ||
| 19 | elif [ ! -s "$rpm" ]; then | ||
| 20 | echo "Can't find $rpm!" | ||
| 21 | exit | ||
| 22 | fi | ||
| 23 | } | ||
| 24 | |||
| 25 | if [ "$1" = "" ]; then | ||
| 26 | usage | ||
| 27 | elif [ "$1" = "-l" ]; then | ||
| 28 | exist | ||
| 29 | type more >/dev/null 2>&1 && pager=more | ||
| 30 | type 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 | ||
| 33 | exit | ||
| 34 | elif [ "$1" = "-x" ]; then | ||
| 35 | exist | ||
| 36 | if [ "$3" = "" ]; then | ||
| 37 | usage | ||
| 38 | elif [ ! -d "$3" ]; then | ||
| 39 | echo "No such directory $3!" | ||
| 40 | exit | ||
| 41 | fi | ||
| 42 | rpm2cpio $rpm | (umask 0 ; cd $3 ; cpio -idmuv) || exit | ||
| 43 | echo | ||
| 44 | echo "Extracted $rpm to $3!" | ||
| 45 | exit | ||
| 46 | else | ||
| 47 | usage | ||
| 48 | fi | ||
