|
|
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: int port; ! 200: register char *ap; ! 201: struct hostent *hp; ! 202: ! 203: if (myname = rindex (*vec, '/')) ! 204: myname++; ! 205: if (myname == NULL || *myname == NULL) ! 206: myname = *vec; ! 207: ! 208: (void) gethostname (myhost, sizeof myhost); ! 209: if (hp = gethostbyname (myhost)) ! 210: (void) strcpy (myhost, hp -> h_name); ! 211: nbits = getdtablesize (); ! 212: ! 213: for (vec++; ap = *vec; vec++) { ! 214: if (*ap == '-') ! 215: switch (*++ap) { ! 216: case 'd': ! 217: options |= SO_DEBUG; ! 218: continue; ! 219: ! 220: case 'p': ! 221: if ((ap = *++vec) == NULL ! 222: || *ap == '-' ! 223: || (port = atoi (ap)) <= 0) ! 224: padios (NULLCP, "usage: %s -p portno", myname); ! 225: isock -> sin_port = htons ((u_short) port); ! 226: continue; ! 227: ! 228: default: ! 229: padios (NULLCP, "-%s: unknown switch", ap); ! 230: } ! 231: ! 232: padios (NULLCP, "usage: %s [switches]", myname); ! 233: } ! 234: } ! 235: ! 236: /* */ ! 237: ! 238: static envinit () { ! 239: int i, ! 240: sd; ! 241: ! 242: if (!(debug = isatty (2))) { ! 243: for (i = 0; i < 5; i++) { ! 244: switch (fork ()) { ! 245: case NOTOK: ! 246: sleep (5); ! 247: continue; ! 248: ! 249: case OK: ! 250: break; ! 251: ! 252: default: ! 253: _exit (0); ! 254: } ! 255: break; ! 256: } ! 257: ! 258: (void) chdir ("/"); ! 259: ! 260: if ((sd = open ("/dev/null", O_RDWR)) == NOTOK) ! 261: padios ("/dev/null", "unable to read"); ! 262: if (sd != 0) ! 263: (void) dup2 (sd, 0), (void) close (sd); ! 264: (void) dup2 (0, 1); ! 265: (void) dup2 (0, 2); ! 266: ! 267: if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) { ! 268: (void) ioctl (sd, TIOCNOTTY, NULLCP); ! 269: (void) close (sd); ! 270: } ! 271: } ! 272: ! 273: for (sd = 3; sd < nbits; sd++) ! 274: (void) close (sd); ! 275: ! 276: (void) signal (SIGPIPE, SIG_IGN); ! 277: ! 278: openlog (myname, LOG_PID); ! 279: padvise (NULLCP, LOG_INFO, "starting"); ! 280: if (debug) ! 281: padvise (NULLCP, LOG_DEBUG, "options=0x%x port=%d", ! 282: options, ntohs (isock -> sin_port)); ! 283: } ! 284: ! 285: /* */ ! 286: ! 287: /* ARGSUSED */ ! 288: ! 289: static int chldser (sig, code, sc) ! 290: int sig; ! 291: long code; ! 292: struct sigcontext *sc; ! 293: { ! 294: union wait status; ! 295: ! 296: while (wait3 (&status, WNOHANG, NULLRP) > 0) ! 297: continue; ! 298: } ! 299: ! 300: /* */ ! 301: ! 302: /* VARARGS2 */ ! 303: ! 304: void padios (what, fmt, a, b, c, d, e, f, g, h, i, j) ! 305: char *what, ! 306: *fmt, ! 307: *a, ! 308: *b, ! 309: *c, ! 310: *d, ! 311: *e, ! 312: *f, ! 313: *g, ! 314: *h, ! 315: *i, ! 316: *j; ! 317: { ! 318: padvise (what, LOG_SALERT, fmt, a, b, c, d, e, f, g, h, i, j); ! 319: _exit (1); ! 320: } ! 321: ! 322: /* */ ! 323: ! 324: /* VARARGS3 */ ! 325: ! 326: void padvise (what, code, fmt, a, b, c, d, e, f, g, h, i, j) ! 327: char *what, ! 328: *fmt, ! 329: *a, ! 330: *b, ! 331: *c, ! 332: *d, ! 333: *e, ! 334: *f, ! 335: *g, ! 336: *h, ! 337: *i, ! 338: *j; ! 339: int code; ! 340: { ! 341: int eindex = errno; ! 342: char buffer[BUFSIZ]; ! 343: ! 344: (void) sprintf (buffer, fmt, a, b, c, d, e, f, g, h, i, j); ! 345: if (what) ! 346: if (eindex > 0 && eindex < sys_nerr) ! 347: syslog (code, "%s %s: %s", buffer, what, sys_errlist[eindex]); ! 348: else ! 349: syslog (code, "%s %s: Error %d", buffer, what, eindex); ! 350: else ! 351: syslog (code, "%s", buffer); ! 352: ! 353: if (debug) { ! 354: fprintf (stderr, "[%d] %s", code, buffer); ! 355: if (what) ! 356: (void) fputc (' ', stderr), perror (what); ! 357: else ! 358: (void) fputc ('\n', stderr); ! 359: (void) fflush (stderr); ! 360: } ! 361: ! 362: errno = eindex; ! 363: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.