aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-09-23 15:58:01 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-09-23 15:58:01 +0000
commitc1876d7364a260e06cd23a3255b9058240527b02 (patch)
tree5d009458a14aa033d16c3a7aeb92fc8bef046728
parent4c196a80fce835e1f02130dfd23b63183e9c919f (diff)
downloadbusybox-w32-c1876d7364a260e06cd23a3255b9058240527b02.tar.gz
busybox-w32-c1876d7364a260e06cd23a3255b9058240527b02.tar.bz2
busybox-w32-c1876d7364a260e06cd23a3255b9058240527b02.zip
inetd: deindent main loop, other readability enhancements
-rw-r--r--networking/inetd.c296
1 files changed, 151 insertions, 145 deletions
diff --git a/networking/inetd.c b/networking/inetd.c
index d6265d875..8c8843b9b 100644
--- a/networking/inetd.c
+++ b/networking/inetd.c
@@ -183,8 +183,7 @@ static struct rlimit rlim_ofile;
183# define INETD_SETPROCTITLE 183# define INETD_SETPROCTITLE
184#endif 184#endif
185 185
186typedef struct servtab 186typedef struct servtab {
187{
188 char *se_hostaddr; /* host address to listen on */ 187 char *se_hostaddr; /* host address to listen on */
189 char *se_service; /* name of service */ 188 char *se_service; /* name of service */
190 int se_socktype; /* type of socket to use */ 189 int se_socktype; /* type of socket to use */
@@ -209,8 +208,7 @@ typedef struct servtab
209#define MAXARGV 20 208#define MAXARGV 20
210 char *se_argv[MAXARGV + 1]; /* program arguments */ 209 char *se_argv[MAXARGV + 1]; /* program arguments */
211 int se_fd; /* open descriptor */ 210 int se_fd; /* open descriptor */
212 union 211 union {
213 {
214 struct sockaddr se_un_ctrladdr; 212 struct sockaddr se_un_ctrladdr;
215 struct sockaddr_in se_un_ctrladdr_in; 213 struct sockaddr_in se_un_ctrladdr_in;
216#ifdef CONFIG_FEATURE_IPV6 214#ifdef CONFIG_FEATURE_IPV6
@@ -232,8 +230,7 @@ typedef struct servtab
232static servtab_t *servtab; 230static servtab_t *servtab;
233 231
234#ifdef INETD_FEATURE_ENABLED 232#ifdef INETD_FEATURE_ENABLED
235struct builtin 233struct builtin {
236{
237 const char *bi_service; /* internally provided service name */ 234 const char *bi_service; /* internally provided service name */
238 int bi_socktype; /* type of socket supported */ 235 int bi_socktype; /* type of socket supported */
239 short bi_fork; /* 1 if should fork before call */ 236 short bi_fork; /* 1 if should fork before call */
@@ -427,7 +424,8 @@ static void setup(servtab_t *sep)
427 int on = 1; 424 int on = 1;
428 int r; 425 int r;
429 426
430 if ((sep->se_fd = socket(sep->se_family, sep->se_socktype, 0)) < 0) { 427 sep->se_fd = socket(sep->se_family, sep->se_socktype, 0);
428 if (sep->se_fd < 0) {
431 bb_perror_msg("%s/%s: socket", sep->se_service, sep->se_proto); 429 bb_perror_msg("%s/%s: socket", sep->se_service, sep->se_proto);
432 return; 430 return;
433 } 431 }
@@ -1355,7 +1353,7 @@ inetd_main(int argc, char *argv[])
1355 } 1353 }
1356 1354
1357 readable = allsock; 1355 readable = allsock;
1358 n = select(maxsock + 1, &readable, NULL, NULL, NULL) 1356 n = select(maxsock + 1, &readable, NULL, NULL, NULL);
1359 if (n <= 0) { 1357 if (n <= 0) {
1360 if (n < 0 && errno != EINTR) { 1358 if (n < 0 && errno != EINTR) {
1361 bb_perror_msg("select"); 1359 bb_perror_msg("select");
@@ -1363,154 +1361,154 @@ inetd_main(int argc, char *argv[])
1363 } 1361 }
1364 continue; 1362 continue;
1365 } 1363 }
1364
1366 for (sep = servtab; n && sep; sep = sep->se_next) { 1365 for (sep = servtab; n && sep; sep = sep->se_next) {
1367 // TODO: undo this unholy mess 1366 if (sep->se_fd == -1 || !FD_ISSET(sep->se_fd, &readable))
1368 if (sep->se_fd != -1 && FD_ISSET(sep->se_fd, &readable)) { 1367 continue;
1369 n--; 1368
1370 if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) { 1369 n--;
1371 ctrl = accept(sep->se_fd, NULL, NULL); 1370 if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) {
1372 if (ctrl < 0) { 1371 ctrl = accept(sep->se_fd, NULL, NULL);
1373 if (errno == EINTR) 1372 if (ctrl < 0) {
1374 continue; 1373 if (errno == EINTR)
1375 bb_perror_msg("accept (for %s)", sep->se_service); 1374 continue;
1375 bb_perror_msg("accept (for %s)", sep->se_service);
1376 continue;
1377 }
1378 if (sep->se_family == AF_INET && sep->se_socktype == SOCK_STREAM) {
1379 struct sockaddr_in peer;
1380 socklen_t plen = sizeof(peer);
1381
1382 if (getpeername(ctrl, (struct sockaddr *) &peer, &plen) < 0) {
1383 bb_error_msg("could not getpeername");
1384 close(ctrl);
1376 continue; 1385 continue;
1377 } 1386 }
1378 if (sep->se_family == AF_INET && sep->se_socktype == SOCK_STREAM) { 1387 if (ntohs(peer.sin_port) == 20) {
1379 struct sockaddr_in peer; 1388 /* XXX ftp bounce */
1380 socklen_t plen = sizeof(peer); 1389 close(ctrl);
1390 continue;
1391 }
1392 }
1393 } else
1394 ctrl = sep->se_fd;
1381 1395
1382 if (getpeername(ctrl, (struct sockaddr *) &peer, &plen) < 0) { 1396 Block_Using_Signals(omask);
1383 bb_error_msg("could not getpeername"); 1397 pid = 0;
1398#ifdef INETD_FEATURE_ENABLED
1399 if (sep->se_bi == 0 || sep->se_bi->bi_fork)
1400#endif
1401 {
1402 if (sep->se_count++ == 0)
1403 (void) gettimeofday(&sep->se_time, NULL);
1404 else if (toomany > 0 && sep->se_count >= sep->se_max) {
1405 struct timeval now;
1406
1407 (void) gettimeofday(&now, NULL);
1408 if (now.tv_sec - sep->se_time.tv_sec > CNT_INTVL) {
1409 sep->se_time = now;
1410 sep->se_count = 1;
1411 } else {
1412 if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
1384 close(ctrl); 1413 close(ctrl);
1414 if (sep->se_family == AF_INET &&
1415 ntohs(sep->se_ctrladdr_in.sin_port) >= IPPORT_RESERVED) {
1416 /*
1417 * Cannot close it -- there are
1418 * thieves on the system.
1419 * Simply ignore the connection.
1420 */
1421 --sep->se_count;
1385 continue; 1422 continue;
1386 } 1423 }
1387 if (ntohs(peer.sin_port) == 20) { 1424 bb_error_msg("%s/%s server failing (looping), service terminated",
1388 /* XXX ftp bounce */ 1425 sep->se_service, sep->se_proto);
1426 if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
1389 close(ctrl); 1427 close(ctrl);
1390 continue; 1428 FD_CLR(sep->se_fd, &allsock);
1391 } 1429 (void) close(sep->se_fd);
1392 } 1430 sep->se_fd = -1;
1393 } else 1431 sep->se_count = 0;
1394 ctrl = sep->se_fd; 1432 nsock--;
1395 Block_Using_Signals(omask); 1433 sigprocmask(SIG_UNBLOCK, &omask, NULL);
1396 pid = 0; 1434 if (!timingout) {
1397#ifdef INETD_FEATURE_ENABLED 1435 timingout = 1;
1398 if (sep->se_bi == 0 || sep->se_bi->bi_fork) 1436 alarm(RETRYTIME);
1399#endif
1400 {
1401 if (sep->se_count++ == 0)
1402 (void) gettimeofday(&sep->se_time, NULL);
1403 else if (toomany > 0 && sep->se_count >= sep->se_max) {
1404 struct timeval now;
1405
1406 (void) gettimeofday(&now, NULL);
1407 if (now.tv_sec - sep->se_time.tv_sec > CNT_INTVL) {
1408 sep->se_time = now;
1409 sep->se_count = 1;
1410 } else {
1411 if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
1412 close(ctrl);
1413 if (sep->se_family == AF_INET &&
1414 ntohs(sep->se_ctrladdr_in.sin_port) >= IPPORT_RESERVED) {
1415 /*
1416 * Cannot close it -- there are
1417 * thieves on the system.
1418 * Simply ignore the connection.
1419 */
1420 --sep->se_count;
1421 continue;
1422 }
1423 bb_error_msg("%s/%s server failing (looping), service terminated",
1424 sep->se_service, sep->se_proto);
1425 if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
1426 close(ctrl);
1427 FD_CLR(sep->se_fd, &allsock);
1428 (void) close(sep->se_fd);
1429 sep->se_fd = -1;
1430 sep->se_count = 0;
1431 nsock--;
1432 sigprocmask(SIG_UNBLOCK, &omask, NULL);
1433 if (!timingout) {
1434 timingout = 1;
1435 alarm(RETRYTIME);
1436 }
1437 continue;
1438 } 1437 }
1438 continue;
1439 } 1439 }
1440 pid = fork();
1441 }
1442 if (pid < 0) {
1443 bb_perror_msg("fork");
1444 if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
1445 close(ctrl);
1446 sigprocmask(SIG_UNBLOCK, &omask, NULL);
1447 sleep(1);
1448 continue;
1449 }
1450 if (pid && sep->se_wait) {
1451 sep->se_wait = pid;
1452 FD_CLR(sep->se_fd, &allsock);
1453 nsock--;
1454 } 1440 }
1441 pid = fork();
1442 }
1443 if (pid < 0) {
1444 bb_perror_msg("fork");
1445 if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
1446 close(ctrl);
1455 sigprocmask(SIG_UNBLOCK, &omask, NULL); 1447 sigprocmask(SIG_UNBLOCK, &omask, NULL);
1456 if (pid == 0) { 1448 sleep(1);
1449 continue;
1450 }
1451 if (pid && sep->se_wait) {
1452 sep->se_wait = pid;
1453 FD_CLR(sep->se_fd, &allsock);
1454 nsock--;
1455 }
1456 sigprocmask(SIG_UNBLOCK, &omask, NULL);
1457 if (pid == 0) {
1457#ifdef INETD_FEATURE_ENABLED 1458#ifdef INETD_FEATURE_ENABLED
1458 if (sep->se_bi) { 1459 if (sep->se_bi) {
1459 (*sep->se_bi->bi_fn)(ctrl, sep); 1460 (*sep->se_bi->bi_fn)(ctrl, sep);
1460 } else 1461 } else
1461#endif 1462#endif
1462 { 1463 {
1463 if ((pwd = getpwnam(sep->se_user)) == NULL) { 1464 pwd = getpwnam(sep->se_user);
1464 bb_error_msg("getpwnam: %s: no such user", sep->se_user); 1465 if (pwd == NULL) {
1465 if (sep->se_socktype != SOCK_STREAM) 1466 bb_error_msg("getpwnam: %s: no such user", sep->se_user);
1466 recv(0, buf, sizeof(buf), 0); 1467 goto do_exit1;
1467 _exit(1); 1468 }
1468 } 1469 if (setsid() < 0)
1469 if (setsid() < 0) 1470 bb_perror_msg("%s: setsid", sep->se_service);
1470 bb_perror_msg("%s: setsid", sep->se_service); 1471 if (sep->se_group && (grp = getgrnam(sep->se_group)) == NULL) {
1471 if (sep->se_group && (grp = getgrnam(sep->se_group)) == NULL) { 1472 bb_error_msg("getgrnam: %s: no such group", sep->se_group);
1472 bb_error_msg("getgrnam: %s: no such group", sep->se_group); 1473 goto do_exit1;
1473 if (sep->se_socktype != SOCK_STREAM) 1474 }
1474 recv(0, buf, sizeof(buf), 0); 1475 if (uid != 0) {
1476 /* a user running private inetd */
1477 if (uid != pwd->pw_uid)
1475 _exit(1); 1478 _exit(1);
1476 } 1479 } else if (pwd->pw_uid) {
1477 if (uid != 0) { 1480 if (sep->se_group)
1478 /* a user running private inetd */ 1481 pwd->pw_gid = grp->gr_gid;
1479 if (uid != pwd->pw_uid) 1482 xsetgid((gid_t) pwd->pw_gid);
1480 _exit(1); 1483 initgroups(pwd->pw_name, pwd->pw_gid);
1481 } else if (pwd->pw_uid) { 1484 xsetuid((uid_t) pwd->pw_uid);
1482 if (sep->se_group) 1485 } else if (sep->se_group) {
1483 pwd->pw_gid = grp->gr_gid; 1486 xsetgid(grp->gr_gid);
1484 xsetgid((gid_t) pwd->pw_gid); 1487 setgroups(1, &grp->gr_gid);
1485 initgroups(pwd->pw_name, pwd->pw_gid);
1486 xsetuid((uid_t) pwd->pw_uid);
1487 } else if (sep->se_group) {
1488 xsetgid(grp->gr_gid);
1489 setgroups(1, &grp->gr_gid);
1490 }
1491 dup2(ctrl, 0);
1492 close(ctrl);
1493 dup2(0, 1);
1494 dup2(0, 2);
1495 if (rlim_ofile.rlim_cur != rlim_ofile_cur)
1496 if (setrlimit(RLIMIT_NOFILE, &rlim_ofile) < 0)
1497 bb_perror_msg("setrlimit");
1498 closelog();
1499 for (tmpint = rlim_ofile_cur - 1; --tmpint > 2;)
1500 (void) close(tmpint);
1501 sigaction(SIGPIPE, &sapipe, NULL);
1502 execv(sep->se_server, sep->se_argv);
1503 if (sep->se_socktype != SOCK_STREAM)
1504 recv(0, buf, sizeof(buf), 0);
1505 bb_perror_msg("execv %s", sep->se_server);
1506 _exit(1);
1507 } 1488 }
1489 dup2(ctrl, 0);
1490 if (ctrl) close(ctrl);
1491 dup2(0, 1);
1492 dup2(0, 2);
1493 if (rlim_ofile.rlim_cur != rlim_ofile_cur)
1494 if (setrlimit(RLIMIT_NOFILE, &rlim_ofile) < 0)
1495 bb_perror_msg("setrlimit");
1496 closelog();
1497 for (tmpint = rlim_ofile_cur - 1; --tmpint > 2;)
1498 (void) close(tmpint);
1499 sigaction(SIGPIPE, &sapipe, NULL);
1500 execv(sep->se_server, sep->se_argv);
1501 bb_perror_msg("execv %s", sep->se_server);
1502do_exit1:
1503 if (sep->se_socktype != SOCK_STREAM)
1504 recv(0, buf, sizeof(buf), 0);
1505 _exit(1);
1508 } 1506 }
1509 if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
1510 close(ctrl);
1511 } 1507 }
1512 } 1508 if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
1513 } 1509 close(ctrl);
1510 } /* for (sep = servtab...) */
1511 } /* for(;;) */
1514} 1512}
1515 1513
1516/* 1514/*
@@ -1542,8 +1540,12 @@ echo_stream(int s, servtab_t *sep)
1542 int i; 1540 int i;
1543 1541
1544 inetd_setproctitle(sep->se_service, s); 1542 inetd_setproctitle(sep->se_service, s);
1545 while ((i = read(s, buffer, sizeof(buffer))) > 0 && 1543 while (1) {
1546 write(s, buffer, i) > 0); 1544 i = read(s, buffer, sizeof(buffer));
1545 if (i <= 0) break;
1546 /* FIXME: this isnt correct - safe_write()? */
1547 if (write(s, buffer, i) <= 0) break;
1548 }
1547 exit(0); 1549 exit(0);
1548} 1550}
1549 1551
@@ -1577,9 +1579,11 @@ discard_stream(int s, servtab_t *sep)
1577 char buffer[BUFSIZE]; 1579 char buffer[BUFSIZE];
1578 1580
1579 inetd_setproctitle(sep->se_service, s); 1581 inetd_setproctitle(sep->se_service, s);
1580 while ((errno = 0, read(s, buffer, sizeof(buffer)) > 0) || 1582 while (1) {
1581 errno == EINTR); 1583 errno = 0;
1582 exit(0); 1584 if (read(s, buffer, sizeof(buffer)) <= 0 && errno != EINTR)
1585 exit(0);
1586 }
1583} 1587}
1584 1588
1585/* Discard service -- ignore data */ 1589/* Discard service -- ignore data */
@@ -1629,8 +1633,10 @@ chargen_stream(int s, servtab_t *sep)
1629 1633
1630 text[LINESIZ] = '\r'; 1634 text[LINESIZ] = '\r';
1631 text[LINESIZ + 1] = '\n'; 1635 text[LINESIZ + 1] = '\n';
1632 for (rs = ring;;) { 1636 rs = ring;
1633 if ((len = endring - rs) >= LINESIZ) 1637 for (;;) {
1638 len = endring - rs;
1639 if (len >= LINESIZ)
1634 memmove(text, rs, LINESIZ); 1640 memmove(text, rs, LINESIZ);
1635 else { 1641 else {
1636 memmove(text, rs, len); 1642 memmove(text, rs, len);