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: }

Defined functions

arginit defined in line 196; used 1 times
  • in line 82
chldser defined in line 288; used 2 times
envinit defined in line 237; used 1 times
  • in line 83
main defined in line 66; never used
padios defined in line 303; used 11 times
padvise defined in line 325; used 24 times
server defined in line 170; used 1 times

Defined variables

debug defined in line 45; used 15 times
in_socket defined in line 55; used 1 times
  • in line 56
isock defined in line 56; used 9 times
myhost defined in line 51; used 7 times
myname defined in line 50; used 11 times
myprotocol defined in line 52; used 2 times
myservice defined in line 53; used 2 times
nbits defined in line 46; used 2 times
options defined in line 47; used 3 times

Defined macros

FAST defined in line 35; used 2 times
NOTOK defined in line 29; used 7 times
NULLCP defined in line 32; used 11 times
NULLRP defined in line 33; used 2 times
OK defined in line 30; never used
Last modified: 1986-04-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1897
Valid CSS Valid XHTML 1.0 Strict