|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.