Annotation of 43BSD/contrib/mh/support/pop/popd.c, revision 1.1.1.1

1.1       root        1: /* popd.c - the POP server */
                      2: 
                      3: /* Author:     Marshall T. Rose        <MRose@UDel>    (MTR)
                      4:                Department of Computer Science and Information Sciences
                      5:                University of Delaware
                      6:                Newark, DE  19716
                      7:                302/451-1951
                      8: 
                      9:    Date:       Sun Oct 28 16:23:26 1984
                     10:  */
                     11: 
                     12: #include <errno.h>
                     13: #include <signal.h>
                     14: #include <stdio.h>
                     15: #include <strings.h>
                     16: #include <syslog.h>
                     17: #include <sys/types.h>
                     18: #include <sys/file.h>
                     19: #include <sys/ioctl.h>
                     20: #include <sys/socket.h>
                     21: #include <sys/time.h>
                     22: #include <sys/resource.h>
                     23: #include <sys/wait.h>
                     24: #include <netinet/in.h>
                     25: #include <netdb.h>
                     26: #include <arpa/inet.h>
                     27: 
                     28: 
                     29: #define        NOTOK   (-1)
                     30: #define        OK      0
                     31: 
                     32: #define        NULLCP  ((char *) 0)
                     33: #define NULLRP ((struct rusage *) 0)
                     34: 
                     35: #define        FAST                    /* fast start-up of BBoards */
                     36: 
                     37: /*  */
                     38: 
                     39: extern int  errno;
                     40: extern int  sys_nerr;
                     41: extern char *sys_errlist[];
                     42: extern char *sys_siglist[];
                     43: 
                     44: 
                     45: int  debug = 0;
                     46: static int  nbits = ((sizeof (int)) * 8);
                     47: static int  options = 0;
                     48: 
                     49: 
                     50: char *myname = "popd";
                     51: char myhost[BUFSIZ];
                     52: static char *myprotocol = "tcp";
                     53: static char *myservice = "pop";
                     54: 
                     55: static struct sockaddr_in   in_socket;
                     56: static struct sockaddr_in  *isock = &in_socket;
                     57: 
                     58: 
                     59: int    chldser ();
                     60: void   padios (), padvise ();
                     61: 
                     62: /*  */
                     63: 
                     64: /* ARGSUSED */
                     65: 
                     66: main (argc, argv, envp)
                     67: int     argc;
                     68: char  **argv,
                     69:       **envp;
                     70: {
                     71:     int     fd,
                     72:             sd;
                     73:     struct servent *sp;
                     74:     struct sockaddr_in  out_socket,
                     75:                        *osock = &out_socket;
                     76: 
                     77:     if ((sp = getservbyname (myservice, myprotocol)) == NULL)
                     78:        padios (NULLCP, "%s/%s: unknown service", myprotocol, myservice);
                     79:     isock -> sin_family = AF_INET;
                     80:     isock -> sin_port = sp -> s_port;
                     81:     isock -> sin_addr.s_addr = INADDR_ANY;
                     82:     arginit (argv);
                     83:     envinit ();
                     84: 
                     85: #ifdef RESTART
                     86:     for (;;) {
                     87:        char    reason[BUFSIZ];
                     88:        union wait status;
                     89: 
                     90:        switch (fork ()) {
                     91:            case NOTOK: 
                     92:                sleep (5);
                     93:                continue;
                     94: 
                     95:            case OK: 
                     96:                break;
                     97: 
                     98:            default: 
                     99:                sleep (60);
                    100:                (void) wait3 (&status, 0, NULLRP);
                    101:                if (WIFEXITED (status))
                    102:                    (void) sprintf (reason, "exit=0%o", status.w_retcode);
                    103:                else
                    104:                    if (WIFSIGNALED (status))
                    105:                        (void) sprintf (reason, "signal=%s%s",
                    106:                                status.w_termsig < NSIG
                    107:                                ? sys_siglist[status.w_termsig] : "unknown",
                    108:                                status.w_coredump ? " (core dumped)" : NULL);
                    109:                    else
                    110:                        (void) strcpy (reason, "stopped(!!)");
                    111:                padvise (NULLCP, LOG_WARNING, "%s/%s server has terminated -- %s",
                    112:                        sp -> s_proto, sp -> s_name, reason);
                    113:                continue;
                    114:        }
                    115:        break;
                    116:     }
                    117: 
                    118:     closelog ();
                    119:     openlog (myname, LOG_PID);
                    120:     padvise (NULLCP, LOG_INFO, "restart");
                    121: #endif RESTART
                    122: 
                    123: /*  */
                    124: 
                    125:     if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == NOTOK)
                    126:        padios ("socket", "unable to create");
                    127:     if (options & SO_DEBUG)
                    128:        if (setsockopt (sd, SOL_SOCKET, SO_DEBUG, NULL, 0) == NOTOK)
                    129:            padvise ("SO_DEBUG", LOG_WARNING, "unable to set socket option");
                    130:     if (setsockopt (sd, SOL_SOCKET, SO_KEEPALIVE, NULL, 0) == NOTOK)
                    131:        padvise ("SO_KEEPALIVE", LOG_WARNING, "unable to set socket option");
                    132:     if (bind (sd, (struct sockaddr *) isock, sizeof *isock) == NOTOK)
                    133:        padios ("socket", "unable to bind");
                    134: 
                    135:     (void) signal (SIGCHLD, chldser);
                    136:     (void) listen (sd, SOMAXCONN);
                    137: #ifdef FAST
                    138:     popinit ();
                    139: #endif FAST
                    140:     for (;;) {
                    141:        int     i = sizeof *osock;
                    142: 
                    143:        if ((fd = accept (sd, (struct sockaddr *) osock, &i)) == NOTOK) {
                    144:            if (errno != EINTR)
                    145:                padvise ("socket", LOG_WARNING,
                    146:                    "unable to accept connection on");
                    147:            continue;
                    148:        }
                    149: #ifdef FAST
                    150:        popassert ();
                    151: #endif FAST
                    152:        switch (fork ()) {
                    153:            case OK: 
                    154:                (void) close (sd);
                    155:                (void) signal (SIGCHLD, SIG_DFL);
                    156:                server (fd, osock);
                    157:                _exit (0);
                    158: 
                    159:            case NOTOK: 
                    160:                padvise ("socket", LOG_WARNING,
                    161:                    "no forks, so rejecting connection on");
                    162:            default: 
                    163:                (void) close (fd);
                    164:        }
                    165:     }
                    166: }
                    167: 
                    168: /*  */
                    169: 
                    170: static server (fd, sin)
                    171: int    fd;
                    172: struct sockaddr_in *sin;
                    173: {
                    174:     u_short port;
                    175:     struct hostent *hp;
                    176:     struct in_addr *addr;
                    177: 
                    178:     closelog ();
                    179:     openlog (myname, LOG_PID);
                    180:     port = ntohs (sin -> sin_port);
                    181:     addr = &sin -> sin_addr;
                    182:     hp = gethostbyaddr (addr, sizeof *addr, sin -> sin_family);
                    183:     padvise (NULLCP, LOG_INFO, "servicing %s/%d",
                    184:            hp ? hp -> h_name : inet_ntoa (*addr), port);
                    185: 
                    186:     (void) dup2 (fd, 0);
                    187:     (void) close (fd);
                    188:     (void) dup2 (0, 1);
                    189: 
                    190:     pop (0, 1, sin -> sin_family == AF_INET && port < IPPORT_RESERVED && hp,
                    191:            hp ? hp -> h_name : NULLCP);
                    192: }
                    193:        
                    194: /*  */
                    195: 
                    196: static arginit (vec)
                    197: char   **vec;
                    198: {
                    199:     register char  *ap;
                    200:     struct hostent *hp;
                    201: 
                    202:     if (myname = rindex (*vec, '/'))
                    203:        myname++;
                    204:     if (myname == NULL || *myname == NULL)
                    205:        myname = *vec;
                    206: 
                    207:     (void) gethostname (myhost, sizeof myhost);
                    208:     if (hp = gethostbyname (myhost))
                    209:        (void) strcpy (myhost, hp -> h_name);
                    210:     nbits = getdtablesize ();
                    211: 
                    212:     for (vec++; ap = *vec; vec++) {
                    213:        if (*ap == '-')
                    214:            switch (*++ap) {
                    215:                case 'd': 
                    216:                    options |= SO_DEBUG;
                    217:                    continue;
                    218: 
                    219:                case 'p': 
                    220:                    if ((ap = *++vec) == NULL
                    221:                            || *ap == '-'
                    222:                            || (isock -> sin_port = atoi (ap)) <= 0)
                    223:                        padios (NULLCP, "usage: %s -p portno", myname);
                    224:                    isock -> sin_port = htons (isock -> sin_port);
                    225:                    continue;
                    226: 
                    227:                default: 
                    228:                    padios (NULLCP, "-%s: unknown switch", ap);
                    229:            }
                    230: 
                    231:        padios (NULLCP, "usage: %s [switches]", myname);
                    232:     }
                    233: }
                    234: 
                    235: /*  */
                    236: 
                    237: static  envinit () {
                    238:     int     i,
                    239:             sd;
                    240: 
                    241:     if (!(debug = isatty (2))) {
                    242:        for (i = 0; i < 5; i++) {
                    243:            switch (fork ()) {
                    244:                case NOTOK: 
                    245:                    sleep (5);
                    246:                    continue;
                    247: 
                    248:                case OK: 
                    249:                    break;
                    250: 
                    251:                default: 
                    252:                    _exit (0);
                    253:            }
                    254:            break;
                    255:        }
                    256: 
                    257:        (void) chdir ("/");
                    258: 
                    259:        if ((sd = open ("/dev/null", O_RDWR)) == NOTOK)
                    260:            padios ("/dev/null", "unable to read");
                    261:        if (sd != 0)
                    262:            (void) dup2 (sd, 0), (void) close (sd);
                    263:        (void) dup2 (0, 1);
                    264:        (void) dup2 (0, 2);
                    265: 
                    266:        if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) {
                    267:            (void) ioctl (sd, TIOCNOTTY, NULLCP);
                    268:            (void) close (sd);
                    269:        }
                    270:     }
                    271: 
                    272:     for (sd = 3; sd < nbits; sd++)
                    273:        (void) close (sd);
                    274: 
                    275:     (void) signal (SIGPIPE, SIG_IGN);
                    276: 
                    277:     openlog (myname, LOG_PID);
                    278:     padvise (NULLCP, LOG_INFO, "starting");
                    279:     if (debug)
                    280:        padvise (NULLCP, LOG_DEBUG, "options=0x%x port=%d",
                    281:                options, ntohs (isock -> sin_port));
                    282: }
                    283: 
                    284: /*  */
                    285: 
                    286: /* ARGSUSED */
                    287: 
                    288: static int chldser (sig, code, sc)
                    289: int    sig;
                    290: long    code;
                    291: struct sigcontext *sc;
                    292: {
                    293:     union wait status;
                    294: 
                    295:     while (wait3 (&status, WNOHANG, NULLRP) > 0)
                    296:        continue;
                    297: }
                    298: 
                    299: /*  */
                    300: 
                    301: /* VARARGS2 */
                    302: 
                    303: void   padios (what, fmt, a, b, c, d, e, f, g, h, i, j)
                    304: char   *what,
                    305:        *fmt,
                    306:        *a,
                    307:        *b,
                    308:        *c,
                    309:        *d,
                    310:        *e,
                    311:        *f,
                    312:        *g,
                    313:        *h,
                    314:        *i,
                    315:        *j;
                    316: {
                    317:     padvise (what, LOG_SALERT, fmt, a, b, c, d, e, f, g, h, i, j);
                    318:     _exit (1);
                    319: }
                    320: 
                    321: /*  */
                    322: 
                    323: /* VARARGS3 */
                    324: 
                    325: void   padvise (what, code, fmt, a, b, c, d, e, f, g, h, i, j)
                    326: char   *what,
                    327:        *fmt,
                    328:        *a,
                    329:        *b,
                    330:        *c,
                    331:        *d,
                    332:        *e,
                    333:        *f,
                    334:        *g,
                    335:        *h,
                    336:        *i,
                    337:        *j;
                    338: int    code;
                    339: {
                    340:     int     eindex = errno;
                    341:     char    buffer[BUFSIZ];
                    342: 
                    343:     (void) sprintf (buffer, fmt, a, b, c, d, e, f, g, h, i, j);
                    344:     if (what)
                    345:        if (eindex > 0 && eindex < sys_nerr)
                    346:            syslog (code, "%s %s: %s", buffer, what, sys_errlist[eindex]);
                    347:        else
                    348:            syslog (code, "%s %s: Error %d", buffer, what, eindex);
                    349:     else
                    350:        syslog (code, "%s", buffer);
                    351: 
                    352:     if (debug) {
                    353:        fprintf (stderr, "[%d] %s", code, buffer);
                    354:        if (what)
                    355:            (void) fputc (' ', stderr), perror (what);
                    356:        else
                    357:            (void) fputc ('\n', stderr);
                    358:        (void) fflush (stderr);
                    359:     }
                    360: 
                    361:     errno = eindex;
                    362: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.