diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-09-23 15:58:01 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-09-23 15:58:01 +0000 |
commit | c1876d7364a260e06cd23a3255b9058240527b02 (patch) | |
tree | 5d009458a14aa033d16c3a7aeb92fc8bef046728 | |
parent | 4c196a80fce835e1f02130dfd23b63183e9c919f (diff) | |
download | busybox-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.c | 296 |
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 | ||
186 | typedef struct servtab | 186 | typedef 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 | |||
232 | static servtab_t *servtab; | 230 | static servtab_t *servtab; |
233 | 231 | ||
234 | #ifdef INETD_FEATURE_ENABLED | 232 | #ifdef INETD_FEATURE_ENABLED |
235 | struct builtin | 233 | struct 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); | ||
1502 | do_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); |