aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-06-10 15:08:44 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-06-10 15:08:44 +0000
commite8a0788b249cbac5bf5b2aa2d81bb8f6b29a7a4b (patch)
treefcdf3d51b6d60986b634c693d71355867bca82ff
parentd4fea900bdb92d7bba71348a40cb00b6748a8ecc (diff)
downloadbusybox-w32-e8a0788b249cbac5bf5b2aa2d81bb8f6b29a7a4b.tar.gz
busybox-w32-e8a0788b249cbac5bf5b2aa2d81bb8f6b29a7a4b.tar.bz2
busybox-w32-e8a0788b249cbac5bf5b2aa2d81bb8f6b29a7a4b.zip
moved biggest stack buffers to malloc space, or made their size configurable
(8k of shell line edit buffer is an overkill) # make ARCH=i386 bloatcheck function old new delta read_line_input 3933 3967 +34 ifaddrlist 348 345 -3 do_loadfont 208 191 -17 edit_file 840 819 -21 .rodata 129112 129080 -32 uncompress 1305 1268 -37 loadfont_main 566 495 -71 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/6 up/down: 34/-181) Total: -147 bytes
-rw-r--r--Makefile.flags1
-rw-r--r--archival/libunarchive/decompress_uncompress.c98
-rw-r--r--console-tools/loadfont.c77
-rw-r--r--editors/Config.in10
-rw-r--r--editors/vi.c50
-rw-r--r--libbb/Config.in12
-rw-r--r--libbb/lineedit.c45
-rw-r--r--networking/traceroute.c39
8 files changed, 181 insertions, 151 deletions
diff --git a/Makefile.flags b/Makefile.flags
index 988d6e708..322e43792 100644
--- a/Makefile.flags
+++ b/Makefile.flags
@@ -70,4 +70,5 @@ endif
70#LDFLAGS += -nostdlib 70#LDFLAGS += -nostdlib
71 71
72# Busybox is a stack-fatty so make sure we increase default size 72# Busybox is a stack-fatty so make sure we increase default size
73# (TODO: use "make stksizes" to find & fix big stack users)
73FLTFLAGS += -s 20000 74FLTFLAGS += -s 20000
diff --git a/archival/libunarchive/decompress_uncompress.c b/archival/libunarchive/decompress_uncompress.c
index ba73f1132..8c3c65d1a 100644
--- a/archival/libunarchive/decompress_uncompress.c
+++ b/archival/libunarchive/decompress_uncompress.c
@@ -7,7 +7,6 @@
7 * (see disclaimer below) 7 * (see disclaimer below)
8 */ 8 */
9 9
10
11/* (N)compress42.c - File compression ala IEEE Computer, Mar 1992. 10/* (N)compress42.c - File compression ala IEEE Computer, Mar 1992.
12 * 11 *
13 * Authors: 12 * Authors:
@@ -34,53 +33,48 @@
34#define OBUFSIZ 2048 33#define OBUFSIZ 2048
35 34
36/* Defines for third byte of header */ 35/* Defines for third byte of header */
37#define MAGIC_1 (char_type)'\037' /* First byte of compressed file */ 36#define BIT_MASK 0x1f /* Mask for 'number of compresssion bits' */
38#define MAGIC_2 (char_type)'\235' /* Second byte of compressed file */ 37 /* Masks 0x20 and 0x40 are free. */
39#define BIT_MASK 0x1f /* Mask for 'number of compresssion bits' */ 38 /* I think 0x20 should mean that there is */
40 /* Masks 0x20 and 0x40 are free. */ 39 /* a fourth header byte (for expansion). */
41 /* I think 0x20 should mean that there is */ 40#define BLOCK_MODE 0x80 /* Block compression if table is full and */
42 /* a fourth header byte (for expansion). */ 41 /* compression rate is dropping flush tables */
43#define BLOCK_MODE 0x80 /* Block compresssion if table is full and */ 42 /* the next two codes should not be changed lightly, as they must not */
44 /* compression rate is dropping flush tables */ 43 /* lie within the contiguous general code space. */
45 /* the next two codes should not be changed lightly, as they must not */ 44#define FIRST 257 /* first free entry */
46 /* lie within the contiguous general code space. */ 45#define CLEAR 256 /* table clear output code */
47#define FIRST 257 /* first free entry */
48#define CLEAR 256 /* table clear output code */
49
50#define INIT_BITS 9 /* initial number of bits/code */
51
52 46
53/* machine variants which require cc -Dmachine: pdp11, z8000, DOS */ 47#define INIT_BITS 9 /* initial number of bits/code */
54#define FAST
55 48
56#define HBITS 17 /* 50% occupancy */
57#define HSIZE (1<<HBITS)
58#define HMASK (HSIZE-1)
59#define HPRIME 9941
60#define BITS 16
61#undef MAXSEG_64K
62#define MAXCODE(n) (1L << (n))
63
64#define htabof(i) htab[i]
65#define codetabof(i) codetab[i]
66#define tab_prefixof(i) codetabof(i)
67#define tab_suffixof(i) ((unsigned char *)(htab))[i]
68#define de_stack ((unsigned char *)&(htab[HSIZE-1]))
69#define clear_htab() memset(htab, -1, HSIZE)
70#define clear_tab_prefixof() memset(codetab, 0, 256);
71 49
50/* machine variants which require cc -Dmachine: pdp11, z8000, DOS */
51#define HBITS 17 /* 50% occupancy */
52#define HSIZE (1<<HBITS)
53#define HMASK (HSIZE-1) /* unused */
54#define HPRIME 9941 /* unused */
55#define BITS 16
56#define BITS_STR "16"
57#undef MAXSEG_64K /* unused */
58#define MAXCODE(n) (1L << (n))
59
60#define htabof(i) htab[i]
61#define codetabof(i) codetab[i]
62#define tab_prefixof(i) codetabof(i)
63#define tab_suffixof(i) ((unsigned char *)(htab))[i]
64#define de_stack ((unsigned char *)&(htab[HSIZE-1]))
65#define clear_tab_prefixof() memset(codetab, 0, 256)
72 66
73/* 67/*
74 * Decompress stdin to stdout. This routine adapts to the codes in the 68 * Decompress stdin to stdout. This routine adapts to the codes in the
75 * file building the "string" table on-the-fly; requiring no table to 69 * file building the "string" table on-the-fly; requiring no table to
76 * be stored in the compressed file. The tables used herein are shared 70 * be stored in the compressed file.
77 * with those of the compress() routine. See the definitions above.
78 */ 71 */
79 72
80USE_DESKTOP(long long) int 73USE_DESKTOP(long long) int
81uncompress(int fd_in, int fd_out) 74uncompress(int fd_in, int fd_out)
82{ 75{
83 USE_DESKTOP(long long total_written = 0;) 76 USE_DESKTOP(long long total_written = 0;)
77 USE_DESKTOP(long long) int retval = -1;
84 unsigned char *stackp; 78 unsigned char *stackp;
85 long code; 79 long code;
86 int finchar; 80 int finchar;
@@ -96,10 +90,10 @@ uncompress(int fd_in, int fd_out)
96 long maxmaxcode; 90 long maxmaxcode;
97 int n_bits; 91 int n_bits;
98 int rsize = 0; 92 int rsize = 0;
99 RESERVE_CONFIG_UBUFFER(inbuf, IBUFSIZ + 64); 93 unsigned char *inbuf; /* were eating insane amounts of stack - */
100 RESERVE_CONFIG_UBUFFER(outbuf, OBUFSIZ + 2048); 94 unsigned char *outbuf; /* bad for some embedded targets */
101 unsigned char htab[HSIZE]; 95 unsigned char *htab;
102 unsigned short codetab[HSIZE]; 96 unsigned short *codetab;
103 97
104 /* Hmm, these were statics - why?! */ 98 /* Hmm, these were statics - why?! */
105 /* user settable max # bits/code */ 99 /* user settable max # bits/code */
@@ -107,8 +101,10 @@ uncompress(int fd_in, int fd_out)
107 /* block compress mode -C compatible with 2.0 */ 101 /* block compress mode -C compatible with 2.0 */
108 int block_mode; /* = BLOCK_MODE; */ 102 int block_mode; /* = BLOCK_MODE; */
109 103
110 memset(inbuf, 0, IBUFSIZ + 64); 104 inbuf = xzalloc(IBUFSIZ + 64);
111 memset(outbuf, 0, OBUFSIZ + 2048); 105 outbuf = xzalloc(OBUFSIZ + 2048);
106 htab = xzalloc(HSIZE); /* wsn't zeroed out before, maybe can xmalloc? */
107 codetab = xzalloc(HSIZE * sizeof(codetab[0]));
112 108
113 insize = 0; 109 insize = 0;
114 110
@@ -116,7 +112,7 @@ uncompress(int fd_in, int fd_out)
116 * to do some cleanup (e.g. delete incomplete unpacked file etc) */ 112 * to do some cleanup (e.g. delete incomplete unpacked file etc) */
117 if (full_read(fd_in, inbuf, 1) != 1) { 113 if (full_read(fd_in, inbuf, 1) != 1) {
118 bb_error_msg("short read"); 114 bb_error_msg("short read");
119 return -1; 115 goto err;
120 } 116 }
121 117
122 maxbits = inbuf[0] & BIT_MASK; 118 maxbits = inbuf[0] & BIT_MASK;
@@ -125,8 +121,8 @@ uncompress(int fd_in, int fd_out)
125 121
126 if (maxbits > BITS) { 122 if (maxbits > BITS) {
127 bb_error_msg("compressed with %d bits, can only handle " 123 bb_error_msg("compressed with %d bits, can only handle "
128 "%d bits", maxbits, BITS); 124 BITS_STR" bits", maxbits);
129 return -1; 125 goto err;
130 } 126 }
131 127
132 n_bits = INIT_BITS; 128 n_bits = INIT_BITS;
@@ -140,7 +136,7 @@ uncompress(int fd_in, int fd_out)
140 free_ent = ((block_mode) ? FIRST : 256); 136 free_ent = ((block_mode) ? FIRST : 256);
141 137
142 /* As above, initialize the first 256 entries in the table. */ 138 /* As above, initialize the first 256 entries in the table. */
143 clear_tab_prefixof(); 139 /*clear_tab_prefixof(); - done by xzalloc */
144 140
145 for (code = 255; code >= 0; --code) { 141 for (code = 255; code >= 0; --code) {
146 tab_suffixof(code) = (unsigned char) code; 142 tab_suffixof(code) = (unsigned char) code;
@@ -232,7 +228,7 @@ uncompress(int fd_in, int fd_out)
232 insize, posbits, p[-1], p[0], p[1], p[2], p[3], 228 insize, posbits, p[-1], p[0], p[1], p[2], p[3],
233 (posbits & 07)); 229 (posbits & 07));
234 bb_error_msg("uncompress: corrupt input"); 230 bb_error_msg("uncompress: corrupt input");
235 return -1; 231 goto err;
236 } 232 }
237 233
238 *--stackp = (unsigned char) finchar; 234 *--stackp = (unsigned char) finchar;
@@ -299,7 +295,11 @@ uncompress(int fd_in, int fd_out)
299 USE_DESKTOP(total_written += outpos;) 295 USE_DESKTOP(total_written += outpos;)
300 } 296 }
301 297
302 RELEASE_CONFIG_BUFFER(inbuf); 298 retval = USE_DESKTOP(total_written) + 0;
303 RELEASE_CONFIG_BUFFER(outbuf); 299 err:
304 return USE_DESKTOP(total_written) + 0; 300 free(inbuf);
301 free(outbuf);
302 free(htab);
303 free(codetab);
304 return retval;
305} 305}
diff --git a/console-tools/loadfont.c b/console-tools/loadfont.c
index 88d7a0401..b046d40e3 100644
--- a/console-tools/loadfont.c
+++ b/console-tools/loadfont.c
@@ -21,43 +21,27 @@ enum {
21}; 21};
22 22
23struct psf_header { 23struct psf_header {
24 unsigned char magic1, magic2; /* Magic number */ 24 unsigned char magic1, magic2; /* Magic number */
25 unsigned char mode; /* PSF font mode */ 25 unsigned char mode; /* PSF font mode */
26 unsigned char charsize; /* Character size */ 26 unsigned char charsize; /* Character size */
27}; 27};
28 28
29#define PSF_MAGIC_OK(x) ((x).magic1 == PSF_MAGIC1 && (x).magic2 == PSF_MAGIC2) 29#define PSF_MAGIC_OK(x) ((x).magic1 == PSF_MAGIC1 && (x).magic2 == PSF_MAGIC2)
30 30
31static void loadnewfont(int fd);
32
33int loadfont_main(int argc, char **argv);
34int loadfont_main(int argc, char **argv)
35{
36 int fd;
37
38 if (argc != 1)
39 bb_show_usage();
40
41 fd = xopen(CURRENT_VC, O_RDWR);
42 loadnewfont(fd);
43
44 return EXIT_SUCCESS;
45}
46
47static void do_loadfont(int fd, unsigned char *inbuf, int unit, int fontsize) 31static void do_loadfont(int fd, unsigned char *inbuf, int unit, int fontsize)
48{ 32{
49 char buf[16384]; 33 char *buf;
50 int i; 34 int i;
51 35
52 memset(buf, 0, sizeof(buf));
53
54 if (unit < 1 || unit > 32) 36 if (unit < 1 || unit > 32)
55 bb_error_msg_and_die("bad character size %d", unit); 37 bb_error_msg_and_die("bad character size %d", unit);
56 38
39 buf = xzalloc(16 * 1024);
40 /*memset(buf, 0, 16 * 1024);*/
57 for (i = 0; i < fontsize; i++) 41 for (i = 0; i < fontsize; i++)
58 memcpy(buf + (32 * i), inbuf + (unit * i), unit); 42 memcpy(buf + (32 * i), inbuf + (unit * i), unit);
59 43
60#if defined( PIO_FONTX ) && !defined( __sparc__ ) 44#if defined(PIO_FONTX) && !defined(__sparc__)
61 { 45 {
62 struct consolefontdesc cfd; 46 struct consolefontdesc cfd;
63 47
@@ -66,12 +50,14 @@ static void do_loadfont(int fd, unsigned char *inbuf, int unit, int fontsize)
66 cfd.chardata = buf; 50 cfd.chardata = buf;
67 51
68 if (ioctl(fd, PIO_FONTX, &cfd) == 0) 52 if (ioctl(fd, PIO_FONTX, &cfd) == 0)
69 return; /* success */ 53 goto ret; /* success */
70 bb_perror_msg("PIO_FONTX ioctl error (trying PIO_FONT)"); 54 bb_perror_msg("PIO_FONTX ioctl (will try PIO_FONT)");
71 } 55 }
72#endif 56#endif
73 if (ioctl(fd, PIO_FONT, buf)) 57 if (ioctl(fd, PIO_FONT, buf))
74 bb_perror_msg_and_die("PIO_FONT ioctl error"); 58 bb_perror_msg_and_die("PIO_FONT ioctl");
59 ret:
60 free(buf);
75} 61}
76 62
77static void 63static void
@@ -124,31 +110,30 @@ do_loadtable(int fd, unsigned char *inbuf, int tailsz, int fontsize)
124 110
125static void loadnewfont(int fd) 111static void loadnewfont(int fd)
126{ 112{
113 enum { INBUF_SIZE = 32*1024 + 1 };
114
127 int unit; 115 int unit;
128 unsigned char inbuf[32768]; /* primitive */ 116 unsigned inputlth, offset;
129 unsigned int inputlth, offset; 117 /* Was on stack, but 32k is a bit too much: */
118 unsigned char *inbuf = xmalloc(INBUF_SIZE);
130 119
131 /* 120 /*
132 * We used to look at the length of the input file 121 * We used to look at the length of the input file
133 * with stat(); now that we accept compressed files, 122 * with stat(); now that we accept compressed files,
134 * just read the entire file. 123 * just read the entire file.
135 */ 124 */
136 inputlth = fread(inbuf, 1, sizeof(inbuf), stdin); 125 inputlth = full_read(STDIN_FILENO, inbuf, INBUF_SIZE);
137 if (ferror(stdin)) 126 if (inputlth < 0)
138 bb_perror_msg_and_die("error reading input font"); 127 bb_perror_msg_and_die("error reading input font");
139 /* use malloc/realloc in case of giant files; 128 if (inputlth >= INBUF_SIZE)
140 maybe these do not occur: 16kB for the font, 129 bb_error_msg_and_die("font too large");
141 and 16kB for the map leaves 32 unicode values
142 for each font position */
143 if (!feof(stdin))
144 bb_perror_msg_and_die("font too large");
145 130
146 /* test for psf first */ 131 /* test for psf first */
147 { 132 {
148 struct psf_header psfhdr; 133 struct psf_header psfhdr;
149 int fontsize; 134 int fontsize;
150 int hastable; 135 int hastable;
151 unsigned int head0, head; 136 unsigned head0, head;
152 137
153 if (inputlth < sizeof(struct psf_header)) 138 if (inputlth < sizeof(struct psf_header))
154 goto no_psf; 139 goto no_psf;
@@ -161,7 +146,7 @@ static void loadnewfont(int fd)
161 if (psfhdr.mode > PSF_MAXMODE) 146 if (psfhdr.mode > PSF_MAXMODE)
162 bb_error_msg_and_die("unsupported psf file mode"); 147 bb_error_msg_and_die("unsupported psf file mode");
163 fontsize = ((psfhdr.mode & PSF_MODE512) ? 512 : 256); 148 fontsize = ((psfhdr.mode & PSF_MODE512) ? 512 : 256);
164#if !defined( PIO_FONTX ) || defined( __sparc__ ) 149#if !defined(PIO_FONTX) || defined(__sparc__)
165 if (fontsize != 256) 150 if (fontsize != 256)
166 bb_error_msg_and_die("only fontsize 256 supported"); 151 bb_error_msg_and_die("only fontsize 256 supported");
167#endif 152#endif
@@ -177,8 +162,8 @@ static void loadnewfont(int fd)
177 do_loadtable(fd, inbuf + head, inputlth - head, fontsize); 162 do_loadtable(fd, inbuf + head, inputlth - head, fontsize);
178 return; 163 return;
179 } 164 }
180 no_psf:
181 165
166 no_psf:
182 /* file with three code pages? */ 167 /* file with three code pages? */
183 if (inputlth == 9780) { 168 if (inputlth == 9780) {
184 offset = 40; 169 offset = 40;
@@ -192,3 +177,17 @@ static void loadnewfont(int fd)
192 } 177 }
193 do_loadfont(fd, inbuf + offset, unit, 256); 178 do_loadfont(fd, inbuf + offset, unit, 256);
194} 179}
180
181int loadfont_main(int argc, char **argv);
182int loadfont_main(int argc, char **argv)
183{
184 int fd;
185
186 if (argc != 1)
187 bb_show_usage();
188
189 fd = xopen(CURRENT_VC, O_RDWR);
190 loadnewfont(fd);
191
192 return EXIT_SUCCESS;
193}
diff --git a/editors/Config.in b/editors/Config.in
index fd840ae9a..936004c9b 100644
--- a/editors/Config.in
+++ b/editors/Config.in
@@ -50,6 +50,16 @@ config VI
50 learning curve. If you are not already comfortable with 'vi' 50 learning curve. If you are not already comfortable with 'vi'
51 you may wish to use something else. 51 you may wish to use something else.
52 52
53config FEATURE_VI_MAX_LEN
54 int "Maximum line length in vi"
55 range 256 16384
56 default 1024
57 depends on VI
58 help
59 vi uses on-stack buffers for intermediate line buffers.
60 You may want to decrease this parameter if your target machine
61 benefits from smaller stack usage.
62
53config FEATURE_VI_COLON 63config FEATURE_VI_COLON
54 bool "Enable \":\" colon commands (no \"ex\" mode)" 64 bool "Enable \":\" colon commands (no \"ex\" mode)"
55 default y 65 default y
diff --git a/editors/vi.c b/editors/vi.c
index cd64aacc9..b961ca5b8 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -32,7 +32,10 @@
32#define Isprint(c) ((unsigned char)(c) >= ' ' && (c) != 0x7f && (unsigned char)(c) != 0x9b) 32#define Isprint(c) ((unsigned char)(c) >= ' ' && (c) != 0x7f && (unsigned char)(c) != 0x9b)
33#endif 33#endif
34 34
35#define MAX_SCR_COLS BUFSIZ 35enum {
36 MAX_LINELEN = CONFIG_FEATURE_VI_MAX_LEN,
37 MAX_SCR_COLS = CONFIG_FEATURE_VI_MAX_LEN,
38};
36 39
37// Misc. non-Ascii keys that report an escape sequence 40// Misc. non-Ascii keys that report an escape sequence
38#define VI_K_UP (char)128 // cursor key Up 41#define VI_K_UP (char)128 // cursor key Up
@@ -545,7 +548,7 @@ static char *get_one_address(char * p, int *addr) // get colon addr, if present
545 char c; 548 char c;
546#endif 549#endif
547#if ENABLE_FEATURE_VI_SEARCH 550#if ENABLE_FEATURE_VI_SEARCH
548 char *pat, buf[BUFSIZ]; 551 char *pat, buf[MAX_LINELEN];
549#endif 552#endif
550 553
551 *addr = -1; // assume no addr 554 *addr = -1; // assume no addr
@@ -648,7 +651,7 @@ static void setops(const char *args, const char *opname, int flg_no,
648static void colon(char * buf) 651static void colon(char * buf)
649{ 652{
650 char c, *orig_buf, *buf1, *q, *r; 653 char c, *orig_buf, *buf1, *q, *r;
651 char *fn, cmd[BUFSIZ], args[BUFSIZ]; 654 char *fn, cmd[MAX_LINELEN], args[MAX_LINELEN];
652 int i, l, li, ch, b, e; 655 int i, l, li, ch, b, e;
653 int useforce = FALSE, forced = FALSE; 656 int useforce = FALSE, forced = FALSE;
654 struct stat st_buf; 657 struct stat st_buf;
@@ -679,8 +682,8 @@ static void colon(char * buf)
679 r = end - 1; 682 r = end - 1;
680 li = count_lines(text, end - 1); 683 li = count_lines(text, end - 1);
681 fn = cfn; // default to current file 684 fn = cfn; // default to current file
682 memset(cmd, '\0', BUFSIZ); // clear cmd[] 685 memset(cmd, '\0', MAX_LINELEN); // clear cmd[]
683 memset(args, '\0', BUFSIZ); // clear args[] 686 memset(args, '\0', MAX_LINELEN); // clear args[]
684 687
685 // look for optional address(es) :. :1 :1,9 :'q,'a :% 688 // look for optional address(es) :. :1 :1,9 :'q,'a :%
686 buf = get_address(buf, &b, &e); 689 buf = get_address(buf, &b, &e);
@@ -763,10 +766,10 @@ static void colon(char * buf)
763 } 766 }
764 if (args[0]) { 767 if (args[0]) {
765 // the user supplied a file name 768 // the user supplied a file name
766 fn= args; 769 fn = args;
767 } else if (cfn && cfn[0]) { 770 } else if (cfn && cfn[0]) {
768 // no user supplied name- use the current filename 771 // no user supplied name- use the current filename
769 fn= cfn; 772 fn = cfn;
770 goto vc5; 773 goto vc5;
771 } else { 774 } else {
772 // no user file name, no current name- punt 775 // no user file name, no current name- punt
@@ -1984,8 +1987,7 @@ static void start_new_cmd_q(char c)
1984 // release old cmd 1987 // release old cmd
1985 free(last_modifying_cmd); 1988 free(last_modifying_cmd);
1986 // get buffer for new cmd 1989 // get buffer for new cmd
1987 last_modifying_cmd = xmalloc(BUFSIZ); 1990 last_modifying_cmd = xzalloc(MAX_LINELEN);
1988 memset(last_modifying_cmd, '\0', BUFSIZ); // clear new cmd queue
1989 // if there is a current cmd count put it in the buffer first 1991 // if there is a current cmd count put it in the buffer first
1990 if (cmdcnt > 0) 1992 if (cmdcnt > 0)
1991 sprintf(last_modifying_cmd, "%d%c", cmdcnt, c); 1993 sprintf(last_modifying_cmd, "%d%c", cmdcnt, c);
@@ -2238,7 +2240,7 @@ static char readit(void) // read (maybe cursor) key from stdin
2238 if (n <= 0) { 2240 if (n <= 0) {
2239 ri0: 2241 ri0:
2240 // the Q is empty, wait for a typed char 2242 // the Q is empty, wait for a typed char
2241 n = read(0, readbuffer, BUFSIZ - 1); 2243 n = read(0, readbuffer, MAX_LINELEN - 1);
2242 if (n < 0) { 2244 if (n < 0) {
2243 if (errno == EINTR) 2245 if (errno == EINTR)
2244 goto ri0; // interrupted sys call 2246 goto ri0; // interrupted sys call
@@ -2268,9 +2270,9 @@ static char readit(void) // read (maybe cursor) key from stdin
2268 tv.tv_usec = 50000; // Wait 5/100 seconds- 1 Sec=1000000 2270 tv.tv_usec = 50000; // Wait 5/100 seconds- 1 Sec=1000000
2269 2271
2270 // keep reading while there are input chars and room in buffer 2272 // keep reading while there are input chars and room in buffer
2271 while (select(1, &rfds, NULL, NULL, &tv) > 0 && n <= (BUFSIZ - 5)) { 2273 while (select(1, &rfds, NULL, NULL, &tv) > 0 && n <= (MAX_LINELEN - 5)) {
2272 // read the rest of the ESC string 2274 // read the rest of the ESC string
2273 int r = read(0, (void *) (readbuffer + n), BUFSIZ - n); 2275 int r = read(0, (void *) (readbuffer + n), MAX_LINELEN - n);
2274 if (r > 0) { 2276 if (r > 0) {
2275 n += r; 2277 n += r;
2276 } 2278 }
@@ -2305,7 +2307,7 @@ static char readit(void) // read (maybe cursor) key from stdin
2305 } 2307 }
2306 // remove key sequence from Q 2308 // remove key sequence from Q
2307 readed_for_parse -= n; 2309 readed_for_parse -= n;
2308 memmove(readbuffer, readbuffer + n, BUFSIZ - n); 2310 memmove(readbuffer, readbuffer + n, MAX_LINELEN - n);
2309 alarm(3); // we are done waiting for input, turn alarm ON 2311 alarm(3); // we are done waiting for input, turn alarm ON
2310 return c; 2312 return c;
2311} 2313}
@@ -2340,7 +2342,7 @@ static char get_one_char(void)
2340 c = readit(); // get the users input 2342 c = readit(); // get the users input
2341 if (last_modifying_cmd != 0) { 2343 if (last_modifying_cmd != 0) {
2342 int len = strlen(last_modifying_cmd); 2344 int len = strlen(last_modifying_cmd);
2343 if (len + 1 >= BUFSIZ) { 2345 if (len >= MAX_LINELEN - 1) {
2344 psbs("last_modifying_cmd overrun"); 2346 psbs("last_modifying_cmd overrun");
2345 } else { 2347 } else {
2346 // add new char to q 2348 // add new char to q
@@ -2358,7 +2360,7 @@ static char *get_input_line(const char * prompt) // get input line- use "status
2358{ 2360{
2359 static char *obufp; 2361 static char *obufp;
2360 2362
2361 char buf[BUFSIZ]; 2363 char buf[MAX_LINELEN];
2362 char c; 2364 char c;
2363 int i; 2365 int i;
2364 2366
@@ -2369,7 +2371,7 @@ static char *get_input_line(const char * prompt) // get input line- use "status
2369 write1(prompt); // write out the :, /, or ? prompt 2371 write1(prompt); // write out the :, /, or ? prompt
2370 2372
2371 i = strlen(buf); 2373 i = strlen(buf);
2372 while (i < BUFSIZ) { 2374 while (i < MAX_LINELEN) {
2373 c = get_one_char(); // read user input 2375 c = get_one_char(); // read user input
2374 if (c == '\n' || c == '\r' || c == 27) 2376 if (c == '\n' || c == '\r' || c == 27)
2375 break; // is this end of input 2377 break; // is this end of input
@@ -2514,16 +2516,16 @@ static int file_write(char * fn, char * first, char * last)
2514//----- Move the cursor to row x col (count from 0, not 1) ------- 2516//----- Move the cursor to row x col (count from 0, not 1) -------
2515static void place_cursor(int row, int col, int opti) 2517static void place_cursor(int row, int col, int opti)
2516{ 2518{
2517 char cm1[BUFSIZ]; 2519 char cm1[MAX_LINELEN];
2518 char *cm; 2520 char *cm;
2519#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR 2521#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
2520 char cm2[BUFSIZ]; 2522 char cm2[MAX_LINELEN];
2521 char *screenp; 2523 char *screenp;
2522 // char cm3[BUFSIZ]; 2524 // char cm3[MAX_LINELEN];
2523 int Rrow = last_row; 2525 int Rrow = last_row;
2524#endif 2526#endif
2525 2527
2526 memset(cm1, '\0', BUFSIZ - 1); // clear the buffer 2528 memset(cm1, '\0', MAX_LINELEN); // clear the buffer
2527 2529
2528 if (row < 0) row = 0; 2530 if (row < 0) row = 0;
2529 if (row >= rows) row = rows - 1; 2531 if (row >= rows) row = rows - 1;
@@ -2539,7 +2541,7 @@ static void place_cursor(int row, int col, int opti)
2539#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR 2541#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
2540 //----- find the minimum # of chars to move cursor ------------- 2542 //----- find the minimum # of chars to move cursor -------------
2541 //----- 2. Try moving with discreet chars (Newline, [back]space, ...) 2543 //----- 2. Try moving with discreet chars (Newline, [back]space, ...)
2542 memset(cm2, '\0', BUFSIZ - 1); // clear the buffer 2544 memset(cm2, '\0', MAX_LINELEN); // clear the buffer
2543 2545
2544 // move to the correct row 2546 // move to the correct row
2545 while (row < Rrow) { 2547 while (row < Rrow) {
@@ -2696,7 +2698,7 @@ static void psb(const char *format, ...)
2696 2698
2697static void ni(const char * s) // display messages 2699static void ni(const char * s) // display messages
2698{ 2700{
2699 char buf[BUFSIZ]; 2701 char buf[MAX_LINELEN];
2700 2702
2701 print_literal(buf, s); 2703 print_literal(buf, s);
2702 psbs("\'%s\' is not implemented", buf); 2704 psbs("\'%s\' is not implemented", buf);
@@ -3900,7 +3902,7 @@ static void crash_dummy()
3900 cd0: 3902 cd0:
3901 startrbi = rbi = 0; 3903 startrbi = rbi = 0;
3902 sleeptime = 0; // how long to pause between commands 3904 sleeptime = 0; // how long to pause between commands
3903 memset(readbuffer, '\0', BUFSIZ); // clear the read buffer 3905 memset(readbuffer, '\0', MAX_LINELEN); // clear the read buffer
3904 // generate a command by percentages 3906 // generate a command by percentages
3905 percent = (int) lrand48() % 100; // get a number from 0-99 3907 percent = (int) lrand48() % 100; // get a number from 0-99
3906 if (percent < Mp) { // Movement commands 3908 if (percent < Mp) { // Movement commands
@@ -3985,7 +3987,7 @@ static void crash_test()
3985 static time_t oldtim; 3987 static time_t oldtim;
3986 3988
3987 time_t tim; 3989 time_t tim;
3988 char d[2], msg[BUFSIZ]; 3990 char d[2], msg[MAX_LINELEN];
3989 3991
3990 msg[0] = '\0'; 3992 msg[0] = '\0';
3991 if (end < text) { 3993 if (end < text) {
diff --git a/libbb/Config.in b/libbb/Config.in
index 112a3d658..a1ff7c056 100644
--- a/libbb/Config.in
+++ b/libbb/Config.in
@@ -30,7 +30,17 @@ config FEATURE_EDITING
30 bool "Command line editing" 30 bool "Command line editing"
31 default n 31 default n
32 help 32 help
33 Enable command editing (mainly for shell). 33 Enable line editing (mainly for shell command line).
34
35config FEATURE_EDITING_MAX_LEN
36 int "Maximum length of input"
37 range 128 8192
38 default 1024
39 depends on FEATURE_EDITING
40 help
41 Line editing code uses on-stack buffers for storage.
42 You may want to decrease this parameter if your target machine
43 benefits from smaller stack usage.
34 44
35config FEATURE_EDITING_FANCY_KEYS 45config FEATURE_EDITING_FANCY_KEYS
36 bool "Additional editing keys" 46 bool "Additional editing keys"
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index b950d7f26..1f2e6a54e 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -28,7 +28,6 @@
28 - not true viewing if length prompt less terminal width 28 - not true viewing if length prompt less terminal width
29 */ 29 */
30 30
31//#include <sys/ioctl.h>
32#include "libbb.h" 31#include "libbb.h"
33 32
34 33
@@ -59,6 +58,7 @@
59#define ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR \ 58#define ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR \
60(ENABLE_FEATURE_USERNAME_COMPLETION || ENABLE_FEATURE_EDITING_FANCY_PROMPT) 59(ENABLE_FEATURE_USERNAME_COMPLETION || ENABLE_FEATURE_EDITING_FANCY_PROMPT)
61 60
61enum { MAX_LINELEN = CONFIG_FEATURE_EDITING_MAX_LEN };
62 62
63static line_input_t *state; 63static line_input_t *state;
64 64
@@ -327,8 +327,8 @@ static void username_tab_completion(char *ud, char *with_shash_flg)
327 home = entry->pw_dir; 327 home = entry->pw_dir;
328 } 328 }
329 if (home) { 329 if (home) {
330 if ((userlen + strlen(home) + 1) < BUFSIZ) { 330 if ((userlen + strlen(home) + 1) < MAX_LINELEN) {
331 char temp2[BUFSIZ]; /* argument size */ 331 char temp2[MAX_LINELEN]; /* argument size */
332 332
333 /* /home/user/... */ 333 /* /home/user/... */
334 sprintf(temp2, "%s%s", home, ud); 334 sprintf(temp2, "%s%s", home, ud);
@@ -410,7 +410,7 @@ static void exe_n_cwd_tab_completion(char *command, int type)
410{ 410{
411 DIR *dir; 411 DIR *dir;
412 struct dirent *next; 412 struct dirent *next;
413 char dirbuf[BUFSIZ]; 413 char dirbuf[MAX_LINELEN];
414 struct stat st; 414 struct stat st;
415 char *path1[1]; 415 char *path1[1];
416 char **paths = path1; 416 char **paths = path1;
@@ -496,16 +496,16 @@ static void exe_n_cwd_tab_completion(char *command, int type)
496#define QUOT (UCHAR_MAX+1) 496#define QUOT (UCHAR_MAX+1)
497 497
498#define collapse_pos(is, in) { \ 498#define collapse_pos(is, in) { \
499 memmove(int_buf+(is), int_buf+(in), (BUFSIZ+1-(is)-(in))*sizeof(int)); \ 499 memmove(int_buf+(is), int_buf+(in), (MAX_LINELEN+1-(is)-(in))*sizeof(int)); \
500 memmove(pos_buf+(is), pos_buf+(in), (BUFSIZ+1-(is)-(in))*sizeof(int)); } 500 memmove(pos_buf+(is), pos_buf+(in), (MAX_LINELEN+1-(is)-(in))*sizeof(int)); }
501 501
502static int find_match(char *matchBuf, int *len_with_quotes) 502static int find_match(char *matchBuf, int *len_with_quotes)
503{ 503{
504 int i, j; 504 int i, j;
505 int command_mode; 505 int command_mode;
506 int c, c2; 506 int c, c2;
507 int int_buf[BUFSIZ + 1]; 507 int int_buf[MAX_LINELEN + 1];
508 int pos_buf[BUFSIZ + 1]; 508 int pos_buf[MAX_LINELEN + 1];
509 509
510 /* set to integer dimension characters and own positions */ 510 /* set to integer dimension characters and own positions */
511 for (i = 0;; i++) { 511 for (i = 0;; i++) {
@@ -731,7 +731,7 @@ static void input_tab(int *lastWasTab)
731 if (!*lastWasTab) { 731 if (!*lastWasTab) {
732 char *tmp, *tmp1; 732 char *tmp, *tmp1;
733 int len_found; 733 int len_found;
734 char matchBuf[BUFSIZ]; 734 char matchBuf[MAX_LINELEN];
735 int find_type; 735 int find_type;
736 int recalc_pos; 736 int recalc_pos;
737 737
@@ -781,6 +781,7 @@ static void input_tab(int *lastWasTab)
781 if (!matches) 781 if (!matches)
782 return; /* not found */ 782 return; /* not found */
783 /* find minimal match */ 783 /* find minimal match */
784 // ash: yet another failure in trying to achieve "we don't die on OOM"
784 tmp1 = xstrdup(matches[0]); 785 tmp1 = xstrdup(matches[0]);
785 for (tmp = tmp1; *tmp; tmp++) 786 for (tmp = tmp1; *tmp; tmp++)
786 for (len_found = 1; len_found < num_matches; len_found++) 787 for (len_found = 1; len_found < num_matches; len_found++)
@@ -807,7 +808,7 @@ static void input_tab(int *lastWasTab)
807 } 808 }
808 len_found = strlen(tmp); 809 len_found = strlen(tmp);
809 /* have space to placed match? */ 810 /* have space to placed match? */
810 if ((len_found - strlen(matchBuf) + command_len) < BUFSIZ) { 811 if ((len_found - strlen(matchBuf) + command_len) < MAX_LINELEN) {
811 /* before word for match */ 812 /* before word for match */
812 command_ps[cursor - recalc_pos] = 0; 813 command_ps[cursor - recalc_pos] = 0;
813 /* save tail line */ 814 /* save tail line */
@@ -888,14 +889,14 @@ static void load_history(const char *fromfile)
888 fp = fopen(fromfile, "r"); 889 fp = fopen(fromfile, "r");
889 if (fp) { 890 if (fp) {
890 for (hi = 0; hi < MAX_HISTORY;) { 891 for (hi = 0; hi < MAX_HISTORY;) {
891 char * hl = xmalloc_getline(fp); 892 char *hl = xmalloc_getline(fp);
892 int l; 893 int l;
893 894
894 if (!hl) 895 if (!hl)
895 break; 896 break;
896 l = strlen(hl); 897 l = strlen(hl);
897 if (l >= BUFSIZ) 898 if (l >= MAX_LINELEN)
898 hl[BUFSIZ-1] = 0; 899 hl[MAX_LINELEN-1] = '\0';
899 if (l == 0 || hl[0] == ' ') { 900 if (l == 0 || hl[0] == ' ') {
900 free(hl); 901 free(hl);
901 continue; 902 continue;
@@ -1264,8 +1265,8 @@ int read_line_input(const char* prompt, char* command, int maxsize, line_input_t
1264#endif 1265#endif
1265 1266
1266// FIXME: audit & improve this 1267// FIXME: audit & improve this
1267 if (maxsize > BUFSIZ) 1268 if (maxsize > MAX_LINELEN)
1268 maxsize = BUFSIZ; 1269 maxsize = MAX_LINELEN;
1269 1270
1270 /* With null flags, no other fields are ever used */ 1271 /* With null flags, no other fields are ever used */
1271 state = st ? st : (line_input_t*) &const_int_0; 1272 state = st ? st : (line_input_t*) &const_int_0;
@@ -1646,14 +1647,14 @@ int read_line_input(const char* prompt, char* command, int maxsize, line_input_t
1646 /* Delete */ 1647 /* Delete */
1647 input_delete(0); 1648 input_delete(0);
1648 break; 1649 break;
1649 case '1': 1650 case '1': // vt100? linux vt? or what?
1650 case 'H': 1651 case '7': // vt100? linux vt? or what?
1651 /* <Home> */ 1652 case 'H': /* xterm's <Home> */
1652 input_backward(cursor); 1653 input_backward(cursor);
1653 break; 1654 break;
1654 case '4': 1655 case '4': // vt100? linux vt? or what?
1655 case 'F': 1656 case '8': // vt100? linux vt? or what?
1656 /* <End> */ 1657 case 'F': /* xterm's <End> */
1657 input_end(); 1658 input_end();
1658 break; 1659 break;
1659 default: 1660 default:
@@ -1766,7 +1767,7 @@ const char *applet_name = "debug stuff usage";
1766 1767
1767int main(int argc, char **argv) 1768int main(int argc, char **argv)
1768{ 1769{
1769 char buff[BUFSIZ]; 1770 char buff[MAX_LINELEN];
1770 char *prompt = 1771 char *prompt =
1771#if ENABLE_FEATURE_EDITING_FANCY_PROMPT 1772#if ENABLE_FEATURE_EDITING_FANCY_PROMPT
1772 "\\[\\033[32;1m\\]\\u@\\[\\x1b[33;1m\\]\\h:" 1773 "\\[\\033[32;1m\\]\\u@\\[\\x1b[33;1m\\]\\h:"
diff --git a/networking/traceroute.c b/networking/traceroute.c
index ce8dc8395..5d39ae3cf 100644
--- a/networking/traceroute.c
+++ b/networking/traceroute.c
@@ -371,6 +371,8 @@ struct globals {
371static int 371static int
372ifaddrlist(struct IFADDRLIST **ipaddrp) 372ifaddrlist(struct IFADDRLIST **ipaddrp)
373{ 373{
374 enum { IFREQ_BUFSIZE = (32 * 1024) / sizeof(struct ifreq) };
375
374 int fd, nipaddr; 376 int fd, nipaddr;
375#ifdef HAVE_SOCKADDR_SA_LEN 377#ifdef HAVE_SOCKADDR_SA_LEN
376 int n; 378 int n;
@@ -379,22 +381,24 @@ ifaddrlist(struct IFADDRLIST **ipaddrp)
379 struct sockaddr_in *addr_sin; 381 struct sockaddr_in *addr_sin;
380 struct IFADDRLIST *al; 382 struct IFADDRLIST *al;
381 struct ifconf ifc; 383 struct ifconf ifc;
382 struct ifreq ibuf[(32 * 1024) / sizeof(struct ifreq)], ifr; 384 struct ifreq ifr;
385 /* Was on stack, but 32k is a bit too much: */
386 struct ifreq *ibuf = xmalloc(IFREQ_BUFSIZE * sizeof(ibuf[0]));
383 struct IFADDRLIST *st_ifaddrlist; 387 struct IFADDRLIST *st_ifaddrlist;
384 388
385 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 389 fd = xsocket(AF_INET, SOCK_DGRAM, 0);
386 390
387 ifc.ifc_len = sizeof(ibuf); 391 ifc.ifc_len = IFREQ_BUFSIZE * sizeof(ibuf[0]);
388 ifc.ifc_buf = (caddr_t)ibuf; 392 ifc.ifc_buf = (caddr_t)ibuf;
389 393
390 if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 || 394 if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0
391 ifc.ifc_len < sizeof(struct ifreq)) { 395 || ifc.ifc_len < sizeof(struct ifreq)
396 ) {
392 if (errno == EINVAL) 397 if (errno == EINVAL)
393 bb_error_msg_and_die( 398 bb_error_msg_and_die(
394 "SIOCGIFCONF: ifreq struct too small (%d bytes)", 399 "SIOCGIFCONF: ifreq struct too small (%d bytes)",
395 (int)sizeof(ibuf)); 400 IFREQ_BUFSIZE * sizeof(ibuf[0]));
396 else 401 bb_perror_msg_and_die("SIOCGIFCONF");
397 bb_perror_msg_and_die("SIOCGIFCONF");
398 } 402 }
399 ifrp = ibuf; 403 ifrp = ibuf;
400 ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len); 404 ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len);
@@ -449,9 +453,10 @@ ifaddrlist(struct IFADDRLIST **ipaddrp)
449 ++nipaddr; 453 ++nipaddr;
450 } 454 }
451 if (nipaddr == 0) 455 if (nipaddr == 0)
452 bb_error_msg_and_die ("can't find any network interfaces"); 456 bb_error_msg_and_die("can't find any network interfaces");
453 (void)close(fd);
454 457
458 free(ibuf);
459 close(fd);
455 *ipaddrp = st_ifaddrlist; 460 *ipaddrp = st_ifaddrlist;
456 return nipaddr; 461 return nipaddr;
457} 462}
@@ -492,11 +497,13 @@ findsaddr(const struct sockaddr_in *to, struct sockaddr_in *from)
492 ++n; 497 ++n;
493 if (n == 1 && strncmp(buf, "Iface", 5) == 0) 498 if (n == 1 && strncmp(buf, "Iface", 5) == 0)
494 continue; 499 continue;
495 if ((i = sscanf(buf, "%255s %x %*s %*s %*s %*s %*s %x", 500 i = sscanf(buf, "%255s %x %*s %*s %*s %*s %*s %x",
496 tdevice, &dest, &tmask)) != 3) 501 tdevice, &dest, &tmask);
497 bb_error_msg_and_die ("junk in buffer"); 502 if (i != 3)
498 if ((to->sin_addr.s_addr & tmask) == dest && 503 bb_error_msg_and_die("junk in buffer");
499 (tmask > mask || mask == 0)) { 504 if ((to->sin_addr.s_addr & tmask) == dest
505 && (tmask > mask || mask == 0)
506 ) {
500 mask = tmask; 507 mask = tmask;
501 strcpy(device, tdevice); 508 strcpy(device, tdevice);
502 } 509 }
@@ -504,7 +511,7 @@ findsaddr(const struct sockaddr_in *to, struct sockaddr_in *from)
504 fclose(f); 511 fclose(f);
505 512
506 if (device[0] == '\0') 513 if (device[0] == '\0')
507 bb_error_msg_and_die ("can't find interface"); 514 bb_error_msg_and_die("can't find interface");
508 515
509 /* Get the interface address list */ 516 /* Get the interface address list */
510 n = ifaddrlist(&al); 517 n = ifaddrlist(&al);
@@ -808,7 +815,7 @@ packet_ok(unsigned char *buf, int cc, struct sockaddr_in *from, int seq)
808 "%s: icmp type %d (%s) code %d\n", 815 "%s: icmp type %d (%s) code %d\n",
809 cc, inet_ntoa(from->sin_addr), 816 cc, inet_ntoa(from->sin_addr),
810 inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code); 817 inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
811 for (i = 4; i < cc ; i += sizeof(*lp)) 818 for (i = 4; i < cc; i += sizeof(*lp))
812 printf("%2d: x%8.8x\n", i, *lp++); 819 printf("%2d: x%8.8x\n", i, *lp++);
813 } 820 }
814#endif 821#endif