aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-12-03 10:45:14 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-12-03 10:45:14 +0000
commit7221c8c22dd527700204eb5cc4d0651af4273f4f (patch)
tree9f45c168efd2a83c7a700dfc2161e9fa2823a222
parent2bec5139964ebf814ffddbedd526651361be69f8 (diff)
downloadbusybox-w32-7221c8c22dd527700204eb5cc4d0651af4273f4f.tar.gz
busybox-w32-7221c8c22dd527700204eb5cc4d0651af4273f4f.tar.bz2
busybox-w32-7221c8c22dd527700204eb5cc4d0651af4273f4f.zip
lineedit: reduce stack usage
netstat: reduce stack usage; fix handling of NULs in unix socket filenames static.has_inode 1 - -1 do_info 119 116 -3 deinit_S 60 51 -9 unix_do_one 578 451 -127 parse_and_put_prompt 966 825 -141 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 0/4 up/down: 0/-281) Total: -281 bytes
-rw-r--r--libbb/lineedit.c93
-rw-r--r--networking/netstat.c70
2 files changed, 80 insertions, 83 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 07db6358d..1397409cc 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -91,7 +91,6 @@ struct statics {
91 91
92 const char *cmdedit_prompt; 92 const char *cmdedit_prompt;
93#if ENABLE_FEATURE_EDITING_FANCY_PROMPT 93#if ENABLE_FEATURE_EDITING_FANCY_PROMPT
94 char *hostname_buf;
95 int num_ok_lines; /* = 1; */ 94 int num_ok_lines; /* = 1; */
96#endif 95#endif
97 96
@@ -136,7 +135,6 @@ static struct statics *const ptr_to_statics __attribute__ ((section (".data")));
136#define command_len (S.command_len ) 135#define command_len (S.command_len )
137#define command_ps (S.command_ps ) 136#define command_ps (S.command_ps )
138#define cmdedit_prompt (S.cmdedit_prompt ) 137#define cmdedit_prompt (S.cmdedit_prompt )
139#define hostname_buf (S.hostname_buf )
140#define num_ok_lines (S.num_ok_lines ) 138#define num_ok_lines (S.num_ok_lines )
141#define user_buf (S.user_buf ) 139#define user_buf (S.user_buf )
142#define home_pwd_buf (S.home_pwd_buf ) 140#define home_pwd_buf (S.home_pwd_buf )
@@ -155,7 +153,6 @@ static struct statics *const ptr_to_statics __attribute__ ((section (".data")));
155static void deinit_S(void) 153static void deinit_S(void)
156{ 154{
157#if ENABLE_FEATURE_EDITING_FANCY_PROMPT 155#if ENABLE_FEATURE_EDITING_FANCY_PROMPT
158 free(hostname_buf);
159 /* This one is allocated only if FANCY_PROMPT is on 156 /* This one is allocated only if FANCY_PROMPT is on
160 * (otherwise it points to verbatim prompt (NOT malloced) */ 157 * (otherwise it points to verbatim prompt (NOT malloced) */
161 free((char*)cmdedit_prompt); 158 free((char*)cmdedit_prompt);
@@ -381,14 +378,14 @@ static void username_tab_completion(char *ud, char *with_shash_flg)
381 if (with_shash_flg) { /* "~/..." or "~user/..." */ 378 if (with_shash_flg) { /* "~/..." or "~user/..." */
382 char *sav_ud = ud - 1; 379 char *sav_ud = ud - 1;
383 char *home = NULL; 380 char *home = NULL;
384 char *temp;
385 381
386 if (*ud == '/') { /* "~/..." */ 382 if (*ud == '/') { /* "~/..." */
387 home = home_pwd_buf; 383 home = home_pwd_buf;
388 } else { 384 } else {
389 /* "~user/..." */ 385 /* "~user/..." */
386 char *temp;
390 temp = strchr(ud, '/'); 387 temp = strchr(ud, '/');
391 *temp = 0; /* ~user\0 */ 388 *temp = '\0'; /* ~user\0 */
392 entry = getpwnam(ud); 389 entry = getpwnam(ud);
393 *temp = '/'; /* restore ~user/... */ 390 *temp = '/'; /* restore ~user/... */
394 ud = temp; 391 ud = temp;
@@ -1163,21 +1160,23 @@ static void parse_and_put_prompt(const char *prmt_ptr)
1163 size_t cur_prmt_len = 0; 1160 size_t cur_prmt_len = 0;
1164 char flg_not_length = '['; 1161 char flg_not_length = '[';
1165 char *prmt_mem_ptr = xzalloc(1); 1162 char *prmt_mem_ptr = xzalloc(1);
1166 char *pwd_buf = xrealloc_getcwd_or_warn(NULL); 1163 char *cwd_buf = xrealloc_getcwd_or_warn(NULL);
1167 char buf2[PATH_MAX + 1]; 1164 char cbuf[2];
1168 char buf[2];
1169 char c; 1165 char c;
1170 char *pbuf; 1166 char *pbuf;
1171 1167
1172 cmdedit_prmt_len = 0; 1168 cmdedit_prmt_len = 0;
1173 1169
1174 if (!pwd_buf) { 1170 if (!cwd_buf) {
1175 pwd_buf = (char *)bb_msg_unknown; 1171 cwd_buf = (char *)bb_msg_unknown;
1176 } 1172 }
1177 1173
1174 cbuf[1] = '\0'; /* never changes */
1175
1178 while (*prmt_ptr) { 1176 while (*prmt_ptr) {
1179 pbuf = buf; 1177 char *free_me = NULL;
1180 pbuf[1] = 0; 1178
1179 pbuf = cbuf;
1181 c = *prmt_ptr++; 1180 c = *prmt_ptr++;
1182 if (c == '\\') { 1181 if (c == '\\') {
1183 const char *cp = prmt_ptr; 1182 const char *cp = prmt_ptr;
@@ -1188,6 +1187,7 @@ static void parse_and_put_prompt(const char *prmt_ptr)
1188 if (*cp == '\0') 1187 if (*cp == '\0')
1189 break; 1188 break;
1190 c = *prmt_ptr++; 1189 c = *prmt_ptr++;
1190
1191 switch (c) { 1191 switch (c) {
1192#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR 1192#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
1193 case 'u': 1193 case 'u':
@@ -1195,87 +1195,81 @@ static void parse_and_put_prompt(const char *prmt_ptr)
1195 break; 1195 break;
1196#endif 1196#endif
1197 case 'h': 1197 case 'h':
1198 pbuf = hostname_buf; 1198 pbuf = free_me = xzalloc(256);
1199 if (!pbuf) { 1199 if (gethostname(pbuf, 255) < 0) {
1200 pbuf = xzalloc(256); 1200 pbuf[0] = '?';
1201 if (gethostname(pbuf, 255) < 0) { 1201 pbuf[1] = '\0';
1202 strcpy(pbuf, "?");
1203 } else {
1204 char *s = strchr(pbuf, '.');
1205 if (s)
1206 *s = '\0';
1207 }
1208 hostname_buf = pbuf;
1209 } 1202 }
1203 *strchrnul(pbuf, '.') = '\0';
1210 break; 1204 break;
1211 case '$': 1205 case '$':
1212 c = (geteuid() == 0 ? '#' : '$'); 1206 c = (geteuid() == 0 ? '#' : '$');
1213 break; 1207 break;
1214#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR 1208#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
1215 case 'w': 1209 case 'w':
1216 pbuf = pwd_buf; 1210 /* /home/user[/something] -> ~[/something] */
1211 pbuf = cwd_buf;
1217 l = strlen(home_pwd_buf); 1212 l = strlen(home_pwd_buf);
1218 if (l != 0 1213 if (l != 0
1219 && strncmp(home_pwd_buf, pbuf, l) == 0 1214 && strncmp(home_pwd_buf, cwd_buf, l) == 0
1220 && (pbuf[l]=='/' || pbuf[l]=='\0') 1215 && (cwd_buf[l]=='/' || cwd_buf[l]=='\0')
1221 && strlen(pwd_buf+l) < PATH_MAX 1216 && strlen(cwd_buf + l) < PATH_MAX
1222 ) { 1217 ) {
1223 pbuf = buf2; 1218 pbuf = free_me = xasprintf("~%s", cwd_buf + l);
1224 *pbuf = '~';
1225 strcpy(pbuf+1, pwd_buf+l);
1226 } 1219 }
1227 break; 1220 break;
1228#endif 1221#endif
1229 case 'W': 1222 case 'W':
1230 pbuf = pwd_buf; 1223 pbuf = cwd_buf;
1231 cp = strrchr(pbuf, '/'); 1224 cp = strrchr(pbuf, '/');
1232 if (cp != NULL && cp != pbuf) 1225 if (cp != NULL && cp != pbuf)
1233 pbuf += (cp-pbuf) + 1; 1226 pbuf += (cp-pbuf) + 1;
1234 break; 1227 break;
1235 case '!': 1228 case '!':
1236 pbuf = buf2; 1229 pbuf = free_me = xasprintf("%d", num_ok_lines);
1237 snprintf(buf2, sizeof(buf2), "%d", num_ok_lines);
1238 break; 1230 break;
1239 case 'e': case 'E': /* \e \E = \033 */ 1231 case 'e': case 'E': /* \e \E = \033 */
1240 c = '\033'; 1232 c = '\033';
1241 break; 1233 break;
1242 case 'x': case 'X': 1234 case 'x': case 'X': {
1235 char buf2[4];
1243 for (l = 0; l < 3;) { 1236 for (l = 0; l < 3;) {
1244 int h; 1237 unsigned h;
1245 buf2[l++] = *prmt_ptr; 1238 buf2[l++] = *prmt_ptr;
1246 buf2[l] = 0; 1239 buf2[l] = '\0';
1247 h = strtol(buf2, &pbuf, 16); 1240 h = strtoul(buf2, &pbuf, 16);
1248 if (h > UCHAR_MAX || (pbuf - buf2) < l) { 1241 if (h > UCHAR_MAX || (pbuf - buf2) < l) {
1249 l--; 1242 buf2[--l] = '\0';
1250 break; 1243 break;
1251 } 1244 }
1252 prmt_ptr++; 1245 prmt_ptr++;
1253 } 1246 }
1254 buf2[l] = 0; 1247 c = (char)strtoul(buf2, NULL, 16);
1255 c = (char)strtol(buf2, NULL, 16);
1256 if (c == 0) 1248 if (c == 0)
1257 c = '?'; 1249 c = '?';
1258 pbuf = buf; 1250 pbuf = cbuf;
1259 break; 1251 break;
1252 }
1260 case '[': case ']': 1253 case '[': case ']':
1261 if (c == flg_not_length) { 1254 if (c == flg_not_length) {
1262 flg_not_length = (flg_not_length == '[' ? ']' : '['); 1255 flg_not_length = (flg_not_length == '[' ? ']' : '[');
1263 continue; 1256 continue;
1264 } 1257 }
1265 break; 1258 break;
1266 } 1259 } /* switch */
1267 } 1260 } /* if */
1268 } 1261 } /* if */
1269 if (pbuf == buf) 1262 cbuf[0] = c;
1270 *pbuf = c;
1271 cur_prmt_len = strlen(pbuf); 1263 cur_prmt_len = strlen(pbuf);
1272 prmt_len += cur_prmt_len; 1264 prmt_len += cur_prmt_len;
1273 if (flg_not_length != ']') 1265 if (flg_not_length != ']')
1274 cmdedit_prmt_len += cur_prmt_len; 1266 cmdedit_prmt_len += cur_prmt_len;
1275 prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf); 1267 prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf);
1276 } 1268 free(free_me);
1277 if (pwd_buf != (char *)bb_msg_unknown) 1269 } /* while */
1278 free(pwd_buf); 1270
1271 if (cwd_buf != (char *)bb_msg_unknown)
1272 free(cwd_buf);
1279 cmdedit_prompt = prmt_mem_ptr; 1273 cmdedit_prompt = prmt_mem_ptr;
1280 put_prompt(); 1274 put_prompt();
1281} 1275}
@@ -1397,7 +1391,6 @@ int read_line_input(const char *prompt, char *command, int maxsize, line_input_t
1397 if (entry) { 1391 if (entry) {
1398 user_buf = xstrdup(entry->pw_name); 1392 user_buf = xstrdup(entry->pw_name);
1399 home_pwd_buf = xstrdup(entry->pw_dir); 1393 home_pwd_buf = xstrdup(entry->pw_dir);
1400 /* They are not freed on exit (too small to bother) */
1401 } 1394 }
1402 } 1395 }
1403#endif 1396#endif
diff --git a/networking/netstat.c b/networking/netstat.c
index 11f141947..d86c2ff5e 100644
--- a/networking/netstat.c
+++ b/networking/netstat.c
@@ -148,7 +148,7 @@ static char *ip_port_str(struct sockaddr *addr, int port, const char *proto, int
148 return host_port; 148 return host_port;
149} 149}
150 150
151static void tcp_do_one(int lnr, const char *line) 151static void tcp_do_one(int lnr, char *line)
152{ 152{
153 char local_addr[64], rem_addr[64]; 153 char local_addr[64], rem_addr[64];
154 char more[512]; 154 char more[512];
@@ -201,7 +201,7 @@ static void tcp_do_one(int lnr, const char *line)
201 } 201 }
202} 202}
203 203
204static void udp_do_one(int lnr, const char *line) 204static void udp_do_one(int lnr, char *line)
205{ 205{
206 char local_addr[64], rem_addr[64]; 206 char local_addr[64], rem_addr[64];
207 const char *state_str; 207 const char *state_str;
@@ -283,7 +283,7 @@ static void udp_do_one(int lnr, const char *line)
283 } 283 }
284} 284}
285 285
286static void raw_do_one(int lnr, const char *line) 286static void raw_do_one(int lnr, char *line)
287{ 287{
288 char local_addr[64], rem_addr[64]; 288 char local_addr[64], rem_addr[64];
289 char more[512]; 289 char more[512];
@@ -339,31 +339,37 @@ static void raw_do_one(int lnr, const char *line)
339 } 339 }
340} 340}
341 341
342static void unix_do_one(int nr, const char *line) 342static void unix_do_one(int nr, char *line)
343{ 343{
344 static smallint has_inode = 0;
345
346 char path[PATH_MAX], ss_flags[32];
347 const char *ss_proto, *ss_state, *ss_type;
348 int num, state, type, inode;
349 void *d;
350 unsigned long refcnt, proto, unix_flags; 344 unsigned long refcnt, proto, unix_flags;
345 unsigned long inode;
346 int type, state;
347 int num, path_ofs;
348 void *d;
349 const char *ss_proto, *ss_state, *ss_type;
350 char ss_flags[32];
351 351
352 if (nr == 0) { 352 if (nr == 0)
353 if (strstr(line, "Inode")) 353 return; /* skip header */
354 has_inode = 1; 354
355 return; 355 {
356 char *last = last_char_is(line, '\n');
357 if (last)
358 *last = '\0';
356 } 359 }
357 path[0] = '\0'; 360
358 num = sscanf(line, "%p: %lX %lX %lX %X %X %d %s", 361 /* 2.6.15 may report lines like "... @/tmp/fam-user-^@^@^@^@^@^@^@..."
359 &d, &refcnt, &proto, &unix_flags, &type, &state, &inode, path); 362 * (those ^@ are NUL bytes). fgets sees them as tons of empty lines. */
360 if (num < 6) { 363 if (!line[0])
361 bb_error_msg("warning, got bogus unix line");
362 return; 364 return;
363 }
364 if (!has_inode)
365 sprintf(path, "%d", inode);
366 365
366 path_ofs = 0; /* paranoia */
367 num = sscanf(line, "%p: %lX %lX %lX %X %X %lu %n",
368 &d, &refcnt, &proto, &unix_flags, &type, &state, &inode, &path_ofs);
369 if (num < 7) {
370 bb_error_msg("got bogus unix line '%s'", line);
371 return;
372 }
367 if ((flags & (NETSTAT_LISTENING|NETSTAT_CONNECTED)) != (NETSTAT_LISTENING|NETSTAT_CONNECTED)) { 373 if ((flags & (NETSTAT_LISTENING|NETSTAT_CONNECTED)) != (NETSTAT_LISTENING|NETSTAT_CONNECTED)) {
368 if ((state == SS_UNCONNECTED) && (unix_flags & SO_ACCEPTCON)) { 374 if ((state == SS_UNCONNECTED) && (unix_flags & SO_ACCEPTCON)) {
369 if (!(flags & NETSTAT_LISTENING)) 375 if (!(flags & NETSTAT_LISTENING))
@@ -439,13 +445,9 @@ static void unix_do_one(int nr, const char *line)
439 strcat(ss_flags, "N "); 445 strcat(ss_flags, "N ");
440 strcat(ss_flags, "]"); 446 strcat(ss_flags, "]");
441 447
442 printf("%-5s %-6ld %-11s %-10s %-13s ", 448 printf("%-5s %-6ld %-11s %-10s %-13s %6lu %s\n",
443 ss_proto, refcnt, ss_flags, ss_type, ss_state); 449 ss_proto, refcnt, ss_flags, ss_type, ss_state, inode,
444 if (has_inode) 450 line + path_ofs);
445 printf("%-6d ", inode);
446 else
447 printf("- ");
448 puts(path);
449} 451}
450 452
451#define _PATH_PROCNET_UDP "/proc/net/udp" 453#define _PATH_PROCNET_UDP "/proc/net/udp"
@@ -456,10 +458,11 @@ static void unix_do_one(int nr, const char *line)
456#define _PATH_PROCNET_RAW6 "/proc/net/raw6" 458#define _PATH_PROCNET_RAW6 "/proc/net/raw6"
457#define _PATH_PROCNET_UNIX "/proc/net/unix" 459#define _PATH_PROCNET_UNIX "/proc/net/unix"
458 460
459static void do_info(const char *file, const char *name, void (*proc)(int, const char *)) 461static void do_info(const char *file, const char *name, void (*proc)(int, char *))
460{ 462{
461 int lnr = 0; 463 int lnr;
462 FILE *procinfo; 464 FILE *procinfo;
465 char *buffer;
463 466
464 procinfo = fopen(file, "r"); 467 procinfo = fopen(file, "r");
465 if (procinfo == NULL) { 468 if (procinfo == NULL) {
@@ -470,13 +473,14 @@ static void do_info(const char *file, const char *name, void (*proc)(int, const
470 } 473 }
471 return; 474 return;
472 } 475 }
476 lnr = 0;
473 do { 477 do {
474 char *buffer = xmalloc_fgets(procinfo); 478 buffer = xmalloc_fgets(procinfo);
475 if (buffer) { 479 if (buffer) {
476 (proc)(lnr++, buffer); 480 (proc)(lnr++, buffer);
477 free(buffer); 481 free(buffer);
478 } 482 }
479 } while (!feof(procinfo)); 483 } while (buffer);
480 fclose(procinfo); 484 fclose(procinfo);
481} 485}
482 486