busybox-1.0.1-rc1.patch
authorEric Andersen <andersen@codepoet.org>
Mon, 18 Jul 2005 23:51:27 +0000 (23:51 -0000)
committerEric Andersen <andersen@codepoet.org>
Mon, 18 Jul 2005 23:51:27 +0000 (23:51 -0000)
http://busybox.net/lists/busybox/2005-July/014974.html

105 files changed:
busybox/.cvsignore [deleted file]
busybox/AUTHORS
busybox/Makefile
busybox/applets/busybox.c
busybox/archival/ar.c
busybox/archival/dpkg.c
busybox/archival/dpkg_deb.c
busybox/archival/gzip.c
busybox/archival/libunarchive/archive_xread_all_eof.c
busybox/archival/libunarchive/decompress_bunzip2.c
busybox/archival/libunarchive/decompress_unzip.c
busybox/archival/tar.c
busybox/coreutils/Config.in
busybox/coreutils/cp.c
busybox/coreutils/cut.c
busybox/coreutils/date.c
busybox/coreutils/expr.c
busybox/coreutils/id.c
busybox/coreutils/install.c
busybox/coreutils/md5_sha1_sum.c
busybox/coreutils/mv.c
busybox/coreutils/test.c
busybox/coreutils/watch.c
busybox/coreutils/who.c
busybox/debianutils/start_stop_daemon.c
busybox/docs/.cvsignore [deleted file]
busybox/docs/busybox.net/.cvsignore [deleted file]
busybox/docs/new-applet-HOWTO.txt
busybox/editors/awk.c
busybox/editors/sed.c
busybox/editors/vi.c
busybox/findutils/grep.c
busybox/include/.cvsignore [deleted file]
busybox/include/applets.h
busybox/include/busybox.h
busybox/include/inet_common.h
busybox/include/libbb.h
busybox/include/usage.h
busybox/init/Config.in
busybox/init/init.c
busybox/libbb/.cvsignore [deleted file]
busybox/libbb/Makefile.in
busybox/libbb/concat_path_file.c
busybox/libbb/copyfd.c
busybox/libbb/getopt_ulflags.c
busybox/libbb/interface.c
busybox/libbb/messages.c
busybox/libbb/syscalls.c
busybox/loginutils/Config.in
busybox/loginutils/getty.c
busybox/loginutils/login.c
busybox/loginutils/su.c
busybox/miscutils/Config.in
busybox/miscutils/devfsd.c
busybox/miscutils/strings.c
busybox/modutils/insmod.c
busybox/networking/httpd.c
busybox/networking/ifconfig.c
busybox/networking/ifupdown.c
busybox/networking/inetd.c
busybox/networking/libiproute/utils.c
busybox/networking/nc.c
busybox/networking/telnetd.c
busybox/networking/tftp.c
busybox/networking/udhcp/dhcpc.c
busybox/scripts/.cvsignore [deleted file]
busybox/scripts/config/.cvsignore [deleted file]
busybox/scripts/config/Makefile
busybox/scripts/config/checklist.c [deleted file]
busybox/scripts/config/colors.h [deleted file]
busybox/scripts/config/conf.c
busybox/scripts/config/confdata.c
busybox/scripts/config/dialog.h [deleted file]
busybox/scripts/config/expr.c
busybox/scripts/config/expr.h
busybox/scripts/config/inputbox.c [deleted file]
busybox/scripts/config/lkc.h
busybox/scripts/config/lkc_proto.h
busybox/scripts/config/lxdialog/BIG.FAT.WARNING [new file with mode: 0644]
busybox/scripts/config/lxdialog/checklist.c [new file with mode: 0644]
busybox/scripts/config/lxdialog/colors.h [new file with mode: 0644]
busybox/scripts/config/lxdialog/dialog.h [new file with mode: 0644]
busybox/scripts/config/lxdialog/inputbox.c [new file with mode: 0644]
busybox/scripts/config/lxdialog/menubox.c [new file with mode: 0644]
busybox/scripts/config/lxdialog/msgbox.c [new file with mode: 0644]
busybox/scripts/config/lxdialog/textbox.c [new file with mode: 0644]
busybox/scripts/config/lxdialog/util.c [new file with mode: 0644]
busybox/scripts/config/lxdialog/yesno.c [new file with mode: 0644]
busybox/scripts/config/mconf.c
busybox/scripts/config/menu.c
busybox/scripts/config/menubox.c [deleted file]
busybox/scripts/config/msgbox.c [deleted file]
busybox/scripts/config/symbol.c
busybox/scripts/config/textbox.c [deleted file]
busybox/scripts/config/util.c
busybox/scripts/config/yesno.c [deleted file]
busybox/scripts/config/zconf.tab.c_shipped
busybox/scripts/config/zconf.y
busybox/shell/lash.c
busybox/sysdeps/linux/Config.in
busybox/sysklogd/Makefile
busybox/sysklogd/logger.c
busybox/util-linux/Config.in
busybox/util-linux/Makefile
busybox/util-linux/hwclock.c

diff --git a/busybox/.cvsignore b/busybox/.cvsignore
deleted file mode 100644 (file)
index 4e4f586..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-busybox
-busybox.links
-_install
-.config
-.menuconfig.log
-.config.cmd
-.config.old
index 87df22d55ffe1382ffd41765e049b405faa69eaa..cf2dedd3ac07289d33e7520d0bae7404d91b3c64 100644 (file)
@@ -2,7 +2,7 @@ List of the authors of code contained in BusyBox.
 
 If you have code in BusyBox, you should be listed here.  If you should be
 listed, or the description of what you have done needs more detail, or is
-incorect, _please_ let me know.
+incorrect, _please_ let me know.
 
  -Erik
 
@@ -69,6 +69,11 @@ Daniel Jacobowitz <dan@debian.org>
 Matt Kraai <kraai@alumni.cmu.edu>
     documentation, bugfixes, test suite
 
+Rob Landley <rob@landley.net>
+    sed (major rewrite in 2003, and I now maintain the thing).
+    bunzip2 (complete from-scratch rewrite, then mjn3 optimized the result.)
+    I've patched lots of other applets, but don't maintain 'em.
+
 Stephan Linz <linz@li-pro.net>
     ipcalc, Red Hat equivalence
 
@@ -76,9 +81,9 @@ John Lombardo <john@deltanet.com>
     tr
 
 Glenn McGrath <bug1@iinet.net.au>
-    Common unarchving code and unarchiving applets, ifupdown, ftpgetput,
-    nameif, sed, patch, fold, install, uudecode. 
-    Various bugfixes, review and apply numerous patches. 
+    Common unarchiving code and unarchiving applets, ifupdown, ftpgetput,
+    nameif, sed, patch, fold, install, uudecode.
+    Various bugfixes, review and apply numerous patches.
 
 Manuel Novoa III <mjn3@codepoet.org>
     cat, head, mkfifo, mknod, rmdir, sleep, tee, tty, uniq, usleep, wc, yes,
index 3e2b3ef185f71c96eb4bfd7591599be2741a0f8b..81c59a0897aab9b51501a566f6e8da311a89dc10 100644 (file)
@@ -22,7 +22,7 @@
 #--------------------------------------------------------------
 noconfig_targets := menuconfig config oldconfig randconfig \
        defconfig allyesconfig allnoconfig clean distclean \
-       release tags  
+       release tags
 
 ifndef TOPDIR
 TOPDIR=$(CURDIR)/
@@ -147,7 +147,7 @@ uninstall: busybox.links
        rm -f $(PREFIX)/bin/busybox
        for i in `cat busybox.links` ; do rm -f $(PREFIX)$$i; done
 
-install-hardlinks: applets/install.sh busybox busybox.links
+install-hardlinks: $(top_srcdir)/applets/install.sh busybox busybox.links
        $(SHELL) $< $(PREFIX) --hardlinks
 
 check: busybox
@@ -193,7 +193,7 @@ scripts/mkdep: $(top_srcdir)/scripts/mkdep.c
 scripts/split-include: $(top_srcdir)/scripts/split-include.c
        $(HOSTCC) $(HOSTCFLAGS) -o $@ $<
 
-.depend: scripts/mkdep
+.depend: scripts/mkdep include/config.h
        rm -f .depend .hdepend;
        mkdir -p include/config;
        scripts/mkdep -I include -- \
@@ -201,7 +201,7 @@ scripts/split-include: $(top_srcdir)/scripts/split-include.c
        scripts/mkdep -I include -- \
          `find $(top_srcdir) -name \*.h -print | sed -e "s,^./,,"` >> .hdepend;
 
-depend dep: include/config.h .depend
+depend dep: .depend
 
 include/config/MARKER: depend scripts/split-include
        scripts/split-include include/config.h include/config
index dbb5e176b71f4dd4977889351fbbb33baec15706..ee74b4c188f9b49af8e335201490762da3df6f10 100644 (file)
@@ -144,25 +144,25 @@ int busybox_main(int argc, char **argv)
                output_width -= 20;
 #endif
 
-               fprintf(stderr, "%s\n\n"
-                               "Usage: busybox [function] [arguments]...\n"
-                               "   or: [function] [arguments]...\n\n"
-                               "\tBusyBox is a multi-call binary that combines many common Unix\n"
-                               "\tutilities into a single executable.  Most people will create a\n"
-                               "\tlink to busybox for each function they wish to use, and BusyBox\n"
-                               "\twill act like whatever it was invoked as.\n"
-                               "\nCurrently defined functions:\n", bb_msg_full_version);
+               printf("%s\n\n"
+                      "Usage: busybox [function] [arguments]...\n"
+                      "   or: [function] [arguments]...\n\n"
+                      "\tBusyBox is a multi-call binary that combines many common Unix\n"
+                      "\tutilities into a single executable.  Most people will create a\n"
+                      "\tlink to busybox for each function they wish to use and BusyBox\n"
+                      "\twill act like whatever it was invoked as!\n"
+                      "\nCurrently defined functions:\n", bb_msg_full_version);
 
                while (a->name != 0) {
                        col +=
-                               fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
-                                               (a++)->name);
+                               printf("%s%s", ((col == 0) ? "\t" : ", "),
+                                      (a++)->name);
                        if (col > output_width && a->name != 0) {
-                               fprintf(stderr, ",\n");
+                               printf(",\n");
                                col = 0;
                        }
                }
-               fprintf(stderr, "\n\n");
+               printf("\n\n");
                exit(0);
        }
 
index 44c5db035a5c08d28a1e63ab230f4c35c3e13e22..8326aa6de6aa1a8d07aa0c0397665a2a23003ccb 100644 (file)
@@ -56,19 +56,21 @@ static void header_verbose_list_ar(const file_header_t *file_header)
 #define AR_OPT_PRESERVE_DATE   0x08
 #define AR_OPT_VERBOSE                 0x10
 #define AR_OPT_CREATE                  0x20
