aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-09-24 10:41:30 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-09-24 10:41:30 +0000
commit512a545f0dfd0717694f8694398c1a811e70b607 (patch)
tree01f54b21525827818acb072c4ecb84475b6d5d58
parent2a1d024333b56a8de1ebd61405ea8f2577127dd8 (diff)
downloadbusybox-w32-512a545f0dfd0717694f8694398c1a811e70b607.tar.gz
busybox-w32-512a545f0dfd0717694f8694398c1a811e70b607.tar.bz2
busybox-w32-512a545f0dfd0717694f8694398c1a811e70b607.zip
inetd: make some fields smaller, move data out of data/bss sections
function old new delta inetd_main 2125 2160 +35 setup 640 645 +5 initring 48 53 +5 reapchild 169 173 +4 retry 92 93 +1 goaway 113 112 -1 inetd_setproctitle 175 173 -2 chargen_dg 229 227 -2 uid 4 - -4 ....................... Argv 4 - -4 rlim_ofile_cur 8 - -8 config 1610 1602 -8 rlim_ofile 16 - -16 getconfigent 1271 1241 -30 builtins 176 132 -44 ring 128 - -128 allsock 128 - -128 ------------------------------------------------------------------------------ (add/remove: 0/18 grow/shrink: 5/6 up/down: 50/-423) Total: -373 bytes text data bss dec hex filename 774144 1051 10708 785903 bfdef busybox_old 774108 1039 10380 785527 bfc77 busybox_unstripped $ size inetd.o inetd_orig.o text data bss dec hex filename 9027 0 0 9027 2343 inetd.o 9064 12 324 9400 24b8 inetd_orig.o
-rw-r--r--networking/inetd.c207
1 files changed, 130 insertions, 77 deletions
diff --git a/networking/inetd.c b/networking/inetd.c
index e4e9f95b0..b3a00cfa5 100644
--- a/networking/inetd.c
+++ b/networking/inetd.c
@@ -190,9 +190,6 @@ extern char **environ;
190 190
191/* Reserve some descriptors, 3 stdio + at least: 1 log, 1 conf. file */ 191/* Reserve some descriptors, 3 stdio + at least: 1 log, 1 conf. file */
192#define FD_MARGIN 8 192#define FD_MARGIN 8
193static rlim_t rlim_ofile_cur = OPEN_MAX;
194static struct rlimit rlim_ofile;
195
196 193
197/* Check unsupporting builtin */ 194/* Check unsupporting builtin */
198#if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_ECHO || \ 195#if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_ECHO || \
@@ -209,11 +206,24 @@ static struct rlimit rlim_ofile;
209# define INETD_SETPROCTITLE 206# define INETD_SETPROCTITLE
210#endif 207#endif
211 208
212typedef struct servtab { 209typedef int8_t socktype_t;
210typedef int8_t family_t;
211struct BUG_too_small {
212 char BUG_socktype_t_too_small[(0
213 | SOCK_STREAM
214 | SOCK_DGRAM
215 | SOCK_RDM
216 | SOCK_SEQPACKET
217 | SOCK_RAW) <= 127 ? 1 : -1];
218 char BUG_family_t_too_small[(0
219 | AF_INET
220 | AF_INET6
221 | AF_UNIX) <= 127 ? 1 : -1];
222};
223
224typedef struct servtab_t {
213 char *se_hostaddr; /* host address to listen on */ 225 char *se_hostaddr; /* host address to listen on */
214 char *se_service; /* name of service */ 226 char *se_service; /* name of service */
215 int se_socktype; /* type of socket to use */
216 int se_family; /* address family */
217 char *se_proto; /* protocol used */ 227 char *se_proto; /* protocol used */
218#if ENABLE_FEATURE_INETD_RPC 228#if ENABLE_FEATURE_INETD_RPC
219 int se_rpcprog; /* rpc program number */ 229 int se_rpcprog; /* rpc program number */
@@ -224,7 +234,9 @@ typedef struct servtab {
224#define isrpcservice(sep) 0 234#define isrpcservice(sep) 0
225#endif 235#endif
226 pid_t se_wait; /* single threaded server */ 236 pid_t se_wait; /* single threaded server */
227 short se_checked; /* looked at during merge */ 237 socktype_t se_socktype; /* type of socket to use */
238 family_t se_family; /* address family */
239 smallint se_checked; /* looked at during merge */
228 char *se_user; /* user name to run as */ 240 char *se_user; /* user name to run as */
229 char *se_group; /* group name to run as */ 241 char *se_group; /* group name to run as */
230#ifdef INETD_FEATURE_ENABLED 242#ifdef INETD_FEATURE_ENABLED
@@ -250,17 +262,16 @@ typedef struct servtab {
250 int se_max; /* max # of instances of this service */ 262 int se_max; /* max # of instances of this service */
251 int se_count; /* number started since se_time */ 263 int se_count; /* number started since se_time */
252 struct timeval se_time; /* start of se_count */ 264 struct timeval se_time; /* start of se_count */
253 struct servtab *se_next; 265 struct servtab_t *se_next;
254} servtab_t; 266} servtab_t;
255 267
256static servtab_t *servtab;
257
258#ifdef INETD_FEATURE_ENABLED 268#ifdef INETD_FEATURE_ENABLED
259struct builtin { 269struct builtin {
260 const char *bi_service; /* internally provided service name */ 270 const char *bi_service; /* internally provided service name */
261 int bi_socktype; /* type of socket supported */ 271 socktype_t bi_socktype; /* type of socket supported */
262 short bi_fork; /* 1 if should fork before call */ 272 uint8_t bi_fork; /* 1 if should fork before call */
263 short bi_wait; /* 1 if should wait for child */ 273// Commented since it is always 0
274// uint8_t bi_wait; /* 1 if should wait for child */
264 void (*bi_fn) (int, servtab_t *); 275 void (*bi_fn) (int, servtab_t *);
265}; 276};
266 277
@@ -293,45 +304,90 @@ static void chargen_dg(int, servtab_t *);
293static const struct builtin builtins[] = { 304static const struct builtin builtins[] = {
294#if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_ECHO 305#if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_ECHO
295 /* Echo received data */ 306 /* Echo received data */
296 {"echo", SOCK_STREAM, 1, 0, echo_stream,}, 307 {"echo", SOCK_STREAM, 1, echo_stream,},
297 {"echo", SOCK_DGRAM, 0, 0, echo_dg,}, 308 {"echo", SOCK_DGRAM, 0, echo_dg,},
298#endif 309#endif
299#if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD 310#if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD
300 /* Internet /dev/null */ 311 /* Internet /dev/null */
301 {"discard", SOCK_STREAM, 1, 0, discard_stream,}, 312 {"discard", SOCK_STREAM, 1, discard_stream,},
302 {"discard", SOCK_DGRAM, 0, 0, discard_dg,}, 313 {"discard", SOCK_DGRAM, 0, discard_dg,},
303#endif 314#endif
304#if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_TIME 315#if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_TIME
305 /* Return 32 bit time since 1900 */ 316 /* Return 32 bit time since 1900 */
306 {"time", SOCK_STREAM, 0, 0, machtime_stream,}, 317 {"time", SOCK_STREAM, 0, machtime_stream,},
307 {"time", SOCK_DGRAM, 0, 0, machtime_dg,}, 318 {"time", SOCK_DGRAM, 0, machtime_dg,},
308#endif 319#endif
309#if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME 320#if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME
310 /* Return human-readable time */ 321 /* Return human-readable time */
311 {"daytime", SOCK_STREAM, 0, 0, daytime_stream,}, 322 {"daytime", SOCK_STREAM, 0, daytime_stream,},
312 {"daytime", SOCK_DGRAM, 0, 0, daytime_dg,}, 323 {"daytime", SOCK_DGRAM, 0, daytime_dg,},
313#endif 324#endif
314#if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN 325#if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN
315 /* Familiar character generator */ 326 /* Familiar character generator */
316 {"chargen", SOCK_STREAM, 1, 0, chargen_stream,}, 327 {"chargen", SOCK_STREAM, 1, chargen_stream,},
317 {"chargen", SOCK_DGRAM, 0, 0, chargen_dg,}, 328 {"chargen", SOCK_DGRAM, 0, chargen_dg,},
318#endif 329#endif
319 {NULL, 0, 0, 0, NULL} 330 { /* zero filled */ }
320}; 331};
321#endif /* INETD_FEATURE_ENABLED */ 332#endif /* INETD_FEATURE_ENABLED */
322 333
323static int global_queuelen = 128; 334struct globals {
324static int nsock, maxsock; 335 rlim_t rlim_ofile_cur;
325static fd_set allsock; 336 struct rlimit rlim_ofile;
326static int toomany; 337 servtab_t *servtab;
327static int timingout; 338 int global_queuelen;
328static struct servent *sp; 339 int nsock;
329static uid_t uid; 340 int maxsock;
330 341 int toomany;
331static const char *config_filename = "/etc/inetd.conf"; 342 int timingout;
332 343 struct servent *sp;
333static FILE *fconfig; 344 uid_t uid;
334static char *defhost; 345 const char *config_filename;
346 FILE *fconfig;
347 char *defhost;
348#ifdef INETD_SETPROCTITLE
349 char **Argv;
350 char *LastArg;
351#endif
352#if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN
353 char *endring;
354 char *ringpos;
355 char ring[128];
356#endif
357 fd_set allsock;
358 /* Used only in nextline() */
359 char line[80]; /* at least 80, see LINE_SIZE */
360};
361#define G (*(struct globals*)&bb_common_bufsiz1)
362enum { LINE_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line) };
363struct BUG_G_too_big {
364 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
365};
366#define rlim_ofile_cur (G.rlim_ofile_cur )
367#define rlim_ofile (G.rlim_ofile )
368#define servtab (G.servtab )
369#define global_queuelen (G.global_queuelen)
370#define nsock (G.nsock )
371#define maxsock (G.maxsock )
372#define toomany (G.toomany )
373#define timingout (G.timingout )
374#define sp (G.sp )
375#define uid (G.uid )
376#define config_filename (G.config_filename)
377#define fconfig (G.fconfig )
378#define defhost (G.defhost )
379#define Argv (G.Argv )
380#define LastArg (G.LastArg )
381#define endring (G.endring )
382#define ringpos (G.ringpos )
383#define ring (G.ring )
384#define allsock (G.allsock )
385#define line (G.line )
386#define INIT_G() do { \
387 rlim_ofile_cur = OPEN_MAX; \
388 global_queuelen = 128; \
389 config_filename = "/etc/inetd.conf"; \
390} while (0)
335 391
336/* xstrdup(NULL) returns NULL, but this one 392/* xstrdup(NULL) returns NULL, but this one
337 * will return newly-allocated "" if called with NULL arg 393 * will return newly-allocated "" if called with NULL arg
@@ -510,12 +566,10 @@ static void setup(servtab_t *sep)
510 566
511static char *nextline(void) 567static char *nextline(void)
512{ 568{
513#define line bb_common_bufsiz1
514
515 char *cp; 569 char *cp;
516 FILE *fd = fconfig; 570 FILE *fd = fconfig;
517 571
518 if (fgets(line, sizeof(line), fd) == NULL) 572 if (fgets(line, LINE_SIZE, fd) == NULL)
519 return NULL; 573 return NULL;
520 cp = strchr(line, '\n'); 574 cp = strchr(line, '\n');
521 if (cp) 575 if (cp)
@@ -740,15 +794,15 @@ static servtab_t *getconfigent(void)
740 const struct builtin *bi; 794 const struct builtin *bi;
741 795
742 for (bi = builtins; bi->bi_service; bi++) 796 for (bi = builtins; bi->bi_service; bi++)
743 if (bi->bi_socktype == sep->se_socktype && 797 if (bi->bi_socktype == sep->se_socktype
744 strcmp(bi->bi_service, sep->se_service) == 0) 798 && strcmp(bi->bi_service, sep->se_service) == 0)
745 break; 799 break;
746 if (bi->bi_service == 0) { 800 if (bi->bi_service == 0) {
747 bb_error_msg("internal service %s unknown", sep->se_service); 801 bb_error_msg("internal service %s unknown", sep->se_service);
748 goto more; 802 goto more;
749 } 803 }
750 sep->se_bi = bi; 804 sep->se_bi = bi;
751 sep->se_wait = bi->bi_wait; 805 sep->se_wait = 0; /* = bi->bi_wait; - always 0 */
752#else 806#else
753 bb_perror_msg("internal service %s unknown", sep->se_service); 807 bb_perror_msg("internal service %s unknown", sep->se_service);
754 goto more; 808 goto more;
@@ -792,36 +846,36 @@ static servtab_t *getconfigent(void)
792 if (LONE_CHAR(nsep->se_hostaddr, '*')) 846 if (LONE_CHAR(nsep->se_hostaddr, '*'))
793 nsep->se_ctrladdr_in.sin_addr.s_addr = INADDR_ANY; 847 nsep->se_ctrladdr_in.sin_addr.s_addr = INADDR_ANY;
794 else if (!inet_aton(nsep->se_hostaddr, &nsep->se_ctrladdr_in.sin_addr)) { 848 else if (!inet_aton(nsep->se_hostaddr, &nsep->se_ctrladdr_in.sin_addr)) {
849 int i;
795 struct hostent *hp; 850 struct hostent *hp;
796 851
797 hp = gethostbyname(nsep->se_hostaddr); 852 hp = gethostbyname(nsep->se_hostaddr);
798 if (hp == 0) { 853 if (hp == NULL) {
799 bb_error_msg("%s: unknown host", nsep->se_hostaddr); 854 bb_error_msg("%s: unknown host", nsep->se_hostaddr);
800 nsep->se_checked = 0; 855 nsep->se_checked = 0;
801 goto skip; 856 goto skip;
802 } else if (hp->h_addrtype != AF_INET) { 857 }
858 if (hp->h_addrtype != AF_INET) {
803 bb_error_msg("%s: address isn't an Internet " 859 bb_error_msg("%s: address isn't an Internet "
804 "address", nsep->se_hostaddr); 860 "address", nsep->se_hostaddr);
805 nsep->se_checked = 0; 861 nsep->se_checked = 0;
806 goto skip; 862 goto skip;
807 } else { 863 }
808 int i = 1; 864 i = 1;
809 865 memmove(&nsep->se_ctrladdr_in.sin_addr,
810 memmove(&nsep->se_ctrladdr_in.sin_addr, 866 hp->h_addr_list[0], sizeof(struct in_addr));
811 hp->h_addr_list[0], sizeof(struct in_addr)); 867 while (hp->h_addr_list[i] != NULL) {
812 while (hp->h_addr_list[i] != NULL) { 868 psep = dupconfig(nsep);
813 psep = dupconfig(nsep); 869 psep->se_hostaddr = xxstrdup(nsep->se_hostaddr);
814 psep->se_hostaddr = xxstrdup(nsep->se_hostaddr); 870 psep->se_checked = 1;
815 psep->se_checked = 1; 871 memmove(&psep->se_ctrladdr_in.sin_addr,
816 memmove(&psep->se_ctrladdr_in.sin_addr, 872 hp->h_addr_list[i], sizeof(struct in_addr));
817 hp->h_addr_list[i], sizeof(struct in_addr)); 873 psep->se_ctrladdr_size = sizeof(psep->se_ctrladdr_in);
818 psep->se_ctrladdr_size = sizeof(psep->se_ctrladdr_in); 874 i++;
819 i++; 875 /* Prepend to list, don't want to look up */
820 /* Prepend to list, don't want to look up */ 876 /* its hostname again. */
821 /* its hostname again. */ 877 psep->se_next = sep;
822 psep->se_next = sep; 878 sep = psep;
823 sep = psep;
824 }
825 } 879 }
826 } 880 }
827 } 881 }
@@ -1219,8 +1273,6 @@ static void goaway(int sig ATTRIBUTE_UNUSED)
1219 1273
1220 1274
1221#ifdef INETD_SETPROCTITLE 1275#ifdef INETD_SETPROCTITLE
1222static char **Argv;
1223static char *LastArg;
1224 1276
1225static void 1277static void
1226inetd_setproctitle(char *a, int s) 1278inetd_setproctitle(char *a, int s)
@@ -1262,10 +1314,14 @@ int inetd_main(int argc, char **argv)
1262 char buf[50]; 1314 char buf[50];
1263 char *stoomany; 1315 char *stoomany;
1264 sigset_t omask, wait_mask; 1316 sigset_t omask, wait_mask;
1265
1266#ifdef INETD_SETPROCTITLE 1317#ifdef INETD_SETPROCTITLE
1267 char **envp = environ; 1318 char **envp;
1319#endif
1268 1320
1321 INIT_G();
1322
1323#ifdef INETD_SETPROCTITLE
1324 envp = environ;
1269 Argv = argv; 1325 Argv = argv;
1270 if (envp == 0 || *envp == 0) 1326 if (envp == 0 || *envp == 0)
1271 envp = argv; 1327 envp = argv;
@@ -1600,8 +1656,6 @@ discard_dg(int s, servtab_t *sep ATTRIBUTE_UNUSED)
1600 1656
1601#if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN 1657#if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN
1602#define LINESIZ 72 1658#define LINESIZ 72
1603static char ring[128];
1604static char *endring;
1605 1659
1606static void 1660static void
1607initring(void) 1661initring(void)
@@ -1609,7 +1663,6 @@ initring(void)
1609 int i; 1663 int i;
1610 1664
1611 endring = ring; 1665 endring = ring;
1612
1613 for (i = 0; i <= 128; ++i) 1666 for (i = 0; i <= 128; ++i)
1614 if (isprint(i)) 1667 if (isprint(i))
1615 *endring++ = i; 1668 *endring++ = i;
@@ -1657,14 +1710,13 @@ chargen_dg(int s, servtab_t *sep ATTRIBUTE_UNUSED)
1657{ 1710{
1658 /* struct sockaddr_storage ss; */ 1711 /* struct sockaddr_storage ss; */
1659 struct sockaddr sa; 1712 struct sockaddr sa;
1660 static char *rs;
1661 int len; 1713 int len;
1662 char text[LINESIZ + 2]; 1714 char text[LINESIZ + 2];
1663 socklen_t size; 1715 socklen_t size;
1664 1716
1665 if (endring == 0) { 1717 if (!endring) {
1666 initring(); 1718 initring();
1667 rs = ring; 1719 ringpos = ring;
1668 } 1720 }
1669 1721
1670 size = sizeof(sa); 1722 size = sizeof(sa);
@@ -1673,14 +1725,15 @@ chargen_dg(int s, servtab_t *sep ATTRIBUTE_UNUSED)
1673 if (dg_badinput((struct sockaddr_in *) &sa)) 1725 if (dg_badinput((struct sockaddr_in *) &sa))
1674 return; 1726 return;
1675 1727
1676 if ((len = endring - rs) >= LINESIZ) 1728 len = endring - ringpos;
1677 memmove(text, rs, LINESIZ); 1729 if (len >= LINESIZ)
1730 memmove(text, ringpos, LINESIZ);
1678 else { 1731 else {
1679 memmove(text, rs, len); 1732 memmove(text, ringpos, len);
1680 memmove(text + len, ring, LINESIZ - len); 1733 memmove(text + len, ring, LINESIZ - len);
1681 } 1734 }
1682 if (++rs == endring) 1735 if (++ringpos == endring)
1683 rs = ring; 1736 ringpos = ring;
1684 text[LINESIZ] = '\r'; 1737 text[LINESIZ] = '\r';
1685 text[LINESIZ + 1] = '\n'; 1738 text[LINESIZ + 1] = '\n';
1686 (void) sendto(s, text, sizeof(text), 0, &sa, sizeof(sa)); 1739 (void) sendto(s, text, sizeof(text), 0, &sa, sizeof(sa));