httpd: reduce ifdef forest. comment out redundant PATH setting
[oweals/busybox.git] / networking / inetd.c
index d6265d8755f77af91dea01580cc95d485bf9427f..75b2b14a76604cee8c845a409f939b83290ed4f4 100644 (file)
 #define _PATH_INETDPID  "/var/run/inetd.pid"
 
 
-#define TOOMANY         0               /* don't start more than TOOMANY */
-
 #define CNT_INTVL       60              /* servers in CNT_INTVL sec. */
 #define RETRYTIME       (60*10)         /* retry after bind or server fail */
 
@@ -183,8 +181,7 @@ static struct rlimit rlim_ofile;
 # define INETD_SETPROCTITLE
 #endif
 
-typedef struct servtab
-{
+typedef struct servtab {
        char *se_hostaddr;                    /* host address to listen on */
        char *se_service;                     /* name of service */
        int se_socktype;                      /* type of socket to use */
@@ -209,8 +206,7 @@ typedef struct servtab
 #define MAXARGV 20
        char *se_argv[MAXARGV + 1];           /* program arguments */
        int se_fd;                            /* open descriptor */
-       union
-       {
+       union {
                struct sockaddr se_un_ctrladdr;
                struct sockaddr_in se_un_ctrladdr_in;
 #ifdef CONFIG_FEATURE_IPV6
@@ -232,8 +228,7 @@ typedef struct servtab
 static servtab_t *servtab;
 
 #ifdef INETD_FEATURE_ENABLED
-struct builtin
-{
+struct builtin {
        const char *bi_service;               /* internally provided service name */
        int bi_socktype;                      /* type of socket supported */
        short bi_fork;                        /* 1 if should fork before call */
@@ -300,7 +295,7 @@ static const struct builtin builtins[] = {
 static int global_queuelen = 128;
 static int nsock, maxsock;
 static fd_set allsock;
-static int toomany = TOOMANY;
+static int toomany;
 static int timingout;
 static struct servent *sp;
 static uid_t uid;
@@ -427,7 +422,8 @@ static void setup(servtab_t *sep)
        int on = 1;
        int r;
 
-       if ((sep->se_fd = socket(sep->se_family, sep->se_socktype, 0)) < 0) {
+       sep->se_fd = socket(sep->se_family, sep->se_socktype, 0);
+       if (sep->se_fd < 0) {
                bb_perror_msg("%s/%s: socket", sep->se_service, sep->se_proto);
                return;
        }
@@ -590,10 +586,10 @@ static servtab_t *getconfigent(void)
        sep = new_servtab();
 
        /* memset(sep, 0, sizeof *sep); */
-more:
+ more:
        /* freeconfig(sep); */
 
-       while ((cp = nextline()) && *cp == '#');
+       while ((cp = nextline()) && *cp == '#') /* skip comment line */;
        if (cp == NULL) {
                /* free(sep); */
                return NULL;
@@ -682,7 +678,7 @@ more:
                        } else if (*ccp != '\0')
                                goto badafterall;
 #else
-               bb_error_msg("%s: rpc services not supported", sep->se_service);
+                       bb_error_msg("%s: rpc services not supported", sep->se_service);
 #endif
                }
        }
@@ -694,7 +690,7 @@ more:
                char *s = strchr(arg, '.');
                if (s) {
                        *s++ = '\0';
-                       sep->se_max = atoi(s);
+                       sep->se_max = xatoi(s);
                } else
                        sep->se_max = toomany;
        }
@@ -930,7 +926,7 @@ static void config(int sig ATTRIBUTE_UNUSED)
                         */
                        if (
 #ifdef INETD_FEATURE_ENABLED
-                                        cp->se_bi == 0 &&
+                               cp->se_bi == 0 &&
 #endif
                                (sep->se_wait == 1 || cp->se_wait == 0))
                                sep->se_wait = cp->se_wait;
@@ -976,7 +972,7 @@ static void config(int sig ATTRIBUTE_UNUSED)
 #ifdef CONFIG_FEATURE_INETD_RPC
                        if (isrpcservice(sep)) {
                                struct rpcent *rp;
-
+                               // FIXME: atoi_or_else(str, 0) would be handy here
                                sep->se_rpcprog = atoi(sep->se_service);
                                if (sep->se_rpcprog == 0) {
                                        rp = getrpcbyname(sep->se_service);
@@ -992,9 +988,9 @@ static void config(int sig ATTRIBUTE_UNUSED)
                                        register_rpc(sep);
                        } else
 #endif
-                                {
+                       {
                                u_short port = htons(atoi(sep->se_service));
-
+                               // FIXME: atoi_or_else(str, 0) would be handy here
                                if (!port) {
                                         /*XXX*/ strncpy(protoname, sep->se_proto, sizeof(protoname));
                                        if (isdigit(protoname[strlen(protoname) - 1]))
@@ -1253,17 +1249,11 @@ inetd_main(int argc, char *argv[])
        LastArg = envp[-1] + strlen(envp[-1]);
 #endif
 
-       openlog(bb_applet_name, LOG_PID | LOG_NOWAIT, LOG_DAEMON);
+       openlog(applet_name, LOG_PID | LOG_NOWAIT, LOG_DAEMON);
 
-       opt = bb_getopt_ulflags(argc, argv, "R:f", &stoomany);
+       opt = getopt32(argc, argv, "R:f", &stoomany);
        if(opt & 1) {
-               char *e;
-
-               toomany = strtoul(stoomany, &e, 0);
-               if (!(toomany >= 0 && *e == '\0')) {
-                               toomany = TOOMANY;
-                               bb_perror_msg("-R %s: bad value for service invocation rate", stoomany);
-               }
+               toomany = xatoi_u(stoomany);
        }
        argc -= optind;
        argv += optind;
@@ -1319,7 +1309,6 @@ inetd_main(int argc, char *argv[])
        sigaddset(&sa.sa_mask, SIGHUP);
        sa.sa_handler = retry;
        sigaction(SIGALRM, &sa, NULL);
-       /* doconfig(); */
        config(SIGHUP);
        sa.sa_handler = config;
        sigaction(SIGHUP, &sa, NULL);
@@ -1355,7 +1344,7 @@ inetd_main(int argc, char *argv[])
                }
 
                readable = allsock;
-               n = select(maxsock + 1, &readable, NULL, NULL, NULL)
+               n = select(maxsock + 1, &readable, NULL, NULL, NULL);
                if (n <= 0) {
                        if (n < 0 && errno != EINTR) {
                                bb_perror_msg("select");
@@ -1363,154 +1352,154 @@ inetd_main(int argc, char *argv[])
                        }
                        continue;
                }
+
                for (sep = servtab; n && sep; sep = sep->se_next) {
-                       // TODO: undo this unholy mess
-                       if (sep->se_fd != -1 && FD_ISSET(sep->se_fd, &readable)) {
-                               n--;
-                               if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) {
-                                       ctrl = accept(sep->se_fd, NULL, NULL);
-                                       if (ctrl < 0) {
-                                               if (errno == EINTR)
-                                                       continue;
-                                               bb_perror_msg("accept (for %s)", sep->se_service);
+                       if (sep->se_fd == -1 || !FD_ISSET(sep->se_fd, &readable))
+                               continue;
+
+                       n--;
+                       if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) {
+                               ctrl = accept(sep->se_fd, NULL, NULL);
+                               if (ctrl < 0) {
+                                       if (errno == EINTR)
+                                               continue;
+                                       bb_perror_msg("accept (for %s)", sep->se_service);
+                                       continue;
+                               }
+                               if (sep->se_family == AF_INET && sep->se_socktype == SOCK_STREAM) {
+                                       struct sockaddr_in peer;
+                                       socklen_t plen = sizeof(peer);
+
+                                       if (getpeername(ctrl, (struct sockaddr *) &peer, &plen) < 0) {
+                                               bb_error_msg("cannot getpeername");
+                                               close(ctrl);
                                                continue;
                                        }
-                                       if (sep->se_family == AF_INET && sep->se_socktype == SOCK_STREAM) {
-                                               struct sockaddr_in peer;
-                                               socklen_t plen = sizeof(peer);
+                                       if (ntohs(peer.sin_port) == 20) {
+                                               /* XXX ftp bounce */
+                                               close(ctrl);
+                                               continue;
+                                       }
+                               }
+                       } else
+                               ctrl = sep->se_fd;
 
-                                               if (getpeername(ctrl, (struct sockaddr *) &peer, &plen) < 0) {
-                                                       bb_error_msg("could not getpeername");
+                       Block_Using_Signals(omask);
+                       pid = 0;
+#ifdef INETD_FEATURE_ENABLED
+                       if (sep->se_bi == 0 || sep->se_bi->bi_fork)
+#endif
+                       {
+                               if (sep->se_count++ == 0)
+                                       (void) gettimeofday(&sep->se_time, NULL);
+                               else if (toomany > 0 && sep->se_count >= sep->se_max) {
+                                       struct timeval now;
+
+                                       (void) gettimeofday(&now, NULL);
+                                       if (now.tv_sec - sep->se_time.tv_sec > CNT_INTVL) {
+                                               sep->se_time = now;
+                                               sep->se_count = 1;
+                                       } else {
+                                               if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
                                                        close(ctrl);
+                                               if (sep->se_family == AF_INET &&
+                                                         ntohs(sep->se_ctrladdr_in.sin_port) >= IPPORT_RESERVED) {
+                                                       /*
+                                                        * Cannot close it -- there are
+                                                        * thieves on the system.
+                                                        * Simply ignore the connection.
+                                                        */
+                                                       --sep->se_count;
                                                        continue;
                                                }
-                                               if (ntohs(peer.sin_port) == 20) {
-                                                       /* XXX ftp bounce */
+                                               bb_error_msg("%s/%s server failing (looping), service terminated",
+                                                             sep->se_service, sep->se_proto);
+                                               if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
                                                        close(ctrl);
-                                                       continue;
-                                               }
-                                       }
-                               } else
-                                       ctrl = sep->se_fd;
-                               Block_Using_Signals(omask);
-                               pid = 0;
-#ifdef INETD_FEATURE_ENABLED
-                               if (sep->se_bi == 0 || sep->se_bi->bi_fork)
-#endif
-                               {
-                                       if (sep->se_count++ == 0)
-                                               (void) gettimeofday(&sep->se_time, NULL);
-                                       else if (toomany > 0 && sep->se_count >= sep->se_max) {
-                                               struct timeval now;
-
-                                               (void) gettimeofday(&now, NULL);
-                                               if (now.tv_sec - sep->se_time.tv_sec > CNT_INTVL) {
-                                                       sep->se_time = now;
-                                                       sep->se_count = 1;
-                                               } else {
-                                                       if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
-                                                               close(ctrl);
-                                                       if (sep->se_family == AF_INET &&
-                                                                 ntohs(sep->se_ctrladdr_in.sin_port) >= IPPORT_RESERVED) {
-                                                               /*
-                                                                * Cannot close it -- there are
-                                                                * thieves on the system.
-                                                                * Simply ignore the connection.
-                                                                */
-                                                               --sep->se_count;
-                                                               continue;
-                                                       }
-                                                       bb_error_msg("%s/%s server failing (looping), service terminated",
-                                                                     sep->se_service, sep->se_proto);
-                                                       if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
-                                                               close(ctrl);
-                                                       FD_CLR(sep->se_fd, &allsock);
-                                                       (void) close(sep->se_fd);
-                                                       sep->se_fd = -1;
-                                                       sep->se_count = 0;
-                                                       nsock--;
-                                                       sigprocmask(SIG_UNBLOCK, &omask, NULL);
-                                                       if (!timingout) {
-                                                               timingout = 1;
-                                                               alarm(RETRYTIME);
-                                                       }
-                                                       continue;
+                                               FD_CLR(sep->se_fd, &allsock);
+                                               (void) close(sep->se_fd);
+                                               sep->se_fd = -1;
+                                               sep->se_count = 0;
+                                               nsock--;
+                                               sigprocmask(SIG_UNBLOCK, &omask, NULL);
+                                               if (!timingout) {
+                                                       timingout = 1;
+                                                       alarm(RETRYTIME);
                                                }
+                                               continue;
                                        }
-                                       pid = fork();
-                               }
-                               if (pid < 0) {
-                                       bb_perror_msg("fork");
-                                       if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
-                                               close(ctrl);
-                                       sigprocmask(SIG_UNBLOCK, &omask, NULL);
-                                       sleep(1);
-                                       continue;
-                               }
-                               if (pid && sep->se_wait) {
-                                       sep->se_wait = pid;
-                                       FD_CLR(sep->se_fd, &allsock);
-                                       nsock--;
                                }
+                               pid = fork();
+                       }
+                       if (pid < 0) {
+                               bb_perror_msg("fork");
+                               if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
+                                       close(ctrl);
                                sigprocmask(SIG_UNBLOCK, &omask, NULL);
-                               if (pid == 0) {
+                               sleep(1);
+                               continue;
+                       }
+                       if (pid && sep->se_wait) {
+                               sep->se_wait = pid;
+                               FD_CLR(sep->se_fd, &allsock);
+                               nsock--;
+                       }
+                       sigprocmask(SIG_UNBLOCK, &omask, NULL);
+                       if (pid == 0) {
 #ifdef INETD_FEATURE_ENABLED
-                                       if (sep->se_bi) {
-                                               (*sep->se_bi->bi_fn)(ctrl, sep);
-                                       } else
+                               if (sep->se_bi) {
+                                       (*sep->se_bi->bi_fn)(ctrl, sep);
+                               } else
 #endif
-                                               {
-                                               if ((pwd = getpwnam(sep->se_user)) == NULL) {
-                                                       bb_error_msg("getpwnam: %s: no such user", sep->se_user);
-                                                       if (sep->se_socktype != SOCK_STREAM)
-                                                               recv(0, buf, sizeof(buf), 0);
-                                                       _exit(1);
-                                               }
-                                               if (setsid() < 0)
-                                                       bb_perror_msg("%s: setsid", sep->se_service);
-                                               if (sep->se_group && (grp = getgrnam(sep->se_group)) == NULL) {
-                                                       bb_error_msg("getgrnam: %s: no such group", sep->se_group);
-                                                       if (sep->se_socktype != SOCK_STREAM)
-                                                               recv(0, buf, sizeof(buf), 0);
+                                       {
+                                       pwd = getpwnam(sep->se_user);
+                                       if (pwd == NULL) {
+                                               bb_error_msg("getpwnam: %s: no such user", sep->se_user);
+                                               goto do_exit1;
+                                       }
+                                       if (setsid() < 0)
+                                               bb_perror_msg("%s: setsid", sep->se_service);
+                                       if (sep->se_group && (grp = getgrnam(sep->se_group)) == NULL) {
+                                               bb_error_msg("getgrnam: %s: no such group", sep->se_group);
+                                               goto do_exit1;
+                                       }
+                                       if (uid != 0) {
+                                               /* a user running private inetd */
+                                               if (uid != pwd->pw_uid)
                                                        _exit(1);
-                                               }
-                                               if (uid != 0) {
-                                                       /* a user running private inetd */
-                                                       if (uid != pwd->pw_uid)
-                                                               _exit(1);
-                                               } else if (pwd->pw_uid) {
-                                                       if (sep->se_group)
-                                                               pwd->pw_gid = grp->gr_gid;
-                                                       xsetgid((gid_t) pwd->pw_gid);
-                                                       initgroups(pwd->pw_name, pwd->pw_gid);
-                                                       xsetuid((uid_t) pwd->pw_uid);
-                                               } else if (sep->se_group) {
-                                                       xsetgid(grp->gr_gid);
-                                                       setgroups(1, &grp->gr_gid);
-                                               }
-                                               dup2(ctrl, 0);
-                                               close(ctrl);
-                                               dup2(0, 1);
-                                               dup2(0, 2);
-                                               if (rlim_ofile.rlim_cur != rlim_ofile_cur)
-                                                       if (setrlimit(RLIMIT_NOFILE, &rlim_ofile) < 0)
-                                                               bb_perror_msg("setrlimit");
-                                               closelog();
-                                               for (tmpint = rlim_ofile_cur - 1; --tmpint > 2;)
-                                                       (void) close(tmpint);
-                                               sigaction(SIGPIPE, &sapipe, NULL);
-                                               execv(sep->se_server, sep->se_argv);
-                                               if (sep->se_socktype != SOCK_STREAM)
-                                                       recv(0, buf, sizeof(buf), 0);
-                                               bb_perror_msg("execv %s", sep->se_server);
-                                               _exit(1);
+                                       } else if (pwd->pw_uid) {
+                                               if (sep->se_group)
+                                                       pwd->pw_gid = grp->gr_gid;
+                                               xsetgid((gid_t) pwd->pw_gid);
+                                               initgroups(pwd->pw_name, pwd->pw_gid);
+                                               xsetuid((uid_t) pwd->pw_uid);
+                                       } else if (sep->se_group) {
+                                               xsetgid(grp->gr_gid);
+                                               setgroups(1, &grp->gr_gid);
                                        }
+                                       dup2(ctrl, 0);
+                                       if (ctrl) close(ctrl);
+                                       dup2(0, 1);
+                                       dup2(0, 2);
+                                       if (rlim_ofile.rlim_cur != rlim_ofile_cur)
+                                               if (setrlimit(RLIMIT_NOFILE, &rlim_ofile) < 0)
+                                                       bb_perror_msg("setrlimit");
+                                       closelog();
+                                       for (tmpint = rlim_ofile_cur - 1; --tmpint > 2;)
+                                               (void) close(tmpint);
+                                       sigaction(SIGPIPE, &sapipe, NULL);
+                                       execv(sep->se_server, sep->se_argv);
+                                       bb_perror_msg("execv %s", sep->se_server);
+do_exit1:
+                                       if (sep->se_socktype != SOCK_STREAM)
+                                               recv(0, buf, sizeof(buf), 0);
+                                       _exit(1);
                                }
-                               if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
-                                       close(ctrl);
                        }
-               }
-       }
+                       if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
+                               close(ctrl);
+               } /* for (sep = servtab...) */
+       } /* for(;;) */
 }
 
 /*
@@ -1542,8 +1531,12 @@ echo_stream(int s, servtab_t *sep)
        int i;
 
        inetd_setproctitle(sep->se_service, s);
-       while ((i = read(s, buffer, sizeof(buffer))) > 0 &&
-                                write(s, buffer, i) > 0);
+       while (1) {
+               i = read(s, buffer, sizeof(buffer));
+               if (i <= 0) break;
+               /* FIXME: this isnt correct - safe_write()? */
+               if (write(s, buffer, i) <= 0) break;
+       }
        exit(0);
 }
 
@@ -1577,9 +1570,11 @@ discard_stream(int s, servtab_t *sep)
        char buffer[BUFSIZE];
 
        inetd_setproctitle(sep->se_service, s);
-       while ((errno = 0, read(s, buffer, sizeof(buffer)) > 0) ||
-                                errno == EINTR);
-       exit(0);
+       while (1) {
+               errno = 0;
+               if (read(s, buffer, sizeof(buffer)) <= 0 && errno != EINTR)
+                       exit(0);
+       }
 }
 
 /* Discard service -- ignore data */
@@ -1629,8 +1624,10 @@ chargen_stream(int s, servtab_t *sep)
 
        text[LINESIZ] = '\r';
        text[LINESIZ + 1] = '\n';
-       for (rs = ring;;) {
-               if ((len = endring - rs) >= LINESIZ)
+       rs = ring;
+       for (;;) {
+               len = endring - rs;
+               if (len >= LINESIZ)
                        memmove(text, rs, LINESIZ);
                else {
                        memmove(text, rs, len);