+#define AR_OPT_INSERT                  0x40
 
 extern int ar_main(int argc, char **argv)
 {
        archive_handle_t *archive_handle;
        unsigned long opt;
+       char *msg_unsupported_err = "Archive %s not supported.  Install binutils 'ar'.";
        char magic[8];
 
        archive_handle = init_handle();
 
        bb_opt_complementaly = "p~tx:t~px:x~pt";
-       opt = bb_getopt_ulflags(argc, argv, "ptxovc");
+       opt = bb_getopt_ulflags(argc, argv, "ptxovcr");
 
-       if ((opt & 0x80000000UL) || (optind == argc)) {
+       if ((opt & BB_GETOPT_ERROR) || (opt == 0) || (optind == argc)) {
                bb_show_usage();
        }
 
@@ -88,7 +90,10 @@ extern int ar_main(int argc, char **argv)
                archive_handle->action_header = header_verbose_list_ar;
        }
        if (opt & AR_OPT_CREATE) {
-               bb_error_msg_and_die("Archive creation not supported.  Install binutils 'ar'.");
+               bb_error_msg_and_die(msg_unsupported_err, "creation");
+       }
+       if (opt & AR_OPT_INSERT) {
+               bb_error_msg_and_die(msg_unsupported_err, "insertion");
        }
 
        archive_handle->src_fd = bb_xopen(argv[optind++], O_RDONLY);
index c096518a2fbed63db5b51ffc36ff1f383d73a99e..d3b56e398673a4567129d3075de55913cc3f3b0f 100644 (file)
@@ -1327,7 +1327,7 @@ void free_array(char **array)
  * the status_hashtable to retrieve the info. This results in smaller code than
  * scanning the status file. The resulting list, however, is unsorted.
  */
-void list_packages(void)
+static void list_packages(void)
 {
         int i;
 
index 5aa9881d58dca9306c0753d10726d331522b9e9e..b95ec2d6ef755dc9a56c845c61a9bc369a2716ab 100644 (file)
@@ -88,7 +88,7 @@ extern int dpkg_deb_main(int argc, char **argv)
                argcount = 2;
        }
 
-       if ((optind + argcount != argc) || (opt & 0x80000000UL)) {
+       if ((optind + argcount != argc) || (opt & BB_GETOPT_ERROR)) {
                bb_show_usage();
        }
 
index d494aa30e6eb51813ec9aaad874f673b1d2b02c7..6cf4b395ef9709b2d4a6e97921ad461ab3aac9c1 100644 (file)
 #include <time.h>
 #include "busybox.h"
 
-#define memzero(s, n)     memset ((void *)(s), 0, (n))
-
-#ifndef RETSIGTYPE
-#  define RETSIGTYPE void
-#endif
-
 typedef unsigned char uch;
 typedef unsigned short ush;
 typedef unsigned long ulg;
@@ -214,9 +208,6 @@ typedef int file_t;         /* Do not use stdio */
 static int zip(int in, int out);
 static int file_read(char *buf, unsigned size);
 
-       /* from gzip.c */
-static RETSIGTYPE abort_gzip(void);
-
                /* from deflate.c */
 static void lm_init(ush * flags);
 static ulg deflate(void);
@@ -335,7 +326,7 @@ static void put_short(ush w)
 /* ========================================================================
  * Signal and error handler.
  */
-static void abort_gzip()
+static void abort_gzip(int ignored)
 {
        exit(ERROR);
 }
@@ -350,13 +341,6 @@ static void clear_bufs(void)
        bytes_in = 0L;
 }
 
-static void write_bb_error_msg(void)
-{
-       fputc('\n', stderr);
-       bb_perror_nomsg();
-       abort_gzip();
-}
-
 /* ===========================================================================
  * Does the same as write(), but also handles partial pipe writes and checks
  * for error return.
@@ -366,9 +350,7 @@ static void write_buf(int fd, void *buf, unsigned cnt)
        unsigned n;
 
        while ((n = write(fd, buf, cnt)) != cnt) {
-               if (n == (unsigned) (-1)) {
-                       write_bb_error_msg();
-               }
+               if (n == (unsigned) (-1)) bb_error_msg_and_die("can't write");
                cnt -= n;
                buf = (void *) ((char *) buf + n);
        }
@@ -559,7 +541,7 @@ static unsigned bi_reverse(unsigned code, int len)
 /* ===========================================================================
  * Write out any remaining bits in an incomplete byte.
  */
-static void bi_windup()
+static void bi_windup(void)
 {
        if (bi_valid > 8) {
                put_short(bi_buf);
@@ -846,7 +828,7 @@ static void lm_init(ush * flags)
        register unsigned j;
 
        /* Initialize the hash table. */
-       memzero((char *) head, HASH_SIZE * sizeof(*head));
+       memset(head, 0, HASH_SIZE * sizeof(*head));
        /* prev will be initialized on the fly */
 
        *flags |= SLOW;
@@ -996,7 +978,7 @@ static void check_match(IPos start, IPos match, int length)
  *    file reads are performed for at least two bytes (required for the
  *    translate_eol option).
  */
-static void fill_window()
+static void fill_window(void)
 {
        register unsigned n, m;
        unsigned more =
@@ -1060,7 +1042,7 @@ static void fill_window()
  * evaluation for matches: a match is finally adopted only if there is
  * no better match at the next window position.
  */
-static ulg deflate()
+static ulg deflate(void)
 {
        IPos hash_head;         /* head of hash chain */
        IPos prev_match;        /* previous match */
@@ -1188,8 +1170,6 @@ static ulg deflate()
 
 typedef struct dirent dir_type;
 
-typedef RETSIGTYPE(*sig_type) (int);
-
 /* ======================================================================== */
 int gzip_main(int argc, char **argv)
 {
@@ -1235,16 +1215,16 @@ int gzip_main(int argc, char **argv)
 
        foreground = signal(SIGINT, SIG_IGN) != SIG_IGN;
        if (foreground) {
-               (void) signal(SIGINT, (sig_type) abort_gzip);
+               (void) signal(SIGINT, abort_gzip);
        }
 #ifdef SIGTERM
        if (signal(SIGTERM, SIG_IGN) != SIG_IGN) {
-               (void) signal(SIGTERM, (sig_type) abort_gzip);
+               (void) signal(SIGTERM, abort_gzip);
        }
 #endif
 #ifdef SIGHUP
        if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
-               (void) signal(SIGHUP, (sig_type) abort_gzip);
+               (void) signal(SIGHUP, abort_gzip);
        }
 #endif
 
@@ -1271,6 +1251,7 @@ int gzip_main(int argc, char **argv)
                for (i = optind; i < argc; i++) {
                        char *path = NULL;
 
+                       clear_bufs();
                        if (strcmp(argv[i], "-") == 0) {
                                time_stamp = 0;
                                ifile_size = -1L;
@@ -1749,7 +1730,7 @@ static void ct_init(ush * attr, int *methodp)
 /* ===========================================================================
  * Initialize a new block.
  */
-static void init_block()
+static void init_block(void)
 {
        int n;                          /* iterates over tree elements */
 
@@ -2162,7 +2143,7 @@ static void send_tree(ct_data * tree, int max_code)
  * Construct the Huffman tree for the bit lengths and return the index in
  * bl_order of the last bit length code to send.
  */
-static const int build_bl_tree()
+static int build_bl_tree(void)
 {
        int max_blindex;        /* index of last bit length code of non zero freq */
 
@@ -2425,7 +2406,7 @@ static void compress_block(ct_data * ltree, ct_data * dtree)
  * IN assertion: the fields freq of dyn_ltree are set and the total of all
  * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
  */
-static void set_file_type()
+static void set_file_type(void)
 {
        int n = 0;
        unsigned ascii_freq = 0;
@@ -2538,7 +2519,7 @@ static int file_read(char *buf, unsigned size)
  * Write the output buffer outbuf[0..outcnt-1] and update bytes_out.
  * (used for the compressed data only)
  */
-static void flush_outbuf()
+static void flush_outbuf(void)
 {
        if (outcnt == 0)
                return;
index 8084e352433e24ff176a9933404258bba912e288..f1eea2928658603eddf6fa86533f7cd851165878 100644 (file)
@@ -26,7 +26,7 @@ extern ssize_t archive_xread_all_eof(archive_handle_t *archive_handle, unsigned
 
        size = bb_full_read(archive_handle->src_fd, buf, count);
        if ((size != 0) && (size != count)) {
-               bb_perror_msg_and_die("Short read, read %d of %d", size, count);
+               bb_perror_msg_and_die("Short read, read %ld of %ld", (long)size, (long)count);
        }
        return(size);
 }
index 259a47776152b8867cd2350bd040aac5cb6577a9..07e3cf01890469582a970a956a6ad4f05bfb2860 100644 (file)
@@ -134,8 +134,6 @@ static unsigned int get_bits(bunzip_data *bd, char bits_wanted)
 
 static int get_next_block(bunzip_data *bd)
 {
-       /* Note: Ignore the warning about hufGroup, base and limit being used uninitialized.
-        * They will be initialized on the fist pass of the loop. */
        struct group_data *hufGroup;
        int dbufCount,nextSym,dbufSize,groupCount,*base,*limit,selector,
                i,j,k,t,runPos,symCount,symTotal,nSelectors,byteCount[256];
@@ -286,16 +284,15 @@ static int get_next_block(bunzip_data *bd)
                mtfSymbol[i]=(unsigned char)i;
        }
        /* Loop through compressed symbols. */
-       runPos=dbufCount=symCount=selector=0;
+       runPos=dbufCount=selector=0;
        for(;;) {
-               /* Determine which Huffman coding group to use. */
-               if(!(symCount--)) {
-                       symCount=GROUP_SIZE-1;
-                       if(selector>=nSelectors) return RETVAL_DATA_ERROR;
-                       hufGroup=bd->groups+selectors[selector++];
-                       base=hufGroup->base-1;
-                       limit=hufGroup->limit-1;
-               }
+               /* fetch next Huffman coding group from list. */
+               symCount=GROUP_SIZE-1;
+               if(selector>=nSelectors) return RETVAL_DATA_ERROR;
+               hufGroup=bd->groups+selectors[selector++];
+               base=hufGroup->base-1;
+               limit=hufGroup->limit-1;
+continue_this_group:
                /* Read next Huffman-coded symbol. */
                /* Note: It is far cheaper to read maxLen bits and back up than it is
                   to read minLen bits and then an additional bit at a time, testing
@@ -346,7 +343,7 @@ got_huff_bits:
                           context).  Thus space is saved. */
                        t += (runPos << nextSym); /* +runPos if RUNA; +2*runPos if RUNB */
                        runPos <<= 1;
-                       continue;
+                       goto end_of_huffman_loop;
                }
                /* When we hit the first non-run symbol after a run, we now know
                   how many times to repeat the last literal, so append that many
@@ -384,6 +381,10 @@ got_huff_bits:
                /* We have our literal byte.  Save it into dbuf. */
                byteCount[uc]++;
                dbuf[dbufCount++] = (unsigned int)uc;
+               /* Skip group initialization if we're not done with this group.  Done this
+                * way to avoid compiler warning. */
+end_of_huffman_loop:
+               if(symCount--) goto continue_this_group;
        }
        /* At this point, we've read all the Huffman-coded symbols (and repeated
        runs) for this block from the input stream, and decoded them into the
index e8cf54bff5f0c712bc51f0a5b84ac7eec1c2b550..b17065d92d1d0ed353394b6d11f38c6d3d5859fc 100644 (file)
@@ -151,7 +151,10 @@ static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current
                        /* Leave the first 4 bytes empty so we can always unwind the bitbuffer
                         * to the front of the bytebuffer, leave 4 bytes free at end of tail
                         * so we can easily top up buffer in check_trailer_gzip() */
-                       bytebuffer_size = 4 + bb_xread(gunzip_src_fd, &bytebuffer[4], bytebuffer_max - 8);
+                       if (!(bytebuffer_size = bb_xread(gunzip_src_fd, &bytebuffer[4], bytebuffer_max - 8))) {
+                               bb_error_msg_and_die("unexpected end of file");
+                       }
+                       bytebuffer_size += 4;
                        bytebuffer_offset = 4;
                }
                bitbuffer |= ((unsigned int) bytebuffer[bytebuffer_offset]) << *current;
index 950e21dd3a8298a7bd20585d0b313ed63355b21b..b2a212397d7324f0aa90632261f66a7add5f471b 100644 (file)
@@ -724,7 +724,7 @@ int tar_main(int argc, char **argv)
                                );
 
        /* Check one and only one context option was given */
-       if(opt & 0x80000000UL) {
+       if(opt & BB_GETOPT_ERROR) {
                bb_show_usage();
        }
 #ifdef CONFIG_FEATURE_TAR_CREATE
index e1f0516fdd9d11945502140243dd31dc7c172bee..5a521b536d608152557849f0e2a03d4c47d4e823 100644 (file)
@@ -545,7 +545,7 @@ config CONFIG_WC
 config CONFIG_WHO
        bool "who"
        default n
-       select CONFIG_FEATURE_U_W_TMP
+       select CONFIG_FEATURE_UTMP
        help
          who is used to show who is logged on.
 
index 6a82f6bffcc61a4257eb2600ec351d44f469cb89..97731e83ffaeee2b368d58d40c78cab8dcb8844d 100644 (file)
@@ -42,7 +42,7 @@
 #include "libcoreutils/coreutils.h"
 
 /* WARNING!! ORDER IS IMPORTANT!! */
-static const char cp_opts[] = "pdRfiar";
+static const char cp_opts[] = "pdRfiarP";
 
 extern int cp_main(int argc, char **argv)
 {
@@ -73,6 +73,12 @@ extern int cp_main(int argc, char **argv)
                 */
                flags |= FILEUTILS_RECUR;
        }
+       if (flags & 128) {
+               /* Make -P a synonym for -d,
+                * -d is the GNU option while -P is the POSIX 2003 option
+                */
+               flags |= FILEUTILS_DEREFERENCE;
+       }
 
        flags ^= FILEUTILS_DEREFERENCE;         /* The sense of this flag was reversed. */
 
index d26e80eee4420d51d33bc481d2c87b187e28657e..e5fb5aff720e222495c52cd7f913216b039430e8 100644 (file)
@@ -300,7 +300,7 @@ extern int cut_main(int argc, char **argv)
        part = opt & (OPT_BYTE_FLGS|OPT_CHAR_FLGS|OPT_FIELDS_FLGS);
        if(part == 0)
                bb_error_msg_and_die("you must specify a list of bytes, characters, or fields");
-       if(opt & 0x80000000UL)
+       if(opt & BB_GETOPT_ERROR)
                bb_error_msg_and_die("only one type of list may be specified");
        parse_lists(sopt);
        if((opt & (OPT_DELIM_FLGS))) {
index 3608df69fceceed08e6967ef16bd97c659e0e8b1..70484e2cd3484f89bd02ebaf52dbe734a634c832 100644 (file)
@@ -136,7 +136,6 @@ int date_main(int argc, char **argv)
 {
        char *date_str = NULL;
        char *date_fmt = NULL;
-       char *t_buff;
        int set_time;
        int utc;
        int use_arg = 0;
@@ -166,7 +165,7 @@ int date_main(int argc, char **argv)
                bb_error_msg_and_die(bb_msg_memory_exhausted);
        }
        use_arg = opt & DATE_OPT_DATE;
-       if(opt & 0x80000000UL)
+       if(opt & BB_GETOPT_ERROR)
                bb_show_usage();
 #ifdef CONFIG_FEATURE_DATE_ISOFMT
        if(opt & DATE_OPT_TIMESPEC) {
@@ -283,10 +282,13 @@ int date_main(int argc, char **argv)
                date_fmt = "%Y.%m.%d-%H:%M:%S";
        }
 
-       /* Print OUTPUT (after ALL that!) */
-       t_buff = xmalloc(201);
-       strftime(t_buff, 200, date_fmt, &tm_time);
-       puts(t_buff);
+       {
+               /* Print OUTPUT (after ALL that!) */
+               RESERVE_CONFIG_BUFFER(t_buff, 201);
+               strftime(t_buff, 200, date_fmt, &tm_time);
+               puts(t_buff);
+               RELEASE_CONFIG_BUFFER(t_buff);
+       }
 
        return EXIT_SUCCESS;
 }
index cbbd4cd0399649e12cb89889bebd6d34ab1b1d26..3f052d92a74f301e56206343629d70b9cce525ee 100644 (file)
@@ -245,10 +245,9 @@ static int arithmetic_common (VALUE *l, VALUE *r, int op)
 static VALUE *docolon (VALUE *sv, VALUE *pv)
 {
        VALUE *v;
-       const char *errmsg;
-       struct re_pattern_buffer re_buffer;
-       struct re_registers re_regs;
-       int len;
+       regex_t re_buffer;
+       const int NMATCH = 2;
+       regmatch_t re_regs[NMATCH];
 
        tostring (sv);
        tostring (pv);
@@ -260,27 +259,22 @@ of a basic regular expression is not portable; it is being ignored",
                pv->u.s);
        }
 
-       len = strlen (pv->u.s);
        memset (&re_buffer, 0, sizeof (re_buffer));
-       memset (&re_regs, 0, sizeof (re_regs));
-       re_buffer.allocated = 2 * len;
-       re_buffer.buffer = (unsigned char *) xmalloc (re_buffer.allocated);
-       re_buffer.translate = 0;
-       re_syntax_options = RE_SYNTAX_POSIX_BASIC;
-       errmsg = re_compile_pattern (pv->u.s, len, &re_buffer);
-       if (errmsg) {
-               bb_error_msg_and_die("%s", errmsg);
-       }
-
-       len = re_match (&re_buffer, sv->u.s, strlen (sv->u.s), 0, &re_regs);
-       if (len >= 0) {
+       memset (re_regs, 0, sizeof (*re_regs));
+       if( regcomp (&re_buffer, pv->u.s, 0) != 0 )
+               bb_error_msg_and_die("Invalid regular expression");
+
+       /* expr uses an anchored pattern match, so check that there was a
+        * match and that the match starts at offset 0. */
+       if (regexec (&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH &&
+                       re_regs[0].rm_so == 0) {
                /* Were \(...\) used? */
-               if (re_buffer.re_nsub > 0) { /* was (re_regs.start[1] >= 0) */
-                       sv->u.s[re_regs.end[1]] = '\0';
-                       v = str_value (sv->u.s + re_regs.start[1]);
+               if (re_buffer.re_nsub > 0) {
+                       sv->u.s[re_regs[1].rm_eo] = '\0';
+                       v = str_value (sv->u.s + re_regs[1].rm_so);
                }
                else
-                       v = int_value (len);
+                       v = int_value (re_regs[0].rm_eo);
        }
        else {
                /* Match failed -- return the right kind of null.  */
@@ -289,7 +283,6 @@ of a basic regular expression is not portable; it is being ignored",
                else
                        v = int_value (0);
        }
-       free (re_buffer.buffer);
        return v;
 }
 
index d5182b953e6d4cb2754e584c230b9e7a8554ab7c..b10a7c1bf1c4d158b1ffb981b89624f432bf6969 100644 (file)
@@ -68,7 +68,7 @@ extern int id_main(int argc, char **argv)
        bb_opt_complementaly = "u~g:g~u";
        flags = bb_getopt_ulflags(argc, argv, "rnug");
 
-       if ((flags & 0x80000000UL)
+       if ((flags & BB_GETOPT_ERROR)
        /* Don't allow -n -r -nr */
        || (flags <= 3 && flags > 0) 
        /* Don't allow more than one username */
index 36dc1d61820978c6214a0187c9c46eac8e807fca..345e75af0943f060d9fb4cff40ecb8d9928e8aad 100644 (file)
@@ -69,7 +69,7 @@ extern int install_main(int argc, char **argv)
        flags = bb_getopt_ulflags(argc, argv, "cdpsg:m:o:", &gid_str, &mode_str, &uid_str);     /* 'a' must be 2nd */
 
        /* Check valid options were given */
-       if(flags & 0x80000000UL) {
+       if(flags & BB_GETOPT_ERROR) {
                bb_show_usage();
        }
 
index bd1c9fc29a60c6b085cc72ba0222373e8c0e73df..543c2ab3f5a3c6de93993e0bd4c03679215d7f0d 100644 (file)
@@ -42,41 +42,28 @@ static unsigned char *hash_bin_to_hex(unsigned char *hash_value,
        max = (hash_length * 2) + 2;
        hex_value = xmalloc(max);
        for (x = len = 0; x < hash_length; x++) {
-               len += snprintf(hex_value + len, max - len, "%02x", hash_value[x]);
+               len += snprintf((char*)(hex_value + len), max - len, "%02x", hash_value[x]);
        }
        return (hex_value);
 }
 
 static uint8_t *hash_file(const char *filename, uint8_t hash_algo)
 {
-       uint8_t *hash_value_bin;
-       uint8_t *hash_value = NULL;
-       uint8_t hash_length;
-       int src_fd;
-
-       if (strcmp(filename, "-") == 0) {
-               src_fd = STDIN_FILENO;
-       } else {
-               src_fd = open(filename, O_RDONLY);
-       }
-
-       if (hash_algo == HASH_MD5) {
-               hash_length = 16;
-       } else {
-               hash_length = 20;
-       }
-
-       hash_value_bin = xmalloc(hash_length);
-
-       if ((src_fd != -1) && (hash_fd(src_fd, -1, hash_algo, hash_value_bin) != -2)) {
-               hash_value = hash_bin_to_hex(hash_value_bin, hash_length);
-       } else {
+       int src_fd = strcmp(filename, "-") == 0 ? STDIN_FILENO :
+               open(filename, O_RDONLY);
+       if (src_fd == -1) {
                bb_perror_msg("%s", filename);
+               return NULL;
+       } else {
+               uint8_t *hash_value;
+               RESERVE_CONFIG_UBUFFER(hash_value_bin, 20);
+               hash_value = hash_fd(src_fd, -1, hash_algo, hash_value_bin) != -2 ?
+                       hash_bin_to_hex(hash_value_bin, hash_algo == HASH_MD5 ? 16 : 20) :
+                       NULL;
+               RELEASE_CONFIG_BUFFER(hash_value_bin);
+               close(src_fd);
+               return hash_value;
        }
-
-       close(src_fd);
-
-       return(hash_value);
 }
 
 /* This could become a common function for md5 as well, by using md5_stream */
@@ -111,7 +98,7 @@ extern int hash_files(int argc, char **argv, const uint8_t hash_algo)
                FILE *pre_computed_stream;
                int count_total = 0;
                int count_failed = 0;
-               unsigned char *file_ptr = argv[optind];
+               char *file_ptr = argv[optind];
                char *line;
 
                if (optind + 1 != argc) {
@@ -142,7 +129,7 @@ extern int hash_files(int argc, char **argv, const uint8_t hash_algo)
 
                        hash_value = hash_file(filename_ptr, hash_algo);
 
-                       if (hash_value && (strcmp(hash_value, line) == 0)) {
+                       if (hash_value && (strcmp((char*)hash_value, line) == 0)) {
                                if (!(flags & FLAG_SILENT))
                                        printf("%s: OK\n", filename_ptr);
                        } else {
@@ -175,7 +162,7 @@ extern int hash_files(int argc, char **argv, const uint8_t hash_algo)
                hash_value = xmalloc(hash_length);
 
                while (optind < argc) {
-                       unsigned char *file_ptr = argv[optind++];
+                       char *file_ptr = argv[optind++];
 
                        hash_value = hash_file(file_ptr, hash_algo);
                        if (hash_value == NULL) {
index 4f08dedc08329fd53fcfb73ec2efd021dc359f45..e1c4529adde5961d3530e896c4fc31a05d3afdee 100644 (file)
@@ -99,10 +99,10 @@ DO_MOVE:
                        struct stat source_stat;
                        int source_exists;
 
-                       if (errno != EXDEV) {
+                       if (errno != EXDEV ||
+                               (source_exists = cp_mv_stat(*argv, &source_stat)) < 1) {
                                bb_perror_msg("unable to rename `%s'", *argv);
-                       }
-                       else if ((source_exists = cp_mv_stat(*argv, &source_stat)) >= 0) {
+                       } else {
                                if (dest_exists) {
                                        if (dest_exists == 3) {
                                                if (source_exists != 3) {
index 8fa6d166fb706509aacb3904a19ff4f9c955c176..5195fafa11f7dc394e40089eba207768a148ea04 100644 (file)
@@ -304,7 +304,7 @@ static arith_t primary(enum token n)
        return strlen(*t_wp) > 0;
 }
 
-static int binop()
+static int binop(void)
 {
        const char *opnd1, *opnd2;
        struct t_op const *op;
@@ -531,7 +531,7 @@ static int test_eaccess(char *path, int mode)
        return (-1);
 }
 
-static void initialize_group_array()
+static void initialize_group_array(void)
 {
        ngroups = getgroups(0, NULL);
        group_array = xrealloc(group_array, ngroups * sizeof(gid_t));
index f9f40189ec68d30f8ae1c8b6a37851bb9e512c38..31fadfb852e33a207838a96735f1e9996ea6e8f9 100644 (file)
@@ -82,7 +82,7 @@ extern int watch_main(int argc, char **argv)
        header[len] = 0;
 
        /* thanks to lye, who showed me how to redirect stdin/stdout */
-       old_stdout = dup(1);
+       old_stdout = dup(STDOUT_FILENO);
 
        while (1) {
                time(&t);
@@ -98,13 +98,11 @@ extern int watch_main(int argc, char **argv)
                        sleep(period);
                } else if (0 == pid) {
                        //child
-                       close(1);
-                       dup(old_stdout);
-                       if (execvp(*watched_argv, watched_argv)) {
-                               bb_error_msg_and_die("Couldn't run command\n");
-                       }
+                       dup2(old_stdout, STDOUT_FILENO);
+                       execvp(*watched_argv, watched_argv);
+                       bb_perror_msg_and_die(*watched_argv);
                } else {
-                       bb_error_msg_and_die("Couldn't vfork\n");
+                       bb_perror_msg_and_die("vfork");
                }
        }
 }
index 9561db132f3bb03d381552f4fd7a1dc5a0557932..0531326bd60c073b2a0837c8a9bd5eb0b662e471 100644 (file)
@@ -74,7 +74,7 @@ extern int who_main(int argc, char **argv)
             } else
                 printf("%-8s  ", "?");
 
-            printf("%-12.12s   %s\n", ctime(&(ut->ut_tv.tv_sec)) + 4, ut->ut_host);
+            printf("%-12.12s   %s\n", ctime((time_t*)&(ut->ut_tv.tv_sec)) + 4, ut->ut_host);
         }
     }
     endutent();
index e15944c597beaa98840545a56c290696c5260c41..1eaf0d78c03d82f2433e673fa29e99fdaa81c601 100644 (file)
@@ -238,7 +238,7 @@ start_stop_daemon_main(int argc, char **argv)
                        &startas, &cmdname, &signame, &userspec, &execname, &pidfile);
 
        /* Check one and only one context option was given */
-       if ((opt & 0x80000000UL) || (opt & (SSD_CTX_STOP | SSD_CTX_START)) == 0) {
+       if ((opt & BB_GETOPT_ERROR) || (opt & (SSD_CTX_STOP | SSD_CTX_START)) == 0) {
                bb_show_usage();
        }
 
diff --git a/busybox/docs/.cvsignore b/busybox/docs/.cvsignore
deleted file mode 100644 (file)
index ec9e94b..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-BusyBox.txt
-BusyBox.1
-BusyBox.html
-busybox.txt
-busybox.ps
-busybox.pdf
-busybox
-busybox.pod
diff --git a/busybox/docs/busybox.net/.cvsignore b/busybox/docs/busybox.net/.cvsignore
deleted file mode 100644 (file)
index 393b002..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-BusyBox.html
-busybox.tar.gz
index 2fc95d36df4834a360ee43f01f9b1d3b6ebd8b64..605974c3a8a00d7dede2ee910e1e6a449a4c8d3f 100644 (file)
@@ -52,10 +52,10 @@ int mu_main(int argc, char **argv)
        char mu;
 
        if ((fd = open("/dev/random", O_RDONLY)) < 0)
-               perror_msg_and_die("/dev/random");
+               bb_perror_msg_and_die("/dev/random");
 
        if ((n = safe_read(fd, &mu, 1)) < 1)
-               perror_msg_and_die("/dev/random");
+               bb_perror_msg_and_die("/dev/random");
 
        return mu;
 }
@@ -137,11 +137,6 @@ algorithm in busybox.c and the Gods of BusyBox smite you. Yea, verily:
        /* all programs below here are alphabetically "greater than" 'mu' */
 
 
-Finally, add a define for your applet to include/config.h
-
-       #undef CONFIG_MU
-
-
 Documentation
 -------------
 
index c1cb2a2e26febff7f46332ad2ca311359aaa5eac..ed8b0f20f5abfd1557766c962637623313a7663a 100644 (file)
@@ -1084,7 +1084,7 @@ static node *parse_expr(unsigned long iexp) {
                        cn->a.n = vn;
                        xtc = TC_OPERAND | TC_UOPPRE | TC_REGEXP;
                        if (tc & (TC_OPERAND | TC_REGEXP)) {
-                               xtc = TC_UOPPRE | TC_BINOP | TC_OPERAND | iexp;
+                               xtc = TC_UOPPRE | TC_UOPPOST | TC_BINOP | TC_OPERAND | iexp;
                                /* one should be very careful with switch on tclass -
                                 * only simple tclasses should be used! */
                                switch (tc) {
@@ -1101,7 +1101,6 @@ static node *parse_expr(unsigned long iexp) {
                                                cn->info |= xS;
                                                cn->r.n = parse_expr(TC_ARRTERM);
                                        }
-                                       xtc = TC_UOPPOST | TC_UOPPRE | TC_BINOP | TC_OPERAND | iexp;
                                        break;
                                
                                  case TC_NUMBER:
index 3d687162188e7a4d1ab2150883788450bbbe0c49..992e5711dbcc99e6e0ae8f7c82fadf83bc89273c 100644 (file)
   resulting sed_cmd_t structures are appended to a linked list
   (sed_cmd_head/sed_cmd_tail).
 
-  process_file() does actual sedding, reading data lines from an input FILE *
+  add_input_file() adds a FILE * to the list of input files.  We need to
+  know them all ahead of time to find the last line for the $ match.
+
+  process_files() does actual sedding, reading data lines from each input FILE *
   (which could be stdin) and applying the sed command list (sed_cmd_head) to
   each of the resulting lines.
 
@@ -112,17 +115,20 @@ typedef struct sed_cmd_s {
 
 /* globals */
 /* options */
-static int be_quiet = 0, in_place=0, regex_type=0;
+static int be_quiet, in_place, regex_type;
 FILE *nonstdout;
-char *outname;
+char *outname,*hold_space;
 
+/* List of input files */
+int input_file_count,current_input_file;
+FILE **input_file_list;
 
 static const char bad_format_in_subst[] =
        "bad format in substitution expression";
 const char *const semicolon_whitespace = "; \n\r\t\v";
 
 regmatch_t regmatch[10];
-static regex_t *previous_regex_ptr = NULL;
+static regex_t *previous_regex_ptr;
 
 /* linked list of sed commands */
 static sed_cmd_t sed_cmd_head;
@@ -169,6 +175,11 @@ static void free_and_close_stuff(void)
                free(sed_cmd);
                sed_cmd = sed_cmd_next;
        }
+
+       if(hold_space) free(hold_space);
+
+    while(current_input_file<input_file_count)
+               fclose(input_file_list[current_input_file++]);
 }
 #endif
 
@@ -563,6 +574,8 @@ void add_cmd(char *cmdstr)
        }
 }
 
+/* Append to a string, reallocating memory as necessary. */
+
 struct pipeline {
        char *buf;      /* Space to hold string */
        int idx;        /* Space used */
@@ -716,20 +729,29 @@ static void flush_append(void)
        append_head=append_tail=NULL;
 }
 
-/* Get next line of input, flushing append buffer and noting if we hit EOF
- * without a newline on the last line.
+void add_input_file(FILE *file)
+{
+       input_file_list=xrealloc(input_file_list,(input_file_count+1)*sizeof(FILE *));
+       input_file_list[input_file_count++]=file;
+}
+
+/* Get next line of input from input_file_list, flushing append buffer and
+ * noting if we ran out of files without a newline on the last line we read.
  */
-static char *get_next_line(FILE * file, int *no_newline)
+static char *get_next_line(int *no_newline)
 {
-       char *temp;
+       char *temp=NULL;
        int len;
 
        flush_append();
-       temp=bb_get_line_from_file(file);
-       if(temp) {
-               len=strlen(temp);
-               if(len && temp[len-1]=='\n') temp[len-1]=0;
-               else *no_newline=1;
+       while(current_input_file<input_file_count) {
+               temp=bb_get_line_from_file(input_file_list[current_input_file]);
+               if(temp) {
+                       len=strlen(temp);
+                       *no_newline=!(len && temp[len-1]=='\n');
+                       if(!*no_newline) temp[len-1]=0;
+                       break;
+               } else fclose(input_file_list[current_input_file++]);
        }
 
        return temp;
@@ -755,15 +777,15 @@ static int puts_maybe_newline(char *s, FILE *file, int missing_newline, int no_n
 
 #define sed_puts(s,n) missing_newline=puts_maybe_newline(s,nonstdout,missing_newline,n)
 
-static void process_file(FILE *file)
+static void process_files(void)
 {
-       char *pattern_space, *next_line, *hold_space=NULL;
-       static int linenum = 0, missing_newline=0;
+       char *pattern_space, *next_line;
+       int linenum = 0, missing_newline=0;
        int no_newline,next_no_newline=0;
 
-       next_line = get_next_line(file,&next_no_newline);
+       next_line = get_next_line(&next_no_newline);
 
-       /* go through every line in the file */
+       /* go through every line in each file */
        for(;;) {
                sed_cmd_t *sed_cmd;
                int substituted=0;
@@ -773,7 +795,7 @@ static void process_file(FILE *file)
                no_newline=next_no_newline;
 
                /* Read one line in advance so we can act on the last line, the '$' address */
-               next_line = get_next_line(file,&next_no_newline);
+               next_line = get_next_line(&next_no_newline);
                linenum++;
 restart:
                /* for every line, go through all the commands */
@@ -908,7 +930,7 @@ restart:
                                        /* Cut and paste text (replace) */
                                        case 'c':
                                                /* Only triggers on last line of a matching range. */
-                                               if (!sed_cmd->in_match) sed_puts(sed_cmd->string,1);
+                                               if (!sed_cmd->in_match) sed_puts(sed_cmd->string,0);
                                                goto discard_line;
 
                                        /* Read file, append contents to output */
@@ -942,7 +964,7 @@ restart:
                                                        free(pattern_space);
                                                        pattern_space = next_line;
                                                        no_newline=next_no_newline;
-                                                       next_line = get_next_line(file,&next_no_newline);
+                                                       next_line = get_next_line(&next_no_newline);
                                                        linenum++;
                                                        break;
                                                }
@@ -972,7 +994,7 @@ restart:
                                                        pattern_space[len]='\n';
                                                        strcpy(pattern_space+len+1, next_line);
                                                        no_newline=next_no_newline;
-                                                       next_line = get_next_line(file,&next_no_newline);
+                                                       next_line = get_next_line(&next_no_newline);
                                                        linenum++;
                                                }
                                                break;
@@ -1007,10 +1029,7 @@ restart:
                                        }
                                        case 'g':       /* Replace pattern space with hold space */
                                                free(pattern_space);
-                                               if (hold_space) {
-                                                       pattern_space = strdup(hold_space);
-                                                       no_newline=0;
-                                               }
+                                               pattern_space = strdup(hold_space ? hold_space : "");
                                                break;
                                        case 'G':       /* Append newline and hold space to pattern space */
                                        {
@@ -1096,9 +1115,7 @@ static void add_cmd_block(char *cmdstr)
 
 extern int sed_main(int argc, char **argv)
 {
-       int status = EXIT_SUCCESS;
-       int opt;
-       uint8_t getpat = 1;
+       int status = EXIT_SUCCESS, opt, getpat = 1;
 
 #ifdef CONFIG_FEATURE_CLEAN_UP
        /* destroy command strings on exit */
@@ -1153,8 +1170,7 @@ extern int sed_main(int argc, char **argv)
                }
        }
 
-       /* if we didn't get a pattern from a -e and no command file was specified,
-        * argv[optind] should be the pattern. no pattern, no worky */
+       /* if we didn't get a pattern from -e or -f, use argv[optind] */
        if(getpat) {
                if (argv[optind] == NULL)
                        bb_show_usage();
@@ -1171,49 +1187,47 @@ extern int sed_main(int argc, char **argv)
         * files were specified or '-' was specified, take input from stdin.
         * Otherwise, we process all the files specified. */
        if (argv[optind] == NULL) {
-               if(in_place) {
-                       fprintf(stderr,"sed: Filename required for -i\n");
-                       exit(1);
-               }
-               process_file(stdin);
+               if(in_place) bb_error_msg_and_die("Filename required for -i");
+               add_input_file(stdin);
+               process_files();
        } else {
                int i;
                FILE *file;
 
                for (i = optind; i < argc; i++) {
                        if(!strcmp(argv[i], "-") && !in_place) {
-                               process_file(stdin);
+                               add_input_file(stdin);
+                               process_files();
                        } else {
                                file = bb_wfopen(argv[i], "r");
                                if (file) {
                                        if(in_place) {
                                                struct stat statbuf;
+                                               int nonstdoutfd;
+                                               
                                                outname=bb_xstrndup(argv[i],strlen(argv[i])+6);
                                                strcat(outname,"XXXXXX");
+                                               if(-1==(nonstdoutfd=mkstemp(outname)))
+                                                       bb_error_msg_and_die("no temp file");
+                                               nonstdout=fdopen(nonstdoutfd,"w");
                                                /* Set permissions of output file */
                                                fstat(fileno(file),&statbuf);
-                                               mkstemp(outname);
-                                               nonstdout=bb_wfopen(outname,"w");
-                                               /* Set permissions of output file */
-                                               fstat(fileno(file),&statbuf);
-                                               fchmod(fileno(nonstdout),statbuf.st_mode);
-                                               atexit(cleanup_outname);
-                                       }
-                                       process_file(file);
-                                       fclose(file);
-                                       if(in_place) {
+                                               fchmod(nonstdoutfd,statbuf.st_mode);
+                                               add_input_file(file);
+                                               process_files();
                                                fclose(nonstdout);
                                                nonstdout=stdout;
                                                unlink(argv[i]);
                                                rename(outname,argv[i]);
                                                free(outname);
                                                outname=0;
-                                       }
+                                       } else add_input_file(file);
                                } else {
                                        status = EXIT_FAILURE;
                                }
                        }
                }
+               if(input_file_count>current_input_file) process_files();
        }
 
        return status;
index cd6cf0ea1f22fbdc02c781141c03bc08e0d86fba..5a47f5a23f2120b8efe92d3e088f608d3aa89021 100644 (file)
@@ -2340,7 +2340,7 @@ static Byte readit(void)  // read (maybe cursor) key from stdin
 }
 
 //----- IO Routines --------------------------------------------
-static Byte get_one_char()
+static Byte get_one_char(void)
 {
        static Byte c;
 
@@ -2600,25 +2600,25 @@ static void place_cursor(int row, int col, int opti)
 }
 
 //----- Erase from cursor to end of line -----------------------
-static void clear_to_eol()
+static void clear_to_eol(void)
 {
        write1(Ceol);   // Erase from cursor to end of line
 }
 
 //----- Erase from cursor to end of screen -----------------------
-static void clear_to_eos()
+static void clear_to_eos(void)
 {
        write1(Ceos);   // Erase from cursor to end of screen
 }
 
 //----- Start standout mode ------------------------------------
-static void standout_start() // send "start reverse video" sequence
+static void standout_start(void) // send "start reverse video" sequence
 {
        write1(SOs);     // Start reverse video mode
 }
 
 //----- End standout mode --------------------------------------
-static void standout_end() // send "end reverse video" sequence
+static void standout_end(void) // send "end reverse video" sequence
 {
        write1(SOn);     // End reverse video mode
 }
@@ -2648,7 +2648,7 @@ static void Indicate_Error(void)
 
 //----- Screen[] Routines --------------------------------------
 //----- Erase the Screen[] memory ------------------------------
-static void screen_erase()
+static void screen_erase(void)
 {
        memset(screen, ' ', screensize);        // clear new screen
 }
index 29f4ecd4f36e9e8d105a53d737fe296f4835c553..9b26add9a465df6aa19caa7a7fe2f4a0f1873984 100644 (file)
@@ -98,7 +98,7 @@ static void print_line(const char *line, int linenum, char decoration)
        }
        last_line_printed = linenum;
 #endif
-       if (print_filename)
+       if (print_filename > 0)
                printf("%s%c", cur_file, decoration);
        if (print_line_num)
                printf("%i%c", linenum, decoration);
@@ -219,7 +219,7 @@ static int grep_file(FILE *file)
 
        /* grep -c: print [filename:]count, even if count is zero */
        if (print_match_counts) {
-               if (print_filename)
+               if (print_filename > 0)
                        printf("%s:", cur_file);
                    printf("%d\n", nmatches);
        }
diff --git a/busybox/include/.cvsignore b/busybox/include/.cvsignore
deleted file mode 100644 (file)
index 9c68c95..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-config
-config.h
index 90d4195cce7d6a1d5cc9a25f149e22ae5651d32e..21f82f57d507fcf92be0bee2828341e86629e10a 100644 (file)
        APPLET_NOUSAGE("pipe_progress", pipe_progress_main, _BB_DIR_BIN, _BB_SUID_NEVER)
 #endif
 #ifdef CONFIG_PIVOT_ROOT
-       APPLET(pivot_root, pivot_root_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
+       APPLET(pivot_root, pivot_root_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
 #endif
 #ifdef CONFIG_POWEROFF
        APPLET(poweroff, poweroff_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
        APPLET(rmmod, rmmod_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
 #endif
 #ifdef CONFIG_ROUTE
-       APPLET(route, route_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
+       APPLET(route, route_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
 #endif
 #ifdef CONFIG_RPM
        APPLET(rpm, rpm_main, _BB_DIR_BIN, _BB_SUID_NEVER)
index f6f575957215af775c7a8a0014bb4738e4785869..3ff3d8a37ac0f005a3ba32cfb3dc3c6ae52ff584 100644 (file)
 #include <sys/stat.h>
 #include <sys/types.h>
 
-#if __GNU_LIBRARY__ < 5
-#ifndef __dietlibc__
-#error "Sorry, libc5 is not supported"
-#endif
+#if __GNU_LIBRARY__ < 5 && \
+    !defined(__dietlibc__) && \
+    !defined(_NEWLIB_VERSION)
+#error "Sorry, this libc version is not supported :("
 #endif
 
 #ifndef BB_EXTRA_VERSION
index afea5deaa4d751ee071ba29336b140703c4f2804..4a9c3a2d7ba5eb93e3200f9a9587cb00214d9d66 100644 (file)
@@ -29,5 +29,7 @@ extern int INET_resolve(const char *name, struct sockaddr_in *s_in, int hostfirs
 extern int INET_rresolve(char *name, size_t len, struct sockaddr_in *s_in,
                         int numeric, unsigned int netmask);
 
+#ifdef CONFIG_FEATURE_IPV6
 extern int INET6_resolve(const char *name, struct sockaddr_in6 *sin6);
 extern int INET6_rresolve(char *name, size_t len, struct sockaddr_in6 *sin6, int numeric);
+#endif
index 93ab5375c330ad244216c6d77a3ed1fd81f72762..467a15cb2c2c3c883c0c987eeba75a992816383e 100644 (file)
@@ -150,6 +150,7 @@ extern FILE *bb_xfopen(const char *path, const char *mode);
 extern int   bb_fclose_nonstdin(FILE *f);
 extern void  bb_fflush_stdout_and_exit(int retval) __attribute__ ((noreturn));
 
+#define BB_GETOPT_ERROR 0x80000000UL
 extern const char *bb_opt_complementaly;
 extern const struct option *bb_applet_long_options;
 extern unsigned long bb_getopt_ulflags(int argc, char **argv, const char *applet_opts, ...);
@@ -323,6 +324,7 @@ extern const char * const bb_msg_full_version;
 extern const char * const bb_msg_memory_exhausted;
 extern const char * const bb_msg_invalid_date;
 extern const char * const bb_msg_io_error;
+extern const char * const bb_msg_read_error;
 extern const char * const bb_msg_write_error;
 extern const char * const bb_msg_name_longer_than_foo;
 extern const char * const bb_msg_unknown;
index 377eb10e70371899afeddb8f2391c9130130a5b1..ad4410196b9c88e0dae5b317d72e6f40215c3278 100644 (file)
        "Copies SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n" \
        "\n" \
        "\t-a\tSame as -dpR\n" \
-       "\t-d\tPreserves links\n" \
+       "\t-d,-P\tPreserves links\n" \
        "\t-p\tPreserves file attributes if possible\n" \
        "\t-f\tforce (implied; ignored) - always set\n" \
        "\t-i\tinteractive, prompt before overwrite\n" \
        "\t-e\tinterpret backslash-escaped characters (i.e., \\t=tab)\n" \
        "\t-E\tdisable interpretation of backslash-escaped characters")
 #define echo_example_usage \
-       "$ echo "Erik is cool"\n" \
+       "$ echo \"Erik is cool\"\n" \
        "Erik is cool\n" \
-       USAGE_FANCY_ECHO("$  echo -e "Erik\\nis\\ncool"\n" \
+       USAGE_FANCY_ECHO("$  echo -e \"Erik\\nis\\ncool\"\n" \
        "Erik\n" \
        "is\n" \
        "cool\n" \
-       "$ echo "Erik\\nis\\ncool"\n" \
+       "$ echo \"Erik\\nis\\ncool\"\n" \
        "Erik\\nis\\ncool\n")
 
 #define env_trivial_usage \
         "$ cat getopt.test\n" \
         "#!/bin/sh\n" \
         "GETOPT=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \\\n" \
-        "       -n 'example.busybox' -- "$@"`\n" \
+        "       -n 'example.busybox' -- \"$@\"`\n" \
         "if [ $? != 0 ] ; then  exit 1 ; fi\n" \
         "eval set -- "$GETOPT"\n" \
         "while true ; do\n" \
        "Formats and prints ARGUMENT(s) according to FORMAT,\n" \
        "Where FORMAT controls the output exactly as in C printf."
 #define printf_example_usage \
-       "$ printf "Val=%d\\n" 5\n" \
+       "$ printf \"Val=%d\\n\" 5\n" \
        "Val=5\n"
 
 #ifdef CONFIG_SELINUX
index 4465e75a161c4d8999c95a9fb7af1165d93afba0..521f8fe1d4dcfd533702bff716199d63f94a8bcb 100644 (file)
@@ -35,6 +35,14 @@ config CONFIG_FEATURE_INIT_COREDUMPS
          core file sizes.  If this option is disabled, processes
          will not generate any core files.
 
+config CONFIG_FEATURE_INIT_SWAPON
+       bool "  Should init run swapon if short on memory?"
+       default y
+       depends on CONFIG_INIT
+       help
+         If the system has less than one megabyte of total memory, init
+         will run '/sbin/swapon -a' to add swap memory.
+
 config CONFIG_FEATURE_EXTRA_QUIET
        bool "  Should init be _extra_ quiet on boot?"
        default y
index 0c8dc89dc5d9c0e61100023dab3b1207e2da18db..8687b106c8b690a044cf10178ab0bab0eb4d5e7a 100644 (file)
@@ -39,7 +39,6 @@
 #include <limits.h>
 #include <sys/fcntl.h>
 #include <sys/ioctl.h>
-#include <sys/mount.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/reboot.h>
@@ -156,7 +155,7 @@ static struct init_action *init_action_list = NULL;
 static char console[CONSOLE_BUFF_SIZE] = _PATH_CONSOLE;
 
 #ifndef CONFIG_SYSLOGD
-static char *log = VC_5;
+static char *log_console = VC_5;
 #endif
 static sig_atomic_t got_cont = 0;
 static const int LOG = 0x1;
@@ -239,9 +238,9 @@ static void message(int device, const char *fmt, ...)
        /* Take full control of the log tty, and never close it.
         * It's mine, all mine!  Muhahahaha! */
        if (log_fd < 0) {
-               if ((log_fd = device_open(log, O_RDWR | O_NDELAY | O_NOCTTY)) < 0) {
+               if ((log_fd = device_open(log_console, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0) {
                        log_fd = -2;
-                       bb_error_msg("Bummer, can't write to log on %s!", log);
+                       bb_error_msg("Bummer, can't write to log on %s!", log_console);
                        device = CONSOLE;
                } else {
                        fcntl(log_fd, F_SETFD, FD_CLOEXEC);
@@ -254,7 +253,7 @@ static void message(int device, const char *fmt, ...)
 
        if (device & CONSOLE) {
                int fd = device_open(_PATH_CONSOLE,
-                                       O_WRONLY | O_NOCTTY | O_NDELAY);
+                                       O_WRONLY | O_NOCTTY | O_NONBLOCK);
                /* Always send console messages to /dev/console so people will see them. */
                if (fd >= 0) {
                        bb_full_write(fd, msg, l);
@@ -309,6 +308,7 @@ static void set_term(int fd)
        tcsetattr(fd, TCSANOW, &tty);
 }
 
+#ifdef CONFIG_FEATURE_INIT_SWAPON
 /* How much memory does this machine have?
    Units are kBytes to avoid overflow on 4GB machines */
 static unsigned int check_free_memory(void)
@@ -337,6 +337,7 @@ static unsigned int check_free_memory(void)
                return(result * u);
        }
 }
+#endif /* CONFIG_FEATURE_INIT_SWAPON */
 
 static void console_init(void)
 {
@@ -381,7 +382,7 @@ static void console_init(void)
        if (fd < 0) {
                /* Perhaps we should panic here? */
 #ifndef CONFIG_SYSLOGD
-               log =
+               log_console =
 #endif
                safe_strncpy(console, "/dev/null", sizeof(console));
        } else {
@@ -393,7 +394,7 @@ static void console_init(void)
                        if (s == NULL || strcmp(s, "linux") == 0)
                                putenv("TERM=vt102");
 #ifndef CONFIG_SYSLOGD
-                       log = console;
+                       log_console = console;
 #endif
                } else {
                        if (s == NULL)
@@ -423,9 +424,8 @@ static void fixup_argv(int argc, char **argv, char *new_argv0)
 
 static pid_t run(const struct init_action *a)
 {
-       struct stat sb;
        int i, junk;
-       pid_t pid, pgrp, tmp_pid;
+       pid_t pid;
        char *s, *tmpCmd, *cmd[INIT_BUFFS_SIZE], *cmdpath;
        char buf[INIT_BUFFS_SIZE + 6];  /* INIT_BUFFS_SIZE+strlen("exec ")+1 */
        sigset_t nmask, omask;
@@ -441,6 +441,8 @@ static pid_t run(const struct init_action *a)
        sigprocmask(SIG_BLOCK, &nmask, &omask);
 
        if ((pid = fork()) == 0) {
+               struct stat sb;
+
                /* Clean up */
                close(0);
                close(1);
@@ -453,6 +455,7 @@ static pid_t run(const struct init_action *a)
                signal(SIGINT, SIG_DFL);
                signal(SIGTERM, SIG_DFL);
                signal(SIGHUP, SIG_DFL);
+               signal(SIGQUIT, SIG_DFL);
                signal(SIGCONT, SIG_DFL);
                signal(SIGSTOP, SIG_DFL);
                signal(SIGTSTP, SIG_DFL);
@@ -464,11 +467,10 @@ static pid_t run(const struct init_action *a)
                /* Open the new terminal device */
                if ((device_open(a->terminal, O_RDWR)) < 0) {
                        if (stat(a->terminal, &sb) != 0) {
-                               message(LOG | CONSOLE, "device '%s' does not exist.",
-                                               a->terminal);
-                               _exit(1);
+                               message(LOG | CONSOLE, "device '%s' does not exist.", a->terminal);
+                       } else {
+                               message(LOG | CONSOLE, "Bummer, can't open %s", a->terminal);
                        }
-                       message(LOG | CONSOLE, "Bummer, can't open %s", a->terminal);
                        _exit(1);
                }
 
@@ -482,6 +484,7 @@ static pid_t run(const struct init_action *a)
                /* If the init Action requires us to wait, then force the
                 * supplied terminal to be the controlling tty. */
                if (a->action & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) {
+                       pid_t pgrp, tmp_pid;
 
                        /* Now fork off another process to just hang around */
                        if ((pid = fork()) < 0) {
@@ -693,6 +696,7 @@ static void shutdown_system(void)
        /* first disable all our signals */
        sigemptyset(&block_signals);
        sigaddset(&block_signals, SIGHUP);
+       sigaddset(&block_signals, SIGQUIT);
        sigaddset(&block_signals, SIGCHLD);
        sigaddset(&block_signals, SIGUSR1);
        sigaddset(&block_signals, SIGUSR2);
@@ -730,13 +734,12 @@ static void exec_signal(int sig)
        for (a = init_action_list; a; a = tmp) {
                tmp = a->next;
                if (a->action & RESTART) {
-                       struct stat sb;
-
                        shutdown_system();
 
                        /* unblock all signals, blocked in shutdown_system() */
                        sigemptyset(&unblock_signals);
                        sigaddset(&unblock_signals, SIGHUP);
+                       sigaddset(&unblock_signals, SIGQUIT);
                        sigaddset(&unblock_signals, SIGCHLD);
                        sigaddset(&unblock_signals, SIGUSR1);
                        sigaddset(&unblock_signals, SIGUSR2);
@@ -754,6 +757,7 @@ static void exec_signal(int sig)
 
                        /* Open the new terminal device */
                        if ((device_open(a->terminal, O_RDWR)) < 0) {
+                               struct stat sb;
                                if (stat(a->terminal, &sb) != 0) {
                                        message(LOG | CONSOLE, "device '%s' does not exist.", a->terminal);
                                } else {
@@ -907,6 +911,7 @@ static void delete_init_action(struct init_action *action)
        }
 }
 
+#ifdef CONFIG_FEATURE_INIT_SWAPON
 /* Make sure there is enough memory to do something useful. *
  * Calls "swapon -a" if needed so be sure /etc/fstab is present... */
 static void check_memory(void)
@@ -934,6 +939,9 @@ static void check_memory(void)
        message(CONSOLE, "Sorry, your computer does not have enough memory.");
        loop_forever();
 }
+#else
+# define check_memory()
+#endif /* CONFIG_FEATURE_INIT_SWAPON */
 
 /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined,
  * then parse_inittab() simply adds in some default
@@ -1097,6 +1105,7 @@ extern int init_main(int argc, char **argv)
        /* Set up sig handlers  -- be sure to
         * clear all of these in run() */
        signal(SIGHUP, exec_signal);
+       signal(SIGQUIT, exec_signal);
        signal(SIGUSR1, halt_signal);
        signal(SIGUSR2, halt_signal);
        signal(SIGINT, ctrlaltdel_signal);
diff --git a/busybox/libbb/.cvsignore b/busybox/libbb/.cvsignore
deleted file mode 100644 (file)
index 2bbe016..0000000
+++ /dev/null
@@ -1 +0,0 @@
-loop.h
index 85d4a967ba35da1db81d5806f8eb3a94b8c7de2b..d4c5ec14a11cb4bd281fe4169c5e00704e30c357 100644 (file)
@@ -53,7 +53,7 @@ LIBBB_OBJS=$(patsubst %.c,$(LIBBB_DIR)%.o, $(LIBBB_SRC))
 LIBBB_MSRC0:=$(srcdir)/messages.c
 LIBBB_MOBJ0:=full_version.o \
        memory_exhausted.o invalid_date.o io_error.o \
-       write_error.o name_longer_than_foo.o unknown.o \
+       read_error.o write_error.o name_longer_than_foo.o unknown.o \
        can_not_create_raw_socket.o perm_denied_are_you_root.o \
        shadow_file.o passwd_file.o group_file.o gshadow_file.o nologin_file.o \
        securetty_file.o motd_file.o \
index 77c054530309ebd6273295c0dddbfa1a4370278a..00233ad9a37ebead3703e9d0b3d4f27afd204da6 100644 (file)
@@ -34,11 +34,11 @@ extern char *concat_path_file(const char *path, const char *filename)
        char *lc;
 
        if (!path)
-           path="";
+               path = "";
        lc = last_char_is(path, '/');
        while (*filename == '/')
                filename++;
-       bb_xasprintf(&outbuf, "%s%s%s", path, (lc==NULL)? "/" : "", filename);
+       bb_xasprintf(&outbuf, "%s%s%s", path, (lc==NULL ? "/" : ""), filename);
 
        return outbuf;
 }
index bf0a390a311e862807913876cbcefdae980aae88..27d65a4195717a6497a9961f1b7dc98455727b65 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Utility routines.
  *
- * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+ * Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@
 #include <unistd.h>
 
 #include "busybox.h"
+#include "libbb.h"
 
 
 #if BUFSIZ < 4096
 #endif
 
 
-/* If size is 0 copy until EOF */
-static size_t bb_full_fd_action(int src_fd, int dst_fd, const size_t size)
+static size_t bb_full_fd_action(int src_fd, int dst_fd, const size_t size2)
 {
-       size_t read_total = 0;
-       RESERVE_CONFIG_BUFFER(buffer,BUFSIZ);
+       int status;
+       size_t xread, wrote, total, size = size2;
 
-       while ((size == 0) || (read_total < size)) {
-               size_t read_try;
-               ssize_t read_actual;
+       if (src_fd < 0) {
+               return -1;
+       }
 
-               if ((size == 0) || (size - read_total > BUFSIZ)) {
-                       read_try = BUFSIZ;
-               } else {
-                       read_try = size - read_total;
-               }
+       if (size == 0) {
+               /* If size is 0 copy until EOF */
+               size = ULONG_MAX;
+       }
 
-               read_actual = safe_read(src_fd, buffer, read_try);
-               if (read_actual > 0) {
-                       if ((dst_fd >= 0) && (bb_full_write(dst_fd, buffer, (size_t) read_actual) != read_actual)) {
-                               bb_perror_msg(bb_msg_write_error);      /* match Read error below */
+       {
+               RESERVE_CONFIG_BUFFER(buffer,BUFSIZ);
+               total = 0;
+               wrote = 0;
+               status = -1;
+               while (total < size)
+               {
+                       xread = BUFSIZ;
+                       if (size < (total + BUFSIZ))
+                               xread = size - total;
+                       xread = bb_full_read(src_fd, buffer, xread);
+                       if (xread > 0) {
+                               if (dst_fd < 0) {
+                                       /* A -1 dst_fd means we need to fake it... */
+                                       wrote = xread;
+                               } else {
+                                       wrote = bb_full_write(dst_fd, buffer, xread);
+                               }
+                               if (wrote < xread) {
+                                       bb_perror_msg(bb_msg_write_error);
+                                       break;
+                               }
+                               total += wrote;
+                       } else if (xread < 0) {
+                               bb_perror_msg(bb_msg_read_error);
+                               break;
+                       } else if (xread == 0) {
+                               /* All done. */
+                               status = 0;
                                break;
                        }
                }
-               else if (read_actual == 0) {
-                       if (size) {
-                               bb_error_msg("Unable to read all data");
-                       }
-                       break;
-               } else {
-                       /* read_actual < 0 */
-                       bb_perror_msg("Read error");
-                       break;
-               }
-
-               read_total += read_actual;
+               RELEASE_CONFIG_BUFFER(buffer);
        }
 
-       RELEASE_CONFIG_BUFFER(buffer);
-
-       return(read_total);
+       if (status == 0 || total)
+               return total;
+       /* Some sortof error occured */
+       return -1;
 }
 
 
index 39a7d1d29a3a9b57a3ae0e8c463bbab9cf5a9500..6197e8d9f18fc3e421bae25dc9729bddbaab0c5a 100644 (file)
 #include <stdlib.h>
 #include "libbb.h"
 
-/*
-You can set bb_opt_complementaly as string with one or more
-complementaly or incongruously options.
-If sequential founded option haved from this string
-then your incongruously pairs unsets and complementaly make add sets.
-Format:
-one char - option for check,
-chars - complementaly option for add sets.
-- chars - option triggered for unsets.
-~ chars - option incongruously.
-*       - option list, called add_to_list(*ptr_from_usaged, optarg)
-:       - separator.
-Example: du applet can have options "-s" and "-d size"
-If getopt found -s then -d option flag unset or if found -d then -s unset.
-For this result you must set bb_opt_complementaly = "s-d:d-s".
-Result have last option flag only from called arguments.
-Warning! You can check returned flag, pointer to "d:" argument seted
-to own optarg always.
-Example two: cut applet must only one type of list may be specified,
-and -b, -c and -f incongruously option, overwited option is error also.
-You must set bb_opt_complementaly = "b~cf:c~bf:f~bc".
-If called have more one specified, return value have error flag -
-high bite set (0x80000000UL).
-Example three: grep applet can have one or more "-e pattern" arguments.
-You should use bb_getopt_ulflags() as
-llist_t *paterns;
-bb_opt_complementaly = "e*";
-bb_getopt_ulflags (argc, argv, "e:", &paterns);
+/*                  Documentation !
+
+unsigned long
+bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...)
+
+          The command line options must be declared in const char
+          *applet_opts as a string of chars, for example:
+
+          flags = bb_getopt_ulflags(argc, argv, "rnug");
+
+          If one of the given options is found, a flag value is added to
+          the return value (an unsigned long).
+
+          The flag value is determined by the position of the char in
+          applet_opts string.  For example, in the above case:
+
+          flags = bb_getopt_ulflags(argc, argv, "rnug");
+
+          "r" will add 1    (bit 1 : 0x01)
+          "n" will add 2    (bit 2 : 0x02)
+          "u  will add 4    (bit 3 : 0x03)
+          "g" will add 8    (bit 4 : 0x04)
+
+           and so on.  You can also look at the return value as a bit 
+           field and each option sets one of bits.
+
+   ":"     If one of the options requires an argument, then add a ":"
+           after the char in applet_opts and provide a pointer to store
+           the argument.  For example:
+
+           char *pointer_to_arg_for_a;
+           char *pointer_to_arg_for_b;
+           char *pointer_to_arg_for_c;
+           char *pointer_to_arg_for_d;
+
+           flags = bb_getopt_ulflags(argc, argv, "a:b:c:d:",
+                            &pointer_to_arg_for_a, &pointer_to_arg_for_b,
+                            &pointer_to_arg_for_c, &pointer_to_arg_for_d);
+
+           The type of the pointer (char* or llist_t *) may be controlled
+           by the "*" special character that is set in the external string
+           bb_opt_complementaly (see below for more info).
+
+static const struct option bb_default_long_options[]
+
+           This struct allows you to define long options.  The syntax for
+           declaring the array is just like that of getopt's longopts.
+
+           static const struct option applet_long_options[] = {
+                   { "verbose", 0, 0, "v" },
+                   { 0, 0, 0, 0 }
+           };
+           bb_applet_long_options = applet_long_options;
+
+           The first parameter is the long option name that you would pass
+           to the applet (without the dashes).
+
+           The second field determines whether the option has an argument.
+           You can set this to 0, 1, or 2, or you can use the long named
+           defines of no_argument, required_argument, and optional_argument.
+
+           The third argument is used only when the long option does not 
+           have a corresponding short option.  In that case, it should be 
+           an integer pointer.  Otherwise (and normally), it should just
+           bet set to NULL.
+
+           The last argument is the corresponding short option (if there
+           is one of course).
+
+           Note: a good applet will make long options configurable via the
+           config process and not a required feature.  The current standard
+           is to name the config option CONFIG_FEATURE_<applet>_LONG_OPTIONS.
+
+const char *bb_opt_complementaly
+
+   ":"     The colon (":") is used to separate groups of two or more chars
+           and/or groups of chars and special characters (stating some
+           conditions to be checked).
+
+   "abc"   If groups of two or more chars are specified, the first char
+           is the main option and the other chars are secondary options.
+           Their flags will be turned on if the main option is found even
+           if they are not specifed on the command line.  For example:
+
+           bb_opt_complementaly = "abc";
+
+           flags = bb_getopt_ulflags(argc, argv, "abcd")
+
+           If getopt() finds "-a" on the command line, then
+           bb_getopt_ulflags's return value will be as if "-a -b -c" were
+           found.
+
+Special characters:
+
+   "-"     A dash between two options causes the second of the two
+           to be unset (and ignored) if it is given on the command line.
+
+           For example:
+           The du applet has the options "-s" and "-d depth".  If
+           bb_getopt_ulflags finds -s, then -d is unset or if it finds -d
+           then -s is unset.  (Note:  busybox implements the GNU
+           "--max-depth" option as "-d".)  To obtain this behavior, you 
+           set bb_opt_complementaly = "s-d:d-s".  Only one flag value is 
+           added to bb_getopt_ulflags's return value depending on the 
+           position of the options on the command line.  If one of the 
+           two options requires an argument pointer (":" in applet_opts 
+           as in "d:") optarg is set accordingly.
+
+           char *smax_print_depth;
+
+           bb_opt_complementaly = "s-d:d-s";
+           opt = bb_getopt_ulflags(argc, argv, "sd:", &smax_print_depth);
+
+           if (opt & 2) {
+                    max_print_depth = bb_xgetularg10_bnd(smax_print_depth,
+                                0, INT_MAX);
+           }
+
+   "~"     A tilde between two options, or between an option and a group
+           of options, means that they are mutually exclusive.  Unlike
+           the "-" case above, an error will be forced if the options
+           are used together.
+
+           For example:
+           The cut applet must have only one type of list specified, so
+           -b, -c and -f are mutally exclusive and should raise an error
+           if specified together.  In this case you must set
+           bb_opt_complementaly = "b~cf:c~bf:f~bc".  If two of the
+           mutually exclusive options are found, bb_getopt_ulflags's
+           return value will have the error flag set (BB_GETOPT_ERROR) so
+           that we can check for it:
+
+           if (flags & BB_GETOPT_ERROR)
+                   bb_show_usage();
+
+   "*"     A star after a char in bb_opt_complementaly means that the
+           option can occur multiple times:
+
+           For example:
+           The grep applet can have one or more "-e pattern" arguments.
+           In this case you should use bb_getopt_ulflags() as follows:
+
+           llist_t *patterns = NULL;
+
+           (this pointer must be initializated to NULL if the list is empty
+           as required by *llist_add_to(llist_t *old_head, char *new_item).)
+
+           bb_opt_complementaly = "e*";
+
+           bb_getopt_ulflags(argc, argv, "e:", &patterns);
+           $ grep -e user -e root /etc/passwd
+           root:x:0:0:root:/root:/bin/bash
+           user:x:500:500::/home/user:/bin/bash
+
 */
 
 const char *bb_opt_complementaly;
 
-typedef struct
-{
+typedef struct {
        unsigned char opt;
        char list_flg;
        unsigned long switch_on;
        unsigned long switch_off;
        unsigned long incongruously;
-       void **optarg;              /* char **optarg or llist_t **optarg */
+       void **optarg;               /* char **optarg or llist_t **optarg */
 } t_complementaly;
 
 /* You can set bb_applet_long_options for parse called long options */
 
 static const struct option bb_default_long_options[] = {
-     /*   { "help", 0, NULL, '?' }, */
+/*     { "help", 0, NULL, '?' }, */
        { 0, 0, 0, 0 }
 };
 
 const struct option *bb_applet_long_options = bb_default_long_options;
 
-
 unsigned long
 bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...)
 {
-  unsigned long flags = 0;
-  t_complementaly complementaly[sizeof(flags) * 8 + 1];
-  int c;
-  const unsigned char *s;
-  t_complementaly *on_off;
-  va_list p;
-
-  va_start (p, applet_opts);
-
-  /* skip GNU extension */
-  s = applet_opts;
-  if(*s == '+' || *s == '-')
-       s++;
-
-  c = 0;
-  on_off = complementaly;
-  for (; *s; s++) {
-       if(c >= (sizeof(flags)*8))
-               break;
-       on_off->opt = *s;
-       on_off->switch_on = (1 << c);
-       on_off->list_flg = 0;
-       on_off->switch_off = 0;
-       on_off->incongruously = 0;
-       on_off->optarg = NULL;
-       if (s[1] == ':') {
-         on_off->optarg = va_arg (p, void **);
-         do
+       unsigned long flags = 0;
+       t_complementaly complementaly[sizeof(flags) * 8 + 1];
+       int c;
+       const unsigned char *s;
+       t_complementaly *on_off;
+       va_list p;
+
+       va_start (p, applet_opts);
+
+       /* skip GNU extension */
+       s = applet_opts;
+       if(*s == '+' || *s == '-')
                s++;
-         while (s[1] == ':');
+
+       c = 0;
+       on_off = complementaly;
+       for (; *s; s++) {
+               if(c >= (sizeof(flags)*8))
+                       break;
+               on_off->opt = *s;
+               on_off->switch_on = (1 << c);
+               on_off->list_flg = 0;
+               on_off->switch_off = 0;
+               on_off->incongruously = 0;
+               on_off->optarg = NULL;
+               if (s[1] == ':') {
+                       on_off->optarg = va_arg (p, void **);
+                       do
+                               s++;
+                       while (s[1] == ':');
+               }
+               on_off++;
+               c++;
        }
-       on_off++;
-       c++;
-  }
-  on_off->opt = 0;
-  c = 0;
-  for (s = bb_opt_complementaly; s && *s; s++) {
-    t_complementaly *pair;
-
-    if (*s == ':') {
-         c = 0;
-         continue;
-    }
-    if (c)
-         continue;
-    for (on_off = complementaly; on_off->opt; on_off++)
-         if (on_off->opt == *s)
-           break;
-    pair = on_off;
-    for(s++; *s && *s != ':'; s++) {
-      if (*s == '-' || *s == '~') {
-         c = *s;
-      } else if(*s == '*') {
-       pair->list_flg++;
-      } else {
-         unsigned long *pair_switch = &(pair->switch_on);
-
-         if(c)
-           pair_switch = c == '-' ? &(pair->switch_off) : &(pair->incongruously);
-         for (on_off = complementaly; on_off->opt; on_off++)
-           if (on_off->opt == *s) {
-                 *pair_switch |= on_off->switch_on;
-                 break;
-           }
-      }
-    }
-    s--;
-  }
-
-  while ((c = getopt_long (argc, argv, applet_opts,
-                           bb_applet_long_options, NULL)) > 0) {
-       for (on_off = complementaly; on_off->opt != c; on_off++) {
-           if(!on_off->opt)
-                       bb_show_usage ();
+       on_off->opt = 0;
+       c = 0;
+       for (s = bb_opt_complementaly; s && *s; s++) {
+               t_complementaly *pair;
+
+               if (*s == ':') {
+                       c = 0;
+                       continue;
+               }
+               if (c)
+                       continue;
+               for (on_off = complementaly; on_off->opt; on_off++)
+                       if (on_off->opt == *s)
+                               break;
+               pair = on_off;
+               for(s++; *s && *s != ':'; s++) {
+                       if (*s == '-' || *s == '~') {
+                               c = *s;
+                       } else if(*s == '*') {
+                               pair->list_flg++;
+                       } else {
+                               unsigned long *pair_switch = &(pair->switch_on);
+                               if(c)
+                                       pair_switch = c == '-' ? &(pair->switch_off) : &(pair->incongruously);
+                               for (on_off = complementaly; on_off->opt; on_off++)
+                                       if (on_off->opt == *s) {
+                                               *pair_switch |= on_off->switch_on;
+                                               break;
+                                       }
+                       }
+               }
+               s--;
        }
-       if(flags & on_off->incongruously)
-           flags |= 0x80000000UL;
-       flags &= ~on_off->switch_off;
-       flags |= on_off->switch_on;
-       if(on_off->list_flg) {
-          *(llist_t **)(on_off->optarg) =
-               llist_add_to(*(llist_t **)(on_off->optarg), optarg);
-       } else if (on_off->optarg) {
-           *(char **)(on_off->optarg) = optarg;
+
+       while ((c = getopt_long (argc, argv, applet_opts,
+                                bb_applet_long_options, NULL)) > 0) {
+               for (on_off = complementaly; on_off->opt != c; on_off++) {
+                       if(!on_off->opt)
+                               bb_show_usage ();
+               }
+               if(flags & on_off->incongruously)
+                       flags |= BB_GETOPT_ERROR;
+               flags &= ~on_off->switch_off;
+               flags |= on_off->switch_on;
+               if(on_off->list_flg) {
+                       *(llist_t **)(on_off->optarg) =
+                               llist_add_to(*(llist_t **)(on_off->optarg), optarg);
+               } else if (on_off->optarg) {
+                       *(char **)(on_off->optarg) = optarg;
+               }
        }
-  }
-  return flags;
+
+       return flags;
 }
index fe2d0b4b2024dbe16ea8bd927915425a4643b82f..c4aa032a4c48deef2d94d011019d7ce1581771dc 100644 (file)
@@ -888,6 +888,20 @@ static int sockets_open(int family)
        return sfd;
 }
 
+#ifdef CONFIG_FEATURE_CLEAN_UP
+static void sockets_close(void)
+{
+       struct aftype **aft;
+       for (aft = aftypes; *aft != NULL; aft++) {
+               struct aftype *af = *aft;
+               if( af->fd != -1 ) {
+                       close(af->fd);
+                       af->fd = -1;
+               }
+       }
+}
+#endif
+
 /* like strcmp(), but knows about numbers */
 static int nstrcmp(const char *a, const char *b)
 {
@@ -1223,17 +1237,13 @@ static int if_fetch(struct interface *ife)
        }
 #endif
 
+#ifdef SIOCGIFMAP
        strcpy(ifr.ifr_name, ifname);
-       if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0)
-               memset(&ife->map, 0, sizeof(struct ifmap));
+       if (ioctl(skfd, SIOCGIFMAP, &ifr) == 0)
+               ife->map = ifr.ifr_map;
        else
-               memcpy(&ife->map, &ifr.ifr_map, sizeof(struct ifmap));
-
-       strcpy(ifr.ifr_name, ifname);
-       if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0)
+#endif
                memset(&ife->map, 0, sizeof(struct ifmap));
-       else
-               ife->map = ifr.ifr_map;
 
 #ifdef HAVE_TXQUEUELEN
        strcpy(ifr.ifr_name, ifname);
@@ -1374,7 +1384,7 @@ static struct hwtype loop_hwtype = {
 #if HAVE_HWETHER
 #include <net/if_arp.h>
 
-#if __GLIBC__ >=2 && __GLIBC_MINOR >= 1
+#if (__GLIBC__ >=2 && __GLIBC_MINOR >= 1) || defined(_NEWLIB_VERSION)
 #include <net/ethernet.h>
 #else
 #include <linux/if_ether.h>
@@ -2078,6 +2088,8 @@ int display_interfaces(char *ifname)
 
        /* Do we have to show the current setup? */
        status = if_print(ifname);
-       close(skfd);
+#ifdef CONFIG_FEATURE_CLEAN_UP
+       sockets_close();
+#endif
        exit(status < 0);
 }
index 671c452d297114f25e35d166c321e13f26d1edae..c3f307ec521ea17093e2d1f0d77386128a999101 100644 (file)
@@ -36,6 +36,9 @@
 #ifdef L_write_error
        const char * const bb_msg_write_error = "Write Error";
 #endif
+#ifdef L_read_error
+       const char * const bb_msg_read_error = "Read Error";
+#endif
 #ifdef L_name_longer_than_foo
        const char * const bb_msg_name_longer_than_foo = "Names longer than %d chars not supported.";
 #endif
index 9e89dbd39f8d3b507398106ee854a2a64f45f111..dac90e24baf7885a84fbc0721c20e6a5dd02369d 100644 (file)
@@ -29,7 +29,7 @@
 #include <sys/syscall.h>
 #include "libbb.h"
 
-int sysfs( int option, unsigned int fs_index, char * buf)
+int sysfs(int option, unsigned int fs_index, char * buf)
 {
        return(syscall(__NR_sysfs, option, fs_index, buf));
 }
@@ -39,60 +39,59 @@ int pivot_root(const char * new_root,const char * put_old)
 #ifndef __NR_pivot_root
 #warning This kernel does not support the pivot_root syscall
 #warning -> The pivot_root system call is being stubbed out...
-    /* BusyBox was compiled against a kernel that did not support
-     *  the pivot_root system call.  To make this application work,
-     *  you will need to recompile with a kernel supporting the
-     *  pivot_root system call.
-     */
-    bb_error_msg("\n\nTo make this application work, you will need to recompile\n"
-           "BusyBox with a kernel supporting the pivot_root system call.\n");
-    errno=ENOSYS;
-    return -1;
+       /* BusyBox was compiled against a kernel that did not support
+        *  the pivot_root system call.  To make this application work,
+        *  you will need to recompile with a kernel supporting the
+        *  pivot_root system call.
+        */
+       bb_error_msg("\n\nTo make this application work, you will need to recompile\n"
+                    "BusyBox with a kernel supporting the pivot_root system call.\n");
+       errno = ENOSYS;
+       return -1;
 #else
-    return(syscall(__NR_pivot_root, new_root, put_old));
-#endif
+       return(syscall(__NR_pivot_root, new_root, put_old));
+#endif /* __NR_pivot_root */
 }
 
 
-
-/* These syscalls are not included in ancient glibc versions */
+/* These syscalls are not included in ancient glibc versions,
+   so we have to define them ourselves, whee ! */
 #if ((__GLIBC__ <= 2) && (__GLIBC_MINOR__ < 1))
 
 int bdflush(int func, int data)
 {
-    return(syscall(__NR_bdflush, func, data));
+       return(syscall(__NR_bdflush, func, data));
 }
 
 #ifndef __alpha__
 # define __NR_klogctl __NR_syslog
 int klogctl(int type, char *b, int len)
 {
-    return(syscall(__NR_klogctl, type, b, len));
+       return(syscall(__NR_klogctl, type, b, len));
 }
-#endif
+#endif /* __alpha__ */
 
 
 int umount2(const char * special_file, int flags)
 {
-#ifndef __NR_pivot_root
+#ifndef __NR_umount2
 #warning This kernel does not support the umount2 syscall
 #warning -> The umount2 system call is being stubbed out...
-    /* BusyBox was compiled against a kernel that did not support
-     *  the umount2 system call.  To make this application work,
-     *  you will need to recompile with a kernel supporting the
-     *  umount2 system call.
-     */
-    bb_error_msg("\n\nTo make this application work, you will need to recompile\n"
-           "BusyBox with a kernel supporting the umount2 system call.\n");
-    errno=ENOSYS;
-    return -1;
+       /* BusyBox was compiled against a kernel that did not support
+        *  the umount2 system call.  To make this application work,
+        *  you will need to recompile with a kernel supporting the
+        *  umount2 system call.
+        */
+       bb_error_msg("\n\nTo make this application work, you will need to recompile\n"
+                    "BusyBox with a kernel supporting the umount2 system call.\n");
+       errno = ENOSYS;
+       return -1;
 #else
-    return(syscall(__NR_umount2, special_file, flags));
-#endif
+       return(syscall(__NR_umount2, special_file, flags));
+#endif /* __NR_pivot_root */
 }
 
-
-#endif
+#endif /* old glibc check */
 
 
 /* END CODE */
index 5619aa9af453315a15fbdbf92cfce457982c15c6..12c208c640acc24544416517b8a4c369378f863a 100644 (file)
@@ -57,14 +57,21 @@ config CONFIG_GETTY
        help
          getty lets you log in on a tty, it is normally invoked by init.
 
-config CONFIG_FEATURE_U_W_TMP
-       bool "  Support utmp and wtmp files"
-       depends on CONFIG_GETTY || CONFIG_LOGIN || CONFIG_SU || CONFIG_WHO || CONFIG_LAST
+config CONFIG_FEATURE_UTMP
+       bool "  Support utmp file"
+       depends on CONFIG_GETTY || CONFIG_LOGIN || CONFIG_SU || CONFIG_WHO 
        default n
        help
-         The files /var/run/utmp and /var/run/wtmp can be used to track when
-         user's have logged into and logged out of the system, allowing programs
-         such as 'who' and 'last' to list who is currently logged in.
+         The file /var/run/utmp is used to track who is currently logged in.
+
+config CONFIG_FEATURE_WTMP
+       bool "  Support wtmp file"
+       depends on CONFIG_GETTY || CONFIG_LOGIN || CONFIG_SU || CONFIG_LAST
+       default n
+       select CONFIG_FEATURE_UTMP
+       help
+         The file /var/run/wtmp is used to track when user's have logged into 
+         and logged out of the system.
 
 config CONFIG_LOGIN
        bool "login"
index 923432ba1168337e10a4ac9d39e453340ee28a86..78009181d7e837517c58d34323a2eac38fe2c92d 100644 (file)
 #include <fcntl.h>
 #include <stdarg.h>
 #include <ctype.h>
-#include <utmp.h>
 #include <getopt.h>
 #include <termios.h>
 #include "busybox.h"
 
+#ifdef CONFIG_FEATURE_UTMP
+#include <utmp.h>
+#endif
+
 #define _PATH_LOGIN     "/bin/login"
 
  /* If USE_SYSLOG is undefined all diagnostics go directly to /dev/console. */
@@ -47,7 +50,7 @@
 
 #ifdef LOGIN_PROCESS                   /* defined in System V utmp.h */
 #define        SYSV_STYLE                              /* select System V style getty */
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_WTMP
 extern void updwtmp(const char *filename, const struct utmp *ut);
 #endif
 #endif  /* LOGIN_PROCESS */
@@ -85,7 +88,7 @@ extern void updwtmp(const char *filename, const struct utmp *ut);
 #define DEF_QUIT       CTL('\\')       /* default quit char */
 #define DEF_KILL       CTL('U')        /* default kill char */
 #define DEF_EOF                CTL('D')        /* default EOF char */
-#define DEF_EOL                0
+#define DEF_EOL                '\n'
 #define DEF_SWITCH     0                       /* default switch char */
 
  /*
@@ -231,9 +234,11 @@ static int caps_lock(const char *s);
 static int bcode(char *s);
 static void error(const char *fmt, ...) __attribute__ ((noreturn));
 
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef SYSV_STYLE
+#ifdef CONFIG_FEATURE_UTMP
 static void update_utmp(char *line);
 #endif
+#endif
 
 /* The following is used for understandable diagnostics. */
 
@@ -260,7 +265,11 @@ int getty_main(int argc, char **argv)
                _PATH_LOGIN,                    /* default login program */
                "tty1",                                 /* default tty line */
                "",                                             /* modem init string */
+#ifdef ISSUE
                ISSUE,                                  /* default issue file */
+#else
+               NULL,
+#endif
                0,                                              /* no baud rates known yet */
        };
 
@@ -289,7 +298,7 @@ int getty_main(int argc, char **argv)
 
 
 #ifdef SYSV_STYLE
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_UTMP
        update_utmp(options.tty);
 #endif
 #endif
@@ -482,7 +491,7 @@ static void parse_speeds(struct options *op, char *arg)
 }
 
 #ifdef SYSV_STYLE
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_UTMP
 
 /* update_utmp - update our utmp entry */
 static void update_utmp(char *line)
@@ -533,30 +542,24 @@ static void update_utmp(char *line)
        pututline(&ut);
        endutent();
 
-       {
-               if (access(_PATH_WTMP, R_OK|W_OK) == -1) {
-                       close(creat(_PATH_WTMP, 0664));
-               }
-               updwtmp(_PATH_WTMP, &ut);
-       }
+#ifdef CONFIG_FEATURE_WTMP
+       if (access(_PATH_WTMP, R_OK|W_OK) == -1) 
+               close(creat(_PATH_WTMP, 0664));
+       updwtmp(_PATH_WTMP, &ut);
+#endif
 }
 
-#endif /* CONFIG_FEATURE_U_W_TMP */
+#endif /* CONFIG_FEATURE_UTMP */
 #endif /* SYSV_STYLE */
 
 /* open_tty - set up tty as standard { input, output, error } */
 static void open_tty(char *tty, struct termio *tp, int local)
 {
-       /* Get rid of the present standard { output, error} if any. */
-
-       (void) close(1);
-       (void) close(2);
-       errno = 0;                                      /* ignore above errors */
-
        /* Set up new standard input, unless we are given an already opened port. */
 
        if (strcmp(tty, "-")) {
                struct stat st;
+               int fd;
 
                /* Sanity checks... */
 
@@ -569,12 +572,11 @@ static void open_tty(char *tty, struct termio *tp, int local)
 
                /* Open the tty as standard input. */
 
-               (void) close(0);
-               errno = 0;                              /* ignore close(2) errors */
-
                debug("open(2)\n");
-               if (open(tty, O_RDWR | O_NONBLOCK, 0) != 0)
+               fd = open(tty, O_RDWR | O_NONBLOCK, 0);
+               if (dup2(fd, STDIN_FILENO) == -1)
                        error("/dev/%s: cannot open as standard input: %m", tty);
+               close(fd);
 
        } else {
 
@@ -587,9 +589,10 @@ static void open_tty(char *tty, struct termio *tp, int local)
                        error("%s: not open for read/write", tty);
        }
 
-       /* Set up standard output and standard error file descriptors. */
+       /* Replace current standard output/error fd's with new ones */
        debug("duping\n");
-       if (dup(0) != 1 || dup(0) != 2) /* set up stdout and stderr */
+       if (dup2(STDIN_FILENO, STDOUT_FILENO) == -1 ||
+           dup2(STDIN_FILENO, STDERR_FILENO) == -1)
                error("%s: dup problem: %m", tty);      /* we have a problem */
 
        /*
index f3630f10228c751aecde25d766e4911e3f2faf48..5ed10b91b706161bc178389273a0faf5ee9a9045 100644 (file)
@@ -23,7 +23,7 @@
 #include <fs_secure.h>
 #endif
 
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_UTMP
 // import from utmp.c
 static void checkutmp(int picky);
 static void setutmp(const char *name, const char *line);
@@ -122,7 +122,7 @@ extern int login_main(int argc, char **argv)
        if ( !isatty ( 0 ) || !isatty ( 1 ) || !isatty ( 2 ))
                return EXIT_FAILURE;            /* Must be a terminal */
 
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_UTMP
        checkutmp ( !amroot );
 #endif
 
@@ -134,13 +134,13 @@ extern int login_main(int argc, char **argv)
        else
                safe_strncpy ( tty, "UNKNOWN", sizeof( tty ));
 
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_UTMP
        if ( amroot )
                memset ( utent.ut_host, 0, sizeof utent.ut_host );
 #endif
 
        if ( opt_host ) {
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_UTMP
                safe_strncpy ( utent.ut_host, opt_host, sizeof( utent. ut_host ));
 #endif
                snprintf ( fromhost, sizeof( fromhost ) - 1, " on `%.100s' from `%.200s'", tty, opt_host );
@@ -222,7 +222,7 @@ auth_ok:
        if ( check_nologin ( pw-> pw_uid == 0 ))
                return EXIT_FAILURE;
 
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_UTMP
        setutmp ( username, tty );
 #endif
 #ifdef CONFIG_SELINUX
@@ -387,7 +387,7 @@ static int is_my_tty ( const char *tty )
 }
 
 
-static void motd ( )
+static void motd (void)
 {
        FILE *fp;
        register int c;
@@ -400,7 +400,7 @@ static void motd ( )
 }
 
 
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_UTMP
 // vv  Taken from tinylogin utmp.c  vv
 
 #define        NO_UTENT \
@@ -478,9 +478,11 @@ static void setutmp(const char *name, const char *line)
        setutent();
        pututline(&utent);
        endutent();
+#ifdef CONFIG_FEATURE_WTMP
        if (access(_PATH_WTMP, R_OK|W_OK) == -1) {
                close(creat(_PATH_WTMP, 0664));
        }
        updwtmp(_PATH_WTMP, &utent);
+#endif
 }
-#endif /* CONFIG_FEATURE_U_W_TMP */
+#endif /* CONFIG_FEATURE_UTMP */
index ec0c16c7dc726177e9200a66e41e0c85c5086dea..1e93aacd4ad3c984404b6613fd715521a63e6bde 100644 (file)
@@ -91,7 +91,7 @@ int su_main ( int argc, char **argv )
                opt_args = argv + optind;
 
 #if defined( SYSLOG_SUCCESS ) || defined( SYSLOG_FAILURE )
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_UTMP
        /* The utmp entry (via getlogin) is probably the best way to identify
           the user, especially if someone su's from a su-shell.  */
        old_user = getlogin ( );
index 77e13e84ea3946759af0ef00a5e5314731f7a19c..767b9c46209e591d81a3a49213f00987bb436c25 100644 (file)
@@ -37,6 +37,7 @@ config CONFIG_FEATURE_CROND_CALL_SENDMAIL
 config CONFIG_CRONTAB
        bool "crontab"
        default n
+       select CONFIG_FEATURE_SUID
        help
          Crontab manipulates the crontab for a particular user.  Only
          the superuser may specify a different user and/or crontab directory.
@@ -86,7 +87,7 @@ config CONFIG_DEVFSD_VERBOSE
 config CONFIG_LAST
        bool "last"
        default n
-       select CONFIG_FEATURE_U_W_TMP
+       select CONFIG_FEATURE_WTMP
        help
          'last' displays a list of the last users that logged into the system.
 
index 5e183e61f103d82cdb255d3ec79f62ce66a7d99d..34945c7b2e763c3fa0a88bf1a4dcb8fc8873383e 100644 (file)
@@ -566,40 +566,36 @@ static void read_config_file (char *path, int optional, unsigned long *event_mas
 #ifdef CONFIG_DEBUG
        msg_logger( NO_DIE, LOG_INFO, "read_config_file(): %s\n", path);
 #endif
-       if (stat (path, &statbuf) != 0 || statbuf.st_size == 0 )
-               goto read_config_file_err;
-
-       if ( S_ISDIR (statbuf.st_mode) )
-       {
-               /* strip last / from dirname so we don't need to check for it later */
-               while( path  && path[1]!='\0' && path[strlen(path)-1] == '/')
-                       path[strlen(path) -1] = '\0';
-
-               dir_operation(READ_CONFIG, path, 0, event_mask);
-               return;
-       }
-
-       if ( ( fp = fopen (path, "r") ) != NULL )
+       if (stat (path, &statbuf) == 0 )
        {
-               while (fgets (buf, STRING_LENGTH, fp) != NULL)
+               /* Don't read 0 length files: ignored */
+               /*if( statbuf.st_size == 0 )
+                               return;*/
+               if ( S_ISDIR (statbuf.st_mode) )
                {
-                       /*  GETS(3)       Linux Programmer's Manual
-                       fgets() reads in at most one less than size characters from stream  and
-                       stores  them  into  the buffer pointed to by s.  Reading stops after an
-                       EOF or a newline.  If a newline is read, it is stored into the  buffer.
-                       A '\0' is stored after the last character in the buffer.
-                       */
-                       /*buf[strlen (buf) - 1] = '\0';*/
-                       /*  Skip whitespace  */
-                       for (line = buf; isspace (*line); ++line)
-                               /*VOID*/;
-                       if (line[0] == '\0' || line[0] == '#' )
-                               continue;
-                       process_config_line (line, event_mask);
+                       /* strip last / from dirname so we don't need to check for it later */
+                       while( path  && path[1]!='\0' && path[strlen(path)-1] == '/')
+                               path[strlen(path) -1] = '\0';
+       
+                       dir_operation(READ_CONFIG, path, 0, event_mask);
+                       return;
                }
-               fclose (fp);
-               errno=0;
-       }
+               if ( ( fp = fopen (path, "r") ) != NULL )
+               {
+                       while (fgets (buf, STRING_LENGTH, fp) != NULL)
+                       {
+                               /*  Skip whitespace  */
+                               for (line = buf; isspace (*line); ++line)
+                                       /*VOID*/;
+                               if (line[0] == '\0' || line[0] == '#' )
+                                       continue;
+                               process_config_line (line, event_mask);
+                       }
+                       fclose (fp);
+               } else {
+                       goto read_config_file_err;
+               }
+       } else {
 read_config_file_err:
 #ifdef CONFIG_DEVFSD_VERBOSE
        msg_logger(((optional ==  0 ) && (errno == ENOENT))? DIE : NO_DIE, LOG_ERR, "read config file: %s: %m\n", path);
@@ -607,6 +603,7 @@ read_config_file_err:
        if(optional ==  0  && errno == ENOENT)
                exit(EXIT_FAILURE);
 #endif
+       }
        return;
 }   /*  End Function read_config_file   */
 
index 92e9f0d1185be3979e938bc3826ea2dc19a6ca3b..d0a0924215724f999effbce761bc5ce2317c8def 100644 (file)
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 #include <getopt.h>
-#include <unistd.h>
 #include <ctype.h>
 #include "busybox.h"
 
 #define ISSTR(ch)      (isprint(ch) || ch == '\t')
 
+#define WHOLE_FILE             1
+#define PRINT_NAME             2
+#define PRINT_OFFSET   4
+#define SIZE                   8
+
 int strings_main(int argc, char **argv)
 {
-       int n=4, c, i, opt=0, status=EXIT_SUCCESS;
-       long t=0, count;
+       int n, c, i = 0, status = EXIT_SUCCESS;
+       unsigned long opt;
+       unsigned long count;
        FILE *file = stdin;
-       char *string=NULL;
-       const char *fmt="%s: ";
-
-       while ((i = getopt(argc, argv, "afon:")) > 0)
-               switch(i)
-               {
-                       case 'a':
-                               break;
-                       case 'f':
-                               opt+=1;
-                               break;
-                       case 'o':
-                               opt+=2;
-                               break;
-                       case 'n':
-                               n = bb_xgetlarg(optarg, 10, 1, INT_MAX);
-                               break;
-                       default:
-                               bb_show_usage();
-               }
-
+       char *string;
+       const char *fmt = "%s: ";
+       char *n_arg = "4";
+       
+       opt = bb_getopt_ulflags (argc, argv, "afon:", &n_arg);
+       /* -a is our default behaviour */
+       
        argc -= optind;
        argv += optind;
 
-       i=0;
-
-       string=xmalloc(n+1);
-       string[n]='\0';
-       n-=1;
-
-       if(argc==0)
-       {
-               fmt="{%s}: ";
-               *argv=(char *)bb_msg_standard_input;
-               goto pipe;
+       n = bb_xgetlarg(n_arg, 10, 1, INT_MAX);
+       string = xcalloc(n + 1, 1);
+       n--;
+       
+       if ( argc == 0) {
+               fmt = "{%s}: ";
+               *argv = (char *)bb_msg_standard_input;
+               goto PIPE;
        }
-
-       for( ;*argv!=NULL && argc>0;argv++)
-       {
-               if((file=bb_wfopen(*argv,"r")))
-               {
-pipe:
-
-                       count=0;
-                       do{
-                               c=fgetc(file);
-                               if(ISSTR(c))
-                               {
-                                       if(i==0)
-                                               t=count;
-                                       if(i<=n)
+       
+       do {
+               if ((file = bb_wfopen(*argv, "r"))) {
+PIPE:
+                       count = 0;
+                       do {
+                               c = fgetc(file);
+                               if (ISSTR(c)) {
+                                       if (i <= n) {
                                                string[i]=c;
-                                       if(i==n)
-                                       {
-                                               if(opt == 1 || opt == 3 )
-                                                       printf(fmt,*argv);
-                                               if(opt >= 2 )
-                                                       printf("%7lo ", t);
+                                       } else {
+                                               putchar(c);
+                                       }
+                                       if (i == n) {
+                                               if (opt & PRINT_NAME) {
+                                                       printf(fmt, *argv);
+                                               }
+                                               if (opt & PRINT_OFFSET) {
+                                                       printf("%7lo ", count - n );
+                                               }
                                                printf("%s", string);
                                        }
-                                       if(i>n)
-                                               putchar(c);
                                        i++;
-                               }
-                               else
-                               {
-                                       if(i>n)
+                               } else {
+                                       if (i > n) {
                                                putchar('\n');
-                                       i=0;
+                                       }
+                                       i = 0;
                                }
                                count++;
-                       }while(c!=EOF);
-
+                       } while (c != EOF);
                        bb_fclose_nonstdin(file);
-               }
-               else
+               } else {
                        status=EXIT_FAILURE;
-       }
-       /*free(string);*/
-       exit(status);
+               }
+       } while ( --argc > 0 );
+#ifdef CONFIG_FEATURE_CLEAN_UP 
+       free(string);
+#endif
+       bb_fflush_stdout_and_exit(status);
 }
 
 /*
index d88dd1be67e742edb1b64c3aebf7303f0139ac19..60f5cf1c7c885d62969539f3b44dd51cf0bec21e 100644 (file)
@@ -269,8 +269,8 @@ extern int insmod_ng_main( int argc, char **argv);
 /* X86_64  */
 #if defined(__x86_64__)
 #define MATCH_MACHINE(x) (x == EM_X86_64)
-#define SHT_RELM       SHT_REL
-#define Elf64_RelM     Elf64_Rel
+#define SHT_RELM       SHT_RELA
+#define Elf64_RelM     Elf64_Rela
 #define ELFCLASSM      ELFCLASS64
 #endif
 
@@ -3432,8 +3432,8 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename,
                ".text",
                ".rodata",
                ".data",
-               ".bss"
-                       ".sbss"
+               ".bss",
+               ".sbss"
        };
 
        if (realpath(filename, real)) {
index 83ded53309b2080c0a67829ac293f30aee31f0be..94fcfc8c18bcd21512f17787659321bb70623e6c 100644 (file)
@@ -734,7 +734,7 @@ static char *encodeString(const char *string)
   while ((ch = *string++)) {
     // very simple check for what to encode
     if (isalnum(ch)) *p++ = ch;
-    else p += sprintf(p, "&#%d", (unsigned char) ch);
+    else p += sprintf(p, "&#%d;", (unsigned char) ch);
   }
   *p=0;
   return out;
index 4e3df2982cfa7e57a8a943de4b5b1d16cb68c913..fc7798f2d04ac19da5e7277870cf33416609ed0f 100644 (file)
@@ -46,8 +46,8 @@
 #include <netpacket/packet.h>
 #include <net/ethernet.h>
 #else
-#include <asm/types.h>
-#include <linux/if_ether.h>
+#include <sys/types.h>
+#include <netinet/if_ether.h>
 #endif
 #include "inet_common.h"
 #include "busybox.h"
@@ -177,7 +177,7 @@ struct in6_ifreq {
 
 struct arg1opt {
        const char *name;
-       unsigned short selector;
+       int selector;
        unsigned short ifr_offset;
 };
 
index 1842be58bcac02c1a7233601796472dda49ec0ef..21afe42d44232629226f3648f8d15c2a5b5c376a 100644 (file)
@@ -150,7 +150,7 @@ struct interfaces_file_t
 
 static char no_act = 0;
 static char verbose = 0;
-static char **environ = NULL;
+static char **__myenviron = NULL;
 
 #ifdef CONFIG_FEATURE_IFUPDOWN_IP
 
@@ -961,16 +961,16 @@ static void set_environ(struct interface_defn_t *iface, char *mode)
        const int n_env_entries = iface->n_options + 5;
        char **ppch;
 
-       if (environ != NULL) {
-               for (ppch = environ; *ppch; ppch++) {
+       if (__myenviron != NULL) {
+               for (ppch = __myenviron; *ppch; ppch++) {
                        free(*ppch);
                        *ppch = NULL;
                }
-               free(environ);
-               environ = NULL;
+               free(__myenviron);
+               __myenviron = NULL;
        }
-       environ = xmalloc(sizeof(char *) * (n_env_entries + 1 /* for final NULL */ ));
-       environend = environ;
+       __myenviron = xmalloc(sizeof(char *) * (n_env_entries + 1 /* for final NULL */ ));
+       environend = __myenviron;
        *environend = NULL;
 
        for (i = 0; i < iface->n_options; i++) {
@@ -1010,7 +1010,7 @@ static int doit(char *str)
                        case -1:                /* failure */
                                return 0;
                        case 0:         /* child */
-                               execle(DEFAULT_SHELL, DEFAULT_SHELL, "-c", str, NULL, environ);
+                               execle(DEFAULT_SHELL, DEFAULT_SHELL, "-c", str, NULL, __myenviron);
                                exit(127);
                }
                waitpid(child, &status, 0);
index 169cc87166d6334cbb60684397306f26490b085a..a1fa29ce4ec19bc3bce67fe75371a40015a367cf 100644 (file)
@@ -560,7 +560,7 @@ static void config(int signum)
                if (sep != 0) {
                        int i;
 
-#define SWAP(type, a, b) {type c=(type)a; (type)a=(type)b; (type)b=(type)c;}
+#define SWAP(type, a, b) {type c=(type)(a); (a)=(type)(b); (b)=(type)c;}
 
                        sigprocmask(SIG_BLOCK, &emptymask, &oldmask);
                        /*
index fa1548609dfb7a0f664de0ca4030159702b77535..d86d4f8f5cd30271e2f11e781be4f6309fb157ef 100644 (file)
@@ -238,7 +238,7 @@ __u32 get_addr32(char *name)
        return addr.data[0];
 }
 
-void incomplete_command()
+void incomplete_command(void)
 {
        bb_error_msg("Command line is not complete. Try option \"help\"");
        exit(-1);
index 3099763b19ec7a5dff37903b0475108c593a1fb1..ab8ec0cd5c456cc47b946cf2ba126d4c78ac48d3 100644 (file)
@@ -79,7 +79,7 @@ int nc_main(int argc, char **argv)
 #ifdef GAPING_SECURITY_HOLE
        if (pr00gie) {
                /* won't need stdin */
-               close (STDIN_FILENO);      
+               close(STDIN_FILENO);      
        }
 #endif /* GAPING_SECURITY_HOLE */
 
@@ -90,8 +90,8 @@ int nc_main(int argc, char **argv)
        if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
                bb_perror_msg_and_die("socket");
        x = 1;
-       if (setsockopt (sfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x)) == -1)
-               bb_perror_msg_and_die ("reuseaddr failed");
+       if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x)) == -1)
+               bb_perror_msg_and_die("reuseaddr");
        address.sin_family = AF_INET;
 
        if (lport != 0) {
@@ -154,7 +154,7 @@ int nc_main(int argc, char **argv)
                for (fd = 0; fd < FD_SETSIZE; fd++) {
                        if (FD_ISSET(fd, &testfds)) {
                                if ((nread = safe_read(fd, buf, sizeof(buf))) < 0)
-                                       bb_perror_msg_and_die("read");
+                                       bb_perror_msg_and_die(bb_msg_read_error);
 
                                if (fd == sfd) {
                                        if (nread == 0)
@@ -167,7 +167,7 @@ int nc_main(int argc, char **argv)
                                }
 
                                if (bb_full_write(ofd, buf, nread) < 0)
-                                       bb_perror_msg_and_die("write");
+                                       bb_perror_msg_and_die(bb_msg_write_error);
                                if (delay > 0) {
                                        sleep(delay);
                                }
index 491c66fd151abc186acf5a3966da4d5b0b348d24..b3d0a1166d8f279bb17d50280bae8f7988043f07 100644 (file)
 
 #define BUFSIZE 4000
 
+#ifdef CONFIG_FEATURE_IPV6
+#define SOCKET_TYPE    AF_INET6
+typedef struct sockaddr_in6 sockaddr_type;
+#else
+#define SOCKET_TYPE    AF_INET
+typedef struct sockaddr_in sockaddr_type;
+#endif
+
+
 #ifdef CONFIG_LOGIN
 static const char *loginpath = "/bin/login";
 #else
@@ -373,7 +382,7 @@ int
 telnetd_main(int argc, char **argv)
 {
 #ifndef CONFIG_FEATURE_TELNETD_INETD
-       struct sockaddr_in sa;
+        sockaddr_type sa;
        int master_fd;
 #endif /* CONFIG_FEATURE_TELNETD_INETD */
        fd_set rdfdset, wrfdset;
@@ -431,7 +440,7 @@ telnetd_main(int argc, char **argv)
 
        /* Grab a TCP socket.  */
 
-       master_fd = socket(AF_INET, SOCK_STREAM, 0);
+        master_fd = socket(SOCKET_TYPE, SOCK_STREAM, 0);
        if (master_fd < 0) {
                bb_perror_msg_and_die("socket");
        }
@@ -440,8 +449,13 @@ telnetd_main(int argc, char **argv)
        /* Set it to listen to specified port.  */
 
        memset((void *)&sa, 0, sizeof(sa));
+#ifdef CONFIG_FEATURE_IPV6
+       sa.sin6_family = AF_INET6;
+       sa.sin6_port = htons(portnbr);
+#else
        sa.sin_family = AF_INET;
        sa.sin_port = htons(portnbr);
+#endif
 
        if (bind(master_fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
                bb_perror_msg_and_die("bind");
index 3c947318bc89f3def3e51fd7ab706eaf7a87802f..47fc3879eb6ae32c6a75d63cbf954a18994e42cd 100644 (file)
@@ -458,6 +458,12 @@ static inline int tftp(const int cmd, const struct hostent *host,
                                opcode = TFTP_ACK;
                                continue;
                        }
+                       /* in case the last ack disappeared into the ether */
+                       if ( tmp == (block_nr - 1) ) {
+                               --block_nr;
+                               opcode = TFTP_ACK;
+                               continue;
+                       }
                }
 
                if (cmd_put && (opcode == TFTP_ACK)) {
index 449b517639fd5f8de0692171bf470def463796d4..91af9153b3a2c3dc503daabaf7eca9337f3a23f4 100644 (file)
@@ -419,6 +419,9 @@ int main(int argc, char *argv[])
                                        (unsigned long) packet.xid, xid);
                                continue;
                        }
+                       /* Ignore packets that aren't for us */
+                       if (memcmp(client_config.arp,packet.chaddr,6))
+                               continue;
 
                        if ((message = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
                                DEBUG(LOG_ERR, "couldnt get option from packet -- ignoring");
diff --git a/busybox/scripts/.cvsignore b/busybox/scripts/.cvsignore
deleted file mode 100644 (file)
index 07fa550..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-mkdep
-split-include
diff --git a/busybox/scripts/config/.cvsignore b/busybox/scripts/config/.cvsignore
deleted file mode 100644 (file)
index e8bf7a7..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-conf
-mconf
-lkc_defs.h
-lex.zconf.c
-zconf.tab.h
-zconf.tab.c
-lex.backup
-zconf.output
index c0b5b9d35e0af41ef149a134879352519d0ddfd0..3c4669f8cca567e1050f10f1638e2b6313535c9d 100644 (file)
@@ -9,7 +9,11 @@ include $(top_builddir)/Rules.mak
 
 all: ncurses conf mconf
 
+ifeq ($(shell uname),SunOS)
+LIBS = -lcurses
+else
 LIBS = -lncurses
+endif
 ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h))
        HOSTNCURSES += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"
 else
@@ -32,14 +36,17 @@ endif
 endif
 endif
 
-CONF_SRC  =conf.c
-MCONF_SRC =mconf.c checklist.c menubox.c textbox.c yesno.c inputbox.c util.c msgbox.c
-SHARED_SRC=zconf.tab.c
-SHARED_DEPS:=$(srcdir)/lkc.h $(srcdir)/lkc_proto.h \
-  lkc_defs.h $(srcdir)/expr.h zconf.tab.h
-CONF_OBJS =$(patsubst %.c,%.o, $(CONF_SRC))
-MCONF_OBJS=$(patsubst %.c,%.o, $(MCONF_SRC))
-SHARED_OBJS=$(patsubst %.c,%.o, $(SHARED_SRC))
+CONF_SRC     = conf.c
+MCONF_SRC    = mconf.c
+LXD_SRC      = lxdialog/checklist.c lxdialog/menubox.c lxdialog/textbox.c \
+               lxdialog/yesno.c lxdialog/inputbox.c lxdialog/util.c \
+               lxdialog/msgbox.c
+SHARED_SRC   = zconf.tab.c
+SHARED_DEPS := $(srcdir)/lkc.h $(srcdir)/lkc_proto.h \
+               lkc_defs.h $(srcdir)/expr.h zconf.tab.h
+CONF_OBJS    = $(patsubst %.c,%.o, $(CONF_SRC))
+MCONF_OBJS   = $(patsubst %.c,%.o, $(MCONF_SRC) $(LXD_SRC))
+SHARED_OBJS  = $(patsubst %.c,%.o, $(SHARED_SRC))
 
 conf: $(CONF_OBJS) $(SHARED_OBJS)
        $(HOSTCC) $(NATIVE_LDFLAGS) $^ -o $@
diff --git a/busybox/scripts/config/checklist.c b/busybox/scripts/config/checklist.c
deleted file mode 100644 (file)
index 4dbd166..0000000
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- *  checklist.c -- implements the checklist box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *     Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
- *     Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-static int list_width, check_x, item_x, checkflag;
-
-/*
- * Print list item
- */
-static void
-print_item (WINDOW * win, const char *item, int status,
-           int choice, int selected)
-{
-    int i;
-
-    /* Clear 'residue' of last item */
-    wattrset (win, menubox_attr);
-    wmove (win, choice, 0);
-    for (i = 0; i < list_width; i++)
-       waddch (win, ' ');
-
-    wmove (win, choice, check_x);
-    wattrset (win, selected ? check_selected_attr : check_attr);
-    if (checkflag == FLAG_CHECK)
-       wprintw (win, "[%c]", status ? 'X' : ' ');
-    else
-       wprintw (win, "(%c)", status ? 'X' : ' ');
-
-    wattrset (win, selected ? tag_selected_attr : tag_attr);
-    mvwaddch(win, choice, item_x, item[0]);
-    wattrset (win, selected ? item_selected_attr : item_attr);
-    waddstr (win, (char *)item+1);
-    if (selected) {
-       wmove (win, choice, check_x+1);
-       wrefresh (win);
-    }
-}
-
-/*
- * Print the scroll indicators.
- */
-static void
-print_arrows (WINDOW * win, int choice, int item_no, int scroll,
-               int y, int x, int height)
-{
-    wmove(win, y, x);
-
-    if (scroll > 0) {
-       wattrset (win, uarrow_attr);
-       waddch (win, ACS_UARROW);
-       waddstr (win, "(-)");
-    }
-    else {
-       wattrset (win, menubox_attr);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-    }
-
-   y = y + height + 1;
-   wmove(win, y, x);
-
-   if ((height < item_no) && (scroll + choice < item_no - 1)) {
-       wattrset (win, darrow_attr);
-       waddch (win, ACS_DARROW);
-       waddstr (win, "(+)");
-    }
-    else {
-       wattrset (win, menubox_border_attr);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-   }
-}
-
-/*
- *  Display the termination buttons
- */
-static void
-print_buttons( WINDOW *dialog, int height, int width, int selected)
-{
-    int x = width / 2 - 11;
-    int y = height - 2;
-
-    print_button (dialog, "Select", y, x, selected == 0);
-    print_button (dialog, " Help ", y, x + 14, selected == 1);
-
-    wmove(dialog, y, x+1 + 14*selected);
-    wrefresh (dialog);
-}
-
-/*
- * Display a dialog box with a list of options that can be turned on or off
- * The `flag' parameter is used to select between radiolist and checklist.
- */
-int
-dialog_checklist (const char *title, const char *prompt, int height, int width,
-       int list_height, int item_no, struct dialog_list_item ** items,
-       int flag)
-
-{
-    int i, x, y, box_x, box_y;
-    int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
-    WINDOW *dialog, *list;
-
-    checkflag = flag;
-
-    /* Allocate space for storing item on/off status */
-    if ((status = malloc (sizeof (int) * item_no)) == NULL) {
-       endwin ();
-       fprintf (stderr,
-                "\nCan't allocate memory in dialog_checklist().\n");
-       exit (-1);
-    }
-
-    /* Initializes status */
-    for (i = 0; i < item_no; i++) {
-       status[i] = (items[i]->selected == 1); /* ON */
-       if ((!choice && status[i]) || items[i]->selected == 2) /* SELECTED */
-            choice = i + 1;
-    }
-    if (choice)
-           choice--;
-
-    max_choice = MIN (list_height, item_no);
-
-    /* center dialog box on screen */
-    x = (COLS - width) / 2;
-    y = (LINES - height) / 2;
-
-    draw_shadow (stdscr, y, x, height, width);
-
-    dialog = newwin (height, width, y, x);
-    keypad (dialog, TRUE);
-
-    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-    wattrset (dialog, border_attr);
-    mvwaddch (dialog, height-3, 0, ACS_LTEE);
-    for (i = 0; i < width - 2; i++)
-       waddch (dialog, ACS_HLINE);
-    wattrset (dialog, dialog_attr);
-    waddch (dialog, ACS_RTEE);
-
-    if (title != NULL && strlen(title) >= width-2 ) {
-       /* truncate long title -- mec */
-       char * title2 = malloc(width-2+1);
-       memcpy( title2, title, width-2 );
-       title2[width-2] = '\0';
-       title = title2;
-    }
-
-    if (title != NULL) {
-       wattrset (dialog, title_attr);
-       mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-       waddstr (dialog, (char *)title);
-       waddch (dialog, ' ');
-    }
-
-    wattrset (dialog, dialog_attr);
-    print_autowrap (dialog, prompt, width - 2, 1, 3);
-
-    list_width = width - 6;
-    box_y = height - list_height - 5;
-    box_x = (width - list_width) / 2 - 1;
-
-    /* create new window for the list */
-    list = subwin (dialog, list_height, list_width, y+box_y+1, x+box_x+1);
-
-    keypad (list, TRUE);
-
-    /* draw a box around the list items */
-    draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2,
-             menubox_border_attr, menubox_attr);
-
-    /* Find length of longest item in order to center checklist */
-    check_x = 0;
-    for (i = 0; i < item_no; i++)
-       check_x = MAX (check_x, + strlen (items[i]->name) + 4);
-
-    check_x = (list_width - check_x) / 2;
-    item_x = check_x + 4;
-
-    if (choice >= list_height) {
-       scroll = choice - list_height + 1;
-       choice -= scroll;
-    }
-
-    /* Print the list */
-    for (i = 0; i < max_choice; i++) {
-       print_item (list, items[scroll + i]->name,
-                   status[i+scroll], i, i == choice);
-    }
-
-    print_arrows(dialog, choice, item_no, scroll,
-                       box_y, box_x + check_x + 5, list_height);
-
-    print_buttons(dialog, height, width, 0);
-
-    wnoutrefresh (list);
-    wnoutrefresh (dialog);
-    doupdate ();
-
-    while (key != ESC) {
-       key = wgetch (dialog);
-
-       for (i = 0; i < max_choice; i++)
-            if (toupper(key) == toupper(items[scroll + i]->name[0]))
-                break;
-
-
-       if ( i < max_choice || key == KEY_UP || key == KEY_DOWN ||
-           key == '+' || key == '-' ) {
-           if (key == KEY_UP || key == '-') {
-               if (!choice) {
-                   if (!scroll)
-                       continue;
-                   /* Scroll list down */
-                   if (list_height > 1) {
-                       /* De-highlight current first item */
-                       print_item (list, items[scroll]->name,
-                                       status[scroll], 0, FALSE);
-                       scrollok (list, TRUE);
-                       wscrl (list, -1);
-                       scrollok (list, FALSE);
-                   }
-                   scroll--;
-                   print_item (list, items[scroll]->name,
-                               status[scroll], 0, TRUE);
-                   wnoutrefresh (list);
-
-                   print_arrows(dialog, choice, item_no, scroll,
-                               box_y, box_x + check_x + 5, list_height);
-
-                   wrefresh (dialog);
-
-                   continue;   /* wait for another key press */
-               } else
-                   i = choice - 1;
-           } else if (key == KEY_DOWN || key == '+') {
-               if (choice == max_choice - 1) {
-                   if (scroll + choice >= item_no - 1)
-                       continue;
-                   /* Scroll list up */
-                   if (list_height > 1) {
-                       /* De-highlight current last item before scrolling up */
-                       print_item (list, items[scroll + max_choice - 1]->name,
-                                   status[scroll + max_choice - 1],
-                                   max_choice - 1, FALSE);
-                       scrollok (list, TRUE);
-                       scroll (list);
-                       scrollok (list, FALSE);
-                   }
-                   scroll++;
-                   print_item (list, items[scroll + max_choice - 1]->name,
-                               status[scroll + max_choice - 1],
-                               max_choice - 1, TRUE);
-                   wnoutrefresh (list);
-
-                   print_arrows(dialog, choice, item_no, scroll,
-                               box_y, box_x + check_x + 5, list_height);
-
-                   wrefresh (dialog);
-
-                   continue;   /* wait for another key press */
-               } else
-                   i = choice + 1;
-           }
-           if (i != choice) {
-               /* De-highlight current item */
-               print_item (list, items[scroll + choice]->name,
-                           status[scroll + choice], choice, FALSE);
-               /* Highlight new item */
-               choice = i;
-               print_item (list, items[scroll + choice]->name,
-                           status[scroll + choice], choice, TRUE);
-               wnoutrefresh (list);
-               wrefresh (dialog);
-           }
-           continue;           /* wait for another key press */
-       }
-       switch (key) {
-       case 'H':
-       case 'h':
-       case '?':
-           for (i = 0; i < item_no; i++)
-               items[i]->selected = 0;
-           items[scroll + choice]->selected = 1;
-           delwin (dialog);
-           free (status);
-           return 1;
-       case TAB:
-       case KEY_LEFT:
-       case KEY_RIGHT:
-           button = ((key == KEY_LEFT ? --button : ++button) < 0)
-                       ? 1 : (button > 1 ? 0 : button);
-
-           print_buttons(dialog, height, width, button);
-           wrefresh (dialog);
-           break;
-       case 'S':
-       case 's':
-       case ' ':
-       case '\n':
-           if (!button) {
-               if (flag == FLAG_CHECK) {
-                   status[scroll + choice] = !status[scroll + choice];
-                   wmove (list, choice, check_x);
-                   wattrset (list, check_selected_attr);
-                   wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' ');
-               } else {
-                   if (!status[scroll + choice]) {
-                       for (i = 0; i < item_no; i++)
-                           status[i] = 0;
-                       status[scroll + choice] = 1;
-                       for (i = 0; i < max_choice; i++)
-                           print_item (list, items[scroll + i]->name,
-                                       status[scroll + i], i, i == choice);
-                   }
-               }
-               wnoutrefresh (list);
-               wrefresh (dialog);
-
-               for (i = 0; i < item_no; i++) {
-                       items[i]->selected = status[i];
-               }
-            } else {
-                   for (i = 0; i < item_no; i++)
-                           items[i]->selected = 0;
-                   items[scroll + choice]->selected = 1;
-           }
-           delwin (dialog);
-           free (status);
-           return button;
-       case 'X':
-       case 'x':
-           key = ESC;
-       case ESC:
-           break;
-       }
-
-       /* Now, update everything... */
-       doupdate ();
-    }
-
-
-    delwin (dialog);
-    free (status);
-    return -1;                 /* ESC pressed */
-}
diff --git a/busybox/scripts/config/colors.h b/busybox/scripts/config/colors.h
deleted file mode 100644 (file)
index d34dd37..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- *  colors.h -- color attribute definitions
- *
- *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-/*
- *   Default color definitions
- *
- *   *_FG = foreground
- *   *_BG = background
- *   *_HL = highlight?
- */
-#define SCREEN_FG                    COLOR_CYAN
-#define SCREEN_BG                    COLOR_BLUE
-#define SCREEN_HL                    TRUE
-
-#define SHADOW_FG                    COLOR_BLACK
-#define SHADOW_BG                    COLOR_BLACK
-#define SHADOW_HL                    TRUE
-
-#define DIALOG_FG                    COLOR_BLACK
-#define DIALOG_BG                    COLOR_WHITE
-#define DIALOG_HL                    FALSE
-
-#define TITLE_FG                     COLOR_YELLOW
-#define TITLE_BG                     COLOR_WHITE
-#define TITLE_HL                     TRUE
-
-#define BORDER_FG                    COLOR_WHITE
-#define BORDER_BG                    COLOR_WHITE
-#define BORDER_HL                    TRUE
-
-#define BUTTON_ACTIVE_FG             COLOR_WHITE
-#define BUTTON_ACTIVE_BG             COLOR_BLUE
-#define BUTTON_ACTIVE_HL             TRUE
-
-#define BUTTON_INACTIVE_FG           COLOR_BLACK
-#define BUTTON_INACTIVE_BG           COLOR_WHITE
-#define BUTTON_INACTIVE_HL           FALSE
-
-#define BUTTON_KEY_ACTIVE_FG         COLOR_WHITE
-#define BUTTON_KEY_ACTIVE_BG         COLOR_BLUE
-#define BUTTON_KEY_ACTIVE_HL         TRUE
-
-#define BUTTON_KEY_INACTIVE_FG       COLOR_RED
-#define BUTTON_KEY_INACTIVE_BG       COLOR_WHITE
-#define BUTTON_KEY_INACTIVE_HL       FALSE
-
-#define BUTTON_LABEL_ACTIVE_FG       COLOR_YELLOW
-#define BUTTON_LABEL_ACTIVE_BG       COLOR_BLUE
-#define BUTTON_LABEL_ACTIVE_HL       TRUE
-
-#define BUTTON_LABEL_INACTIVE_FG     COLOR_BLACK
-#define BUTTON_LABEL_INACTIVE_BG     COLOR_WHITE
-#define BUTTON_LABEL_INACTIVE_HL     TRUE
-
-#define INPUTBOX_FG                  COLOR_BLACK
-#define INPUTBOX_BG                  COLOR_WHITE
-#define INPUTBOX_HL                  FALSE
-
-#define INPUTBOX_BORDER_FG           COLOR_BLACK
-#define INPUTBOX_BORDER_BG           COLOR_WHITE
-#define INPUTBOX_BORDER_HL           FALSE
-
-#define SEARCHBOX_FG                 COLOR_BLACK
-#define SEARCHBOX_BG                 COLOR_WHITE
-#define SEARCHBOX_HL                 FALSE
-
-#define SEARCHBOX_TITLE_FG           COLOR_YELLOW
-#define SEARCHBOX_TITLE_BG           COLOR_WHITE
-#define SEARCHBOX_TITLE_HL           TRUE
-
-#define SEARCHBOX_BORDER_FG          COLOR_WHITE
-#define SEARCHBOX_BORDER_BG          COLOR_WHITE
-#define SEARCHBOX_BORDER_HL          TRUE
-
-#define POSITION_INDICATOR_FG        COLOR_YELLOW
-#define POSITION_INDICATOR_BG        COLOR_WHITE
-#define POSITION_INDICATOR_HL        TRUE
-
-#define MENUBOX_FG                   COLOR_BLACK
-#define MENUBOX_BG                   COLOR_WHITE
-#define MENUBOX_HL                   FALSE
-
-#define MENUBOX_BORDER_FG            COLOR_WHITE
-#define MENUBOX_BORDER_BG            COLOR_WHITE
-#define MENUBOX_BORDER_HL            TRUE
-
-#define ITEM_FG                      COLOR_BLACK
-#define ITEM_BG                      COLOR_WHITE
-#define ITEM_HL                      FALSE
-
-#define ITEM_SELECTED_FG             COLOR_WHITE
-#define ITEM_SELECTED_BG             COLOR_BLUE
-#define ITEM_SELECTED_HL             TRUE
-
-#define TAG_FG                       COLOR_YELLOW
-#define TAG_BG                       COLOR_WHITE
-#define TAG_HL                       TRUE
-
-#define TAG_SELECTED_FG              COLOR_YELLOW
-#define TAG_SELECTED_BG              COLOR_BLUE
-#define TAG_SELECTED_HL              TRUE
-
-#define TAG_KEY_FG                   COLOR_YELLOW
-#define TAG_KEY_BG                   COLOR_WHITE
-#define TAG_KEY_HL                   TRUE
-
-#define TAG_KEY_SELECTED_FG          COLOR_YELLOW
-#define TAG_KEY_SELECTED_BG          COLOR_BLUE
-#define TAG_KEY_SELECTED_HL          TRUE
-
-#define CHECK_FG                     COLOR_BLACK
-#define CHECK_BG                     COLOR_WHITE
-#define CHECK_HL                     FALSE
-
-#define CHECK_SELECTED_FG            COLOR_WHITE
-#define CHECK_SELECTED_BG            COLOR_BLUE
-#define CHECK_SELECTED_HL            TRUE
-
-#define UARROW_FG                    COLOR_GREEN
-#define UARROW_BG                    COLOR_WHITE
-#define UARROW_HL                    TRUE
-
-#define DARROW_FG                    COLOR_GREEN
-#define DARROW_BG                    COLOR_WHITE
-#define DARROW_HL                    TRUE
-
-/* End of default color definitions */
-
-#define C_ATTR(x,y)                  ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
-#define COLOR_NAME_LEN               10
-#define COLOR_COUNT                  8
-
-/*
- * Global variables
- */
-
-typedef struct {
-    char name[COLOR_NAME_LEN];
-    int value;
-} color_names_st;
-
-extern color_names_st color_names[];
-extern int color_table[][3];
index 3b0c1c1b53378215f5378fda666cc76e24934191..78c1af5967f12d5586f1f57d4bcf33a19f093a30 100644 (file)
@@ -31,14 +31,14 @@ char *defconfig_file;
 static int indent = 1;
 static int valid_stdin = 1;
 static int conf_cnt;
-static char line[128];
+static signed char line[128];
 static struct menu *rootEntry;
 
 static char nohelp_text[] = "Sorry, no help available for this option yet.\n";
 
-static void strip(char *str)
+static void strip(signed char *str)
 {
-       char *p = str;
+       signed char *p = str;
        int l;
 
        while ((isspace(*p)))
index fd3a345e268ab36532c8f725fd21d350ae3162fd..7b9000e8492d052236ea75fb60ae0676f3c5348f 100644 (file)
@@ -23,10 +23,10 @@ const char *conf_confnames[] = {
        NULL,
 };
 
-static char *conf_expand_value(const char *in)
+static char *conf_expand_value(const signed char *in)
 {
        struct symbol *sym;
-       const char *src;
+       const signed char *src;
        static char res_value[SYMBOL_MAXLENGTH];
        char *dst, name[SYMBOL_MAXLENGTH];
 
@@ -287,7 +287,7 @@ int conf_write(const char *name)
        } else
                basename = conf_def_filename;
 
-       sprintf(newname, "%s.tmpconfig.%d", dirname, getpid());
+       sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid());
        out = fopen(newname, "w");
        if (!out)
                return 1;
diff --git a/busybox/scripts/config/dialog.h b/busybox/scripts/config/dialog.h
deleted file mode 100644 (file)
index 6486cc8..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-
-/*
- *  dialog.h -- common declarations for all dialog modules
- *
- *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef CURSES_LOC
-#include CURSES_LOC
-
-/*
- * Colors in ncurses 1.9.9e do not work properly since foreground and
- * background colors are OR'd rather than separately masked.  This version
- * of dialog was hacked to work with ncurses 1.9.9e, making it incompatible
- * with standard curses.  The simplest fix (to make this work with standard
- * curses) uses the wbkgdset() function, not used in the original hack.
- * Turn it off if we're building with 1.9.9e, since it just confuses things.
- */
-#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE)
-#define OLD_NCURSES 1
-#undef  wbkgdset
-#define wbkgdset(w,p) /*nothing*/
-#else
-#define OLD_NCURSES 0
-#endif
-
-#define TR(params) _tracef params
-
-#define ESC 27
-#define TAB 9
-#define MAX_LEN 2048
-#define BUF_SIZE (10*1024)
-#define MIN(x,y) (x < y ? x : y)
-#define MAX(x,y) (x > y ? x : y)
-
-
-#ifndef ACS_ULCORNER
-#define ACS_ULCORNER '+'
-#endif
-#ifndef ACS_LLCORNER
-#define ACS_LLCORNER '+'
-#endif
-#ifndef ACS_URCORNER
-#define ACS_URCORNER '+'
-#endif
-#ifndef ACS_LRCORNER
-#define ACS_LRCORNER '+'
-#endif
-#ifndef ACS_HLINE
-#define ACS_HLINE '-'
-#endif
-#ifndef ACS_VLINE
-#define ACS_VLINE '|'
-#endif
-#ifndef ACS_LTEE
-#define ACS_LTEE '+'
-#endif
-#ifndef ACS_RTEE
-#define ACS_RTEE '+'
-#endif
-#ifndef ACS_UARROW
-#define ACS_UARROW '^'
-#endif
-#ifndef ACS_DARROW
-#define ACS_DARROW 'v'
-#endif
-
-/*
- * Attribute names
- */
-#define screen_attr                   attributes[0]
-#define shadow_attr                   attributes[1]
-#define dialog_attr                   attributes[2]
-#define title_attr                    attributes[3]
-#define border_attr                   attributes[4]
-#define button_active_attr            attributes[5]
-#define button_inactive_attr          attributes[6]
-#define button_key_active_attr        attributes[7]
-#define button_key_inactive_attr      attributes[8]
-#define button_label_active_attr      attributes[9]
-#define button_label_inactive_attr    attributes[10]
-#define inputbox_attr                 attributes[11]
-#define inputbox_border_attr          attributes[12]
-#define searchbox_attr                attributes[13]
-#define searchbox_title_attr          attributes[14]
-#define searchbox_border_attr         attributes[15]
-#define position_indicator_attr       attributes[16]
-#define menubox_attr                  attributes[17]
-#define menubox_border_attr           attributes[18]
-#define item_attr                     attributes[19]
-#define item_selected_attr            attributes[20]
-#define tag_attr                      attributes[21]
-#define tag_selected_attr             attributes[22]
-#define tag_key_attr                  attributes[23]
-#define tag_key_selected_attr         attributes[24]
-#define check_attr                    attributes[25]
-#define check_selected_attr           attributes[26]
-#define uarrow_attr                   attributes[27]
-#define darrow_attr                   attributes[28]
-
-/* number of attributes */
-#define ATTRIBUTE_COUNT               29
-
-/*
- * Global variables
- */
-extern bool use_colors;
-
-extern chtype attributes[];
-#endif
-
-extern char *backtitle;
-
-struct dialog_list_item {
-       char *name;
-       int namelen;
-       char *tag;
-       int selected; /* Set to 1 by dialog_*() function. */
-};
-
-/*
- * Function prototypes
- */
-
-void init_dialog (void);
-void end_dialog (void);
-void dialog_clear (void);
-#ifdef CURSES_LOC
-void attr_clear (WINDOW * win, int height, int width, chtype attr);
-void color_setup (void);
-void print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x);
-void print_button (WINDOW * win, const char *label, int y, int x, int selected);
-void draw_box (WINDOW * win, int y, int x, int height, int width, chtype box,
-               chtype border);
-void draw_shadow (WINDOW * win, int y, int x, int height, int width);
-#endif
-
-int first_alpha (const char *string, const char *exempt);
-int dialog_yesno (const char *title, const char *prompt, int height, int width);
-int dialog_msgbox (const char *title, const char *prompt, int height,
-               int width, int pause);
-int dialog_textbox (const char *title, const char *file, int height, int width);
-int dialog_menu (const char *title, const char *prompt, int height, int width,
-               int menu_height, const char *choice, int item_no,
-               struct dialog_list_item ** items);
-int dialog_checklist (const char *title, const char *prompt, int height,
-               int width, int list_height, int item_no,
-               struct dialog_list_item ** items, int flag);
-extern unsigned char dialog_input_result[];
-int dialog_inputbox (const char *title, const char *prompt, int height,
-               int width, const char *init);
-
-struct dialog_list_item *first_sel_item(int item_no,
-               struct dialog_list_item ** items);
-
-/*
- * This is the base for fictitious keys, which activate
- * the buttons.
- *
- * Mouse-generated keys are the following:
- *   -- the first 32 are used as numbers, in addition to '0'-'9'
- *   -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o')
- *   -- uppercase chars are used to invoke the button (M_EVENT + 'O')
- */
-#ifdef CURSES_LOC
-#define M_EVENT (KEY_MAX+1)
-#endif
-
-
-/*
- * The `flag' parameter in checklist is used to select between
- * radiolist and checklist
- */
-#define FLAG_CHECK 1
-#define FLAG_RADIO 0
index 10f45232b4c716df8a301fd6c75f0f547b3018bc..30e4f9d69c2fbc2e080022f6fe5db49985207d9d 100644 (file)
@@ -1087,3 +1087,13 @@ void expr_fprint(struct expr *e, FILE *out)
 {
        expr_print(e, expr_print_file_helper, out, E_NONE);
 }
+
+static void expr_print_gstr_helper(void *data, const char *str)
+{
+       str_append((struct gstr*)data, str);
+}
+
+void expr_gstr_print(struct expr *e, struct gstr *gs)
+{
+       expr_print(e, expr_print_gstr_helper, gs, E_NONE);
+}
index cac51f6a86e843caede25601a350f8d619260605..7d39ff43e6e1facd64d6267cd443919b3d1c7381 100644 (file)
@@ -174,6 +174,8 @@ void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, s
 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
 
 void expr_fprint(struct expr *e, FILE *out);
+struct gstr; /* forward */
+void expr_gstr_print(struct expr *e, struct gstr *gs);
 
 static inline int expr_is_yes(struct expr *e)
 {
diff --git a/busybox/scripts/config/inputbox.c b/busybox/scripts/config/inputbox.c
deleted file mode 100644 (file)
index fa7bebc..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- *  inputbox.c -- implements the input box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-unsigned char dialog_input_result[MAX_LEN + 1];
-
-/*
- *  Print the termination buttons
- */
-static void
-print_buttons(WINDOW *dialog, int height, int width, int selected)
-{
-    int x = width / 2 - 11;
-    int y = height - 2;
-
-    print_button (dialog, "  Ok  ", y, x, selected==0);
-    print_button (dialog, " Help ", y, x + 14, selected==1);
-
-    wmove(dialog, y, x+1+14*selected);
-    wrefresh(dialog);
-}
-
-/*
- * Display a dialog box for inputing a string
- */
-int
-dialog_inputbox (const char *title, const char *prompt, int height, int width,
-                const char *init)
-{
-    int i, x, y, box_y, box_x, box_width;
-    int input_x = 0, scroll = 0, key = 0, button = -1;
-    unsigned char *instr = dialog_input_result;
-    WINDOW *dialog;
-
-    /* center dialog box on screen */
-    x = (COLS - width) / 2;
-    y = (LINES - height) / 2;
-
-
-    draw_shadow (stdscr, y, x, height, width);
-
-    dialog = newwin (height, width, y, x);
-    keypad (dialog, TRUE);
-
-    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-    wattrset (dialog, border_attr);
-    mvwaddch (dialog, height-3, 0, ACS_LTEE);
-    for (i = 0; i < width - 2; i++)
-       waddch (dialog, ACS_HLINE);
-    wattrset (dialog, dialog_attr);
-    waddch (dialog, ACS_RTEE);
-
-    if (title != NULL && strlen(title) >= width-2 ) {
-       /* truncate long title -- mec */
-       char * title2 = malloc(width-2+1);
-       memcpy( title2, title, width-2 );
-       title2[width-2] = '\0';
-       title = title2;
-    }
-
-    if (title != NULL) {
-       wattrset (dialog, title_attr);
-       mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-       waddstr (dialog, (char *)title);
-       waddch (dialog, ' ');
-    }
-
-    wattrset (dialog, dialog_attr);
-    print_autowrap (dialog, prompt, width - 2, 1, 3);
-
-    /* Draw the input field box */
-    box_width = width - 6;
-    getyx (dialog, y, x);
-    box_y = y + 2;
-    box_x = (width - box_width) / 2;
-    draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2,
-             border_attr, dialog_attr);
-
-    print_buttons(dialog, height, width, 0);
-
-    /* Set up the initial value */
-    wmove (dialog, box_y, box_x);
-    wattrset (dialog, inputbox_attr);
-
-    if (!init)
-       instr[0] = '\0';
-    else
-       strcpy (instr, init);
-
-    input_x = strlen (instr);
-
-    if (input_x >= box_width) {
-       scroll = input_x - box_width + 1;
-       input_x = box_width - 1;
-       for (i = 0; i < box_width - 1; i++)
-           waddch (dialog, instr[scroll + i]);
-    } else
-       waddstr (dialog, instr);
-
-    wmove (dialog, box_y, box_x + input_x);
-
-    wrefresh (dialog);
-
-    while (key != ESC) {
-       key = wgetch (dialog);
-
-       if (button == -1) {     /* Input box selected */
-           switch (key) {
-           case TAB:
-           case KEY_UP:
-           case KEY_DOWN:
-               break;
-           case KEY_LEFT:
-               continue;
-           case KEY_RIGHT:
-               continue;
-           case KEY_BACKSPACE:
-           case 127:
-               if (input_x || scroll) {
-                   wattrset (dialog, inputbox_attr);
-                   if (!input_x) {
-                       scroll = scroll < box_width - 1 ?
-                           0 : scroll - (box_width - 1);
-                       wmove (dialog, box_y, box_x);
-                       for (i = 0; i < box_width; i++)
-                           waddch (dialog, instr[scroll + input_x + i] ?
-                                   instr[scroll + input_x + i] : ' ');
-                       input_x = strlen (instr) - scroll;
-                   } else
-                       input_x--;
-                   instr[scroll + input_x] = '\0';
-                   mvwaddch (dialog, box_y, input_x + box_x, ' ');
-                   wmove (dialog, box_y, input_x + box_x);
-                   wrefresh (dialog);
-               }
-               continue;
-           default:
-               if (key < 0x100 && isprint (key)) {
-                   if (scroll + input_x < MAX_LEN) {
-                       wattrset (dialog, inputbox_attr);
-                       instr[scroll + input_x] = key;
-                       instr[scroll + input_x + 1] = '\0';
-                       if (input_x == box_width - 1) {
-                           scroll++;
-                           wmove (dialog, box_y, box_x);
-                           for (i = 0; i < box_width - 1; i++)
-                               waddch (dialog, instr[scroll + i]);
-                       } else {
-                           wmove (dialog, box_y, input_x++ + box_x);
-                           waddch (dialog, key);
-                       }
-                       wrefresh (dialog);
-                   } else
-                       flash ();       /* Alarm user about overflow */
-                   continue;
-               }
-           }
-       }
-       switch (key) {
-       case 'O':
-       case 'o':
-           delwin (dialog);
-           return 0;
-       case 'H':
-       case 'h':
-           delwin (dialog);
-           return 1;
-       case KEY_UP:
-       case KEY_LEFT:
-           switch (button) {
-           case -1:
-               button = 1;     /* Indicates "Cancel" button is selected */
-               print_buttons(dialog, height, width, 1);
-               break;
-           case 0:
-               button = -1;    /* Indicates input box is selected */
-               print_buttons(dialog, height, width, 0);
-               wmove (dialog, box_y, box_x + input_x);
-               wrefresh (dialog);
-               break;
-           case 1:
-               button = 0;     /* Indicates "OK" button is selected */
-               print_buttons(dialog, height, width, 0);
-               break;
-           }
-           break;
-       case TAB:
-       case KEY_DOWN:
-       case KEY_RIGHT:
-           switch (button) {
-           case -1:
-               button = 0;     /* Indicates "OK" button is selected */
-               print_buttons(dialog, height, width, 0);
-               break;
-           case 0:
-               button = 1;     /* Indicates "Cancel" button is selected */
-               print_buttons(dialog, height, width, 1);
-               break;
-           case 1:
-               button = -1;    /* Indicates input box is selected */
-               print_buttons(dialog, height, width, 0);
-               wmove (dialog, box_y, box_x + input_x);
-               wrefresh (dialog);
-               break;
-           }
-           break;
-       case ' ':
-       case '\n':
-           delwin (dialog);
-           return (button == -1 ? 0 : button);
-       case 'X':
-       case 'x':
-           key = ESC;
-       case ESC:
-           break;
-       }
-    }
-
-    delwin (dialog);
-    return -1;                 /* ESC pressed */
-}
index dd040f7a86276d35e5fe225086370dc0a9546636..b8a67fc9d6476d4b4b812f4226f7376f4c08584d 100644 (file)
@@ -56,11 +56,21 @@ void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
 void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
 void menu_finalize(struct menu *parent);
 void menu_set_type(int type);
+
+/* util.c */
 struct file *file_lookup(const char *name);
 int file_write_dep(const char *name);
 
-extern struct menu *current_entry;
-extern struct menu *current_menu;
+struct gstr {
+       size_t len;
+       char  *s;
+};
+struct gstr str_new(void);
+struct gstr str_assign(const char *s);
+void str_free(struct gstr *gs);
+void str_append(struct gstr *gs, const char *s);
+void str_printf(struct gstr *gs, const char *fmt, ...);
+const char *str_get(struct gstr *gs);
 
 /* symbol.c */
 void sym_init(void);
index 97c79178ee3d9e421ae85432b3c69b0c967495df..6dc6d0c48e7ac8e617e1010ac97e572db9328423 100644 (file)
@@ -18,6 +18,7 @@ P(sym_change_count,int,);
 
 P(sym_lookup,struct symbol *,(const char *name, int isconst));
 P(sym_find,struct symbol *,(const char *name));
+P(sym_re_search,struct symbol **,(const char *pattern));
 P(sym_type_name,const char *,(enum symbol_type type));
 P(sym_calc_value,void,(struct symbol *sym));
 P(sym_get_type,enum symbol_type,(struct symbol *sym));
diff --git a/busybox/scripts/config/lxdialog/BIG.FAT.WARNING b/busybox/scripts/config/lxdialog/BIG.FAT.WARNING
new file mode 100644 (file)
index 0000000..a8999d8
--- /dev/null
@@ -0,0 +1,4 @@
+This is NOT the official version of dialog.  This version has been
+significantly modified from the original.  It is for use by the Linux
+kernel configuration script.  Please do not bother Savio Lam with 
+questions about this program.
diff --git a/busybox/scripts/config/lxdialog/checklist.c b/busybox/scripts/config/lxdialog/checklist.c
new file mode 100644 (file)
index 0000000..71de4a1
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+ *  checklist.c -- implements the checklist box
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *     Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
+ *     Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+static int list_width, check_x, item_x, checkflag;
+
+/*
+ * Print list item
+ */
+static void
+print_item (WINDOW * win, const char *item, int status,
+           int choice, int selected)
+{
+    int i;
+
+    /* Clear 'residue' of last item */
+    wattrset (win, menubox_attr);
+    wmove (win, choice, 0);
+    for (i = 0; i < list_width; i++)
+       waddch (win, ' ');
+
+    wmove (win, choice, check_x);
+    wattrset (win, selected ? check_selected_attr : check_attr);
+    if (checkflag == FLAG_CHECK)
+       wprintw (win, "[%c]", status ? 'X' : ' ');
+    else
+       wprintw (win, "(%c)", status ? 'X' : ' ');
+
+    wattrset (win, selected ? tag_selected_attr : tag_attr);
+    mvwaddch(win, choice, item_x, item[0]);
+    wattrset (win, selected ? item_selected_attr : item_attr);
+    waddstr (win, (char *)item+1);
+    if (selected) {
+       wmove (win, choice, check_x+1);
+       wrefresh (win);
+    }
+}
+
+/*
+ * Print the scroll indicators.
+ */
+static void
+print_arrows (WINDOW * win, int choice, int item_no, int scroll,
+               int y, int x, int height)
+{
+    wmove(win, y, x);
+
+    if (scroll > 0) {
+       wattrset (win, uarrow_attr);
+       waddch (win, ACS_UARROW);
+       waddstr (win, "(-)");
+    }
+    else {
+       wattrset (win, menubox_attr);
+       waddch (win, ACS_HLINE);
+       waddch (win, ACS_HLINE);
+       waddch (win, ACS_HLINE);
+       waddch (win, ACS_HLINE);
+    }
+
+   y = y + height + 1;
+   wmove(win, y, x);
+
+   if ((height < item_no) && (scroll + choice < item_no - 1)) {
+       wattrset (win, darrow_attr);
+       waddch (win, ACS_DARROW);
+       waddstr (win, "(+)");
+    }
+    else {
+       wattrset (win, menubox_border_attr);
+       waddch (win, ACS_HLINE);
+       waddch (win, ACS_HLINE);
+       waddch (win, ACS_HLINE);
+       waddch (win, ACS_HLINE);
+   }
+}
+
+/*
+ *  Display the termination buttons
+ */
+static void
+print_buttons( WINDOW *dialog, int height, int width, int selected)
+{
+    int x = width / 2 - 11;
+    int y = height - 2;
+
+    print_button (dialog, "Select", y, x, selected == 0);
+    print_button (dialog, " Help ", y, x + 14, selected == 1);
+
+    wmove(dialog, y, x+1 + 14*selected);
+    wrefresh (dialog);
+}
+
+/*
+ * Display a dialog box with a list of options that can be turned on or off
+ * The `flag' parameter is used to select between radiolist and checklist.
+ */
+int
+dialog_checklist (const char *title, const char *prompt, int height, int width,
+       int list_height, int item_no, struct dialog_list_item ** items,
+       int flag)
+       
+{
+    int i, x, y, box_x, box_y;
+    int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
+    WINDOW *dialog, *list;
+
+    checkflag = flag;
+
+    /* Allocate space for storing item on/off status */
+    if ((status = malloc (sizeof (int) * item_no)) == NULL) {
+       endwin ();
+       fprintf (stderr,
+                "\nCan't allocate memory in dialog_checklist().\n");
+       exit (-1);
+    }
+
+    /* Initializes status */
+    for (i = 0; i < item_no; i++) {
+       status[i] = (items[i]->selected == 1); /* ON */
+       if ((!choice && status[i]) || items[i]->selected == 2) /* SELECTED */
+            choice = i + 1;
+    }
+    if (choice)
+           choice--;
+
+    max_choice = MIN (list_height, item_no);
+
+    /* center dialog box on screen */
+    x = (COLS - width) / 2;
+    y = (LINES - height) / 2;
+
+    draw_shadow (stdscr, y, x, height, width);
+
+    dialog = newwin (height, width, y, x);
+    keypad (dialog, TRUE);
+
+    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
+    wattrset (dialog, border_attr);
+    mvwaddch (dialog, height-3, 0, ACS_LTEE);
+    for (i = 0; i < width - 2; i++)
+       waddch (dialog, ACS_HLINE);
+    wattrset (dialog, dialog_attr);
+    waddch (dialog, ACS_RTEE);
+
+    if (title != NULL && strlen(title) >= width-2 ) {
+       /* truncate long title -- mec */
+       char * title2 = malloc(width-2+1);
+       memcpy( title2, title, width-2 );
+       title2[width-2] = '\0';
+       title = title2;
+    }
+
+    if (title != NULL) {
+       wattrset (dialog, title_attr);
+       mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
+       waddstr (dialog, (char *)title);
+       waddch (dialog, ' ');
+    }
+
+    wattrset (dialog, dialog_attr);
+    print_autowrap (dialog, prompt, width - 2, 1, 3);
+
+    list_width = width - 6;
+    box_y = height - list_height - 5;
+    box_x = (width - list_width) / 2 - 1;
+
+    /* create new window for the list */
+    list = subwin (dialog, list_height, list_width, y+box_y+1, x+box_x+1);
+
+    keypad (list, TRUE);
+
+    /* draw a box around the list items */
+    draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2,
+             menubox_border_attr, menubox_attr);
+
+    /* Find length of longest item in order to center checklist */
+    check_x = 0;
+    for (i = 0; i < item_no; i++) 
+       check_x = MAX (check_x, + strlen (items[i]->name) + 4);
+
+    check_x = (list_width - check_x) / 2;
+    item_x = check_x + 4;
+
+    if (choice >= list_height) {
+       scroll = choice - list_height + 1;
+       choice -= scroll;
+    }
+
+    /* Print the list */
+    for (i = 0; i < max_choice; i++) {
+       print_item (list, items[scroll + i]->name,
+                   status[i+scroll], i, i == choice);
+    }
+
+    print_arrows(dialog, choice, item_no, scroll,
+                       box_y, box_x + check_x + 5, list_height);
+
+    print_buttons(dialog, height, width, 0);
+
+    wnoutrefresh (list);
+    wnoutrefresh (dialog);
+    doupdate ();
+
+    while (key != ESC) {
+       key = wgetch (dialog);
+
+       for (i = 0; i < max_choice; i++)
+            if (toupper(key) == toupper(items[scroll + i]->name[0]))
+                break;
+
+
+       if ( i < max_choice || key == KEY_UP || key == KEY_DOWN || 
+           key == '+' || key == '-' ) {
+           if (key == KEY_UP || key == '-') {
+               if (!choice) {
+                   if (!scroll)
+                       continue;
+                   /* Scroll list down */
+                   if (list_height > 1) {
+                       /* De-highlight current first item */
+                       print_item (list, items[scroll]->name,
+                                       status[scroll], 0, FALSE);
+                       scrollok (list, TRUE);
+                       wscrl (list, -1);
+                       scrollok (list, FALSE);
+                   }
+                   scroll--;
+                   print_item (list, items[scroll]->name,
+                               status[scroll], 0, TRUE);
+                   wnoutrefresh (list);
+
+                   print_arrows(dialog, choice, item_no, scroll,
+                               box_y, box_x + check_x + 5, list_height);
+
+                   wrefresh (dialog);
+
+                   continue;   /* wait for another key press */
+               } else
+                   i = choice - 1;
+           } else if (key == KEY_DOWN || key == '+') {
+               if (choice == max_choice - 1) {
+                   if (scroll + choice >= item_no - 1)
+                       continue;
+                   /* Scroll list up */
+                   if (list_height > 1) {
+                       /* De-highlight current last item before scrolling up */
+                       print_item (list, items[scroll + max_choice - 1]->name,
+                                   status[scroll + max_choice - 1],
+                                   max_choice - 1, FALSE);
+                       scrollok (list, TRUE);
+                       scroll (list);
+                       scrollok (list, FALSE);
+                   }
+                   scroll++;
+                   print_item (list, items[scroll + max_choice - 1]->name,
+                               status[scroll + max_choice - 1],
+                               max_choice - 1, TRUE);
+                   wnoutrefresh (list);
+
+                   print_arrows(dialog, choice, item_no, scroll,
+                               box_y, box_x + check_x + 5, list_height);
+
+                   wrefresh (dialog);
+
+                   continue;   /* wait for another key press */
+               } else
+                   i = choice + 1;
+           }
+           if (i != choice) {
+               /* De-highlight current item */
+               print_item (list, items[scroll + choice]->name,
+                           status[scroll + choice], choice, FALSE);
+               /* Highlight new item */
+               choice = i;
+               print_item (list, items[scroll + choice]->name,
+                           status[scroll + choice], choice, TRUE);
+               wnoutrefresh (list);
+               wrefresh (dialog);
+           }
+           continue;           /* wait for another key press */
+       }
+       switch (key) {
+       case 'H':
+       case 'h':
+       case '?':
+           for (i = 0; i < item_no; i++)
+               items[i]->selected = 0;
+           items[scroll + choice]->selected = 1;
+           delwin (dialog);
+           free (status);
+           return 1;
+       case TAB:
+       case KEY_LEFT:
+       case KEY_RIGHT:
+           button = ((key == KEY_LEFT ? --button : ++button) < 0)
+                       ? 1 : (button > 1 ? 0 : button);
+
+           print_buttons(dialog, height, width, button);
+           wrefresh (dialog);
+           break;
+       case 'S':
+       case 's':
+       case ' ':
+       case '\n':
+           if (!button) {
+               if (flag == FLAG_CHECK) {
+                   status[scroll + choice] = !status[scroll + choice];
+                   wmove (list, choice, check_x);
+                   wattrset (list, check_selected_attr);
+                   wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' ');
+               } else {
+                   if (!status[scroll + choice]) {
+                       for (i = 0; i < item_no; i++)
+                           status[i] = 0;
+                       status[scroll + choice] = 1;
+                       for (i = 0; i < max_choice; i++)
+                           print_item (list, items[scroll + i]->name,
+                                       status[scroll + i], i, i == choice);
+                   }
+               }
+               wnoutrefresh (list);
+               wrefresh (dialog);
+            
+               for (i = 0; i < item_no; i++) {
+                       items[i]->selected = status[i];
+               }
+            } else {
+                   for (i = 0; i < item_no; i++)
+                           items[i]->selected = 0;
+                   items[scroll + choice]->selected = 1;
+           }
+           delwin (dialog);
+           free (status);
+           return button;
+       case 'X':
+       case 'x':
+           key = ESC;
+       case ESC:
+           break;
+       }
+
+       /* Now, update everything... */
+       doupdate ();
+    }
+    
+
+    delwin (dialog);
+    free (status);
+    return -1;                 /* ESC pressed */
+}
diff --git a/busybox/scripts/config/lxdialog/colors.h b/busybox/scripts/config/lxdialog/colors.h
new file mode 100644 (file)
index 0000000..d34dd37
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ *  colors.h -- color attribute definitions
+ *
+ *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ *   Default color definitions
+ *
+ *   *_FG = foreground
+ *   *_BG = background
+ *   *_HL = highlight?
+ */
+#define SCREEN_FG                    COLOR_CYAN
+#define SCREEN_BG                    COLOR_BLUE
+#define SCREEN_HL                    TRUE
+
+#define SHADOW_FG                    COLOR_BLACK
+#define SHADOW_BG                    COLOR_BLACK
+#define SHADOW_HL                    TRUE
+
+#define DIALOG_FG                    COLOR_BLACK
+#define DIALOG_BG                    COLOR_WHITE
+#define DIALOG_HL                    FALSE
+
+#define TITLE_FG                     COLOR_YELLOW
+#define TITLE_BG                     COLOR_WHITE
+#define TITLE_HL                     TRUE
+
+#define BORDER_FG                    COLOR_WHITE
+#define BORDER_BG                    COLOR_WHITE
+#define BORDER_HL                    TRUE
+
+#define BUTTON_ACTIVE_FG             COLOR_WHITE
+#define BUTTON_ACTIVE_BG             COLOR_BLUE
+#define BUTTON_ACTIVE_HL             TRUE
+
+#define BUTTON_INACTIVE_FG           COLOR_BLACK
+#define BUTTON_INACTIVE_BG           COLOR_WHITE
+#define BUTTON_INACTIVE_HL           FALSE
+
+#define BUTTON_KEY_ACTIVE_FG         COLOR_WHITE
+#define BUTTON_KEY_ACTIVE_BG         COLOR_BLUE
+#define BUTTON_KEY_ACTIVE_HL         TRUE
+
+#define BUTTON_KEY_INACTIVE_FG       COLOR_RED
+#define BUTTON_KEY_INACTIVE_BG       COLOR_WHITE
+#define BUTTON_KEY_INACTIVE_HL       FALSE
+
+#define BUTTON_LABEL_ACTIVE_FG       COLOR_YELLOW
+#define BUTTON_LABEL_ACTIVE_BG       COLOR_BLUE
+#define BUTTON_LABEL_ACTIVE_HL       TRUE
+
+#define BUTTON_LABEL_INACTIVE_FG     COLOR_BLACK
+#define BUTTON_LABEL_INACTIVE_BG     COLOR_WHITE
+#define BUTTON_LABEL_INACTIVE_HL     TRUE
+
+#define INPUTBOX_FG                  COLOR_BLACK
+#define INPUTBOX_BG                  COLOR_WHITE
+#define INPUTBOX_HL                  FALSE
+
+#define INPUTBOX_BORDER_FG           COLOR_BLACK
+#define INPUTBOX_BORDER_BG           COLOR_WHITE
+#define INPUTBOX_BORDER_HL           FALSE
+
+#define SEARCHBOX_FG                 COLOR_BLACK
+#define SEARCHBOX_BG                 COLOR_WHITE
+#define SEARCHBOX_HL                 FALSE
+
+#define SEARCHBOX_TITLE_FG           COLOR_YELLOW
+#define SEARCHBOX_TITLE_BG           COLOR_WHITE
+#define SEARCHBOX_TITLE_HL           TRUE
+
+#define SEARCHBOX_BORDER_FG          COLOR_WHITE
+#define SEARCHBOX_BORDER_BG          COLOR_WHITE
+#define SEARCHBOX_BORDER_HL          TRUE
+
+#define POSITION_INDICATOR_FG        COLOR_YELLOW
+#define POSITION_INDICATOR_BG        COLOR_WHITE
+#define POSITION_INDICATOR_HL        TRUE
+
+#define MENUBOX_FG                   COLOR_BLACK
+#define MENUBOX_BG                   COLOR_WHITE
+#define MENUBOX_HL                   FALSE
+
+#define MENUBOX_BORDER_FG            COLOR_WHITE
+#define MENUBOX_BORDER_BG            COLOR_WHITE
+#define MENUBOX_BORDER_HL            TRUE
+
+#define ITEM_FG                      COLOR_BLACK
+#define ITEM_BG                      COLOR_WHITE
+#define ITEM_HL                      FALSE
+
+#define ITEM_SELECTED_FG             COLOR_WHITE
+#define ITEM_SELECTED_BG             COLOR_BLUE
+#define ITEM_SELECTED_HL             TRUE
+
+#define TAG_FG                       COLOR_YELLOW
+#define TAG_BG                       COLOR_WHITE
+#define TAG_HL                       TRUE
+
+#define TAG_SELECTED_FG              COLOR_YELLOW
+#define TAG_SELECTED_BG              COLOR_BLUE
+#define TAG_SELECTED_HL              TRUE
+
+#define TAG_KEY_FG                   COLOR_YELLOW
+#define TAG_KEY_BG                   COLOR_WHITE
+#define TAG_KEY_HL                   TRUE
+
+#define TAG_KEY_SELECTED_FG          COLOR_YELLOW
+#define TAG_KEY_SELECTED_BG          COLOR_BLUE
+#define TAG_KEY_SELECTED_HL          TRUE
+
+#define CHECK_FG                     COLOR_BLACK
+#define CHECK_BG                     COLOR_WHITE
+#define CHECK_HL                     FALSE
+
+#define CHECK_SELECTED_FG            COLOR_WHITE
+#define CHECK_SELECTED_BG            COLOR_BLUE
+#define CHECK_SELECTED_HL            TRUE
+
+#define UARROW_FG                    COLOR_GREEN
+#define UARROW_BG                    COLOR_WHITE
+#define UARROW_HL                    TRUE
+
+#define DARROW_FG                    COLOR_GREEN
+#define DARROW_BG                    COLOR_WHITE
+#define DARROW_HL                    TRUE
+
+/* End of default color definitions */
+
+#define C_ATTR(x,y)                  ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
+#define COLOR_NAME_LEN               10
+#define COLOR_COUNT                  8
+
+/*
+ * Global variables
+ */
+
+typedef struct {
+    char name[COLOR_NAME_LEN];
+    int value;
+} color_names_st;
+
+extern color_names_st color_names[];
+extern int color_table[][3];
diff --git a/busybox/scripts/config/lxdialog/dialog.h b/busybox/scripts/config/lxdialog/dialog.h
new file mode 100644 (file)
index 0000000..7bab3ad
--- /dev/null
@@ -0,0 +1,199 @@
+
+/*
+ *  dialog.h -- common declarations for all dialog modules
+ *
+ *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef CURSES_LOC
+#ifdef __sun__
+#define CURS_MACROS
+#endif
+#include CURSES_LOC
+
+/*
+ * Colors in ncurses 1.9.9e do not work properly since foreground and
+ * background colors are OR'd rather than separately masked.  This version
+ * of dialog was hacked to work with ncurses 1.9.9e, making it incompatible
+ * with standard curses.  The simplest fix (to make this work with standard
+ * curses) uses the wbkgdset() function, not used in the original hack.
+ * Turn it off if we're building with 1.9.9e, since it just confuses things.
+ */
+#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE)
+#define OLD_NCURSES 1
+#undef  wbkgdset
+#define wbkgdset(w,p) /*nothing*/
+#else
+#define OLD_NCURSES 0
+#endif
+
+#define TR(params) _tracef params
+
+#define ESC 27
+#define TAB 9
+#define MAX_LEN 2048
+#define BUF_SIZE (10*1024)
+#define MIN(x,y) (x < y ? x : y)
+#define MAX(x,y) (x > y ? x : y)
+
+
+#ifndef ACS_ULCORNER
+#define ACS_ULCORNER '+'
+#endif
+#ifndef ACS_LLCORNER
+#define ACS_LLCORNER '+'
+#endif
+#ifndef ACS_URCORNER
+#define ACS_URCORNER '+'
+#endif
+#ifndef ACS_LRCORNER
+#define ACS_LRCORNER '+'
+#endif
+#ifndef ACS_HLINE
+#define ACS_HLINE '-'
+#endif
+#ifndef ACS_VLINE
+#define ACS_VLINE '|'
+#endif
+#ifndef ACS_LTEE
+#define ACS_LTEE '+'
+#endif
+#ifndef ACS_RTEE
+#define ACS_RTEE '+'
+#endif
+#ifndef ACS_UARROW
+#define ACS_UARROW '^'
+#endif
+#ifndef ACS_DARROW
+#define ACS_DARROW 'v'
+#endif
+
+/* 
+ * Attribute names
+ */
+#define screen_attr                   attributes[0]
+#define shadow_attr                   attributes[1]
+#define dialog_attr                   attributes[2]
+#define title_attr                    attributes[3]
+#define border_attr                   attributes[4]
+#define button_active_attr            attributes[5]
+#define button_inactive_attr          attributes[6]
+#define button_key_active_attr        attributes[7]
+#define button_key_inactive_attr      attributes[8]
+#define button_label_active_attr      attributes[9]
+#define button_label_inactive_attr    attributes[10]
+#define inputbox_attr                 attributes[11]
+#define inputbox_border_attr          attributes[12]
+#define searchbox_attr                attributes[13]
+#define searchbox_title_attr          attributes[14]
+#define searchbox_border_attr         attributes[15]
+#define position_indicator_attr       attributes[16]
+#define menubox_attr                  attributes[17]
+#define menubox_border_attr           attributes[18]
+#define item_attr                     attributes[19]
+#define item_selected_attr            attributes[20]
+#define tag_attr                      attributes[21]
+#define tag_selected_attr             attributes[22]
+#define tag_key_attr                  attributes[23]
+#define tag_key_selected_attr         attributes[24]
+#define check_attr                    attributes[25]
+#define check_selected_attr           attributes[26]
+#define uarrow_attr                   attributes[27]
+#define darrow_attr                   attributes[28]
+
+/* number of attributes */
+#define ATTRIBUTE_COUNT               29
+
+/*
+ * Global variables
+ */
+extern bool use_colors;
+
+extern chtype attributes[];
+#endif
+
+extern const char *backtitle;
+
+struct dialog_list_item {
+       char *name;
+       int namelen;
+       char *tag;
+       int selected; /* Set to 1 by dialog_*() function. */
+};
+
+/*
+ * Function prototypes
+ */
+
+void init_dialog (void);
+void end_dialog (void);
+void dialog_clear (void);
+#ifdef CURSES_LOC
+void attr_clear (WINDOW * win, int height, int width, chtype attr);
+void color_setup (void);
+void print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x);
+void print_button (WINDOW * win, const char *label, int y, int x, int selected);
+void draw_box (WINDOW * win, int y, int x, int height, int width, chtype box,
+               chtype border);
+void draw_shadow (WINDOW * win, int y, int x, int height, int width);
+#endif
+
+int first_alpha (const char *string, const char *exempt);
+int dialog_yesno (const char *title, const char *prompt, int height, int width);
+int dialog_msgbox (const char *title, const char *prompt, int height,
+               int width, int pause);
+int dialog_textbox (const char *title, const char *file, int height, int width);
+int dialog_menu (const char *title, const char *prompt, int height, int width,
+               int menu_height, const char *choice, int item_no, 
+               struct dialog_list_item ** items);
+int dialog_checklist (const char *title, const char *prompt, int height,
+               int width, int list_height, int item_no,
+               struct dialog_list_item ** items, int flag);
+extern unsigned char dialog_input_result[];
+int dialog_inputbox (const char *title, const char *prompt, int height,
+               int width, const char *init);
+
+struct dialog_list_item *first_sel_item(int item_no,
+               struct dialog_list_item ** items);
+
+/*
+ * This is the base for fictitious keys, which activate
+ * the buttons.
+ *
+ * Mouse-generated keys are the following:
+ *   -- the first 32 are used as numbers, in addition to '0'-'9'
+ *   -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o')
+ *   -- uppercase chars are used to invoke the button (M_EVENT + 'O')
+ */
+#ifdef CURSES_LOC
+#define M_EVENT (KEY_MAX+1)
+#endif
+
+
+/*
+ * The `flag' parameter in checklist is used to select between
+ * radiolist and checklist
+ */
+#define FLAG_CHECK 1
+#define FLAG_RADIO 0
diff --git a/busybox/scripts/config/lxdialog/inputbox.c b/busybox/scripts/config/lxdialog/inputbox.c
new file mode 100644 (file)
index 0000000..fa7bebc
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ *  inputbox.c -- implements the input box
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+unsigned char dialog_input_result[MAX_LEN + 1];
+
+/*
+ *  Print the termination buttons
+ */
+static void
+print_buttons(WINDOW *dialog, int height, int width, int selected)
+{
+    int x = width / 2 - 11;
+    int y = height - 2;
+
+    print_button (dialog, "  Ok  ", y, x, selected==0);
+    print_button (dialog, " Help ", y, x + 14, selected==1);
+
+    wmove(dialog, y, x+1+14*selected);
+    wrefresh(dialog);
+}
+
+/*
+ * Display a dialog box for inputing a string
+ */
+int
+dialog_inputbox (const char *title, const char *prompt, int height, int width,
+                const char *init)
+{
+    int i, x, y, box_y, box_x, box_width;
+    int input_x = 0, scroll = 0, key = 0, button = -1;
+    unsigned char *instr = dialog_input_result;
+    WINDOW *dialog;
+
+    /* center dialog box on screen */
+    x = (COLS - width) / 2;
+    y = (LINES - height) / 2;
+
+
+    draw_shadow (stdscr, y, x, height, width);
+
+    dialog = newwin (height, width, y, x);
+    keypad (dialog, TRUE);
+
+    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
+    wattrset (dialog, border_attr);
+    mvwaddch (dialog, height-3, 0, ACS_LTEE);
+    for (i = 0; i < width - 2; i++)
+       waddch (dialog, ACS_HLINE);
+    wattrset (dialog, dialog_attr);
+    waddch (dialog, ACS_RTEE);
+
+    if (title != NULL && strlen(title) >= width-2 ) {
+       /* truncate long title -- mec */
+       char * title2 = malloc(width-2+1);
+       memcpy( title2, title, width-2 );
+       title2[width-2] = '\0';
+       title = title2;
+    }
+
+    if (title != NULL) {
+       wattrset (dialog, title_attr);
+       mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
+       waddstr (dialog, (char *)title);
+       waddch (dialog, ' ');
+    }
+
+    wattrset (dialog, dialog_attr);
+    print_autowrap (dialog, prompt, width - 2, 1, 3);
+
+    /* Draw the input field box */
+    box_width = width - 6;
+    getyx (dialog, y, x);
+    box_y = y + 2;
+    box_x = (width - box_width) / 2;
+    draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2,
+             border_attr, dialog_attr);
+
+    print_buttons(dialog, height, width, 0);
+
+    /* Set up the initial value */
+    wmove (dialog, box_y, box_x);
+    wattrset (dialog, inputbox_attr);
+
+    if (!init)
+       instr[0] = '\0';
+    else
+       strcpy (instr, init);
+
+    input_x = strlen (instr);
+
+    if (input_x >= box_width) {
+       scroll = input_x - box_width + 1;
+       input_x = box_width - 1;
+       for (i = 0; i < box_width - 1; i++)
+           waddch (dialog, instr[scroll + i]);
+    } else
+       waddstr (dialog, instr);
+
+    wmove (dialog, box_y, box_x + input_x);
+
+    wrefresh (dialog);
+
+    while (key != ESC) {
+       key = wgetch (dialog);
+
+       if (button == -1) {     /* Input box selected */
+           switch (key) {
+           case TAB:
+           case KEY_UP:
+           case KEY_DOWN:
+               break;
+           case KEY_LEFT:
+               continue;
+           case KEY_RIGHT:
+               continue;
+           case KEY_BACKSPACE:
+           case 127:
+               if (input_x || scroll) {
+                   wattrset (dialog, inputbox_attr);
+                   if (!input_x) {
+                       scroll = scroll < box_width - 1 ?
+                           0 : scroll - (box_width - 1);
+                       wmove (dialog, box_y, box_x);
+                       for (i = 0; i < box_width; i++)
+                           waddch (dialog, instr[scroll + input_x + i] ?
+                                   instr[scroll + input_x + i] : ' ');
+                       input_x = strlen (instr) - scroll;
+                   } else
+                       input_x--;
+                   instr[scroll + input_x] = '\0';
+                   mvwaddch (dialog, box_y, input_x + box_x, ' ');
+                   wmove (dialog, box_y, input_x + box_x);
+                   wrefresh (dialog);
+               }
+               continue;
+           default:
+               if (key < 0x100 && isprint (key)) {
+                   if (scroll + input_x < MAX_LEN) {
+                       wattrset (dialog, inputbox_attr);
+                       instr[scroll + input_x] = key;
+                       instr[scroll + input_x + 1] = '\0';
+                       if (input_x == box_width - 1) {
+                           scroll++;
+                           wmove (dialog, box_y, box_x);
+                           for (i = 0; i < box_width - 1; i++)
+                               waddch (dialog, instr[scroll + i]);
+                       } else {
+                           wmove (dialog, box_y, input_x++ + box_x);
+                           waddch (dialog, key);
+                       }
+                       wrefresh (dialog);
+                   } else
+                       flash ();       /* Alarm user about overflow */
+                   continue;
+               }
+           }
+       }
+       switch (key) {
+       case 'O':
+       case 'o':
+           delwin (dialog);
+           return 0;
+       case 'H':
+       case 'h':
+           delwin (dialog);
+           return 1;
+       case KEY_UP:
+       case KEY_LEFT:
+           switch (button) {
+           case -1:
+               button = 1;     /* Indicates "Cancel" button is selected */
+               print_buttons(dialog, height, width, 1);
+               break;
+           case 0:
+               button = -1;    /* Indicates input box is selected */
+               print_buttons(dialog, height, width, 0);
+               wmove (dialog, box_y, box_x + input_x);
+               wrefresh (dialog);
+               break;
+           case 1:
+               button = 0;     /* Indicates "OK" button is selected */
+               print_buttons(dialog, height, width, 0);
+               break;
+           }
+           break;
+       case TAB:
+       case KEY_DOWN:
+       case KEY_RIGHT:
+           switch (button) {
+           case -1:
+               button = 0;     /* Indicates "OK" button is selected */
+               print_buttons(dialog, height, width, 0);
+               break;
+           case 0:
+               button = 1;     /* Indicates "Cancel" button is selected */
+               print_buttons(dialog, height, width, 1);
+               break;
+           case 1:
+               button = -1;    /* Indicates input box is selected */
+               print_buttons(dialog, height, width, 0);
+               wmove (dialog, box_y, box_x + input_x);
+               wrefresh (dialog);
+               break;
+           }
+           break;
+       case ' ':
+       case '\n':
+           delwin (dialog);
+           return (button == -1 ? 0 : button);
+       case 'X':
+       case 'x':
+           key = ESC;
+       case ESC:
+           break;
+       }
+    }
+
+    delwin (dialog);
+    return -1;                 /* ESC pressed */
+}
diff --git a/busybox/scripts/config/lxdialog/menubox.c b/busybox/scripts/config/lxdialog/menubox.c
new file mode 100644 (file)
index 0000000..873dc58
--- /dev/null
@@ -0,0 +1,438 @@
+/*
+ *  menubox.c -- implements the menu box
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *  Changes by Clifford Wolf (god@clifford.at)
+ *
+ *  [ 1998-06-13 ]
+ *
+ *    *)  A bugfix for the Page-Down problem
+ *
+ *    *)  Formerly when I used Page Down and Page Up, the cursor would be set 
+ *        to the first position in the menu box.  Now lxdialog is a bit
+ *        smarter and works more like other menu systems (just have a look at
+ *        it).
+ *
+ *    *)  Formerly if I selected something my scrolling would be broken because
+ *        lxdialog is re-invoked by the Menuconfig shell script, can't
+ *        remember the last scrolling position, and just sets it so that the
+ *        cursor is at the bottom of the box.  Now it writes the temporary file
+ *        lxdialog.scrltmp which contains this information. The file is
+ *        deleted by lxdialog if the user leaves a submenu or enters a new
+ *        one, but it would be nice if Menuconfig could make another "rm -f"
+ *        just to be sure.  Just try it out - you will recognise a difference!
+ *
+ *  [ 1998-06-14 ]
+ *
+ *    *)  Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
+ *        and menus change their size on the fly.
+ *
+ *    *)  If for some reason the last scrolling position is not saved by
+ *        lxdialog, it sets the scrolling so that the selected item is in the
+ *        middle of the menu box, not at the bottom.
+ *
+ * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
+ * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
+ * This fixes a bug in Menuconfig where using ' ' to descend into menus
+ * would leave mis-synchronized lxdialog.scrltmp files lying around,
+ * fscanf would read in 'scroll', and eventually that value would get used.
+ */
+
+#include "dialog.h"
+
+static int menu_width, item_x;
+
+/*
+ * Print menu item
+ */
+static void
+print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey)
+{
+    int j;
+    char menu_item[menu_width+1];
+
+    strncpy(menu_item, item, menu_width);
+    menu_item[menu_width] = 0;
+    j = first_alpha(menu_item, "YyNnMmHh");
+
+    /* Clear 'residue' of last item */
+    wattrset (win, menubox_attr);
+    wmove (win, choice, 0);
+#if OLD_NCURSES
+    {
+        int i;
+        for (i = 0; i < menu_width; i++)
+           waddch (win, ' ');
+    }
+#else
+    wclrtoeol(win);
+#endif
+    wattrset (win, selected ? item_selected_attr : item_attr);
+    mvwaddstr (win, choice, item_x, menu_item);
+    if (hotkey) {
+       wattrset (win, selected ? tag_key_selected_attr : tag_key_attr);
+       mvwaddch(win, choice, item_x+j, menu_item[j]);
+    }
+    if (selected) {
+       wmove (win, choice, item_x+1);
+       wrefresh (win);
+    }
+}
+
+/*
+ * Print the scroll indicators.
+ */
+static void
+print_arrows (WINDOW * win, int item_no, int scroll,
+               int y, int x, int height)
+{
+    int cur_y, cur_x;
+
+    getyx(win, cur_y, cur_x);
+
+    wmove(win, y, x);
+
+    if (scroll > 0) {
+       wattrset (win, uarrow_attr);
+       waddch (win, ACS_UARROW);
+       waddstr (win, "(-)");
+    }
+    else {
+       wattrset (win, menubox_attr);
+       waddch (win, ACS_HLINE);
+       waddch (win, ACS_HLINE);
+       waddch (win, ACS_HLINE);
+       waddch (win, ACS_HLINE);
+    }
+
+   y = y + height + 1;
+   wmove(win, y, x);
+
+   if ((height < item_no) && (scroll + height < item_no)) {
+       wattrset (win, darrow_attr);
+       waddch (win, ACS_DARROW);
+       waddstr (win, "(+)");
+    }
+    else {
+       wattrset (win, menubox_border_attr);
+       waddch (win, ACS_HLINE);
+       waddch (win, ACS_HLINE);
+       waddch (win, ACS_HLINE);
+       waddch (win, ACS_HLINE);
+   }
+
+   wmove(win, cur_y, cur_x);
+}
+
+/*
+ * Display the termination buttons.
+ */
+static void
+print_buttons (WINDOW *win, int height, int width, int selected)
+{
+    int x = width / 2 - 16;
+    int y = height - 2;
+
+    print_button (win, "Select", y, x, selected == 0);
+    print_button (win, " Exit ", y, x + 12, selected == 1);
+    print_button (win, " Help ", y, x + 24, selected == 2);
+
+    wmove(win, y, x+1+12*selected);
+    wrefresh (win);
+}
+
+/*
+ * Display a menu for choosing among a number of options
+ */
+int
+dialog_menu (const char *title, const char *prompt, int height, int width,
+               int menu_height, const char *current, int item_no,
+               struct dialog_list_item ** items)
+{
+    int i, j, x, y, box_x, box_y;
+    int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice;
+    WINDOW *dialog, *menu;
+    FILE *f;
+
+    max_choice = MIN (menu_height, item_no);
+
+    /* center dialog box on screen */
+    x = (COLS - width) / 2;
+    y = (LINES - height) / 2;
+
+    draw_shadow (stdscr, y, x, height, width);
+
+    dialog = newwin (height, width, y, x);
+    keypad (dialog, TRUE);
+
+    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
+    wattrset (dialog, border_attr);
+    mvwaddch (dialog, height - 3, 0, ACS_LTEE);
+    for (i = 0; i < width - 2; i++)
+       waddch (dialog, ACS_HLINE);
+    wattrset (dialog, dialog_attr);
+    wbkgdset (dialog, dialog_attr & A_COLOR);
+    waddch (dialog, ACS_RTEE);
+
+    if (title != NULL && strlen(title) >= width-2 ) {
+       /* truncate long title -- mec */
+       char * title2 = malloc(width-2+1);
+       memcpy( title2, title, width-2 );
+       title2[width-2] = '\0';
+       title = title2;
+    }
+
+    if (title != NULL) {
+       wattrset (dialog, title_attr);
+       mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
+       waddstr (dialog, (char *)title);
+       waddch (dialog, ' ');
+    }
+
+    wattrset (dialog, dialog_attr);
+    print_autowrap (dialog, prompt, width - 2, 1, 3);
+
+    menu_width = width - 6;
+    box_y = height - menu_height - 5;
+    box_x = (width - menu_width) / 2 - 1;
+
+    /* create new window for the menu */
+    menu = subwin (dialog, menu_height, menu_width,
+               y + box_y + 1, x + box_x + 1);
+    keypad (menu, TRUE);
+
+    /* draw a box around the menu items */
+    draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2,
+             menubox_border_attr, menubox_attr);
+
+    /*
+     * Find length of longest item in order to center menu.
+     * Set 'choice' to default item. 
+     */
+    item_x = 0;
+    for (i = 0; i < item_no; i++) {
+       item_x = MAX (item_x, MIN(menu_width, strlen (items[i]->name) + 2));
+       if (strcmp(current, items[i]->tag) == 0) choice = i;
+    }
+
+    item_x = (menu_width - item_x) / 2;
+
+    /* get the scroll info from the temp file */
+    if ( (f=fopen("lxdialog.scrltmp","r")) != NULL ) {
+       if ( (fscanf(f,"%d\n",&scroll) == 1) && (scroll <= choice) &&
+            (scroll+max_choice > choice) && (scroll >= 0) &&
+            (scroll+max_choice <= item_no) ) {
+           first_item = scroll;
+           choice = choice - scroll;
+           fclose(f);
+       } else {
+           scroll=0;
+           remove("lxdialog.scrltmp");
+           fclose(f);
+           f=NULL;
+       }
+    }
+    if ( (choice >= max_choice) || (f==NULL && choice >= max_choice/2) ) {
+       if (choice >= item_no-max_choice/2)
+           scroll = first_item = item_no-max_choice;
+       else
+           scroll = first_item = choice - max_choice/2;
+       choice = choice - scroll;
+    }
+
+    /* Print the menu */
+    for (i=0; i < max_choice; i++) {
+       print_item (menu, items[first_item + i]->name, i, i == choice,
+                    (items[first_item + i]->tag[0] != ':'));
+    }
+
+    wnoutrefresh (menu);
+
+    print_arrows(dialog, item_no, scroll,
+                box_y, box_x+item_x+1, menu_height);
+
+    print_buttons (dialog, height, width, 0);
+    wmove (menu, choice, item_x+1);
+    wrefresh (menu);
+
+    while (key != ESC) {
+       key = wgetch(menu);
+
+       if (key < 256 && isalpha(key)) key = tolower(key);
+
+       if (strchr("ynmh", key))
+               i = max_choice;
+       else {
+        for (i = choice+1; i < max_choice; i++) {
+               j = first_alpha(items[scroll + i]->name, "YyNnMmHh");
+               if (key == tolower(items[scroll + i]->name[j]))
+                       break;
+       }
+       if (i == max_choice)
+                       for (i = 0; i < max_choice; i++) {
+                       j = first_alpha(items[scroll + i]->name, "YyNnMmHh");
+                       if (key == tolower(items[scroll + i]->name[j]))
+                               break;
+               }
+       }
+
+       if (i < max_choice || 
+            key == KEY_UP || key == KEY_DOWN ||
+            key == '-' || key == '+' ||
+            key == KEY_PPAGE || key == KEY_NPAGE) {
+
+            print_item (menu, items[scroll + choice]->name, choice, FALSE,
+                       (items[scroll + choice]->tag[0] != ':'));
+
+           if (key == KEY_UP || key == '-') {
+                if (choice < 2 && scroll) {
+                   /* Scroll menu down */
+                    scrollok (menu, TRUE);
+                    wscrl (menu, -1);
+                    scrollok (menu, FALSE);
+
+                    scroll--;
+
+                    print_item (menu, items[scroll]->name, 0, FALSE,
+                               (items[scroll]->tag[0] != ':'));
+               } else
+                   choice = MAX(choice - 1, 0);
+
+           } else if (key == KEY_DOWN || key == '+')  {
+
+               print_item (menu, items[scroll + choice]->name, choice, FALSE,
+                                (items[scroll + choice]->tag[0] != ':'));
+
+                if ((choice > max_choice-3) &&
+                    (scroll + max_choice < item_no)
+                   ) {
+                   /* Scroll menu up */
+                   scrollok (menu, TRUE);
+                    scroll (menu);
+                    scrollok (menu, FALSE);
+
+                    scroll++;
+
+                    print_item (menu, items[scroll + max_choice - 1]->name,
+                               max_choice-1, FALSE,
+                               (items[scroll + max_choice - 1]->tag[0] != ':'));
+                } else
+                    choice = MIN(choice+1, max_choice-1);
+
+           } else if (key == KEY_PPAGE) {
+               scrollok (menu, TRUE);
+                for (i=0; (i < max_choice); i++) {
+                    if (scroll > 0) {
+                       wscrl (menu, -1);
+                       scroll--;
+                       print_item (menu, items[scroll]->name, 0, FALSE,
+                       (items[scroll]->tag[0] != ':'));
+                    } else {
+                        if (choice > 0)
+                            choice--;
+                    }
+                }
+                scrollok (menu, FALSE);
+
+            } else if (key == KEY_NPAGE) {
+                for (i=0; (i < max_choice); i++) {
+                    if (scroll+max_choice < item_no) {
+                       scrollok (menu, TRUE);
+                       scroll(menu);
+                       scrollok (menu, FALSE);
+                       scroll++;
+                       print_item (menu, items[scroll + max_choice - 1]->name,
+                                   max_choice-1, FALSE,
+                                   (items[scroll + max_choice - 1]->tag[0] != ':'));
+                   } else {
+                       if (choice+1 < max_choice)
+                           choice++;
+                   }
+                }
+
+            } else
+                choice = i;
+
+            print_item (menu, items[scroll + choice]->name, choice, TRUE,
+                       (items[scroll + choice]->tag[0] != ':'));
+
+            print_arrows(dialog, item_no, scroll,
+                         box_y, box_x+item_x+1, menu_height);
+
+            wnoutrefresh (dialog);
+            wrefresh (menu);
+
+           continue;           /* wait for another key press */
+        }
+
+       switch (key) {
+       case KEY_LEFT:
+       case TAB:
+       case KEY_RIGHT:
+           button = ((key == KEY_LEFT ? --button : ++button) < 0)
+                       ? 2 : (button > 2 ? 0 : button);
+
+           print_buttons(dialog, height, width, button);
+           wrefresh (menu);
+           break;
+       case ' ':
+       case 's':
+       case 'y':
+       case 'n':
+       case 'm':
+       case '/':
+           /* save scroll info */
+           if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) {
+               fprintf(f,"%d\n",scroll);
+               fclose(f);
+           }
+           delwin (dialog);
+            items[scroll + choice]->selected = 1;
+            switch (key) {
+            case 's': return 3;
+            case 'y': return 3;
+            case 'n': return 4;
+            case 'm': return 5;
+            case ' ': return 6;
+            case '/': return 7;
+            }
+           return 0;
+       case 'h':
+       case '?':
+           button = 2;
+       case '\n':
+           delwin (dialog);
+           items[scroll + choice]->selected = 1;
+
+           remove("lxdialog.scrltmp");
+           return button;
+       case 'e':
+       case 'x':
+           key = ESC;
+       case ESC:
+           break;
+       }
+    }
+
+    delwin (dialog);
+    remove("lxdialog.scrltmp");
+    return -1;                 /* ESC pressed */
+}
diff --git a/busybox/scripts/config/lxdialog/msgbox.c b/busybox/scripts/config/lxdialog/msgbox.c
new file mode 100644 (file)
index 0000000..93692e1
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ *  msgbox.c -- implements the message box and info box
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+/*
+ * Display a message box. Program will pause and display an "OK" button
+ * if the parameter 'pause' is non-zero.
+ */
+int
+dialog_msgbox (const char *title, const char *prompt, int height, int width,
+               int pause)
+{
+    int i, x, y, key = 0;
+    WINDOW *dialog;
+
+    /* center dialog box on screen */
+    x = (COLS - width) / 2;
+    y = (LINES - height) / 2;
+
+    draw_shadow (stdscr, y, x, height, width);
+
+    dialog = newwin (height, width, y, x);
+    keypad (dialog, TRUE);
+
+    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
+
+    if (title != NULL && strlen(title) >= width-2 ) {
+       /* truncate long title -- mec */
+       char * title2 = malloc(width-2+1);
+       memcpy( title2, title, width-2 );
+       title2[width-2] = '\0';
+       title = title2;
+    }
+
+    if (title != NULL) {
+       wattrset (dialog, title_attr);
+       mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
+       waddstr (dialog, (char *)title);
+       waddch (dialog, ' ');
+    }
+    wattrset (dialog, dialog_attr);
+    print_autowrap (dialog, prompt, width - 2, 1, 2);
+
+    if (pause) {
+       wattrset (dialog, border_attr);
+       mvwaddch (dialog, height - 3, 0, ACS_LTEE);
+       for (i = 0; i < width - 2; i++)
+           waddch (dialog, ACS_HLINE);
+       wattrset (dialog, dialog_attr);
+       waddch (dialog, ACS_RTEE);
+
+       print_button (dialog, "  Ok  ",
+                     height - 2, width / 2 - 4, TRUE);
+
+       wrefresh (dialog);
+       while (key != ESC && key != '\n' && key != ' ' &&
+               key != 'O' && key != 'o' && key != 'X' && key != 'x')
+           key = wgetch (dialog);
+    } else {
+       key = '\n';
+       wrefresh (dialog);
+    }
+
+    delwin (dialog);
+    return key == ESC ? -1 : 0;
+}
diff --git a/busybox/scripts/config/lxdialog/textbox.c b/busybox/scripts/config/lxdialog/textbox.c
new file mode 100644 (file)
index 0000000..a5a460b
--- /dev/null
@@ -0,0 +1,556 @@
+/*
+ *  textbox.c -- implements the text box
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+static void back_lines (int n);
+static void print_page (WINDOW * win, int height, int width);
+static void print_line (WINDOW * win, int row, int width);
+static char *get_line (void);
+static void print_position (WINDOW * win, int height, int width);
+
+static int hscroll, fd, file_size, bytes_read;
+static int begin_reached = 1, end_reached, page_length;
+static char *buf, *page;
+
+/*
+ * Display text from a file in a dialog box.
+ */
+int
+dialog_textbox (const char *title, const char *file, int height, int width)
+{
+    int i, x, y, cur_x, cur_y, fpos, key = 0;
+    int passed_end;
+    char search_term[MAX_LEN + 1];
+    WINDOW *dialog, *text;
+
+    search_term[0] = '\0';     /* no search term entered yet */
+
+    /* Open input file for reading */
+    if ((fd = open (file, O_RDONLY)) == -1) {
+       endwin ();
+       fprintf (stderr,
+                "\nCan't open input file in dialog_textbox().\n");
+       exit (-1);
+    }
+    /* Get file size. Actually, 'file_size' is the real file size - 1,
+       since it's only the last byte offset from the beginning */
+    if ((file_size = lseek (fd, 0, SEEK_END)) == -1) {
+       endwin ();
+       fprintf (stderr, "\nError getting file size in dialog_textbox().\n");
+       exit (-1);
+    }
+    /* Restore file pointer to beginning of file after getting file size */
+    if (lseek (fd, 0, SEEK_SET) == -1) {
+       endwin ();
+       fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n");
+       exit (-1);
+    }
+    /* Allocate space for read buffer */
+    if ((buf = malloc (BUF_SIZE + 1)) == NULL) {
+       endwin ();
+       fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n");
+       exit (-1);
+    }
+    if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
+       endwin ();
+       fprintf (stderr, "\nError reading file in dialog_textbox().\n");
+       exit (-1);
+    }
+    buf[bytes_read] = '\0';    /* mark end of valid data */
+    page = buf;                        /* page is pointer to start of page to be displayed */
+
+    /* center dialog box on screen */
+    x = (COLS - width) / 2;
+    y = (LINES - height) / 2;
+
+
+    draw_shadow (stdscr, y, x, height, width);
+
+    dialog = newwin (height, width, y, x);
+    keypad (dialog, TRUE);
+
+    /* Create window for text region, used for scrolling text */
+    text = subwin (dialog, height - 4, width - 2, y + 1, x + 1);
+    wattrset (text, dialog_attr);
+    wbkgdset (text, dialog_attr & A_COLOR);
+
+    keypad (text, TRUE);
+
+    /* register the new window, along with its borders */
+    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
+
+    wattrset (dialog, border_attr);
+    mvwaddch (dialog, height-3, 0, ACS_LTEE);
+    for (i = 0; i < width - 2; i++)
+       waddch (dialog, ACS_HLINE);
+    wattrset (dialog, dialog_attr);
+    wbkgdset (dialog, dialog_attr & A_COLOR);
+    waddch (dialog, ACS_RTEE);
+
+    if (title != NULL && strlen(title) >= width-2 ) {
+       /* truncate long title -- mec */
+       char * title2 = malloc(width-2+1);
+       memcpy( title2, title, width-2 );
+       title2[width-2] = '\0';
+       title = title2;
+    }
+
+    if (title != NULL) {
+       wattrset (dialog, title_attr);
+       mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
+       waddstr (dialog, (char *)title);
+       waddch (dialog, ' ');
+    }
+    print_button (dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
+    wnoutrefresh (dialog);
+    getyx (dialog, cur_y, cur_x);      /* Save cursor position */
+
+    /* Print first page of text */
+    attr_clear (text, height - 4, width - 2, dialog_attr);
+    print_page (text, height - 4, width - 2);
+    print_position (dialog, height, width);
+    wmove (dialog, cur_y, cur_x);      /* Restore cursor position */
+    wrefresh (dialog);
+
+    while ((key != ESC) && (key != '\n')) {
+       key = wgetch (dialog);
+       switch (key) {
+       case 'E':               /* Exit */
+       case 'e':
+       case 'X':
+       case 'x':
+           delwin (dialog);
+           free (buf);
+           close (fd);
+           return 0;
+       case 'g':               /* First page */
+       case KEY_HOME:
+           if (!begin_reached) {
+               begin_reached = 1;
+               /* First page not in buffer? */
+               if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
+                   endwin ();
+                   fprintf (stderr,
+                     "\nError moving file pointer in dialog_textbox().\n");
+                   exit (-1);
+               }
+               if (fpos > bytes_read) {        /* Yes, we have to read it in */
+                   if (lseek (fd, 0, SEEK_SET) == -1) {
+                       endwin ();
+                       fprintf (stderr, "\nError moving file pointer in "
+                                "dialog_textbox().\n");
+                       exit (-1);
+                   }
+                   if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
+                       endwin ();
+                       fprintf (stderr,
+                            "\nError reading file in dialog_textbox().\n");
+                       exit (-1);
+                   }
+                   buf[bytes_read] = '\0';
+               }
+               page = buf;
+               print_page (text, height - 4, width - 2);
+               print_position (dialog, height, width);
+               wmove (dialog, cur_y, cur_x);   /* Restore cursor position */
+               wrefresh (dialog);
+           }
+           break;
+       case 'G':               /* Last page */
+       case KEY_END:
+
+           end_reached = 1;
+           /* Last page not in buffer? */
+           if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
+               endwin ();
+               fprintf (stderr,
+                     "\nError moving file pointer in dialog_textbox().\n");
+               exit (-1);
+           }
+           if (fpos < file_size) {     /* Yes, we have to read it in */
+               if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) {
+                   endwin ();
+                   fprintf (stderr,
+                     "\nError moving file pointer in dialog_textbox().\n");
+                   exit (-1);
+               }
+               if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
+                   endwin ();
+                   fprintf (stderr,
+                            "\nError reading file in dialog_textbox().\n");
+                   exit (-1);
+               }
+               buf[bytes_read] = '\0';
+           }
+           page = buf + bytes_read;
+           back_lines (height - 4);
+           print_page (text, height - 4, width - 2);
+           print_position (dialog, height, width);
+           wmove (dialog, cur_y, cur_x);       /* Restore cursor position */
+           wrefresh (dialog);
+           break;
+       case 'K':               /* Previous line */
+       case 'k':
+       case KEY_UP:
+           if (!begin_reached) {
+               back_lines (page_length + 1);
+
+               /* We don't call print_page() here but use scrolling to ensure
+                  faster screen update. However, 'end_reached' and
+                  'page_length' should still be updated, and 'page' should
+                  point to start of next page. This is done by calling
+                  get_line() in the following 'for' loop. */
+               scrollok (text, TRUE);
+               wscrl (text, -1);       /* Scroll text region down one line */
+               scrollok (text, FALSE);
+               page_length = 0;
+               passed_end = 0;
+               for (i = 0; i < height - 4; i++) {
+                   if (!i) {
+                       /* print first line of page */
+                       print_line (text, 0, width - 2);
+                       wnoutrefresh (text);
+                   } else
+                       /* Called to update 'end_reached' and 'page' */
+                       get_line ();
+                   if (!passed_end)
+                       page_length++;
+                   if (end_reached && !passed_end)
+                       passed_end = 1;
+               }
+
+               print_position (dialog, height, width);
+               wmove (dialog, cur_y, cur_x);   /* Restore cursor position */
+               wrefresh (dialog);
+           }
+           break;
+       case 'B':               /* Previous page */
+       case 'b':
+       case KEY_PPAGE:
+           if (begin_reached)
+               break;
+           back_lines (page_length + height - 4);
+           print_page (text, height - 4, width - 2);
+           print_position (dialog, height, width);
+           wmove (dialog, cur_y, cur_x);
+           wrefresh (dialog);
+           break;
+       case 'J':               /* Next line */
+       case 'j':
+       case KEY_DOWN:
+           if (!end_reached) {
+               begin_reached = 0;
+               scrollok (text, TRUE);
+               scroll (text);  /* Scroll text region up one line */
+               scrollok (text, FALSE);
+               print_line (text, height - 5, width - 2);
+               wnoutrefresh (text);
+               print_position (dialog, height, width);
+               wmove (dialog, cur_y, cur_x);   /* Restore cursor position */
+               wrefresh (dialog);
+           }
+           break;
+       case KEY_NPAGE:         /* Next page */
+       case ' ':
+           if (end_reached)
+               break;
+
+           begin_reached = 0;
+           print_page (text, height - 4, width - 2);
+           print_position (dialog, height, width);
+           wmove (dialog, cur_y, cur_x);
+           wrefresh (dialog);
+           break;
+       case '0':               /* Beginning of line */
+       case 'H':               /* Scroll left */
+       case 'h':
+       case KEY_LEFT:
+           if (hscroll <= 0)
+               break;
+
+           if (key == '0')
+               hscroll = 0;
+           else
+               hscroll--;
+           /* Reprint current page to scroll horizontally */
+           back_lines (page_length);
+           print_page (text, height - 4, width - 2);
+           wmove (dialog, cur_y, cur_x);
+           wrefresh (dialog);
+           break;
+       case 'L':               /* Scroll right */
+       case 'l':
+       case KEY_RIGHT:
+           if (hscroll >= MAX_LEN)
+               break;
+           hscroll++;
+           /* Reprint current page to scroll horizontally */
+           back_lines (page_length);
+           print_page (text, height - 4, width - 2);
+           wmove (dialog, cur_y, cur_x);
+           wrefresh (dialog);
+           break;
+       case ESC:
+           break;
+       }
+    }
+
+    delwin (dialog);
+    free (buf);
+    close (fd);
+    return 1;                  /* ESC pressed */
+}
+
+/*
+ * Go back 'n' lines in text file. Called by dialog_textbox().
+ * 'page' will be updated to point to the desired line in 'buf'.
+ */
+static void
+back_lines (int n)
+{
+    int i, fpos;
+
+    begin_reached = 0;
+    /* We have to distinguish between end_reached and !end_reached
+       since at end of file, the line is not ended by a '\n'.
+       The code inside 'if' basically does a '--page' to move one
+       character backward so as to skip '\n' of the previous line */
+    if (!end_reached) {
+       /* Either beginning of buffer or beginning of file reached? */
+       if (page == buf) {
+           if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
+               endwin ();
+               fprintf (stderr, "\nError moving file pointer in "
+                        "back_lines().\n");
+               exit (-1);
+           }
+           if (fpos > bytes_read) {    /* Not beginning of file yet */
+               /* We've reached beginning of buffer, but not beginning of
+                  file yet, so read previous part of file into buffer.
+                  Note that we only move backward for BUF_SIZE/2 bytes,
+                  but not BUF_SIZE bytes to avoid re-reading again in
+                  print_page() later */
+               /* Really possible to move backward BUF_SIZE/2 bytes? */
+               if (fpos < BUF_SIZE / 2 + bytes_read) {
+                   /* No, move less then */
+                   if (lseek (fd, 0, SEEK_SET) == -1) {
+                       endwin ();
+                       fprintf (stderr, "\nError moving file pointer in "
+                                "back_lines().\n");
+                       exit (-1);
+                   }
+                   page = buf + fpos - bytes_read;
+               } else {        /* Move backward BUF_SIZE/2 bytes */
+                   if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR)
+                       == -1) {
+                       endwin ();
+                       fprintf (stderr, "\nError moving file pointer "
+                                "in back_lines().\n");
+                       exit (-1);
+                   }
+                   page = buf + BUF_SIZE / 2;
+               }
+               if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
+                   endwin ();
+                   fprintf (stderr, "\nError reading file in back_lines().\n");
+                   exit (-1);
+               }
+               buf[bytes_read] = '\0';
+           } else {            /* Beginning of file reached */
+               begin_reached = 1;
+               return;
+           }
+       }
+       if (*(--page) != '\n') {        /* '--page' here */
+           /* Something's wrong... */
+           endwin ();
+           fprintf (stderr, "\nInternal error in back_lines().\n");
+           exit (-1);
+       }
+    }
+    /* Go back 'n' lines */
+    for (i = 0; i < n; i++)
+       do {
+           if (page == buf) {
+               if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
+                   endwin ();
+                   fprintf (stderr,
+                         "\nError moving file pointer in back_lines().\n");
+                   exit (-1);
+               }
+               if (fpos > bytes_read) {
+                   /* Really possible to move backward BUF_SIZE/2 bytes? */
+                   if (fpos < BUF_SIZE / 2 + bytes_read) {
+                       /* No, move less then */
+                       if (lseek (fd, 0, SEEK_SET) == -1) {
+                           endwin ();
+                           fprintf (stderr, "\nError moving file pointer "
+                                    "in back_lines().\n");
+                           exit (-1);
+                       }
+                       page = buf + fpos - bytes_read;
+                   } else {    /* Move backward BUF_SIZE/2 bytes */
+                       if (lseek (fd, -(BUF_SIZE / 2 + bytes_read),
+                                  SEEK_CUR) == -1) {
+                           endwin ();
+                           fprintf (stderr, "\nError moving file pointer"
+                                    " in back_lines().\n");
+                           exit (-1);
+                       }
+                       page = buf + BUF_SIZE / 2;
+                   }
+                   if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
+                       endwin ();
+                       fprintf (stderr, "\nError reading file in "
+                                "back_lines().\n");
+                       exit (-1);
+                   }
+                   buf[bytes_read] = '\0';
+               } else {        /* Beginning of file reached */
+                   begin_reached = 1;
+                   return;
+               }
+           }
+       } while (*(--page) != '\n');
+    page++;
+}
+
+/*
+ * Print a new page of text. Called by dialog_textbox().
+ */
+static void
+print_page (WINDOW * win, int height, int width)
+{
+    int i, passed_end = 0;
+
+    page_length = 0;
+    for (i = 0; i < height; i++) {
+       print_line (win, i, width);
+       if (!passed_end)
+           page_length++;
+       if (end_reached && !passed_end)
+           passed_end = 1;
+    }
+    wnoutrefresh (win);
+}
+
+/*
+ * Print a new line of text. Called by dialog_textbox() and print_page().
+ */
+static void
+print_line (WINDOW * win, int row, int width)
+{
+    int y, x;
+    char *line;
+
+    line = get_line ();
+    line += MIN (strlen (line), hscroll);      /* Scroll horizontally */
+    wmove (win, row, 0);       /* move cursor to correct line */
+    waddch (win, ' ');
+    waddnstr (win, line, MIN (strlen (line), width - 2));
+
+    getyx (win, y, x);
+    /* Clear 'residue' of previous line */
+#if OLD_NCURSES
+    {
+        int i;
+        for (i = 0; i < width - x; i++)
+           waddch (win, ' ');
+    }
+#else
+    wclrtoeol(win);
+#endif
+}
+
+/*
+ * Return current line of text. Called by dialog_textbox() and print_line().
+ * 'page' should point to start of current line before calling, and will be
+ * updated to point to start of next line.
+ */
+static char *
+get_line (void)
+{
+    int i = 0, fpos;
+    static char line[MAX_LEN + 1];
+
+    end_reached = 0;
+    while (*page != '\n') {
+       if (*page == '\0') {
+           /* Either end of file or end of buffer reached */
+           if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
+               endwin ();
+               fprintf (stderr, "\nError moving file pointer in "
+                        "get_line().\n");
+               exit (-1);
+           }
+           if (fpos < file_size) {     /* Not end of file yet */
+               /* We've reached end of buffer, but not end of file yet,
+                  so read next part of file into buffer */
+               if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
+                   endwin ();
+                   fprintf (stderr, "\nError reading file in get_line().\n");
+                   exit (-1);
+               }
+               buf[bytes_read] = '\0';
+               page = buf;
+           } else {
+               if (!end_reached)
+                   end_reached = 1;
+               break;
+           }
+       } else if (i < MAX_LEN)
+           line[i++] = *(page++);
+       else {
+           /* Truncate lines longer than MAX_LEN characters */
+           if (i == MAX_LEN)
+               line[i++] = '\0';
+           page++;
+       }
+    }
+    if (i <= MAX_LEN)
+       line[i] = '\0';
+    if (!end_reached)
+       page++;                 /* move pass '\n' */
+
+    return line;
+}
+
+/*
+ * Print current position
+ */
+static void
+print_position (WINDOW * win, int height, int width)
+{
+    int fpos, percent;
+
+    if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
+       endwin ();
+       fprintf (stderr, "\nError moving file pointer in print_position().\n");
+       exit (-1);
+    }
+    wattrset (win, position_indicator_attr);
+    wbkgdset (win, position_indicator_attr & A_COLOR);
+    percent = !file_size ?
+       100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
+    wmove (win, height - 3, width - 9);
+    wprintw (win, "(%3d%%)", percent);
+}
diff --git a/busybox/scripts/config/lxdialog/util.c b/busybox/scripts/config/lxdialog/util.c
new file mode 100644 (file)
index 0000000..6f83951
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+ *  util.c
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+
+/* use colors by default? */
+bool use_colors = 1;
+
+const char *backtitle = NULL;
+
+const char *dialog_result;
+
+/* 
+ * Attribute values, default is for mono display
+ */
+chtype attributes[] =
+{
+    A_NORMAL,                  /* screen_attr */
+    A_NORMAL,                  /* shadow_attr */
+    A_NORMAL,                  /* dialog_attr */
+    A_BOLD,                    /* title_attr */
+    A_NORMAL,                  /* border_attr */
+    A_REVERSE,                 /* button_active_attr */
+    A_DIM,                     /* button_inactive_attr */
+    A_REVERSE,                 /* button_key_active_attr */
+    A_BOLD,                    /* button_key_inactive_attr */
+    A_REVERSE,                 /* button_label_active_attr */
+    A_NORMAL,                  /* button_label_inactive_attr */
+    A_NORMAL,                  /* inputbox_attr */
+    A_NORMAL,                  /* inputbox_border_attr */
+    A_NORMAL,                  /* searchbox_attr */
+    A_BOLD,                    /* searchbox_title_attr */
+    A_NORMAL,                  /* searchbox_border_attr */
+    A_BOLD,                    /* position_indicator_attr */
+    A_NORMAL,                  /* menubox_attr */
+    A_NORMAL,                  /* menubox_border_attr */
+    A_NORMAL,                  /* item_attr */
+    A_REVERSE,                 /* item_selected_attr */
+    A_BOLD,                    /* tag_attr */
+    A_REVERSE,                 /* tag_selected_attr */
+    A_BOLD,                    /* tag_key_attr */
+    A_REVERSE,                 /* tag_key_selected_attr */
+    A_BOLD,                    /* check_attr */
+    A_REVERSE,                 /* check_selected_attr */
+    A_BOLD,                    /* uarrow_attr */
+    A_BOLD                     /* darrow_attr */
+};
+
+
+#include "colors.h"
+
+/*
+ * Table of color values
+ */
+int color_table[][3] =
+{
+    {SCREEN_FG, SCREEN_BG, SCREEN_HL},
+    {SHADOW_FG, SHADOW_BG, SHADOW_HL},
+    {DIALOG_FG, DIALOG_BG, DIALOG_HL},
+    {TITLE_FG, TITLE_BG, TITLE_HL},
+    {BORDER_FG, BORDER_BG, BORDER_HL},
+    {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
+    {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
+    {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
+    {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL},
+    {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL},
+    {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
+     BUTTON_LABEL_INACTIVE_HL},
+    {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
+    {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
+    {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
+    {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
+    {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
+    {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
+    {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
+    {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
+    {ITEM_FG, ITEM_BG, ITEM_HL},
+    {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
+    {TAG_FG, TAG_BG, TAG_HL},
+    {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
+    {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
+    {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
+    {CHECK_FG, CHECK_BG, CHECK_HL},
+    {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
+    {UARROW_FG, UARROW_BG, UARROW_HL},
+    {DARROW_FG, DARROW_BG, DARROW_HL},
+};                             /* color_table */
+
+/*
+ * Set window to attribute 'attr'
+ */
+void
+attr_clear (WINDOW * win, int height, int width, chtype attr)
+{
+    int i, j;
+
+    wattrset (win, attr);
+    for (i = 0; i < height; i++) {
+       wmove (win, i, 0);
+       for (j = 0; j < width; j++)
+           waddch (win, ' ');
+    }
+    touchwin (win);
+}
+
+void dialog_clear (void)
+{
+    attr_clear (stdscr, LINES, COLS, screen_attr);
+    /* Display background title if it exists ... - SLH */
+    if (backtitle != NULL) {
+        int i;
+
+        wattrset (stdscr, screen_attr);
+        mvwaddstr (stdscr, 0, 1, (char *)backtitle);
+        wmove (stdscr, 1, 1);
+        for (i = 1; i < COLS - 1; i++)
+            waddch (stdscr, ACS_HLINE);
+    }
+    wnoutrefresh (stdscr);
+}
+
+/*
+ * Do some initialization for dialog
+ */
+void
+init_dialog (void)
+{
+    initscr ();                        /* Init curses */
+    keypad (stdscr, TRUE);
+    cbreak ();
+    noecho ();
+
+
+    if (use_colors)    /* Set up colors */
+       color_setup ();
+
+
+    dialog_clear ();
+}
+
+/*
+ * Setup for color display
+ */
+void
+color_setup (void)
+{
+    int i;
+
+    if (has_colors ()) {       /* Terminal supports color? */
+       start_color ();
+
+       /* Initialize color pairs */
+       for (i = 0; i < ATTRIBUTE_COUNT; i++)
+           init_pair (i + 1, color_table[i][0], color_table[i][1]);
+
+       /* Setup color attributes */
+       for (i = 0; i < ATTRIBUTE_COUNT; i++)
+           attributes[i] = C_ATTR (color_table[i][2], i + 1);
+    }
+}
+
+/*
+ * End using dialog functions.
+ */
+void
+end_dialog (void)
+{
+    endwin ();
+}
+
+
+/*
+ * Print a string of text in a window, automatically wrap around to the
+ * next line if the string is too long to fit on one line. Newline
+ * characters '\n' are replaced by spaces.  We start on a new line
+ * if there is no room for at least 4 nonblanks following a double-space.
+ */
+void
+print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x)
+{
+    int newl, cur_x, cur_y;
+    int i, prompt_len, room, wlen;
+    char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
+
+    strcpy (tempstr, prompt);
+
+    prompt_len = strlen(tempstr);
+       
+    /*
+     * Remove newlines
+     */
+    for(i=0; i<prompt_len; i++) {
+       if(tempstr[i] == '\n') tempstr[i] = ' ';
+    }
+
+    if (prompt_len <= width - x * 2) { /* If prompt is short */
+       wmove (win, y, (width - prompt_len) / 2);
+       waddstr (win, tempstr);
+    } else {
+       cur_x = x;
+       cur_y = y;
+       newl = 1;
+       word = tempstr;
+       while (word && *word) {
+           sp = index(word, ' ');
+           if (sp)
+               *sp++ = 0;
+
+           /* Wrap to next line if either the word does not fit,
+              or it is the first word of a new sentence, and it is
+              short, and the next word does not fit. */
+           room = width - cur_x;
+           wlen = strlen(word);
+           if (wlen > room ||
+              (newl && wlen < 4 && sp && wlen+1+strlen(sp) > room
+                    && (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) {
+               cur_y++;
+               cur_x = x;
+           }
+           wmove (win, cur_y, cur_x);
+           waddstr (win, word);
+           getyx (win, cur_y, cur_x);
+           cur_x++;
+           if (sp && *sp == ' ') {
+               cur_x++;        /* double space */
+               while (*++sp == ' ');
+               newl = 1;
+           } else
+               newl = 0;
+           word = sp;
+       }
+    }
+}
+
+/*
+ * Print a button
+ */
+void
+print_button (WINDOW * win, const char *label, int y, int x, int selected)
+{
+    int i, temp;
+
+    wmove (win, y, x);
+    wattrset (win, selected ? button_active_attr : button_inactive_attr);
+    waddstr (win, "<");
+    temp = strspn (label, " ");
+    label += temp;
+    wattrset (win, selected ? button_label_active_attr
+             : button_label_inactive_attr);
+    for (i = 0; i < temp; i++)
+       waddch (win, ' ');
+    wattrset (win, selected ? button_key_active_attr
+             : button_key_inactive_attr);
+    waddch (win, label[0]);
+    wattrset (win, selected ? button_label_active_attr
+             : button_label_inactive_attr);
+    waddstr (win, (char *)label + 1);
+    wattrset (win, selected ? button_active_attr : button_inactive_attr);
+    waddstr (win, ">");
+    wmove (win, y, x + temp + 1);
+}
+
+/*
+ * Draw a rectangular box with line drawing characters
+ */
+void
+draw_box (WINDOW * win, int y, int x, int height, int width,
+         chtype box, chtype border)
+{
+    int i, j;
+
+    wattrset (win, 0);
+    for (i = 0; i < height; i++) {
+       wmove (win, y + i, x);
+       for (j = 0; j < width; j++)
+           if (!i && !j)
+               waddch (win, border | ACS_ULCORNER);
+           else if (i == height - 1 && !j)
+               waddch (win, border | ACS_LLCORNER);
+           else if (!i && j == width - 1)
+               waddch (win, box | ACS_URCORNER);
+           else if (i == height - 1 && j == width - 1)
+               waddch (win, box | ACS_LRCORNER);
+           else if (!i)
+               waddch (win, border | ACS_HLINE);
+           else if (i == height - 1)
+               waddch (win, box | ACS_HLINE);
+           else if (!j)
+               waddch (win, border | ACS_VLINE);
+           else if (j == width - 1)
+               waddch (win, box | ACS_VLINE);
+           else
+               waddch (win, box | ' ');
+    }
+}
+
+/*
+ * Draw shadows along the right and bottom edge to give a more 3D look
+ * to the boxes
+ */
+void
+draw_shadow (WINDOW * win, int y, int x, int height, int width)
+{
+    int i;
+
+    if (has_colors ()) {       /* Whether terminal supports color? */
+       wattrset (win, shadow_attr);
+       wmove (win, y + height, x + 2);
+       for (i = 0; i < width; i++)
+           waddch (win, winch (win) & A_CHARTEXT);
+       for (i = y + 1; i < y + height + 1; i++) {
+           wmove (win, i, x + width);
+           waddch (win, winch (win) & A_CHARTEXT);
+           waddch (win, winch (win) & A_CHARTEXT);
+       }
+       wnoutrefresh (win);
+    }
+}
+
+/*
+ *  Return the position of the first alphabetic character in a string.
+ */
+int
+first_alpha(const char *string, const char *exempt)
+{
+       int i, in_paren=0, c;
+
+       for (i = 0; i < strlen(string); i++) {
+               c = tolower(string[i]);
+
+               if (strchr("<[(", c)) ++in_paren;
+               if (strchr(">])", c) && in_paren > 0) --in_paren;
+
+               if ((! in_paren) && isalpha(c) && 
+                    strchr(exempt, c) == 0)
+                       return i;
+       }
+
+       return 0;
+}
+
+/*
+ * Get the first selected item in the dialog_list_item list.
+ */
+struct dialog_list_item *
+first_sel_item(int item_no, struct dialog_list_item ** items)
+{
+       int i;
+
+       for (i = 0; i < item_no; i++) {
+               if (items[i]->selected)
+                       return items[i];
+       }
+
+       return NULL;
+}
diff --git a/busybox/scripts/config/lxdialog/yesno.c b/busybox/scripts/config/lxdialog/yesno.c
new file mode 100644 (file)
index 0000000..11fcc25
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ *  yesno.c -- implements the yes/no box
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+/*
+ * Display termination buttons
+ */
+static void
+print_buttons(WINDOW *dialog, int height, int width, int selected)
+{
+    int x = width / 2 - 10;
+    int y = height - 2;
+
+    print_button (dialog, " Yes ", y, x, selected == 0);
+    print_button (dialog, "  No  ", y, x + 13, selected == 1);
+
+    wmove(dialog, y, x+1 + 13*selected );
+    wrefresh (dialog);
+}
+
+/*
+ * Display a dialog box with two buttons - Yes and No
+ */
+int
+dialog_yesno (const char *title, const char *prompt, int height, int width)
+{
+    int i, x, y, key = 0, button = 0;
+    WINDOW *dialog;
+
+    /* center dialog box on screen */
+    x = (COLS - width) / 2;
+    y = (LINES - height) / 2;
+
+    draw_shadow (stdscr, y, x, height, width);
+
+    dialog = newwin (height, width, y, x);
+    keypad (dialog, TRUE);
+
+    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
+    wattrset (dialog, border_attr);
+    mvwaddch (dialog, height-3, 0, ACS_LTEE);
+    for (i = 0; i < width - 2; i++)
+       waddch (dialog, ACS_HLINE);
+    wattrset (dialog, dialog_attr);
+    waddch (dialog, ACS_RTEE);
+
+    if (title != NULL && strlen(title) >= width-2 ) {
+       /* truncate long title -- mec */
+       char * title2 = malloc(width-2+1);
+       memcpy( title2, title, width-2 );
+       title2[width-2] = '\0';
+       title = title2;
+    }
+
+    if (title != NULL) {
+       wattrset (dialog, title_attr);
+       mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
+       waddstr (dialog, (char *)title);
+       waddch (dialog, ' ');
+    }
+
+    wattrset (dialog, dialog_attr);
+    print_autowrap (dialog, prompt, width - 2, 1, 3);
+
+    print_buttons(dialog, height, width, 0);
+
+    while (key != ESC) {
+       key = wgetch (dialog);
+       switch (key) {
+       case 'Y':
+       case 'y':
+           delwin (dialog);
+           return 0;
+       case 'N':
+       case 'n':
+           delwin (dialog);
+           return 1;
+
+       case TAB:
+       case KEY_LEFT:
+       case KEY_RIGHT:
+           button = ((key == KEY_LEFT ? --button : ++button) < 0)
+                       ? 1 : (button > 1 ? 0 : button);
+
+           print_buttons(dialog, height, width, button);
+           wrefresh (dialog);
+           break;
+       case ' ':
+       case '\n':
+           delwin (dialog);
+           return button;
+       case ESC:
+           break;
+       }
+    }
+
+    delwin (dialog);
+    return -1;                 /* ESC pressed */
+}
index 63b4ff72f456452bcfb3d59f1bf67395210d6456..5bc2abdd87313e542684e405bce869df75d287d5 100644 (file)
 #include <termios.h>
 #include <unistd.h>
 
-#include "dialog.h"
+#include "lxdialog/dialog.h"
 
 #define LKC_DIRECT_LINK
 #include "lkc.h"
 
 static char menu_backtitle[128];
-static const char menu_instructions[] =
+static const char mconf_readme[] =
+"Overview\n"
+"--------\n"
+"Some features may be built directly into BusyBox.  Some features\n"
+"may be completely removed altogether.  There are also certain\n"
+"parameters which are not really features, but must be\n"
+"entered in as decimal or hexadecimal numbers or possibly text.\n"
+"\n"
+"Menu items beginning with [*] or [ ] represent features\n"
+"configured to be built in or removed respectively.\n"
+"\n"
+"To change any of these features, highlight it with the cursor\n"
+"keys and press <Y> to build it in or <N> to removed it.\n"
+"You may also press the <Space Bar> to cycle\n"
+"through the available options (ie. Y->N->Y).\n"
+"\n"
+"Some additional keyboard hints:\n"
+"\n"
+"Menus\n"
+"----------\n"
+"o  Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
+"   you wish to change or submenu wish to select and press <Enter>.\n"
+"   Submenus are designated by \"--->\".\n"
+"\n"
+"   Shortcut: Press the option's highlighted letter (hotkey).\n"
+"             Pressing a hotkey more than once will sequence\n"
+"             through all visible items which use that hotkey.\n"
+"\n"
+"   You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
+"   unseen options into view.\n"
+"\n"
+"o  To exit a menu use the cursor keys to highlight the <Exit> button\n"
+"   and press <ENTER>.\n"
+"\n"
+"   Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey\n"
+"             using those letters.  You may press a single <ESC>, but\n"
+"             there is a delayed response which you may find annoying.\n"
+"\n"
+"   Also, the <TAB> and cursor keys will cycle between <Select>,\n"
+"   <Exit> and <Help>\n"
+"\n"
+"o  To get help with an item, use the cursor keys to highlight <Help>\n"
+"   and Press <ENTER>.\n"
+"\n"
+"   Shortcut: Press <H> or <?>.\n"
+"\n"
+"\n"
+"Radiolists  (Choice lists)\n"
+"-----------\n"
+"o  Use the cursor keys to select the option you wish to set and press\n"
+"   <S> or the <SPACE BAR>.\n"
+"\n"
+"   Shortcut: Press the first letter of the option you wish to set then\n"
+"             press <S> or <SPACE BAR>.\n"
+"\n"
+"o  To see available help for the item, use the cursor keys to highlight\n"
+"   <Help> and Press <ENTER>.\n"
+"\n"
+"   Shortcut: Press <H> or <?>.\n"
+"\n"
+"   Also, the <TAB> and cursor keys will cycle between <Select> and\n"
+"   <Help>\n"
+"\n"
+"\n"
+"Data Entry\n"
+"-----------\n"
+"o  Enter the requested information and press <ENTER>\n"
+"   If you are entering hexadecimal values, it is not necessary to\n"
+"   add the '0x' prefix to the entry.\n"
+"\n"
+"o  For help, use the <TAB> or cursor keys to highlight the help option\n"
+"   and press <ENTER>.  You can try <TAB><H> as well.\n"
+"\n"
+"\n"
+"Text Box    (Help Window)\n"
+"--------\n"
+"o  Use the cursor keys to scroll up/down/left/right.  The VI editor\n"
+"   keys h,j,k,l function here as do <SPACE BAR> and <B> for those\n"
+"   who are familiar with less and lynx.\n"
+"\n"
+"o  Press <E>, <X>, <Enter> or <Esc><Esc> to exit.\n"
+"\n"
+"\n"
+"Alternate Configuration Files\n"
+"-----------------------------\n"
+"Menuconfig supports the use of alternate configuration files for\n"
+"those who, for various reasons, find it necessary to switch\n"
+"between different configurations.\n"
+"\n"
+"At the end of the main menu you will find two options.  One is\n"
+"for saving the current configuration to a file of your choosing.\n"
+"The other option is for loading a previously saved alternate\n"
+"configuration.\n"
+"\n"
+"Even if you don't use alternate configuration files, but you\n"
+"find during a Menuconfig session that you have completely messed\n"
+"up your settings, you may use the \"Load Alternate...\" option to\n"
+"restore your previously saved settings from \".config\" without\n"
+"restarting Menuconfig.\n"
+"\n"
+"Other information\n"
+"-----------------\n"
+"If you use Menuconfig in an XTERM window make sure you have your\n"
+"$TERM variable set to point to a xterm definition which supports color.\n"
+"Otherwise, Menuconfig will look rather bad.  Menuconfig will not\n"
+"display correctly in a RXVT window because rxvt displays only one\n"
+"intensity of color, bright.\n"
+"\n"
+"Menuconfig will display larger menus on screens or xterms which are\n"
+"set to display more than the standard 25 row by 80 column geometry.\n"
+"In order for this to work, the \"stty size\" command must be able to\n"
+"display the screen's current row and column geometry.  I STRONGLY\n"
+"RECOMMEND that you make sure you do NOT have the shell variables\n"
+"LINES and COLUMNS exported into your environment.  Some distributions\n"
+"export those variables via /etc/profile.  Some ncurses programs can\n"
+"become confused when those variables (LINES & COLUMNS) don't reflect\n"
+"the true screen size.\n"
+"\n"
+"Optional personality available\n"
+"------------------------------\n"
+"If you prefer to have all of the options listed in a single\n"
+"menu, rather than the default multimenu hierarchy, run the menuconfig\n"
+"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
+"\n"
+"make MENUCONFIG_MODE=single_menu menuconfig\n"
+"\n"
+"<Enter> will then unroll the appropriate category, or enfold it if it\n"
+"is already unrolled.\n"
+"\n"
+"Note that this mode can eventually be a little more CPU expensive\n"
+"(especially with a larger number of unrolled categories) than the\n"
+"default mode.\n",
+menu_instructions[] =
        "Arrow keys navigate the menu.  "
        "<Enter> selects submenus --->.  "
        "Highlighted letters are hotkeys.  "
        "Pressing <Y> selectes a feature, while <N> will exclude a feature.  "
-       "Press <Esc><Esc> to exit, <?> for Help.  "
+       "Press <Esc><Esc> to exit, <?> for Help, </> for Search.  "
        "Legend: [*] feature is selected  [ ] feature is excluded",
 radiolist_instructions[] =
        "Use the arrow keys to navigate this window or "
@@ -85,23 +217,50 @@ save_config_help[] =
        "\n"
        "If you are uncertain what all this means then you should probably\n"
        "leave this blank.\n",
-top_menu_help[] =
+search_help[] =
        "\n"
-       "Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
-       "you wish to change or submenu wish to select and press <Enter>.\n"
-       "Submenus are designated by \"--->\".\n"
+       "Search for CONFIG_ symbols and display their relations.\n"
+       "Example: search for \"^FOO\"\n"
+       "Result:\n"
+       "-----------------------------------------------------------------\n"
+       "Symbol: FOO [=m]\n"
+       "Prompt: Foo bus is used to drive the bar HW\n"
+       "Defined at drivers/pci/Kconfig:47\n"
+       "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
+       "Location:\n"
+       "  -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
+       "    -> PCI support (PCI [=y])\n"
+       "      -> PCI access mode (<choice> [=y])\n"
+       "Selects: LIBCRC32\n"
+       "Selected by: BAR\n"
+       "-----------------------------------------------------------------\n"
+       "o The line 'Prompt:' shows the text used in the menu structure for\n"
+       "  this CONFIG_ symbol\n"
+       "o The 'Defined at' line tell at what file / line number the symbol\n"
+       "  is defined\n"
+       "o The 'Depends on:' line tell what symbols needs to be defined for\n"
+       "  this symbol to be visible in the menu (selectable)\n"
+       "o The 'Location:' lines tell where in the menu structure this symbol\n"
+       "  is located\n"
+       "    A location followed by a [=y] indicate that this is a selectable\n"
+       "    menu item - and current value is displayed inside brackets.\n"
+       "o The 'Selects:' line tell what symbol will be automatically\n"
+       "  selected if this symbol is selected (y or m)\n"
+       "o The 'Selected by' line tell what symbol has selected this symbol\n"
        "\n"
-       "Shortcut: Press the option's highlighted letter (hotkey).\n"
-       "\n"
-       "You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
-       "unseen options into view.\n"
-;
+       "Only relevant lines are shown.\n"
+       "\n\n"
+       "Search examples:\n"
+       "Examples: USB  => find all CONFIG_ symbols containing USB\n"
+       "          ^USB => find all CONFIG_ symbols starting with USB\n"
+       "          USB$ => find all CONFIG_ symbols ending with USB\n"
+       "\n";
 
 static char filename[PATH_MAX+1] = ".config";
-static int indent = 0;
+static int indent;
 static struct termios ios_org;
-static int rows, cols;
-struct menu *current_menu;
+static int rows = 0, cols = 0;
+static struct menu *current_menu;
 static int child_count;
 static int single_menu_mode;
 
@@ -116,33 +275,31 @@ static void conf_save(void);
 static void show_textbox(const char *title, const char *text, int r, int c);
 static void show_helptext(const char *title, const char *text);
 static void show_help(struct menu *menu);
-static void show_readme(void);
+static void show_file(const char *filename, const char *title, int r, int c);
 
 static void init_wsize(void)
 {
        struct winsize ws;
        char *env;
 
-       if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
-               rows = 24;
-               cols = 80;
-       } else {
+       if (!ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)) {
                rows = ws.ws_row;
                cols = ws.ws_col;
-               if (!rows) {
-                       env = getenv("LINES");
-                       if (env)
-                               rows = atoi(env);
-                       if (!rows)
-                               rows = 24;
-               }
-               if (!cols) {
-                       env = getenv("COLUMNS");
-                       if (env)
-                               cols = atoi(env);
-                       if (!cols)
-                               cols = 80;
-               }
+       }
+
+       if (!rows) {
+               env = getenv("LINES");
+               if (env)
+                       rows = atoi(env);
+               if (!rows)
+                       rows = 24;
+       }
+       if (!cols) {
+               env = getenv("COLUMNS");
+               if (env)
+                       cols = atoi(env);
+               if (!cols)
+                       cols = 80;
        }
 
        if (rows < 19 || cols < 80) {
@@ -214,6 +371,103 @@ static void cdone(void)
        item_no = 0;
 }
 
+static void get_prompt_str(struct gstr *r, struct property *prop)
+{
+       int i, j;
+       struct menu *submenu[8], *menu;
+
+       str_printf(r, "Prompt: %s\n", prop->text);
+       str_printf(r, "  Defined at %s:%d\n", prop->menu->file->name,
+               prop->menu->lineno);
+       if (!expr_is_yes(prop->visible.expr)) {
+               str_append(r, "  Depends on: ");
+               expr_gstr_print(prop->visible.expr, r);
+               str_append(r, "\n");
+       }
+       menu = prop->menu->parent;
+       for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
+               submenu[i++] = menu;
+       if (i > 0) {
+               str_printf(r, "  Location:\n");
+               for (j = 4; --i >= 0; j += 2) {
+                       menu = submenu[i];
+                       str_printf(r, "%*c-> %s", j, ' ', menu_get_prompt(menu));
+                       if (menu->sym) {
+                               str_printf(r, " (%s [=%s])", menu->sym->name ?
+                                       menu->sym->name : "<choice>",
+                                       sym_get_string_value(menu->sym));
+                       }
+                       str_append(r, "\n");
+               }
+       }
+}
+
+static void get_symbol_str(struct gstr *r, struct symbol *sym)
+{
+       bool hit;
+       struct property *prop;
+
+       str_printf(r, "Symbol: %s [=%s]\n", sym->name,
+                                      sym_get_string_value(sym));
+       for_all_prompts(sym, prop)
+               get_prompt_str(r, prop);
+       hit = false;
+       for_all_properties(sym, prop, P_SELECT) {
+               if (!hit) {
+                       str_append(r, "  Selects: ");
+                       hit = true;
+               } else
+                       str_printf(r, " && ");
+               expr_gstr_print(prop->expr, r);
+       }
+       if (hit)
+               str_append(r, "\n");
+       if (sym->rev_dep.expr) {
+               str_append(r, "  Selected by: ");
+               expr_gstr_print(sym->rev_dep.expr, r);
+               str_append(r, "\n");
+       }
+       str_append(r, "\n\n");
+}
+
+static struct gstr get_relations_str(struct symbol **sym_arr)
+{
+       struct symbol *sym;
+       struct gstr res = str_new();
+       int i;
+
+       for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
+               get_symbol_str(&res, sym);
+       if (!i)
+               str_append(&res, "No matches found.\n");
+       return res;
+}
+
+static void search_conf(void)
+{
+       struct symbol **sym_arr;
+       struct gstr res;
+
+again:
+       switch (dialog_inputbox("Search Configuration Parameter",
+                               "Enter Keyword", 10, 75,
+                               NULL)) {
+       case 0:
+               break;
+       case 1:
+               show_helptext("Search Configuration", search_help);
+               goto again;
+       default:
+               return;
+       }
+
+       sym_arr = sym_re_search(dialog_input_result);
+       res = get_relations_str(sym_arr);
+       free(sym_arr);
+       show_textbox("Search Results", str_get(&res), 0, 0);
+       str_free(&res);
+}
+
 static void build_conf(struct menu *menu)
 {
        struct symbol *sym;
@@ -308,6 +562,11 @@ static void build_conf(struct menu *menu)
                        return;
                }
        } else {
+               if (menu == current_menu) {
+                       cprint_tag(":%p", menu);
+                       cprint_name("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+                       goto conf_childs;
+               }
                child_count++;
                val = sym_get_tristate_value(sym);
                if (sym_is_choice_value(sym) && val == yes) {
@@ -376,7 +635,7 @@ static void conf(struct menu *menu)
        while (1) {
                indent = 0;
                child_count = 0;
-               current_menu = menu;
+               current_menu = menu;
                cdone(); cinit();
                build_conf(menu);
                if (!child_count)
@@ -441,7 +700,7 @@ static void conf(struct menu *menu)
                        if (sym)
                                show_help(submenu);
                        else
-                               show_readme();
+                               show_helptext("README", mconf_readme);
                        break;
                case 3:
                        if (type == 't') {
@@ -465,6 +724,9 @@ static void conf(struct menu *menu)
                        else if (type == 'm')
                                conf(submenu);
                        break;
+               case 7:
+                       search_conf();
+                       break;
                }
        }
 }
@@ -476,37 +738,39 @@ static void show_textbox(const char *title, const char *text, int r, int c)
        fd = creat(".help.tmp", 0777);
        write(fd, text, strlen(text));
        close(fd);
-       while (dialog_textbox(title, ".help.tmp", r, c) < 0)
-               ;
+       show_file(".help.tmp", title, r, c);
        unlink(".help.tmp");
 }
 
 static void show_helptext(const char *title, const char *text)
 {
-       show_textbox(title, text, rows, cols);
+       show_textbox(title, text, 0, 0);
 }
 
 static void show_help(struct menu *menu)
 {
-       const char *help;
-       char *helptext;
+       struct gstr help = str_new();
        struct symbol *sym = menu->sym;
 
-       help = sym->help;
-       if (!help)
-               help = nohelp_text;
-       if (sym->name) {
-               helptext = malloc(strlen(sym->name) + strlen(help) + 16);
-               sprintf(helptext, "%s:\n\n%s", sym->name, help);
-               show_helptext(menu_get_prompt(menu), helptext);
-               free(helptext);
-       } else
-               show_helptext(menu_get_prompt(menu), help);
+       if (sym->help)
+       {
+               if (sym->name) {
+                       str_printf(&help, "%s:\n\n", sym->name);
+                       str_append(&help, sym->help);
+                       str_append(&help, "\n");
+               }
+       } else {
+               str_append(&help, nohelp_text);
+       }
+       get_symbol_str(&help, sym);
+       show_helptext(menu_get_prompt(menu), str_get(&help));
+       str_free(&help);
 }
 
-static void show_readme(void)
+static void show_file(const char *filename, const char *title, int r, int c)
 {
-       show_helptext("Help", top_menu_help);
+       while (dialog_textbox(title, filename, r ? r : rows, c ? c : cols) < 0)
+               ;
 }
 
 static void conf_choice(struct menu *menu)
@@ -667,9 +931,9 @@ static void winch_handler(int sig)
 
 int main(int ac, char **av)
 {
-       int stat;
-       char *mode;
        struct symbol *sym;
+       char *mode;
+       int stat;
 
        conf_parse(av[1]);
        conf_read(NULL);
@@ -697,7 +961,7 @@ int main(int ac, char **av)
        init_dialog();
        do {
                stat = dialog_yesno(NULL,
-                               "Do you wish to save your new BusyBox configuration?", 5, 60);
+                                   "Do you wish to save your new BusyBox configuration?", 5, 60);
        } while (stat < 0);
        end_dialog();
 
index 6425296fc334893702cb317d1d3fab64a7616e27..0c13156f33441fc8fc787b92ab038b752c87a563 100644 (file)
@@ -10,7 +10,6 @@
 #include "lkc.h"
 
 struct menu rootmenu;
-struct menu *current_menu, *current_entry;
 static struct menu **last_entry_ptr;
 
 struct file *file_list;
@@ -389,43 +388,3 @@ struct menu *menu_get_parent_menu(struct menu *menu)
        return menu;
 }
 
-struct file *file_lookup(const char *name)
-{
-       struct file *file;
-
-       for (file = file_list; file; file = file->next) {
-               if (!strcmp(name, file->name))
-                       return file;
-       }
-
-       file = malloc(sizeof(*file));
-       memset(file, 0, sizeof(*file));
-       file->name = strdup(name);
-       file->next = file_list;
-       file_list = file;
-       return file;
-}
-
-int file_write_dep(const char *name)
-{
-       struct file *file;
-       FILE *out;
-
-       if (!name)
-               name = ".config.cmd";
-       out = fopen(".config.tmp", "w");
-       if (!out)
-               return 1;
-       fprintf(out, "deps_config := \\\n");
-       for (file = file_list; file; file = file->next) {
-               if (file->next)
-                       fprintf(out, "\t%s \\\n", file->name);
-               else
-                       fprintf(out, "\t%s\n", file->name);
-       }
-       fprintf(out, "\n.config include/config.h: $(deps_config)\n\n$(deps_config):\n");
-       fclose(out);
-       rename(".config.tmp", name);
-       return 0;
-}
-
diff --git a/busybox/scripts/config/menubox.c b/busybox/scripts/config/menubox.c
deleted file mode 100644 (file)
index 431f09f..0000000
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- *  menubox.c -- implements the menu box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- *  Changes by Clifford Wolf (god@clifford.at)
- *
- *  [ 1998-06-13 ]
- *
- *    *)  A bugfix for the Page-Down problem
- *
- *    *)  Formerly when I used Page Down and Page Up, the cursor would be set
- *        to the first position in the menu box.  Now lxdialog is a bit
- *        smarter and works more like other menu systems (just have a look at
- *        it).
- *
- *    *)  Formerly if I selected something my scrolling would be broken because
- *        lxdialog is re-invoked by the Menuconfig shell script, can't
- *        remember the last scrolling position, and just sets it so that the
- *        cursor is at the bottom of the box.  Now it writes the temporary file
- *        lxdialog.scrltmp which contains this information. The file is
- *        deleted by lxdialog if the user leaves a submenu or enters a new
- *        one, but it would be nice if Menuconfig could make another "rm -f"
- *        just to be sure.  Just try it out - you will recognise a difference!
- *
- *  [ 1998-06-14 ]
- *
- *    *)  Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
- *        and menus change their size on the fly.
- *
- *    *)  If for some reason the last scrolling position is not saved by
- *        lxdialog, it sets the scrolling so that the selected item is in the
- *        middle of the menu box, not at the bottom.
- *
- * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
- * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
- * This fixes a bug in Menuconfig where using ' ' to descend into menus
- * would leave mis-synchronized lxdialog.scrltmp files lying around,
- * fscanf would read in 'scroll', and eventually that value would get used.
- */
-
-#include "dialog.h"
-
-static int menu_width, item_x;
-
-/*
- * Print menu item
- */
-static void
-print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey)
-{
-    int j;
-    char menu_item[menu_width+1];
-
-    strncpy(menu_item, item, menu_width);
-    menu_item[menu_width] = 0;
-    j = first_alpha(menu_item, "YyNnMm");
-
-    /* Clear 'residue' of last item */
-    wattrset (win, menubox_attr);
-    wmove (win, choice, 0);
-#if OLD_NCURSES
-    {
-        int i;
-        for (i = 0; i < menu_width; i++)
-           waddch (win, ' ');
-    }
-#else
-    wclrtoeol(win);
-#endif
-    wattrset (win, selected ? item_selected_attr : item_attr);
-    mvwaddstr (win, choice, item_x, menu_item);
-    if (hotkey) {
-       wattrset (win, selected ? tag_key_selected_attr : tag_key_attr);
-       mvwaddch(win, choice, item_x+j, menu_item[j]);
-    }
-    if (selected) {
-       wmove (win, choice, item_x+1);
-       wrefresh (win);
-    }
-}
-
-/*
- * Print the scroll indicators.
- */
-static void
-print_arrows (WINDOW * win, int item_no, int scroll,
-               int y, int x, int height)
-{
-    int cur_y, cur_x;
-
-    getyx(win, cur_y, cur_x);
-
-    wmove(win, y, x);
-
-    if (scroll > 0) {
-       wattrset (win, uarrow_attr);
-       waddch (win, ACS_UARROW);
-       waddstr (win, "(-)");
-    }
-    else {
-       wattrset (win, menubox_attr);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-    }
-
-   y = y + height + 1;
-   wmove(win, y, x);
-
-   if ((height < item_no) && (scroll + height < item_no)) {
-       wattrset (win, darrow_attr);
-       waddch (win, ACS_DARROW);
-       waddstr (win, "(+)");
-    }
-    else {
-       wattrset (win, menubox_border_attr);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-   }
-
-   wmove(win, cur_y, cur_x);
-}
-
-/*
- * Display the termination buttons.
- */
-static void
-print_buttons (WINDOW *win, int height, int width, int selected)
-{
-    int x = width / 2 - 16;
-    int y = height - 2;
-
-    print_button (win, "Select", y, x, selected == 0);
-    print_button (win, " Exit ", y, x + 12, selected == 1);
-    print_button (win, " Help ", y, x + 24, selected == 2);
-
-    wmove(win, y, x+1+12*selected);
-    wrefresh (win);
-}
-
-/*
- * Display a menu for choosing among a number of options
- */
-int
-dialog_menu (const char *title, const char *prompt, int height, int width,
-               int menu_height, const char *current, int item_no,
-               struct dialog_list_item ** items)
-{
-    int i, j, x, y, box_x, box_y;
-    int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice;
-    WINDOW *dialog, *menu;
-    FILE *f;
-
-    max_choice = MIN (menu_height, item_no);
-
-    /* center dialog box on screen */
-    x = (COLS - width) / 2;
-    y = (LINES - height) / 2;
-
-    draw_shadow (stdscr, y, x, height, width);
-
-    dialog = newwin (height, width, y, x);
-    keypad (dialog, TRUE);
-
-    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-    wattrset (dialog, border_attr);
-    mvwaddch (dialog, height - 3, 0, ACS_LTEE);
-    for (i = 0; i < width - 2; i++)
-       waddch (dialog, ACS_HLINE);
-    wattrset (dialog, dialog_attr);
-    wbkgdset (dialog, dialog_attr & A_COLOR);
-    waddch (dialog, ACS_RTEE);
-
-    if (title != NULL && strlen(title) >= width-2 ) {
-       /* truncate long title -- mec */
-       char * title2 = malloc(width-2+1);
-       memcpy( title2, title, width-2 );
-       title2[width-2] = '\0';
-       title = title2;
-    }
-
-    if (title != NULL) {
-       wattrset (dialog, title_attr);
-       mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-       waddstr (dialog, (char *)title);
-       waddch (dialog, ' ');
-    }
-
-    wattrset (dialog, dialog_attr);
-    print_autowrap (dialog, prompt, width - 2, 1, 3);
-
-    menu_width = width - 6;
-    box_y = height - menu_height - 5;
-    box_x = (width - menu_width) / 2 - 1;
-
-    /* create new window for the menu */
-    menu = subwin (dialog, menu_height, menu_width,
-               y + box_y + 1, x + box_x + 1);
-    keypad (menu, TRUE);
-
-    /* draw a box around the menu items */
-    draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2,
-             menubox_border_attr, menubox_attr);
-
-    /*
-     * Find length of longest item in order to center menu.
-     * Set 'choice' to default item.
-     */
-    item_x = 0;
-    for (i = 0; i < item_no; i++) {
-       item_x = MAX (item_x, MIN(menu_width, strlen (items[i]->name) + 2));
-       if (strcmp(current, items[i]->tag) == 0) choice = i;
-    }
-
-    item_x = (menu_width - item_x) / 2;
-
-    /* get the scroll info from the temp file */
-    if ( (f=fopen("lxdialog.scrltmp","r")) != NULL ) {
-       if ( (fscanf(f,"%d\n",&scroll) == 1) && (scroll <= choice) &&
-            (scroll+max_choice > choice) && (scroll >= 0) &&
-            (scroll+max_choice <= item_no) ) {
-           first_item = scroll;
-           choice = choice - scroll;
-           fclose(f);
-       } else {
-           scroll=0;
-           remove("lxdialog.scrltmp");
-           fclose(f);
-           f=NULL;
-       }
-    }
-    if ( (choice >= max_choice) || (f==NULL && choice >= max_choice/2) ) {
-       if (choice >= item_no-max_choice/2)
-           scroll = first_item = item_no-max_choice;
-       else
-           scroll = first_item = choice - max_choice/2;
-       choice = choice - scroll;
-    }
-
-    /* Print the menu */
-    for (i=0; i < max_choice; i++) {
-       print_item (menu, items[first_item + i]->name, i, i == choice,
-                    (items[first_item + i]->tag[0] != ':'));
-    }
-
-    wnoutrefresh (menu);
-
-    print_arrows(dialog, item_no, scroll,
-                box_y, box_x+item_x+1, menu_height);
-
-    print_buttons (dialog, height, width, 0);
-    wmove (menu, choice, item_x+1);
-    wrefresh (menu);
-
-    while (key != ESC) {
-       key = wgetch(menu);
-
-       if (key < 256 && isalpha(key)) key = tolower(key);
-
-       if (strchr("ynm", key))
-               i = max_choice;
-       else {
-        for (i = choice+1; i < max_choice; i++) {
-               j = first_alpha(items[scroll + i]->name, "YyNnMm>");
-               if (key == tolower(items[scroll + i]->name[j]))
-                       break;
-       }
-       if (i == max_choice)
-                       for (i = 0; i < max_choice; i++) {
-                       j = first_alpha(items[scroll + i]->name, "YyNnMm>");
-                       if (key == tolower(items[scroll + i]->name[j]))
-                               break;
-               }
-       }
-
-       if (i < max_choice ||
-            key == KEY_UP || key == KEY_DOWN ||
-            key == '-' || key == '+' ||
-            key == KEY_PPAGE || key == KEY_NPAGE) {
-
-            print_item (menu, items[scroll + choice]->name, choice, FALSE,
-                       (items[scroll + choice]->tag[0] != ':'));
-
-           if (key == KEY_UP || key == '-') {
-                if (choice < 2 && scroll) {
-                   /* Scroll menu down */
-                    scrollok (menu, TRUE);
-                    wscrl (menu, -1);
-                    scrollok (menu, FALSE);
-
-                    scroll--;
-
-                    print_item (menu, items[scroll]->name, 0, FALSE,
-                               (items[scroll]->tag[0] != ':'));
-               } else
-                   choice = MAX(choice - 1, 0);
-
-           } else if (key == KEY_DOWN || key == '+')  {
-
-               print_item (menu, items[scroll + choice]->name, choice, FALSE,
-                                (items[scroll + choice]->tag[0] != ':'));
-
-                if ((choice > max_choice-3) &&
-                    (scroll + max_choice < item_no)
-                   ) {
-                   /* Scroll menu up */
-                   scrollok (menu, TRUE);
-                    scroll (menu);
-                    scrollok (menu, FALSE);
-
-                    scroll++;
-
-                    print_item (menu, items[scroll + max_choice - 1]->name,
-                               max_choice-1, FALSE,
-                               (items[scroll + max_choice - 1]->tag[0] != ':'));
-                } else
-                    choice = MIN(choice+1, max_choice-1);
-
-           } else if (key == KEY_PPAGE) {
-               scrollok (menu, TRUE);
-                for (i=0; (i < max_choice); i++) {
-                    if (scroll > 0) {
-                       wscrl (menu, -1);
-                       scroll--;
-                       print_item (menu, items[scroll]->name, 0, FALSE,
-                       (items[scroll]->tag[0] != ':'));
-                    } else {
-                        if (choice > 0)
-                            choice--;
-                    }
-                }
-                scrollok (menu, FALSE);
-
-            } else if (key == KEY_NPAGE) {
-                for (i=0; (i < max_choice); i++) {
-                    if (scroll+max_choice < item_no) {
-                       scrollok (menu, TRUE);
-                       scroll(menu);
-                       scrollok (menu, FALSE);
-                       scroll++;
-                       print_item (menu, items[scroll + max_choice - 1]->name,
-                                   max_choice-1, FALSE,
-                                   (items[scroll + max_choice - 1]->tag[0] != ':'));
-                   } else {
-                       if (choice+1 < max_choice)
-                           choice++;
-                   }
-                }
-
-            } else
-                choice = i;
-
-            print_item (menu, items[scroll + choice]->name, choice, TRUE,
-                       (items[scroll + choice]->tag[0] != ':'));
-
-            print_arrows(dialog, item_no, scroll,
-                         box_y, box_x+item_x+1, menu_height);
-
-            wnoutrefresh (dialog);
-            wrefresh (menu);
-
-           continue;           /* wait for another key press */
-        }
-
-       switch (key) {
-       case KEY_LEFT:
-       case TAB:
-       case KEY_RIGHT:
-           button = ((key == KEY_LEFT ? --button : ++button) < 0)
-                       ? 2 : (button > 2 ? 0 : button);
-
-           print_buttons(dialog, height, width, button);
-           wrefresh (menu);
-           break;
-       case ' ':
-       case 's':
-       case 'y':
-       case 'n':
-       case 'm':
-           /* save scroll info */
-           if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) {
-               fprintf(f,"%d\n",scroll);
-               fclose(f);
-           }
-           delwin (dialog);
-            items[scroll + choice]->selected = 1;
-            switch (key) {
-            case 's': return 3;
-            case 'y': return 3;
-            case 'n': return 4;
-            case 'm': return 5;
-            case ' ': return 6;
-            }
-           return 0;
-       case 'h':
-       case '?':
-           button = 2;
-       case '\n':
-           delwin (dialog);
-           items[scroll + choice]->selected = 1;
-
-           remove("lxdialog.scrltmp");
-           return button;
-       case 'e':
-       case 'x':
-           key = ESC;
-       case ESC:
-           break;
-       }
-    }
-
-    delwin (dialog);
-    remove("lxdialog.scrltmp");
-    return -1;                 /* ESC pressed */
-}
diff --git a/busybox/scripts/config/msgbox.c b/busybox/scripts/config/msgbox.c
deleted file mode 100644 (file)
index 93692e1..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *  msgbox.c -- implements the message box and info box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-/*
- * Display a message box. Program will pause and display an "OK" button
- * if the parameter 'pause' is non-zero.
- */
-int
-dialog_msgbox (const char *title, const char *prompt, int height, int width,
-               int pause)
-{
-    int i, x, y, key = 0;
-    WINDOW *dialog;
-
-    /* center dialog box on screen */
-    x = (COLS - width) / 2;
-    y = (LINES - height) / 2;
-
-    draw_shadow (stdscr, y, x, height, width);
-
-    dialog = newwin (height, width, y, x);
-    keypad (dialog, TRUE);
-
-    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-
-    if (title != NULL && strlen(title) >= width-2 ) {
-       /* truncate long title -- mec */
-       char * title2 = malloc(width-2+1);
-       memcpy( title2, title, width-2 );
-       title2[width-2] = '\0';
-       title = title2;
-    }
-
-    if (title != NULL) {
-       wattrset (dialog, title_attr);
-       mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-       waddstr (dialog, (char *)title);
-       waddch (dialog, ' ');
-    }
-    wattrset (dialog, dialog_attr);
-    print_autowrap (dialog, prompt, width - 2, 1, 2);
-
-    if (pause) {
-       wattrset (dialog, border_attr);
-       mvwaddch (dialog, height - 3, 0, ACS_LTEE);
-       for (i = 0; i < width - 2; i++)
-           waddch (dialog, ACS_HLINE);
-       wattrset (dialog, dialog_attr);
-       waddch (dialog, ACS_RTEE);
-
-       print_button (dialog, "  Ok  ",
-                     height - 2, width / 2 - 4, TRUE);
-
-       wrefresh (dialog);
-       while (key != ESC && key != '\n' && key != ' ' &&
-               key != 'O' && key != 'o' && key != 'X' && key != 'x')
-           key = wgetch (dialog);
-    } else {
-       key = '\n';
-       wrefresh (dialog);
-    }
-
-    delwin (dialog);
-    return key == ESC ? -1 : 0;
-}
index a9fae9c13afb8c863d7ca8aaae37467e302b2981..ea629728ac1713ee4f59744a66bbee9c8dc84444 100644 (file)
@@ -6,6 +6,7 @@
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
+#include <regex.h>
 #include <sys/utsname.h>
 
 #define LKC_DIRECT_LINK
@@ -414,7 +415,7 @@ tristate sym_toggle_tristate_value(struct symbol *sym)
 
 bool sym_string_valid(struct symbol *sym, const char *str)
 {
-       char ch;
+       signed char ch;
 
        switch (sym->type) {
        case S_STRING:
@@ -649,6 +650,43 @@ struct symbol *sym_find(const char *name)
        return symbol;
 }
 
+struct symbol **sym_re_search(const char *pattern)
+{
+       struct symbol *sym, **sym_arr = NULL;
+       int i, cnt, size;
+       regex_t re;
+
+       cnt = size = 0;
+       /* Skip if empty */
+       if (strlen(pattern) == 0)
+               return NULL;
+       if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
+               return NULL;
+
+       for_all_symbols(i, sym) {
+               if (sym->flags & SYMBOL_CONST || !sym->name)
+                       continue;
+               if (regexec(&re, sym->name, 0, NULL, 0))
+                       continue;
+               if (cnt + 1 >= size) {
+                       void *tmp = sym_arr;
+                       size += 16;
+                       sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
+                       if (!sym_arr) {
+                               free(tmp);
+                               return NULL;
+                       }
+               }
+               sym_arr[cnt++] = sym;
+       }
+       if (sym_arr)
+               sym_arr[cnt] = NULL;
+       regfree(&re);
+
+       return sym_arr;
+}
+
+
 struct symbol *sym_check_deps(struct symbol *sym);
 
 static struct symbol *sym_check_expr_deps(struct expr *e)
diff --git a/busybox/scripts/config/textbox.c b/busybox/scripts/config/textbox.c
deleted file mode 100644 (file)
index a5a460b..0000000
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- *  textbox.c -- implements the text box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-static void back_lines (int n);
-static void print_page (WINDOW * win, int height, int width);
-static void print_line (WINDOW * win, int row, int width);
-static char *get_line (void);
-static void print_position (WINDOW * win, int height, int width);
-
-static int hscroll, fd, file_size, bytes_read;
-static int begin_reached = 1, end_reached, page_length;
-static char *buf, *page;
-
-/*
- * Display text from a file in a dialog box.
- */
-int
-dialog_textbox (const char *title, const char *file, int height, int width)
-{
-    int i, x, y, cur_x, cur_y, fpos, key = 0;
-    int passed_end;
-    char search_term[MAX_LEN + 1];
-    WINDOW *dialog, *text;
-
-    search_term[0] = '\0';     /* no search term entered yet */
-
-    /* Open input file for reading */
-    if ((fd = open (file, O_RDONLY)) == -1) {
-       endwin ();
-       fprintf (stderr,
-                "\nCan't open input file in dialog_textbox().\n");
-       exit (-1);
-    }
-    /* Get file size. Actually, 'file_size' is the real file size - 1,
-       since it's only the last byte offset from the beginning */
-    if ((file_size = lseek (fd, 0, SEEK_END)) == -1) {
-       endwin ();
-       fprintf (stderr, "\nError getting file size in dialog_textbox().\n");
-       exit (-1);
-    }
-    /* Restore file pointer to beginning of file after getting file size */
-    if (lseek (fd, 0, SEEK_SET) == -1) {
-       endwin ();
-       fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n");
-       exit (-1);
-    }
-    /* Allocate space for read buffer */
-    if ((buf = malloc (BUF_SIZE + 1)) == NULL) {
-       endwin ();
-       fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n");
-       exit (-1);
-    }
-    if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-       endwin ();
-       fprintf (stderr, "\nError reading file in dialog_textbox().\n");
-       exit (-1);
-    }
-    buf[bytes_read] = '\0';    /* mark end of valid data */
-    page = buf;                        /* page is pointer to start of page to be displayed */
-
-    /* center dialog box on screen */
-    x = (COLS - width) / 2;
-    y = (LINES - height) / 2;
-
-
-    draw_shadow (stdscr, y, x, height, width);
-
-    dialog = newwin (height, width, y, x);
-    keypad (dialog, TRUE);
-
-    /* Create window for text region, used for scrolling text */
-    text = subwin (dialog, height - 4, width - 2, y + 1, x + 1);
-    wattrset (text, dialog_attr);
-    wbkgdset (text, dialog_attr & A_COLOR);
-
-    keypad (text, TRUE);
-
-    /* register the new window, along with its borders */
-    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-
-    wattrset (dialog, border_attr);
-    mvwaddch (dialog, height-3, 0, ACS_LTEE);
-    for (i = 0; i < width - 2; i++)
-       waddch (dialog, ACS_HLINE);
-    wattrset (dialog, dialog_attr);
-    wbkgdset (dialog, dialog_attr & A_COLOR);
-    waddch (dialog, ACS_RTEE);
-
-    if (title != NULL && strlen(title) >= width-2 ) {
-       /* truncate long title -- mec */
-       char * title2 = malloc(width-2+1);
-       memcpy( title2, title, width-2 );
-       title2[width-2] = '\0';
-       title = title2;
-    }
-
-    if (title != NULL) {
-       wattrset (dialog, title_attr);
-       mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-       waddstr (dialog, (char *)title);
-       waddch (dialog, ' ');
-    }
-    print_button (dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
-    wnoutrefresh (dialog);
-    getyx (dialog, cur_y, cur_x);      /* Save cursor position */
-
-    /* Print first page of text */
-    attr_clear (text, height - 4, width - 2, dialog_attr);
-    print_page (text, height - 4, width - 2);
-    print_position (dialog, height, width);
-    wmove (dialog, cur_y, cur_x);      /* Restore cursor position */
-    wrefresh (dialog);
-
-    while ((key != ESC) && (key != '\n')) {
-       key = wgetch (dialog);
-       switch (key) {
-       case 'E':               /* Exit */
-       case 'e':
-       case 'X':
-       case 'x':
-           delwin (dialog);
-           free (buf);
-           close (fd);
-           return 0;
-       case 'g':               /* First page */
-       case KEY_HOME:
-           if (!begin_reached) {
-               begin_reached = 1;
-               /* First page not in buffer? */
-               if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-                   endwin ();
-                   fprintf (stderr,
-                     "\nError moving file pointer in dialog_textbox().\n");
-                   exit (-1);
-               }
-               if (fpos > bytes_read) {        /* Yes, we have to read it in */
-                   if (lseek (fd, 0, SEEK_SET) == -1) {
-                       endwin ();
-                       fprintf (stderr, "\nError moving file pointer in "
-                                "dialog_textbox().\n");
-                       exit (-1);
-                   }
-                   if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-                       endwin ();
-                       fprintf (stderr,
-                            "\nError reading file in dialog_textbox().\n");
-                       exit (-1);
-                   }
-                   buf[bytes_read] = '\0';
-               }
-               page = buf;
-               print_page (text, height - 4, width - 2);
-               print_position (dialog, height, width);
-               wmove (dialog, cur_y, cur_x);   /* Restore cursor position */
-               wrefresh (dialog);
-           }
-           break;
-       case 'G':               /* Last page */
-       case KEY_END:
-
-           end_reached = 1;
-           /* Last page not in buffer? */
-           if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-               endwin ();
-               fprintf (stderr,
-                     "\nError moving file pointer in dialog_textbox().\n");
-               exit (-1);
-           }
-           if (fpos < file_size) {     /* Yes, we have to read it in */
-               if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) {
-                   endwin ();
-                   fprintf (stderr,
-                     "\nError moving file pointer in dialog_textbox().\n");
-                   exit (-1);
-               }
-               if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-                   endwin ();
-                   fprintf (stderr,
-                            "\nError reading file in dialog_textbox().\n");
-                   exit (-1);
-               }
-               buf[bytes_read] = '\0';
-           }
-           page = buf + bytes_read;
-           back_lines (height - 4);
-           print_page (text, height - 4, width - 2);
-           print_position (dialog, height, width);
-           wmove (dialog, cur_y, cur_x);       /* Restore cursor position */
-           wrefresh (dialog);
-           break;
-       case 'K':               /* Previous line */
-       case 'k':
-       case KEY_UP:
-           if (!begin_reached) {
-               back_lines (page_length + 1);
-
-               /* We don't call print_page() here but use scrolling to ensure
-                  faster screen update. However, 'end_reached' and
-                  'page_length' should still be updated, and 'page' should
-                  point to start of next page. This is done by calling
-                  get_line() in the following 'for' loop. */
-               scrollok (text, TRUE);
-               wscrl (text, -1);       /* Scroll text region down one line */
-               scrollok (text, FALSE);
-               page_length = 0;
-               passed_end = 0;
-               for (i = 0; i < height - 4; i++) {
-                   if (!i) {
-                       /* print first line of page */
-                       print_line (text, 0, width - 2);
-                       wnoutrefresh (text);
-                   } else
-                       /* Called to update 'end_reached' and 'page' */
-                       get_line ();
-                   if (!passed_end)
-                       page_length++;
-                   if (end_reached && !passed_end)
-                       passed_end = 1;
-               }
-
-               print_position (dialog, height, width);
-               wmove (dialog, cur_y, cur_x);   /* Restore cursor position */
-               wrefresh (dialog);
-           }
-           break;
-       case 'B':               /* Previous page */
-       case 'b':
-       case KEY_PPAGE:
-           if (begin_reached)
-               break;
-           back_lines (page_length + height - 4);
-           print_page (text, height - 4, width - 2);
-           print_position (dialog, height, width);
-           wmove (dialog, cur_y, cur_x);
-           wrefresh (dialog);
-           break;
-       case 'J':               /* Next line */
-       case 'j':
-       case KEY_DOWN:
-           if (!end_reached) {
-               begin_reached = 0;
-               scrollok (text, TRUE);
-               scroll (text);  /* Scroll text region up one line */
-               scrollok (text, FALSE);
-               print_line (text, height - 5, width - 2);
-               wnoutrefresh (text);
-               print_position (dialog, height, width);
-               wmove (dialog, cur_y, cur_x);   /* Restore cursor position */
-               wrefresh (dialog);
-           }
-           break;
-       case KEY_NPAGE:         /* Next page */
-       case ' ':
-           if (end_reached)
-               break;
-
-           begin_reached = 0;
-           print_page (text, height - 4, width - 2);
-           print_position (dialog, height, width);
-           wmove (dialog, cur_y, cur_x);
-           wrefresh (dialog);
-           break;
-       case '0':               /* Beginning of line */
-       case 'H':               /* Scroll left */
-       case 'h':
-       case KEY_LEFT:
-           if (hscroll <= 0)
-               break;
-
-           if (key == '0')
-               hscroll = 0;
-           else
-               hscroll--;
-           /* Reprint current page to scroll horizontally */
-           back_lines (page_length);
-           print_page (text, height - 4, width - 2);
-           wmove (dialog, cur_y, cur_x);
-           wrefresh (dialog);
-           break;
-       case 'L':               /* Scroll right */
-       case 'l':
-       case KEY_RIGHT:
-           if (hscroll >= MAX_LEN)
-               break;
-           hscroll++;
-           /* Reprint current page to scroll horizontally */
-           back_lines (page_length);
-           print_page (text, height - 4, width - 2);
-           wmove (dialog, cur_y, cur_x);
-           wrefresh (dialog);
-           break;
-       case ESC:
-           break;
-       }
-    }
-
-    delwin (dialog);
-    free (buf);
-    close (fd);
-    return 1;                  /* ESC pressed */
-}
-
-/*
- * Go back 'n' lines in text file. Called by dialog_textbox().
- * 'page' will be updated to point to the desired line in 'buf'.
- */
-static void
-back_lines (int n)
-{
-    int i, fpos;
-
-    begin_reached = 0;
-    /* We have to distinguish between end_reached and !end_reached
-       since at end of file, the line is not ended by a '\n'.
-       The code inside 'if' basically does a '--page' to move one
-       character backward so as to skip '\n' of the previous line */
-    if (!end_reached) {
-       /* Either beginning of buffer or beginning of file reached? */
-       if (page == buf) {
-           if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-               endwin ();
-               fprintf (stderr, "\nError moving file pointer in "
-                        "back_lines().\n");
-               exit (-1);
-           }
-           if (fpos > bytes_read) {    /* Not beginning of file yet */
-               /* We've reached beginning of buffer, but not beginning of
-                  file yet, so read previous part of file into buffer.
-                  Note that we only move backward for BUF_SIZE/2 bytes,
-                  but not BUF_SIZE bytes to avoid re-reading again in
-                  print_page() later */
-               /* Really possible to move backward BUF_SIZE/2 bytes? */
-               if (fpos < BUF_SIZE / 2 + bytes_read) {
-                   /* No, move less then */
-                   if (lseek (fd, 0, SEEK_SET) == -1) {
-                       endwin ();
-                       fprintf (stderr, "\nError moving file pointer in "
-                                "back_lines().\n");
-                       exit (-1);
-                   }
-                   page = buf + fpos - bytes_read;
-               } else {        /* Move backward BUF_SIZE/2 bytes */
-                   if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR)
-                       == -1) {
-                       endwin ();
-                       fprintf (stderr, "\nError moving file pointer "
-                                "in back_lines().\n");
-                       exit (-1);
-                   }
-                   page = buf + BUF_SIZE / 2;
-               }
-               if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-                   endwin ();
-                   fprintf (stderr, "\nError reading file in back_lines().\n");
-                   exit (-1);
-               }
-               buf[bytes_read] = '\0';
-           } else {            /* Beginning of file reached */
-               begin_reached = 1;
-               return;
-           }
-       }
-       if (*(--page) != '\n') {        /* '--page' here */
-           /* Something's wrong... */
-           endwin ();
-           fprintf (stderr, "\nInternal error in back_lines().\n");
-           exit (-1);
-       }
-    }
-    /* Go back 'n' lines */
-    for (i = 0; i < n; i++)
-       do {
-           if (page == buf) {
-               if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-                   endwin ();
-                   fprintf (stderr,
-                         "\nError moving file pointer in back_lines().\n");
-                   exit (-1);
-               }
-               if (fpos > bytes_read) {
-                   /* Really possible to move backward BUF_SIZE/2 bytes? */
-                   if (fpos < BUF_SIZE / 2 + bytes_read) {
-                       /* No, move less then */
-                       if (lseek (fd, 0, SEEK_SET) == -1) {
-                           endwin ();
-                           fprintf (stderr, "\nError moving file pointer "
-                                    "in back_lines().\n");
-                           exit (-1);
-                       }
-                       page = buf + fpos - bytes_read;
-                   } else {    /* Move backward BUF_SIZE/2 bytes */
-                       if (lseek (fd, -(BUF_SIZE / 2 + bytes_read),
-                                  SEEK_CUR) == -1) {
-                           endwin ();
-                           fprintf (stderr, "\nError moving file pointer"
-                                    " in back_lines().\n");
-                           exit (-1);
-                       }
-                       page = buf + BUF_SIZE / 2;
-                   }
-                   if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-                       endwin ();
-                       fprintf (stderr, "\nError reading file in "
-                                "back_lines().\n");
-                       exit (-1);
-                   }
-                   buf[bytes_read] = '\0';
-               } else {        /* Beginning of file reached */
-                   begin_reached = 1;
-                   return;
-               }
-           }
-       } while (*(--page) != '\n');
-    page++;
-}
-
-/*
- * Print a new page of text. Called by dialog_textbox().
- */
-static void
-print_page (WINDOW * win, int height, int width)
-{
-    int i, passed_end = 0;
-
-    page_length = 0;
-    for (i = 0; i < height; i++) {
-       print_line (win, i, width);
-       if (!passed_end)
-           page_length++;
-       if (end_reached && !passed_end)
-           passed_end = 1;
-    }
-    wnoutrefresh (win);
-}
-
-/*
- * Print a new line of text. Called by dialog_textbox() and print_page().
- */
-static void
-print_line (WINDOW * win, int row, int width)
-{
-    int y, x;
-    char *line;
-
-    line = get_line ();
-    line += MIN (strlen (line), hscroll);      /* Scroll horizontally */
-    wmove (win, row, 0);       /* move cursor to correct line */
-    waddch (win, ' ');
-    waddnstr (win, line, MIN (strlen (line), width - 2));
-
-    getyx (win, y, x);
-    /* Clear 'residue' of previous line */
-#if OLD_NCURSES
-    {
-        int i;
-        for (i = 0; i < width - x; i++)
-           waddch (win, ' ');
-    }
-#else
-    wclrtoeol(win);
-#endif
-}
-
-/*
- * Return current line of text. Called by dialog_textbox() and print_line().
- * 'page' should point to start of current line before calling, and will be
- * updated to point to start of next line.
- */
-static char *
-get_line (void)
-{
-    int i = 0, fpos;
-    static char line[MAX_LEN + 1];
-
-    end_reached = 0;
-    while (*page != '\n') {
-       if (*page == '\0') {
-           /* Either end of file or end of buffer reached */
-           if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-               endwin ();
-               fprintf (stderr, "\nError moving file pointer in "
-                        "get_line().\n");
-               exit (-1);
-           }
-           if (fpos < file_size) {     /* Not end of file yet */
-               /* We've reached end of buffer, but not end of file yet,
-                  so read next part of file into buffer */
-               if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-                   endwin ();
-                   fprintf (stderr, "\nError reading file in get_line().\n");
-                   exit (-1);
-               }
-               buf[bytes_read] = '\0';
-               page = buf;
-           } else {
-               if (!end_reached)
-                   end_reached = 1;
-               break;
-           }
-       } else if (i < MAX_LEN)
-           line[i++] = *(page++);
-       else {
-           /* Truncate lines longer than MAX_LEN characters */
-           if (i == MAX_LEN)
-               line[i++] = '\0';
-           page++;
-       }
-    }
-    if (i <= MAX_LEN)
-       line[i] = '\0';
-    if (!end_reached)
-       page++;                 /* move pass '\n' */
-
-    return line;
-}
-
-/*
- * Print current position
- */
-static void
-print_position (WINDOW * win, int height, int width)
-{
-    int fpos, percent;
-
-    if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-       endwin ();
-       fprintf (stderr, "\nError moving file pointer in print_position().\n");
-       exit (-1);
-    }
-    wattrset (win, position_indicator_attr);
-    wbkgdset (win, position_indicator_attr & A_COLOR);
-    percent = !file_size ?
-       100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
-    wmove (win, height - 3, width - 9);
-    wprintw (win, "(%3d%%)", percent);
-}
index 0a2f82757003826dcf7486d0d0503f70828c19f2..a72f5ea66d371fae9e3c532f0f76376073c4380f 100644 (file)
 /*
- *  util.c
+ * Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org>
+ * Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org>
  *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-
-/* use colors by default? */
-bool use_colors = 1;
-
-char *backtitle = NULL;
-
-const char *dialog_result;
-
-/*
- * Attribute values, default is for mono display
- */
-chtype attributes[] =
-{
-    A_NORMAL,                  /* screen_attr */
-    A_NORMAL,                  /* shadow_attr */
-    A_NORMAL,                  /* dialog_attr */
-    A_BOLD,                    /* title_attr */
-    A_NORMAL,                  /* border_attr */
-    A_REVERSE,                 /* button_active_attr */
-    A_DIM,                     /* button_inactive_attr */
-    A_REVERSE,                 /* button_key_active_attr */
-    A_BOLD,                    /* button_key_inactive_attr */
-    A_REVERSE,                 /* button_label_active_attr */
-    A_NORMAL,                  /* button_label_inactive_attr */
-    A_NORMAL,                  /* inputbox_attr */
-    A_NORMAL,                  /* inputbox_border_attr */
-    A_NORMAL,                  /* searchbox_attr */
-    A_BOLD,                    /* searchbox_title_attr */
-    A_NORMAL,                  /* searchbox_border_attr */
-    A_BOLD,                    /* position_indicator_attr */
-    A_NORMAL,                  /* menubox_attr */
-    A_NORMAL,                  /* menubox_border_attr */
-    A_NORMAL,                  /* item_attr */
-    A_REVERSE,                 /* item_selected_attr */
-    A_BOLD,                    /* tag_attr */
-    A_REVERSE,                 /* tag_selected_attr */
-    A_BOLD,                    /* tag_key_attr */
-    A_REVERSE,                 /* tag_key_selected_attr */
-    A_BOLD,                    /* check_attr */
-    A_REVERSE,                 /* check_selected_attr */
-    A_BOLD,                    /* uarrow_attr */
-    A_BOLD                     /* darrow_attr */
-};
-
-
-#include "colors.h"
-
-/*
- * Table of color values
- */
-int color_table[][3] =
-{
-    {SCREEN_FG, SCREEN_BG, SCREEN_HL},
-    {SHADOW_FG, SHADOW_BG, SHADOW_HL},
-    {DIALOG_FG, DIALOG_BG, DIALOG_HL},
-    {TITLE_FG, TITLE_BG, TITLE_HL},
-    {BORDER_FG, BORDER_BG, BORDER_HL},
-    {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
-    {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
-    {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
-    {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL},
-    {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL},
-    {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
-     BUTTON_LABEL_INACTIVE_HL},
-    {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
-    {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
-    {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
-    {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
-    {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
-    {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
-    {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
-    {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
-    {ITEM_FG, ITEM_BG, ITEM_HL},
-    {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
-    {TAG_FG, TAG_BG, TAG_HL},
-    {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
-    {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
-    {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
-    {CHECK_FG, CHECK_BG, CHECK_HL},
-    {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
-    {UARROW_FG, UARROW_BG, UARROW_HL},
-    {DARROW_FG, DARROW_BG, DARROW_HL},
-};                             /* color_table */
-
-/*
- * Set window to attribute 'attr'
+ * Released under the terms of the GNU GPL v2.0.
  */
-void
-attr_clear (WINDOW * win, int height, int width, chtype attr)
-{
-    int i, j;
-
-    wattrset (win, attr);
-    for (i = 0; i < height; i++) {
-       wmove (win, i, 0);
-       for (j = 0; j < width; j++)
-           waddch (win, ' ');
-    }
-    touchwin (win);
-}
 
-void dialog_clear (void)
-{
-    attr_clear (stdscr, LINES, COLS, screen_attr);
-    /* Display background title if it exists ... - SLH */
-    if (backtitle != NULL) {
-        int i;
-
-        wattrset (stdscr, screen_attr);
-        mvwaddstr (stdscr, 0, 1, (char *)backtitle);
-        wmove (stdscr, 1, 1);
-        for (i = 1; i < COLS - 1; i++)
-            waddch (stdscr, ACS_HLINE);
-    }
-    wnoutrefresh (stdscr);
-}
+#include <string.h>
+#include "lkc.h"
 
-/*
- * Do some initialization for dialog
- */
-void
-init_dialog (void)
-{
-    initscr ();                        /* Init curses */
-    keypad (stdscr, TRUE);
-    cbreak ();
-    noecho ();
-
-
-    if (use_colors)    /* Set up colors */
-       color_setup ();
-
-
-    dialog_clear ();
-}
-
-/*
- * Setup for color display
- */
-void
-color_setup (void)
+/* file already present in list? If not add it */
+struct file *file_lookup(const char *name)
 {
-    int i;
+       struct file *file;
 
-    if (has_colors ()) {       /* Terminal supports color? */
-       start_color ();
-
-       /* Initialize color pairs */
-       for (i = 0; i < ATTRIBUTE_COUNT; i++)
-           init_pair (i + 1, color_table[i][0], color_table[i][1]);
+       for (file = file_list; file; file = file->next) {
+               if (!strcmp(name, file->name))
+                       return file;
+       }
 
-       /* Setup color attributes */
-       for (i = 0; i < ATTRIBUTE_COUNT; i++)
-           attributes[i] = C_ATTR (color_table[i][2], i + 1);
-    }
+       file = malloc(sizeof(*file));
+       memset(file, 0, sizeof(*file));
+       file->name = strdup(name);
+       file->next = file_list;
+       file_list = file;
+       return file;
 }
 
-/*
- * End using dialog functions.
- */
-void
-end_dialog (void)
+/* write a dependency file as used by kbuild to track dependencies */
+int file_write_dep(const char *name)
 {
-    endwin ();
+       struct file *file;
+       FILE *out;
+
+       if (!name)
+               name = ".config.cmd";
+       out = fopen(".config.tmp", "w");
+       if (!out)
+               return 1;
+       fprintf(out, "deps_config := \\\n");
+       for (file = file_list; file; file = file->next) {
+               if (file->next)
+                       fprintf(out, "\t%s \\\n", file->name);
+               else
+                       fprintf(out, "\t%s\n", file->name);
+       }
+       fprintf(out, "\n.config include/config.h: $(deps_config)\n\n$(deps_config):\n");
+       fclose(out);
+       rename(".config.tmp", name);
+       return 0;
 }
 
 
-/*
- * Print a string of text in a window, automatically wrap around to the
- * next line if the string is too long to fit on one line. Newline
- * characters '\n' are replaced by spaces.  We start on a new line
- * if there is no room for at least 4 nonblanks following a double-space.
- */
-void
-print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x)
+/* Allocate initial growable sting */
+struct gstr str_new(void)
 {
-    int newl, cur_x, cur_y;
-    int i, prompt_len, room, wlen;
-    char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
-
-    strcpy (tempstr, prompt);
-
-    prompt_len = strlen(tempstr);
-
-    /*
-     * Remove newlines
-     */
-    for(i=0; i<prompt_len; i++) {
-       if(tempstr[i] == '\n') tempstr[i] = ' ';
-    }
-
-    if (prompt_len <= width - x * 2) { /* If prompt is short */
-       wmove (win, y, (width - prompt_len) / 2);
-       waddstr (win, tempstr);
-    } else {
-       cur_x = x;
-       cur_y = y;
-       newl = 1;
-       word = tempstr;
-       while (word && *word) {
-           sp = index(word, ' ');
-           if (sp)
-               *sp++ = 0;
-
-           /* Wrap to next line if either the word does not fit,
-              or it is the first word of a new sentence, and it is
-              short, and the next word does not fit. */
-           room = width - cur_x;
-           wlen = strlen(word);
-           if (wlen > room ||
-              (newl && wlen < 4 && sp && wlen+1+strlen(sp) > room
-                    && (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) {
-               cur_y++;
-               cur_x = x;
-           }
-           wmove (win, cur_y, cur_x);
-           waddstr (win, word);
-           getyx (win, cur_y, cur_x);
-           cur_x++;
-           if (sp && *sp == ' ') {
-               cur_x++;        /* double space */
-               while (*++sp == ' ');
-               newl = 1;
-           } else
-               newl = 0;
-           word = sp;
-       }
-    }
+       struct gstr gs;
+       gs.s = malloc(sizeof(char) * 64);
+       gs.len = 16;
+       strcpy(gs.s, "\0");
+       return gs;
 }
 
-/*
- * Print a button
- */
-void
-print_button (WINDOW * win, const char *label, int y, int x, int selected)
+/* Allocate and assign growable string */
+struct gstr str_assign(const char *s)
 {
-    int i, temp;
-
-    wmove (win, y, x);
-    wattrset (win, selected ? button_active_attr : button_inactive_attr);
-    waddstr (win, "<");
-    temp = strspn (label, " ");
-    label += temp;
-    wattrset (win, selected ? button_label_active_attr
-             : button_label_inactive_attr);
-    for (i = 0; i < temp; i++)
-       waddch (win, ' ');
-    wattrset (win, selected ? button_key_active_attr
-             : button_key_inactive_attr);
-    waddch (win, label[0]);
-    wattrset (win, selected ? button_label_active_attr
-             : button_label_inactive_attr);
-    waddstr (win, (char *)label + 1);
-    wattrset (win, selected ? button_active_attr : button_inactive_attr);
-    waddstr (win, ">");
-    wmove (win, y, x + temp + 1);
+       struct gstr gs;
+       gs.s = strdup(s);
+       gs.len = strlen(s) + 1;
+       return gs;
 }
 
-/*
- * Draw a rectangular box with line drawing characters
- */
-void
-draw_box (WINDOW * win, int y, int x, int height, int width,
-         chtype box, chtype border)
+/* Free storage for growable string */
+void str_free(struct gstr *gs)
 {
-    int i, j;
-
-    wattrset (win, 0);
-    for (i = 0; i < height; i++) {
-       wmove (win, y + i, x);
-       for (j = 0; j < width; j++)
-           if (!i && !j)
-               waddch (win, border | ACS_ULCORNER);
-           else if (i == height - 1 && !j)
-               waddch (win, border | ACS_LLCORNER);
-           else if (!i && j == width - 1)
-               waddch (win, box | ACS_URCORNER);
-           else if (i == height - 1 && j == width - 1)
-               waddch (win, box | ACS_LRCORNER);
-           else if (!i)
-               waddch (win, border | ACS_HLINE);
-           else if (i == height - 1)
-               waddch (win, box | ACS_HLINE);
-           else if (!j)
-               waddch (win, border | ACS_VLINE);
-           else if (j == width - 1)
-               waddch (win, box | ACS_VLINE);
-           else
-               waddch (win, box | ' ');
-    }
+       if (gs->s)
+               free(gs->s);
+       gs->s = NULL;
+       gs->len = 0;
 }
 
-/*
- * Draw shadows along the right and bottom edge to give a more 3D look
- * to the boxes
- */
-void
-draw_shadow (WINDOW * win, int y, int x, int height, int width)
+/* Append to growable string */
+void str_append(struct gstr *gs, const char *s)
 {
-    int i;
-
-    if (has_colors ()) {       /* Whether terminal supports color? */
-       wattrset (win, shadow_attr);
-       wmove (win, y + height, x + 2);
-       for (i = 0; i < width; i++)
-           waddch (win, winch (win) & A_CHARTEXT);
-       for (i = y + 1; i < y + height + 1; i++) {
-           wmove (win, i, x + width);
-           waddch (win, winch (win) & A_CHARTEXT);
-           waddch (win, winch (win) & A_CHARTEXT);
+       size_t l = strlen(gs->s) + strlen(s) + 1;
+       if (l > gs->len) {
+               gs->s   = realloc(gs->s, l);
+               gs->len = l;
        }
-       wnoutrefresh (win);
-    }
+       strcat(gs->s, s);
 }
 
-/*
- *  Return the position of the first alphabetic character in a string.
- */
-int
-first_alpha(const char *string, const char *exempt)
+/* Append printf formatted string to growable string */
+void str_printf(struct gstr *gs, const char *fmt, ...)
 {
-       int i, in_paren=0, c;
-
-       for (i = 0; i < strlen(string); i++) {
-               c = tolower(string[i]);
-
-               if (strchr("<[(", c)) ++in_paren;
-               if (strchr(">])", c) && in_paren > 0) --in_paren;
-
-               if ((! in_paren) && isalpha(c) &&
-                    strchr(exempt, c) == 0)
-                       return i;
-       }
-
-       return 0;
+       va_list ap;
+       char s[10000]; /* big enough... */
+       va_start(ap, fmt);
+       vsnprintf(s, sizeof(s), fmt, ap);
+       str_append(gs, s);
+       va_end(ap);
 }
 
-/*
- * Get the first selected item in the dialog_list_item list.
- */
-struct dialog_list_item *
-first_sel_item(int item_no, struct dialog_list_item ** items)
+/* Retreive value of growable string */
+const char *str_get(struct gstr *gs)
 {
-       int i;
-
-       for (i = 0; i < item_no; i++) {
-               if (items[i]->selected)
-                       return items[i];
-       }
-
-       return NULL;
+       return gs->s;
 }
+
diff --git a/busybox/scripts/config/yesno.c b/busybox/scripts/config/yesno.c
deleted file mode 100644 (file)
index 11fcc25..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- *  yesno.c -- implements the yes/no box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-/*
- * Display termination buttons
- */
-static void
-print_buttons(WINDOW *dialog, int height, int width, int selected)
-{
-    int x = width / 2 - 10;
-    int y = height - 2;
-
-    print_button (dialog, " Yes ", y, x, selected == 0);
-    print_button (dialog, "  No  ", y, x + 13, selected == 1);
-
-    wmove(dialog, y, x+1 + 13*selected );
-    wrefresh (dialog);
-}
-
-/*
- * Display a dialog box with two buttons - Yes and No
- */
-int
-dialog_yesno (const char *title, const char *prompt, int height, int width)
-{
-    int i, x, y, key = 0, button = 0;
-    WINDOW *dialog;
-
-    /* center dialog box on screen */
-    x = (COLS - width) / 2;
-    y = (LINES - height) / 2;
-
-    draw_shadow (stdscr, y, x, height, width);
-
-    dialog = newwin (height, width, y, x);
-    keypad (dialog, TRUE);
-
-    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-    wattrset (dialog, border_attr);
-    mvwaddch (dialog, height-3, 0, ACS_LTEE);
-    for (i = 0; i < width - 2; i++)
-       waddch (dialog, ACS_HLINE);
-    wattrset (dialog, dialog_attr);
-    waddch (dialog, ACS_RTEE);
-
-    if (title != NULL && strlen(title) >= width-2 ) {
-       /* truncate long title -- mec */
-       char * title2 = malloc(width-2+1);
-       memcpy( title2, title, width-2 );
-       title2[width-2] = '\0';
-       title = title2;
-    }
-
-    if (title != NULL) {
-       wattrset (dialog, title_attr);
-       mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-       waddstr (dialog, (char *)title);
-       waddch (dialog, ' ');
-    }
-
-    wattrset (dialog, dialog_attr);
-    print_autowrap (dialog, prompt, width - 2, 1, 3);
-
-    print_buttons(dialog, height, width, 0);
-
-    while (key != ESC) {
-       key = wgetch (dialog);
-       switch (key) {
-       case 'Y':
-       case 'y':
-           delwin (dialog);
-           return 0;
-       case 'N':
-       case 'n':
-           delwin (dialog);
-           return 1;
-
-       case TAB:
-       case KEY_LEFT:
-       case KEY_RIGHT:
-           button = ((key == KEY_LEFT ? --button : ++button) < 0)
-                       ? 1 : (button > 1 ? 0 : button);
-
-           print_buttons(dialog, height, width, button);
-           wrefresh (dialog);
-           break;
-       case ' ':
-       case '\n':
-           delwin (dialog);
-           return button;
-       case ESC:
-           break;
-       }
-    }
-
-    delwin (dialog);
-    return -1;                 /* ESC pressed */
-}
index a5f69a026a431b419ea368405b04bed26365941f..66982c1ddfd7797cf04544d8ec252d7cf86439c1 100644 (file)
@@ -175,6 +175,8 @@ static bool zconf_endtoken(int token, int starttoken, int endtoken);
 
 struct symbol *symbol_hash[257];
 
+static struct menu *current_menu, *current_entry;
+
 #define YYERROR_VERBOSE
 
 
@@ -2119,6 +2121,7 @@ void zconfdump(FILE *out)
 }
 
 #include "lex.zconf.c"
+#include "util.c"
 #include "confdata.c"
 #include "expr.c"
 #include "symbol.c"
index 658495cda2aea0d6ef48a77f3de27eb489a0ab5a..5ebaf0a78f06e5903b4a0aa87b9c1ce6b38a706b 100644 (file)
@@ -25,6 +25,8 @@ static bool zconf_endtoken(int token, int starttoken, int endtoken);
 
 struct symbol *symbol_hash[257];
 
+static struct menu *current_menu, *current_entry;
+
 #define YYERROR_VERBOSE
 %}
 %expect 40
@@ -681,6 +683,7 @@ void zconfdump(FILE *out)
 }
 
 #include "lex.zconf.c"
+#include "util.c"
 #include "confdata.c"
 #include "expr.c"
 #include "symbol.c"
index f454e699084beb1afda05b521a7a54d1c13c5451..c4655acd8850350da8565ac49c173da7d9214f78 100644 (file)
@@ -1277,11 +1277,17 @@ static int pseudo_exec(struct child_prog *child)
        name = child->argv[0];
 
        {
-           char** argv_l=child->argv;
-           int argc_l;
-           for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);
-           optind = 1;
-           run_applet_by_name(name, argc_l, child->argv);
+               char** argv_l=child->argv;
+               int argc_l;
+#ifdef _NEWLIB_VERSION
+               /* newlib uses __getopt_initialized for getopt() in 
+                * addition to optind, see newlib/libc/sys/linux/getopt.c
+                */
+               extern int __getopt_initialized = 0;
+#endif
+               for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);
+               optind = 1;
+               run_applet_by_name(name, argc_l, child->argv);
        }
 #endif
 
index 744a84d18f42d771fa68459b67deb9b255c37127..0c10de928fa9642954b73aaee558eb550204f318 100644 (file)
@@ -94,14 +94,14 @@ config CONFIG_FEATURE_SUID
 
 config CONFIG_FEATURE_SUID_CONFIG
        bool "Runtime SUID/SGID configuration via /etc/busybox.conf"
-       default y if CONFIG_FEATURE_SUID
+       default n if CONFIG_FEATURE_SUID
        depends on CONFIG_FEATURE_SUID
        help
          Allow the SUID / SGID state of an applet to be determined runtime by
          checking /etc/busybox.conf.  The format of this file is as follows:
 
          <applet> = [Ssx-][Ssx-][x-] (<username>|<uid>).(<groupname>|<gid>)
-       
+
          An example might help:
 
          [SUID]
@@ -113,6 +113,13 @@ config CONFIG_FEATURE_SUID_CONFIG
 
          cp = --- # disable applet cp for everyone
 
+         The file has to be owned by user root, group root and has to be
+         writeable only by root:
+               (chown 0.0 /etc/busybox.conf; chmod 600 /etc/busybox.conf)
+         The busybox executable has to be owned by user root, group
+         root and has to be setuid root for this to work:
+               (chown 0.0 /bin/busybox; chmod 4755 /bin/busybox)
+
          Robert 'sandman' Griebl has more information here:
          <url: http://www.softforge.de/bb/suid.html >.
 
index 78b0c00909ae131164448be77abc0836236eba13..611f46b2d2137cf23a666735296222a75adc437f 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile for busybox
 #
-# Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 #
 
 top_srcdir=..
-top_buildddir=..
+top_builddir=..
 srcdir=$(top_srcdir)/sysklogd
 SYSKLOGD_DIR:=./
 include $(top_builddir)/Rules.mak
@@ -29,4 +29,3 @@ all: $(libraries-y)
 
 clean:
        rm -f *.o *.a $(AR_TARGET)
-
index 16155316fbd04f66f8da7033b09d6c16561ed5a2..fee33b788e6ada0eba7feb6d55f5dcbc8e1d8dc0 100644 (file)
@@ -127,7 +127,7 @@ extern int logger_main(int argc, char **argv)
                }
        }
 
-       openlog(name, option, (pri | LOG_FACMASK));
+       openlog(name, option, 0);
        if (optind == argc) {
                do {
                        /* read from stdin */
@@ -152,8 +152,8 @@ extern int logger_main(int argc, char **argv)
                        message = xrealloc(message, len);
                        if(!i)
                                message[0] = 0;
-                        else
-                       strcat(message, " ");
+                       else
+                               strcat(message, " ");
                        strcat(message, *argv);
                        argv++;
                }
index 24d5487268ea6417800f93808a44228d8b83b9c2..db7c8bd7d83ca7db134345388025f15b2b906ae8 100644 (file)
@@ -221,6 +221,7 @@ config CONFIG_LOSETUP
 config CONFIG_MKSWAP
        bool "mkswap"
        default n
+       select CONFIG_FEATURE_SUID
        help
          The mkswap utility is used to configure a file or disk partition as
          Linux swap space.  This allows Linux to use the entire file or
@@ -234,6 +235,7 @@ config CONFIG_MKSWAP
 config CONFIG_MORE
        bool "more"
        default n
+       select CONFIG_FEATURE_SUID
        help
          more is a simple utility which allows you to read text one screen
          sized page at a time.  If you want to read text that is larger than
index 4401fd1edf98b92f855a711f8bccb90225621e6c..efcf6e3bbeb9404a7ba2f1ac009df63907d7cd58 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile for busybox
 #
-# Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 #
 
 top_srcdir=..
-top_buildddir=..
+top_builddir=..
 srcdir=$(top_srcdir)/util-linux
 UTILLINUX_DIR:=./
 include $(top_builddir)/Rules.mak
@@ -29,4 +29,3 @@ all: $(libraries-y)
 
 clean:
        rm -f *.o *.a $(AR_TARGET)
-
index a260d74480af45465f1f1156b8a5af28831cd709..3c26839537caba155dceff4a0b17fcc9f97f68ab 100644 (file)
@@ -46,7 +46,7 @@ struct linux_rtc_time {
        int tm_yday;
        int tm_isdst;
 };
-                
+
 #define RTC_SET_TIME   _IOW('p', 0x0a, struct linux_rtc_time) /* Set RTC time    */
 #define RTC_RD_TIME    _IOR('p', 0x09, struct linux_rtc_time) /* Read RTC time   */
 
@@ -182,11 +182,11 @@ static int check_utc(void)
        return utc;
 }
 
-#define HWCLOCK_OPT_LOCALTIME  1
-#define HWCLOCK_OPT_UTC        2
-#define HWCLOCK_OPT_SHOW       4
-#define HWCLOCK_OPT_HCTOSYS    8
-#define HWCLOCK_OPT_SYSTOHC    16
+#define HWCLOCK_OPT_LOCALTIME  0x01
+#define HWCLOCK_OPT_UTC        0x02
+#define HWCLOCK_OPT_SHOW       0x04
+#define HWCLOCK_OPT_HCTOSYS    0x08
+#define HWCLOCK_OPT_SYSTOHC    0x10
 
 extern int hwclock_main ( int argc, char **argv )
 {
@@ -208,16 +208,16 @@ static const struct option hwclock_long_options[] = {
        bb_opt_complementaly = "r~ws:w~rs:s~wr:l~u:u~l";
        opt = bb_getopt_ulflags(argc, argv, "lursw");
        /* Check only one mode was given */
-       if(opt & 0x80000000UL) {
+       if(opt & BB_GETOPT_ERROR) {
                bb_show_usage();
        }
 
        /* If -u or -l wasn't given check if we are using utc */
-       if (opt & (HWCLOCK_OPT_UTC | HWCLOCK_OPT_LOCALTIME)) 
+       if (opt & (HWCLOCK_OPT_UTC | HWCLOCK_OPT_LOCALTIME))
                utc = opt & HWCLOCK_OPT_UTC;
        else
                utc = check_utc();
-       
+
        if (opt & HWCLOCK_OPT_HCTOSYS) {
                return to_sys_clock ( utc );
        }