From: Eric Andersen Date: Mon, 18 Jul 2005 23:51:27 +0000 (-0000) Subject: busybox-1.0.1-rc1.patch X-Git-Tag: 1_01~24 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=164a716f964bba247c660bc70149234f95146871;p=oweals%2Fbusybox.git busybox-1.0.1-rc1.patch http://busybox.net/lists/busybox/2005-July/014974.html --- diff --git a/busybox/.cvsignore b/busybox/.cvsignore deleted file mode 100644 index 4e4f5863e..000000000 --- a/busybox/.cvsignore +++ /dev/null @@ -1,7 +0,0 @@ -busybox -busybox.links -_install -.config -.menuconfig.log -.config.cmd -.config.old diff --git a/busybox/AUTHORS b/busybox/AUTHORS index 87df22d55..cf2dedd3a 100644 --- a/busybox/AUTHORS +++ b/busybox/AUTHORS @@ -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 Matt Kraai documentation, bugfixes, test suite +Rob Landley + 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 ipcalc, Red Hat equivalence @@ -76,9 +81,9 @@ John Lombardo tr Glenn McGrath - 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 cat, head, mkfifo, mknod, rmdir, sleep, tee, tty, uniq, usleep, wc, yes, diff --git a/busybox/Makefile b/busybox/Makefile index 3e2b3ef18..81c59a089 100644 --- a/busybox/Makefile +++ b/busybox/Makefile @@ -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 diff --git a/busybox/applets/busybox.c b/busybox/applets/busybox.c index dbb5e176b..ee74b4c18 100644 --- a/busybox/applets/busybox.c +++ b/busybox/applets/busybox.c @@ -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); } diff --git a/busybox/archival/ar.c b/busybox/archival/ar.c index 44c5db035..8326aa6de 100644 --- a/busybox/archival/ar.c +++ b/busybox/archival/ar.c @@ -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); diff --git a/busybox/archival/dpkg.c b/busybox/archival/dpkg.c index c096518a2..d3b56e398 100644 --- a/busybox/archival/dpkg.c +++ b/busybox/archival/dpkg.c @@ -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; diff --git a/busybox/archival/dpkg_deb.c b/busybox/archival/dpkg_deb.c index 5aa9881d5..b95ec2d6e 100644 --- a/busybox/archival/dpkg_deb.c +++ b/busybox/archival/dpkg_deb.c @@ -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(); } diff --git a/busybox/archival/gzip.c b/busybox/archival/gzip.c index d494aa30e..6cf4b395e 100644 --- a/busybox/archival/gzip.c +++ b/busybox/archival/gzip.c @@ -51,12 +51,6 @@ #include #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; diff --git a/busybox/archival/libunarchive/archive_xread_all_eof.c b/busybox/archival/libunarchive/archive_xread_all_eof.c index 8084e3524..f1eea2928 100644 --- a/busybox/archival/libunarchive/archive_xread_all_eof.c +++ b/busybox/archival/libunarchive/archive_xread_all_eof.c @@ -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); } diff --git a/busybox/archival/libunarchive/decompress_bunzip2.c b/busybox/archival/libunarchive/decompress_bunzip2.c index 259a47776..07e3cf018 100644 --- a/busybox/archival/libunarchive/decompress_bunzip2.c +++ b/busybox/archival/libunarchive/decompress_bunzip2.c @@ -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 diff --git a/busybox/archival/libunarchive/decompress_unzip.c b/busybox/archival/libunarchive/decompress_unzip.c index e8cf54bff..b17065d92 100644 --- a/busybox/archival/libunarchive/decompress_unzip.c +++ b/busybox/archival/libunarchive/decompress_unzip.c @@ -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; diff --git a/busybox/archival/tar.c b/busybox/archival/tar.c index 950e21dd3..b2a212397 100644 --- a/busybox/archival/tar.c +++ b/busybox/archival/tar.c @@ -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 diff --git a/busybox/coreutils/Config.in b/busybox/coreutils/Config.in index e1f0516fd..5a521b536 100644 --- a/busybox/coreutils/Config.in +++ b/busybox/coreutils/Config.in @@ -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. diff --git a/busybox/coreutils/cp.c b/busybox/coreutils/cp.c index 6a82f6bff..97731e83f 100644 --- a/busybox/coreutils/cp.c +++ b/busybox/coreutils/cp.c @@ -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. */ diff --git a/busybox/coreutils/cut.c b/busybox/coreutils/cut.c index d26e80eee..e5fb5aff7 100644 --- a/busybox/coreutils/cut.c +++ b/busybox/coreutils/cut.c @@ -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))) { diff --git a/busybox/coreutils/date.c b/busybox/coreutils/date.c index 3608df69f..70484e2cd 100644 --- a/busybox/coreutils/date.c +++ b/busybox/coreutils/date.c @@ -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; } diff --git a/busybox/coreutils/expr.c b/busybox/coreutils/expr.c index cbbd4cd03..3f052d92a 100644 --- a/busybox/coreutils/expr.c +++ b/busybox/coreutils/expr.c @@ -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; } diff --git a/busybox/coreutils/id.c b/busybox/coreutils/id.c index d5182b953..b10a7c1bf 100644 --- a/busybox/coreutils/id.c +++ b/busybox/coreutils/id.c @@ -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 */ diff --git a/busybox/coreutils/install.c b/busybox/coreutils/install.c index 36dc1d618..345e75af0 100644 --- a/busybox/coreutils/install.c +++ b/busybox/coreutils/install.c @@ -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(); } diff --git a/busybox/coreutils/md5_sha1_sum.c b/busybox/coreutils/md5_sha1_sum.c index bd1c9fc29..543c2ab3f 100644 --- a/busybox/coreutils/md5_sha1_sum.c +++ b/busybox/coreutils/md5_sha1_sum.c @@ -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) { diff --git a/busybox/coreutils/mv.c b/busybox/coreutils/mv.c index 4f08dedc0..e1c4529ad 100644 --- a/busybox/coreutils/mv.c +++ b/busybox/coreutils/mv.c @@ -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) { diff --git a/busybox/coreutils/test.c b/busybox/coreutils/test.c index 8fa6d166f..5195fafa1 100644 --- a/busybox/coreutils/test.c +++ b/busybox/coreutils/test.c @@ -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)); diff --git a/busybox/coreutils/watch.c b/busybox/coreutils/watch.c index f9f40189e..31fadfb85 100644 --- a/busybox/coreutils/watch.c +++ b/busybox/coreutils/watch.c @@ -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"); } } } diff --git a/busybox/coreutils/who.c b/busybox/coreutils/who.c index 9561db132..0531326bd 100644 --- a/busybox/coreutils/who.c +++ b/busybox/coreutils/who.c @@ -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(); diff --git a/busybox/debianutils/start_stop_daemon.c b/busybox/debianutils/start_stop_daemon.c index e15944c59..1eaf0d78c 100644 --- a/busybox/debianutils/start_stop_daemon.c +++ b/busybox/debianutils/start_stop_daemon.c @@ -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 index ec9e94b27..000000000 --- a/busybox/docs/.cvsignore +++ /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 index 393b00210..000000000 --- a/busybox/docs/busybox.net/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -BusyBox.html -busybox.tar.gz diff --git a/busybox/docs/new-applet-HOWTO.txt b/busybox/docs/new-applet-HOWTO.txt index 2fc95d36d..605974c3a 100644 --- a/busybox/docs/new-applet-HOWTO.txt +++ b/busybox/docs/new-applet-HOWTO.txt @@ -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 ------------- diff --git a/busybox/editors/awk.c b/busybox/editors/awk.c index c1cb2a2e2..ed8b0f20f 100644 --- a/busybox/editors/awk.c +++ b/busybox/editors/awk.c @@ -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: diff --git a/busybox/editors/sed.c b/busybox/editors/sed.c index 3d6871621..992e5711d 100644 --- a/busybox/editors/sed.c +++ b/busybox/editors/sed.c @@ -34,7 +34,10 @@ 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_filein_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; diff --git a/busybox/editors/vi.c b/busybox/editors/vi.c index cd6cf0ea1..5a47f5a23 100644 --- a/busybox/editors/vi.c +++ b/busybox/editors/vi.c @@ -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 } diff --git a/busybox/findutils/grep.c b/busybox/findutils/grep.c index 29f4ecd4f..9b26add9a 100644 --- a/busybox/findutils/grep.c +++ b/busybox/findutils/grep.c @@ -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 index 9c68c9576..000000000 --- a/busybox/include/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -config -config.h diff --git a/busybox/include/applets.h b/busybox/include/applets.h index 90d4195cc..21f82f57d 100644 --- a/busybox/include/applets.h +++ b/busybox/include/applets.h @@ -440,7 +440,7 @@ 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) @@ -482,7 +482,7 @@ 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) diff --git a/busybox/include/busybox.h b/busybox/include/busybox.h index f6f575957..3ff3d8a37 100644 --- a/busybox/include/busybox.h +++ b/busybox/include/busybox.h @@ -32,10 +32,10 @@ #include #include -#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 diff --git a/busybox/include/inet_common.h b/busybox/include/inet_common.h index afea5deaa..4a9c3a2d7 100644 --- a/busybox/include/inet_common.h +++ b/busybox/include/inet_common.h @@ -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 diff --git a/busybox/include/libbb.h b/busybox/include/libbb.h index 93ab5375c..467a15cb2 100644 --- a/busybox/include/libbb.h +++ b/busybox/include/libbb.h @@ -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; diff --git a/busybox/include/usage.h b/busybox/include/usage.h index 377eb10e7..ad4410196 100644 --- a/busybox/include/usage.h +++ b/busybox/include/usage.h @@ -204,7 +204,7 @@ "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" \ @@ -522,13 +522,13 @@ "\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 \ @@ -751,7 +751,7 @@ "$ 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" \ @@ -1940,7 +1940,7 @@ "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 diff --git a/busybox/init/Config.in b/busybox/init/Config.in index 4465e75a1..521f8fe1d 100644 --- a/busybox/init/Config.in +++ b/busybox/init/Config.in @@ -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 diff --git a/busybox/init/init.c b/busybox/init/init.c index 0c8dc89dc..8687b106c 100644 --- a/busybox/init/init.c +++ b/busybox/init/init.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -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 index 2bbe016f5..000000000 --- a/busybox/libbb/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -loop.h diff --git a/busybox/libbb/Makefile.in b/busybox/libbb/Makefile.in index 85d4a967b..d4c5ec14a 100644 --- a/busybox/libbb/Makefile.in +++ b/busybox/libbb/Makefile.in @@ -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 \ diff --git a/busybox/libbb/concat_path_file.c b/busybox/libbb/concat_path_file.c index 77c054530..00233ad9a 100644 --- a/busybox/libbb/concat_path_file.c +++ b/busybox/libbb/concat_path_file.c @@ -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; } diff --git a/busybox/libbb/copyfd.c b/busybox/libbb/copyfd.c index bf0a390a3..27d65a419 100644 --- a/busybox/libbb/copyfd.c +++ b/busybox/libbb/copyfd.c @@ -2,7 +2,7 @@ /* * Utility routines. * - * Copyright (C) 1999-2004 by Erik Andersen + * Copyright (C) 1999-2005 by Erik Andersen * * 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 #include "busybox.h" +#include "libbb.h" #if BUFSIZ < 4096 @@ -33,46 +34,59 @@ #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; } diff --git a/busybox/libbb/getopt_ulflags.c b/busybox/libbb/getopt_ulflags.c index 39a7d1d29..6197e8d9f 100644 --- a/busybox/libbb/getopt_ulflags.c +++ b/busybox/libbb/getopt_ulflags.c @@ -26,146 +26,270 @@ #include #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__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; } diff --git a/busybox/libbb/interface.c b/busybox/libbb/interface.c index fe2d0b4b2..c4aa032a4 100644 --- a/busybox/libbb/interface.c +++ b/busybox/libbb/interface.c @@ -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 -#if __GLIBC__ >=2 && __GLIBC_MINOR >= 1 +#if (__GLIBC__ >=2 && __GLIBC_MINOR >= 1) || defined(_NEWLIB_VERSION) #include #else #include @@ -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); } diff --git a/busybox/libbb/messages.c b/busybox/libbb/messages.c index 671c452d2..c3f307ec5 100644 --- a/busybox/libbb/messages.c +++ b/busybox/libbb/messages.c @@ -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 diff --git a/busybox/libbb/syscalls.c b/busybox/libbb/syscalls.c index 9e89dbd39..dac90e24b 100644 --- a/busybox/libbb/syscalls.c +++ b/busybox/libbb/syscalls.c @@ -29,7 +29,7 @@ #include #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 */ diff --git a/busybox/loginutils/Config.in b/busybox/loginutils/Config.in index 5619aa9af..12c208c64 100644 --- a/busybox/loginutils/Config.in +++ b/busybox/loginutils/Config.in @@ -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" diff --git a/busybox/loginutils/getty.c b/busybox/loginutils/getty.c index 923432ba1..78009181d 100644 --- a/busybox/loginutils/getty.c +++ b/busybox/loginutils/getty.c @@ -25,11 +25,14 @@ #include #include #include -#include #include #include #include "busybox.h" +#ifdef CONFIG_FEATURE_UTMP +#include +#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 */ /* diff --git a/busybox/loginutils/login.c b/busybox/loginutils/login.c index f3630f102..5ed10b91b 100644 --- a/busybox/loginutils/login.c +++ b/busybox/loginutils/login.c @@ -23,7 +23,7 @@ #include #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 */ diff --git a/busybox/loginutils/su.c b/busybox/loginutils/su.c index ec0c16c7d..1e93aacd4 100644 --- a/busybox/loginutils/su.c +++ b/busybox/loginutils/su.c @@ -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 ( ); diff --git a/busybox/miscutils/Config.in b/busybox/miscutils/Config.in index 77e13e84e..767b9c462 100644 --- a/busybox/miscutils/Config.in +++ b/busybox/miscutils/Config.in @@ -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. diff --git a/busybox/miscutils/devfsd.c b/busybox/miscutils/devfsd.c index 5e183e61f..34945c7b2 100644 --- a/busybox/miscutils/devfsd.c +++ b/busybox/miscutils/devfsd.c @@ -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 */ diff --git a/busybox/miscutils/strings.c b/busybox/miscutils/strings.c index 92e9f0d11..d0a092421 100644 --- a/busybox/miscutils/strings.c +++ b/busybox/miscutils/strings.c @@ -27,99 +27,82 @@ #include #include -#include #include -#include #include #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); } /* diff --git a/busybox/modutils/insmod.c b/busybox/modutils/insmod.c index d88dd1be6..60f5cf1c7 100644 --- a/busybox/modutils/insmod.c +++ b/busybox/modutils/insmod.c @@ -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)) { diff --git a/busybox/networking/httpd.c b/busybox/networking/httpd.c index 83ded5330..94fcfc8c1 100644 --- a/busybox/networking/httpd.c +++ b/busybox/networking/httpd.c @@ -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; diff --git a/busybox/networking/ifconfig.c b/busybox/networking/ifconfig.c index 4e3df2982..fc7798f2d 100644 --- a/busybox/networking/ifconfig.c +++ b/busybox/networking/ifconfig.c @@ -46,8 +46,8 @@ #include #include #else -#include -#include +#include +#include #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; }; diff --git a/busybox/networking/ifupdown.c b/busybox/networking/ifupdown.c index 1842be58b..21afe42d4 100644 --- a/busybox/networking/ifupdown.c +++ b/busybox/networking/ifupdown.c @@ -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); diff --git a/busybox/networking/inetd.c b/busybox/networking/inetd.c index 169cc8716..a1fa29ce4 100644 --- a/busybox/networking/inetd.c +++ b/busybox/networking/inetd.c @@ -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); /* diff --git a/busybox/networking/libiproute/utils.c b/busybox/networking/libiproute/utils.c index fa1548609..d86d4f8f5 100644 --- a/busybox/networking/libiproute/utils.c +++ b/busybox/networking/libiproute/utils.c @@ -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); diff --git a/busybox/networking/nc.c b/busybox/networking/nc.c index 3099763b1..ab8ec0cd5 100644 --- a/busybox/networking/nc.c +++ b/busybox/networking/nc.c @@ -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); } diff --git a/busybox/networking/telnetd.c b/busybox/networking/telnetd.c index 491c66fd1..b3d0a1166 100644 --- a/busybox/networking/telnetd.c +++ b/busybox/networking/telnetd.c @@ -49,6 +49,15 @@ #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"); diff --git a/busybox/networking/tftp.c b/busybox/networking/tftp.c index 3c947318b..47fc3879e 100644 --- a/busybox/networking/tftp.c +++ b/busybox/networking/tftp.c @@ -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)) { diff --git a/busybox/networking/udhcp/dhcpc.c b/busybox/networking/udhcp/dhcpc.c index 449b51763..91af9153b 100644 --- a/busybox/networking/udhcp/dhcpc.c +++ b/busybox/networking/udhcp/dhcpc.c @@ -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 index 07fa550f5..000000000 --- a/busybox/scripts/.cvsignore +++ /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 index e8bf7a75b..000000000 --- a/busybox/scripts/config/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -conf -mconf -lkc_defs.h -lex.zconf.c -zconf.tab.h -zconf.tab.c -lex.backup -zconf.output diff --git a/busybox/scripts/config/Makefile b/busybox/scripts/config/Makefile index c0b5b9d35..3c4669f8c 100644 --- a/busybox/scripts/config/Makefile +++ b/busybox/scripts/config/Makefile @@ -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="" 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 index 4dbd16616..000000000 --- a/busybox/scripts/config/checklist.c +++ /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 index d34dd37c6..000000000 --- a/busybox/scripts/config/colors.h +++ /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]; diff --git a/busybox/scripts/config/conf.c b/busybox/scripts/config/conf.c index 3b0c1c1b5..78c1af596 100644 --- a/busybox/scripts/config/conf.c +++ b/busybox/scripts/config/conf.c @@ -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))) diff --git a/busybox/scripts/config/confdata.c b/busybox/scripts/config/confdata.c index fd3a345e2..7b9000e84 100644 --- a/busybox/scripts/config/confdata.c +++ b/busybox/scripts/config/confdata.c @@ -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 index 6486cc8f7..000000000 --- a/busybox/scripts/config/dialog.h +++ /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 -#include -#include -#include -#include -#include - -#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 diff --git a/busybox/scripts/config/expr.c b/busybox/scripts/config/expr.c index 10f45232b..30e4f9d69 100644 --- a/busybox/scripts/config/expr.c +++ b/busybox/scripts/config/expr.c @@ -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); +} diff --git a/busybox/scripts/config/expr.h b/busybox/scripts/config/expr.h index cac51f6a8..7d39ff43e 100644 --- a/busybox/scripts/config/expr.h +++ b/busybox/scripts/config/expr.h @@ -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 index fa7bebc69..000000000 --- a/busybox/scripts/config/inputbox.c +++ /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 */ -} diff --git a/busybox/scripts/config/lkc.h b/busybox/scripts/config/lkc.h index dd040f7a8..b8a67fc9d 100644 --- a/busybox/scripts/config/lkc.h +++ b/busybox/scripts/config/lkc.h @@ -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); diff --git a/busybox/scripts/config/lkc_proto.h b/busybox/scripts/config/lkc_proto.h index 97c79178e..6dc6d0c48 100644 --- a/busybox/scripts/config/lkc_proto.h +++ b/busybox/scripts/config/lkc_proto.h @@ -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 index 000000000..a8999d82b --- /dev/null +++ b/busybox/scripts/config/lxdialog/BIG.FAT.WARNING @@ -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 index 000000000..71de4a191 --- /dev/null +++ b/busybox/scripts/config/lxdialog/checklist.c @@ -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 index 000000000..d34dd37c6 --- /dev/null +++ b/busybox/scripts/config/lxdialog/colors.h @@ -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 index 000000000..7bab3ad0e --- /dev/null +++ b/busybox/scripts/config/lxdialog/dialog.h @@ -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 +#include +#include +#include +#include +#include + +#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 index 000000000..fa7bebc69 --- /dev/null +++ b/busybox/scripts/config/lxdialog/inputbox.c @@ -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 index 000000000..873dc587b --- /dev/null +++ b/busybox/scripts/config/lxdialog/menubox.c @@ -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 index 000000000..93692e1fb --- /dev/null +++ b/busybox/scripts/config/lxdialog/msgbox.c @@ -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 index 000000000..a5a460b5c --- /dev/null +++ b/busybox/scripts/config/lxdialog/textbox.c @@ -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 index 000000000..6f83951b9 --- /dev/null +++ b/busybox/scripts/config/lxdialog/util.c @@ -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 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 index 000000000..11fcc25f5 --- /dev/null +++ b/busybox/scripts/config/lxdialog/yesno.c @@ -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 */ +} diff --git a/busybox/scripts/config/mconf.c b/busybox/scripts/config/mconf.c index 63b4ff72f..5bc2abdd8 100644 --- a/busybox/scripts/config/mconf.c +++ b/busybox/scripts/config/mconf.c @@ -23,18 +23,150 @@ #include #include -#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 to build it in or to removed it.\n" +"You may also press the 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 .\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 and keys to scroll\n" +" unseen options into view.\n" +"\n" +"o To exit a menu use the cursor keys to highlight the button\n" +" and press .\n" +"\n" +" Shortcut: Press or or if there is no hotkey\n" +" using those letters. You may press a single , but\n" +" there is a delayed response which you may find annoying.\n" +"\n" +" Also, the and cursor keys will cycle between and\n" +" \n" +"\n" +"\n" +"Data Entry\n" +"-----------\n" +"o Enter the requested information and press \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 or cursor keys to highlight the help option\n" +" and press . You can try 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 and for those\n" +" who are familiar with less and lynx.\n" +"\n" +"o Press , , or 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" +" 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. " " selects submenus --->. " "Highlighted letters are hotkeys. " "Pressing selectes a feature, while will exclude a feature. " - "Press to exit, for Help. " + "Press 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 .\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 ( [=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 and 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 : "", + 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(); diff --git a/busybox/scripts/config/menu.c b/busybox/scripts/config/menu.c index 6425296fc..0c13156f3 100644 --- a/busybox/scripts/config/menu.c +++ b/busybox/scripts/config/menu.c @@ -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 index 431f09fc9..000000000 --- a/busybox/scripts/config/menubox.c +++ /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 index 93692e1fb..000000000 --- a/busybox/scripts/config/msgbox.c +++ /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; -} diff --git a/busybox/scripts/config/symbol.c b/busybox/scripts/config/symbol.c index a9fae9c13..ea629728a 100644 --- a/busybox/scripts/config/symbol.c +++ b/busybox/scripts/config/symbol.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #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 index a5a460b5c..000000000 --- a/busybox/scripts/config/textbox.c +++ /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); -} diff --git a/busybox/scripts/config/util.c b/busybox/scripts/config/util.c index 0a2f82757..a72f5ea66 100644 --- a/busybox/scripts/config/util.c +++ b/busybox/scripts/config/util.c @@ -1,375 +1,109 @@ /* - * util.c + * Copyright (C) 2002-2005 Roman Zippel + * Copyright (C) 2002-2005 Sam Ravnborg * - * 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 +#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 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 index 11fcc25f5..000000000 --- a/busybox/scripts/config/yesno.c +++ /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 */ -} diff --git a/busybox/scripts/config/zconf.tab.c_shipped b/busybox/scripts/config/zconf.tab.c_shipped index a5f69a026..66982c1dd 100644 --- a/busybox/scripts/config/zconf.tab.c_shipped +++ b/busybox/scripts/config/zconf.tab.c_shipped @@ -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" diff --git a/busybox/scripts/config/zconf.y b/busybox/scripts/config/zconf.y index 658495cda..5ebaf0a78 100644 --- a/busybox/scripts/config/zconf.y +++ b/busybox/scripts/config/zconf.y @@ -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" diff --git a/busybox/shell/lash.c b/busybox/shell/lash.c index f454e6990..c4655acd8 100644 --- a/busybox/shell/lash.c +++ b/busybox/shell/lash.c @@ -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 diff --git a/busybox/sysdeps/linux/Config.in b/busybox/sysdeps/linux/Config.in index 744a84d18..0c10de928 100644 --- a/busybox/sysdeps/linux/Config.in +++ b/busybox/sysdeps/linux/Config.in @@ -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: = [Ssx-][Ssx-][x-] (|).(|) - + 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: . diff --git a/busybox/sysklogd/Makefile b/busybox/sysklogd/Makefile index 78b0c0090..611f46b2d 100644 --- a/busybox/sysklogd/Makefile +++ b/busybox/sysklogd/Makefile @@ -1,6 +1,6 @@ # Makefile for busybox # -# Copyright (C) 1999-2004 by Erik Andersen +# Copyright (C) 1999-2005 by Erik Andersen # # 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) - diff --git a/busybox/sysklogd/logger.c b/busybox/sysklogd/logger.c index 16155316f..fee33b788 100644 --- a/busybox/sysklogd/logger.c +++ b/busybox/sysklogd/logger.c @@ -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++; } diff --git a/busybox/util-linux/Config.in b/busybox/util-linux/Config.in index 24d548726..db7c8bd7d 100644 --- a/busybox/util-linux/Config.in +++ b/busybox/util-linux/Config.in @@ -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 diff --git a/busybox/util-linux/Makefile b/busybox/util-linux/Makefile index 4401fd1ed..efcf6e3bb 100644 --- a/busybox/util-linux/Makefile +++ b/busybox/util-linux/Makefile @@ -1,6 +1,6 @@ # Makefile for busybox # -# Copyright (C) 1999-2004 by Erik Andersen +# Copyright (C) 1999-2005 by Erik Andersen # # 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) - diff --git a/busybox/util-linux/hwclock.c b/busybox/util-linux/hwclock.c index a260d7448..3c2683953 100644 --- a/busybox/util-linux/hwclock.c +++ b/busybox/util-linux/hwclock.c @@ -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 ); }