1: #ifndef lint
   2: static char sccsid[] = "@(#)ns_main.c	4.3 (Berkeley) 5/30/86";
   3: #endif
   4: 
   5: /*
   6:  * Copyright (c) 1986 Regents of the University of California
   7:  *	All Rights Reserved
   8:  */
   9: 
  10: /*
  11:  * Internet Name server (see rfc883 & others).
  12:  */
  13: 
  14: #include <sys/param.h>
  15: #include <sys/file.h>
  16: #include <sys/time.h>
  17: #include <sys/wait.h>
  18: #include <sys/resource.h>
  19: #include <sys/ioctl.h>
  20: #include <sys/socket.h>
  21: #include <netinet/in.h>
  22: #include <stdio.h>
  23: #include <syslog.h>
  24: #include <errno.h>
  25: #include <signal.h>
  26: #include <arpa/nameser.h>
  27: #include <arpa/inet.h>
  28: #include "ns.h"
  29: #include "db.h"
  30: 
  31: #ifdef BOOTFILE             /* default boot file */
  32: char    *bootfile = BOOTFILE;
  33: #else
  34: char    *bootfile = "/etc/named.boot";
  35: #endif
  36: 
  37: #ifdef DEBUGFILE            /* default debug output file */
  38: char    *debugfile = DEBUGFILE;
  39: #else
  40: char    *debugfile = "/usr/tmp/named.run";
  41: #endif
  42: 
  43: #ifdef PIDFILE              /* file to store current named PID */
  44: char    *PidFile = PIDFILE;
  45: #else
  46: char    *PidFile = "/etc/named.pid";
  47: #endif
  48: 
  49: #ifndef FD_SET
  50: #define NFDBITS     32
  51: #define FD_SETSIZE  32
  52: #define FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
  53: #define FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
  54: #define FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
  55: #define FD_ZERO(p)  bzero((char *)(p), sizeof(*(p)))
  56: #endif
  57: 
  58: FILE    *fp;                /* file descriptor for pid file */
  59: 
  60: #ifdef DEBUG
  61: FILE    *ddt;
  62: #endif
  63: 
  64: int debug = 0;          /* debugging flag */
  65: int ds;             /* datagram socket */
  66: int read_interrupted = 0;       /* flag for read timer */
  67: int needreload = 0;         /* received SIGHUP, need to reload db */
  68: int needmaint = 0;          /* need to call ns_maint()*/
  69: int rbufsize = 8 * 1024;        /* UDP recive buffer size */
  70: 
  71: struct  qstream *streamq = QSTREAM_NULL; /* list of open streams */
  72: struct  sockaddr_in nsaddr;
  73: struct  timeval tt;
  74: short   ns_port;
  75: 
  76: char        **Argv = NULL;      /* pointer to argument vector */
  77: char        *LastArg = NULL;    /* end of argv */
  78: 
  79: extern char *malloc(), *realloc(), *calloc();
  80: 
  81: extern int errno;
  82: 
  83: 
  84: 
  85: main(argc, argv, envp)
  86:     int argc;
  87:     char *argv[], *envp[];
  88: {
  89:     register int n, udpcnt;
  90:     register char *arg;
  91:     register struct qstream *sp;
  92:     int vs, len;
  93:     int nfds;
  94:     int on = 1;
  95:     int rfd, size;
  96:     u_long lasttime, maxctime;
  97:     char buf[BUFSIZ];
  98: 
  99:     fd_set mask, tmpmask;
 100: 
 101:     struct timeval t, *tp;
 102:     struct sockaddr_in from;
 103:     struct qstream *candidate = QSTREAM_NULL;
 104:     extern int onintr(), maint_alarm(), reapchild(), doadump(), onhup();
 105:     extern int sigsetdebug(), signodebug(), sigprof();
 106:     extern struct qstream *sqadd();
 107:     extern char Version[];
 108:     struct  sigvec sv;
 109: 
 110:     ns_port = htons(NAMESERVER_PORT);
 111: 
 112:     /*
 113: 	**  Save start and extent of argv for setproctitle.
 114: 	*/
 115: 
 116:     Argv = argv;
 117:     if (envp == 0 || *envp == 0)
 118:         envp = argv;
 119:     while (*envp)
 120:         envp++;
 121:     LastArg = envp[-1] + strlen(envp[-1]);
 122: 
 123:     while (--argc > 0) {
 124:         arg = *++argv;
 125:         if (*arg == '-') {
 126:             while (*++arg)
 127:                 switch (*arg) {
 128:                 case 'b':
 129:                     if (--argc <= 0)
 130:                         usage();
 131:                     bootfile = *++argv;
 132:                     break;
 133: 
 134:                 case 'd':
 135:                     ++argv;
 136: 
 137:                     if (*argv != 0) {
 138:                         if (**argv == '-') {
 139:                         argv--;
 140:                         break;
 141:                         }
 142:                         debug = atoi(*argv);
 143:                         --argc;
 144:                     }
 145:                     if (debug <= 0)
 146:                         debug = 1;
 147:                     setdebug(1);
 148:                     break;
 149: 
 150:                 case 'p':
 151:                     if (--argc <= 0)
 152:                         usage();
 153:                     ns_port = htons((u_short)atoi(*++argv));
 154:                     break;
 155: 
 156:                 default:
 157:                     usage();
 158:                 }
 159:         } else
 160:             bootfile = *argv;
 161:     }
 162: 
 163:     if (!debug) {
 164:         if (fork())
 165:             exit(0);
 166:         for (n = getdtablesize() - 1; n >= 0; n--)
 167:             (void) close(n);
 168:         (void) open("/dev/null", O_RDONLY);
 169:         (void) dup2(0, 1);
 170:         (void) dup2(0, 2);
 171:         n = open("/dev/tty", O_RDWR);
 172:         if (n > 0) {
 173:             (void) ioctl(n, TIOCNOTTY, (char *)NULL);
 174:             (void) close(n);
 175:         }
 176:     }
 177: #ifdef DEBUG
 178:     else {
 179:         fprintf(ddt,"Debug turned ON, Level %d\n",debug);
 180:         fprintf(ddt,"Version = %s\t",Version);
 181:         fprintf(ddt,"bootfile = %s\n",bootfile);
 182:     }
 183: #endif
 184: 
 185: #ifdef BSD4_3
 186:     openlog("named", LOG_PID|LOG_CONS|LOG_NDELAY, LOG_DAEMON);
 187: #else
 188:     openlog("named", LOG_PID);
 189: #endif
 190: 
 191:     nsaddr.sin_family = AF_INET;
 192:     nsaddr.sin_addr.s_addr = INADDR_ANY;
 193:     nsaddr.sin_port = ns_port;
 194:     /*
 195: 	** Initialize and load database.
 196: 	*/
 197:     ns_init(bootfile);
 198: 
 199:     /* Block signals during maintenance */
 200:     sv.sv_handler = maint_alarm;
 201:     sv.sv_onstack = 0;
 202:     sv.sv_mask = ~0;
 203: 
 204:     (void) sigvec(SIGALRM, &sv, (struct sigvec *)0);
 205: 
 206:     (void) signal(SIGHUP, onhup);
 207:     (void) signal(SIGCHLD, reapchild);
 208:     (void) signal(SIGPIPE, SIG_IGN);
 209:     (void) signal(SIGSYS, sigprof);
 210: 
 211: #if BSD >= 43
 212:     /* flames to mckusick@monet.Berkeley.EDU - I lost the battle -KJD */
 213:     (void) signal(SIGINT, doadump);
 214:     (void) signal(SIGUSR1, sigsetdebug);
 215:     (void) signal(SIGUSR2, signodebug);
 216: #else   BSD
 217:     (void) signal(SIGQUIT, doadump);
 218:     (void) signal(SIGEMT, sigsetdebug);
 219:     (void) signal(SIGFPE, signodebug);
 220: #endif BSD
 221: 
 222: #ifdef DEBUG
 223:     if (debug) {
 224:         fprintf(ddt,"database initialized\n");
 225:     }
 226: #endif
 227:     /*
 228: 	** Open stream port.
 229: 	*/
 230:     if ((vs = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
 231:         syslog(LOG_ERR, "socket(SOCK_STREAM): %m");
 232:         exit(1);
 233:     }
 234:     (void)setsockopt(vs, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
 235:     if (bind(vs, &nsaddr, sizeof(nsaddr))) {
 236:         syslog(LOG_ERR, "bind(vs): %m");
 237:         exit(1);
 238:     }
 239:     (void) listen(vs, 5);
 240:     /*
 241: 	** Open datagram port.
 242: 	*/
 243:     if ((ds = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
 244:         syslog(LOG_ERR, "socket(SOCK_DGRAM): %m");
 245:         exit(1);
 246:     }
 247:     (void)setsockopt(ds, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
 248: #ifdef BSD4_3
 249:     (void)setsockopt(ds, SOL_SOCKET, SO_RCVBUF, (char *)&rbufsize,
 250:         sizeof(rbufsize));
 251: #endif
 252:     (void) fcntl(ds, F_SETFL, FNDELAY);
 253:     if (bind(ds, &nsaddr, sizeof(nsaddr))) {
 254:         syslog(LOG_ERR, "bind(ds): %m");
 255:         exit(1);
 256:     }
 257:     /* tuck my process id away */
 258:     fp = fopen(PidFile, "w");
 259:     if (fp != NULL) {
 260:         fprintf(fp, "%d\n", getpid());
 261:         (void) fclose(fp);
 262:     }
 263: 
 264:     t.tv_usec = 0;
 265: 
 266: #ifdef DEBUG
 267:     if (debug)
 268:         fprintf(ddt,"Ready to answer queries.\n");
 269: #endif
 270:     nfds = getdtablesize();       /* get the number of file descriptors */
 271:     if (nfds > FD_SETSIZE) {
 272:         syslog(LOG_ERR, "Return from getdtablesize() > FD_SETSIZE");
 273: #ifdef DEBUG
 274:         if (debug)
 275:               fprintf(ddt,"Return from getdtablesize() > FD_SETSIZE\n");
 276: #endif
 277:     }
 278:     FD_ZERO(&mask);
 279:     FD_SET(vs, &mask);
 280:     FD_SET(ds, &mask);
 281:     for (;;) {
 282:         /*
 283: 		** Wait until a query arrives; can be interrupted by maintenance
 284: 		*/
 285:         if (retryqp != NULL) {
 286:             if (gettimeofday(&tt, (struct timezone *)0) < 0)
 287:                 syslog(LOG_ERR, "gettimeofday failed: %m");
 288:             t.tv_sec = (long) retryqp->q_time - tt.tv_sec;
 289:             if (t.tv_sec <= 0) {
 290:                 retry(retryqp);
 291:                 continue;
 292:             }
 293:             tp = &t;
 294:         } else
 295:             tp = NULL;
 296:         if(needreload) {
 297:             needreload = 0;
 298:             db_reload();
 299:         }
 300:         if(needmaint) {
 301:             needmaint = 0;
 302:             ns_maint();
 303:         }
 304:         tmpmask = mask;
 305:         n = select(nfds, &tmpmask, (fd_set *)NULL, (fd_set *)NULL, tp);
 306:         if (n < 0) {
 307:             if (errno == EINTR)
 308:                 continue;
 309:             syslog(LOG_ERR, "select: %m");
 310:             break;
 311:         }
 312:         if (n == 0) {
 313:             retry(retryqp);
 314:             continue;
 315:         }
 316:         if (gettimeofday(&tt, (struct timezone *)0) < 0) {
 317:             syslog(LOG_ERR, "gettimeofday failed: %m");
 318:             break;
 319:         }
 320:         /*
 321: 		** Process datagram
 322: 		*/
 323:         if (FD_ISSET(ds, &tmpmask))
 324:             for(udpcnt = 0; udpcnt < 25; udpcnt++) {
 325:             len = sizeof(from);
 326:             if ((n = recvfrom(ds, buf, sizeof(buf), 0,
 327:                 &from, &len)) < 0)
 328:             {
 329:                 if ((n == -1) && (errno == EWOULDBLOCK))
 330:                     break;
 331:                 syslog(LOG_WARNING, "recvfrom: %m");
 332:                 break;
 333:             }
 334: #ifdef DEBUG
 335:             if (debug)
 336:                 fprintf(ddt,"datagram from %s, %d (%d)\n",
 337:                     inet_ntoa(from.sin_addr),
 338:                     ntohs(from.sin_port), n);
 339:             if (debug >= 10)
 340:                 fp_query(buf, ddt);
 341: #endif
 342:             /*
 343: 			 * Consult database to get the answer.
 344: 			 */
 345:             if (gettimeofday(&tt, (struct timezone *)0) < 0) {
 346:                 syslog(LOG_ERR, "gettimeofday failed: %m");
 347:                 break;
 348:             }
 349:             ns_req(buf, n, PACKETSZ, QSTREAM_NULL, &from);
 350:             }
 351:         /*
 352: 		** Process stream connection
 353: 		*/
 354:         if (FD_ISSET(vs, &tmpmask)) {
 355:             len = sizeof(from);
 356:             rfd = accept(vs, &from, &len);
 357:             if (gettimeofday(&tt, (struct timezone *)0) < 0) {
 358:                 syslog(LOG_ERR, "gettimeofday failed: %m");
 359:                 break;
 360:             }
 361:             if (rfd < 0) {
 362:                 if (errno == EMFILE) {
 363:                 if (streamq != NULL) {
 364:                     maxctime = 0;
 365:                     candidate = QSTREAM_NULL;
 366:                     for (sp = streamq; sp != QSTREAM_NULL;
 367:                        sp = sp->s_next)
 368:                     {
 369:                     if (sp->s_refcnt != 0)
 370:                         continue;
 371:                     lasttime = tt.tv_sec - sp->s_time;
 372:                     if (lasttime >= 900)
 373:                         sqrm(sp, &tmpmask);
 374:                     else if (lasttime > maxctime) {
 375:                         candidate = sp;
 376:                         maxctime = lasttime;
 377:                     }
 378:                     }
 379:                     rfd = accept(vs, &from, &len);
 380:                     if ((rfd < 0) && (errno == EMFILE))
 381:                     if (candidate != QSTREAM_NULL) {
 382:                         sqrm(candidate, &tmpmask);
 383:                             rfd = accept(vs, &from, &len);
 384:                         if (rfd < 0)
 385:                             syslog(LOG_WARNING,
 386:                             "accept: %m");
 387:                         continue;
 388:                     }
 389:                 } else {
 390:                     syslog(LOG_WARNING, "accept: %m");
 391:                     continue;
 392:                 }
 393:                 } else {
 394:                 syslog(LOG_WARNING, "accept: %m");
 395:                 continue;
 396:                 }
 397:             }
 398:             (void) fcntl(rfd, F_SETFL, FNDELAY);
 399:             (void) setsockopt(rfd, SOL_SOCKET, SO_KEEPALIVE,
 400:                 (char *)&on, sizeof(on));
 401:             if ((sp = sqadd()) == QSTREAM_NULL)
 402:                 (void) close(rfd);
 403:             sp->s_rfd = rfd;    /* stream file descriptor */
 404:             sp->s_size = -1;    /* amount of data to recive */
 405:             if (gettimeofday(&tt, (struct timezone *)0) < 0) {
 406:                 syslog(LOG_ERR, "gettimeofday failed: %m");
 407:                 break;
 408:             }
 409:             sp->s_time = tt.tv_sec; /* last transaction time */
 410:             sp->s_from = from;  /* address to respond to */
 411:             sp->s_bufsize = 0;
 412:             sp->s_bufp = (char *)&sp->s_tempsize;
 413:             sp->s_refcnt = 0;
 414:             FD_SET(rfd, &mask);
 415:             FD_SET(rfd, &tmpmask);
 416: #ifdef DEBUG
 417:             if (debug)
 418:             {
 419:                 fprintf(ddt,"stream from %s, %d (%d)\n",
 420:                     inet_ntoa(sp->s_from.sin_addr),
 421:                     ntohs(sp->s_from.sin_port), n);
 422:             }
 423: #endif
 424:         }
 425: #ifdef DEBUG
 426:         if (debug > 2)
 427:             fprintf(ddt,"streamq  = x%x\n",streamq);
 428: #endif
 429:         if (streamq != NULL) {
 430:             for (sp = streamq; sp != QSTREAM_NULL; sp = sp->s_next)
 431:                 if (FD_ISSET(sp->s_rfd, &tmpmask)) {
 432: #ifdef DEBUG
 433:                 if (debug > 5) {
 434:                     fprintf(ddt,
 435:                     "sp x%x rfd %d size %d time %d ",
 436:                     sp, sp->s_rfd, sp->s_size,
 437:                     sp->s_time );
 438:                     fprintf(ddt," next x%x \n", sp->s_next );
 439:                     fprintf(ddt,"\tbufsize %d",sp->s_bufsize);
 440:                     fprintf(ddt," buf x%x%d ",sp->s_buf);
 441:                     fprintf(ddt," bufp x%x%d\n",sp->s_bufp);
 442:                 }
 443: #endif DEBUG
 444:                 if (sp->s_size < 0) {
 445:                     size = sizeof(u_short) -
 446:                 (sp->s_bufp - (char *)&sp->s_tempsize);
 447:                     while (size > 0 &&
 448:                        (n = read(sp->s_rfd, sp->s_bufp, size)) > 0){
 449:                         sp->s_bufp += n;
 450:                         size -= n;
 451:                     }
 452:                     if ((n == -1) && (errno == EWOULDBLOCK))
 453:                         continue;
 454:                     if (n <= 0) {
 455:                         sp->s_refcnt = 0;
 456:                         sqrm(sp, &mask);
 457:                         continue;
 458:                     }
 459:                     if ((sp->s_bufp - (char *)&sp->s_tempsize) ==
 460:                     sizeof(u_short)) {
 461:                     sp->s_size = htons(sp->s_tempsize);
 462:                     if (sp->s_bufsize == 0) {
 463:                         if ( (sp->s_buf = malloc(BUFSIZ))
 464:                         == NULL) {
 465:                             sp->s_buf = buf;
 466:                             sp->s_size  = sizeof(buf);
 467:                         } else {
 468:                             sp->s_bufsize = BUFSIZ;
 469:                         }
 470:                     }
 471:                     if (sp->s_size > sp->s_bufsize &&
 472:                       sp->s_bufsize != 0) {
 473:                         if ((sp->s_buf = realloc(
 474:                         (char *)sp->s_buf,
 475:                         (unsigned)sp->s_size)) == NULL){
 476:                             sp->s_buf = buf;
 477:                             sp->s_bufsize = 0;
 478:                             sp->s_size  = sizeof(buf);
 479:                        } else {
 480:                             sp->s_bufsize = sp->s_size;
 481:                        }
 482:                     }
 483:                     sp->s_bufp = sp->s_buf;
 484:                     }
 485:                 }
 486:                 if (gettimeofday(&tt, (struct timezone *)0) < 0) {
 487:                     syslog(LOG_ERR, "gettimeofday failed: %m");
 488:                     break;
 489:                 }
 490:                 sp->s_time = tt.tv_sec;
 491:                 while (sp->s_size > 0 &&
 492:                   (n = read(sp->s_rfd, sp->s_buf, sp->s_size)) > 0)
 493:                 {
 494:                     sp->s_bufp += n;
 495:                     sp->s_size -= n;
 496:                 }
 497:                 /*
 498: 			     * we don't have enough memory for the query.
 499: 			     * if we have a query id, then we will send an
 500: 			     * error back to the user.
 501: 			     */
 502:                 if (sp->s_bufsize == 0 &&
 503:                 (sp->s_bufp - sp->s_buf > sizeof(u_short))) {
 504:                     HEADER *hp;
 505: 
 506:                     hp = (HEADER *)sp->s_buf;
 507:                     hp->qr = 1;
 508:                     hp->ra = 1;
 509:                     hp->ancount = 0;
 510:                     hp->qdcount = 0;
 511:                     hp->nscount = 0;
 512:                     hp->arcount = 0;
 513:                     hp->rcode = SERVFAIL;
 514:                     (void) writemsg(sp->s_rfd, sp->s_buf,
 515:                     sizeof(HEADER));
 516:                     continue;
 517:                 }
 518:                 if ((n == -1) && (errno == EWOULDBLOCK))
 519:                     continue;
 520:                 if (n <= 0) {
 521:                     sp->s_refcnt = 0;
 522:                     sqrm(sp, &mask);
 523:                     continue;
 524:                 }
 525:                 /*
 526: 			     * Consult database to get the answer.
 527: 			     */
 528:                 if (sp->s_size == 0) {
 529:                     sp->s_refcnt++;
 530:                     ns_req(sp->s_buf,
 531:                     sp->s_bufp - sp->s_buf,
 532:                     sp->s_bufsize, sp,
 533:                     &sp->s_from);
 534:                     sp->s_bufp = (char *)&sp->s_tempsize;
 535:                     sp->s_size = -1;
 536:                     continue;
 537:                 }
 538:             }
 539:         }
 540:     }
 541:     (void) close(vs);
 542:     (void) close(ds);
 543:     return (0);
 544: }
 545: 
 546: usage()
 547: {
 548:     fprintf(stderr, "Usage: named [-d #] [-p port] [{-b} bootfile]\n");
 549:     exit(1);
 550: }
 551: 
 552: /*
 553: ** Set flag saying to reload database upon receiving SIGHUP.
 554: ** Must make sure that someone isn't walking through a data
 555: ** structure at the time.
 556: */
 557: 
 558: onhup()
 559: {
 560:     needreload = 1;
 561: }
 562: 
 563: /*
 564: ** Set flag saying to call ns_maint()
 565: ** Must make sure that someone isn't walking through a data
 566: ** structure at the time.
 567: */
 568: 
 569: maint_alarm()
 570: {
 571:     needmaint = 1;
 572: }
 573: 
 574: /*
 575: ** Set flag saying to read was interrupted
 576: ** used for a read timer
 577: */
 578: 
 579: read_alarm()
 580: {
 581:     extern int read_interrupted;
 582:     read_interrupted = 1;
 583: }
 584: 
 585: reapchild()
 586: {
 587:     union wait status;
 588: 
 589:     while (wait3(&status, WNOHANG, (struct rusage *)NULL) > 0)
 590:         ;
 591: }
 592: 
 593: /*
 594: ** Turn on or off debuging by open or closeing the debug file
 595: */
 596: 
 597: setdebug(code)
 598: int code;
 599: {
 600: #if defined(lint) && !defined(DEBUG)
 601:     code = code;
 602: #endif
 603: #ifdef DEBUG
 604: 
 605:     if (code) {
 606:         ddt = freopen(debugfile, "w+", stderr);
 607:         if ( ddt == NULL)
 608:             syslog(LOG_WARNING, "can't open debug file: %m");
 609:         else
 610:             setlinebuf(ddt);
 611:     }
 612:     else {
 613:         fprintf(ddt,"Debug turned OFF, Level %d\n",debug);
 614:         (void) fclose(ddt);
 615:         debug = 0;
 616:     }
 617: #endif
 618: }
 619: 
 620: /*
 621: ** Catch a special signal  SIGEMT and set debug level
 622: **
 623: **  SIGEMT - if debuging is off then turn on debuging else incremnt the level
 624: **
 625: ** Handy for looking in on long running name servers.
 626: */
 627: 
 628: sigsetdebug()
 629: {
 630: 
 631: #ifdef DEBUG
 632:     if (debug == 0) {
 633:         debug++;
 634:         setdebug(1);
 635:     }
 636:     else {
 637:         debug++;
 638:     }
 639:     fprintf(ddt,"Debug turned ON, Level %d\n",debug);
 640: #endif
 641: }
 642: 
 643: /*
 644: ** Catch a special signal's SIGFPE and turn off debugging
 645: **
 646: **  SIGFPE - turn off debugging
 647: */
 648: 
 649: signodebug()
 650: {
 651:     setdebug(0);
 652: }
 653: 
 654: 
 655: /*
 656: ** Catch a special signal SIGSYS
 657: **
 658: **  this is setup to fork and exit to drop to /usr/tmp/gmon.out
 659: **   and keep the server running
 660: */
 661: 
 662: sigprof()
 663: {
 664: #ifdef DEBUG
 665:     if (debug)
 666:         fprintf(ddt,"sigprof()\n");
 667: #endif
 668:     if ( fork() == 0)
 669:     {
 670:         (void) chdir("/usr/tmp");
 671:         exit(1);
 672:     }
 673: }
 674: 
 675: /*
 676: ** Routines for managing stream queue
 677: */
 678: 
 679: struct qstream *
 680: sqadd()
 681: {
 682:     register struct qstream *sqp;
 683: 
 684:     if ((sqp = (struct qstream *)calloc(1, sizeof(struct qstream)))
 685:         == NULL ) {
 686: #ifdef DEBUG
 687:         if (debug >= 5)
 688:             fprintf(ddt,"sqadd: malloc error\n");
 689: #endif
 690:         syslog(LOG_ERR, "sqadd: Out Of Memory");
 691:         return(QSTREAM_NULL);
 692:     }
 693: #ifdef DEBUG
 694:     if (debug > 3)
 695:         fprintf(ddt,"sqadd(x%x)\n", sqp);
 696: #endif
 697: 
 698:     sqp->s_next = streamq;
 699:     streamq = sqp;
 700:     return(sqp);
 701: }
 702: 
 703: sqrm(qp, mask)
 704:     register struct qstream *qp;
 705:     fd_set *mask;
 706: {
 707:     register struct qstream *qsp;
 708: 
 709: #ifdef DEBUG
 710:     if (debug > 1) {
 711:         fprintf(ddt,"sqrm(%#x, %d ) rfcnt=%d\n",
 712:             qp, qp->s_rfd, qp->s_refcnt);
 713:     }
 714: #endif
 715:     if (qp->s_refcnt != 0)
 716:         return;
 717: 
 718:     if (qp->s_bufsize != 0)
 719:         (void) free(qp->s_buf);
 720:     FD_CLR(qp->s_rfd, mask);
 721:     (void) close(qp->s_rfd);
 722:     if (qp == streamq) {
 723:         streamq = qp->s_next;
 724:     } else {
 725:         for (qsp = streamq; qsp->s_next != qp; qsp = qsp->s_next)
 726:             ;
 727:         qsp->s_next = qp->s_next;
 728:     }
 729:     (void)free((char *)qp);
 730: }
 731: 
 732: setproctitle(a, s)
 733:     char *a;
 734:     int s;
 735: {
 736:     int size;
 737:     register char *cp;
 738:     struct sockaddr_in sin;
 739:     char buf[80];
 740: 
 741:     cp = Argv[0];
 742:     size = sizeof(sin);
 743:     if (getpeername(s, &sin, &size) == 0)
 744:         (void) sprintf(buf, "-%s [%s]", a, inet_ntoa(sin.sin_addr));
 745:     else
 746:         (void) sprintf(buf, "-%s", a);
 747:     (void) strncpy(cp, buf, LastArg - cp);
 748:     cp += strlen(cp);
 749:     while (cp < LastArg)
 750:         *cp++ = ' ';
 751: }

Defined functions

main defined in line 85; never used
maint_alarm defined in line 569; used 2 times
onhup defined in line 558; used 2 times
read_alarm defined in line 579; used 4 times
reapchild defined in line 585; used 2 times
setdebug defined in line 597; used 3 times
setproctitle defined in line 732; used 1 times
signodebug defined in line 649; used 3 times
sigprof defined in line 662; used 2 times
sigsetdebug defined in line 628; used 3 times
sqadd defined in line 679; used 2 times
sqrm defined in line 703; used 4 times
usage defined in line 546; used 3 times

Defined variables

Argv defined in line 76; used 2 times
LastArg defined in line 77; used 3 times
PidFile defined in line 46; used 1 times
bootfile defined in line 34; used 4 times
debugfile defined in line 40; used 1 times
ds defined in line 65; used 26 times
needmaint defined in line 68; used 3 times
needreload defined in line 67; used 3 times
ns_port defined in line 74; used 3 times
nsaddr defined in line 72; used 7 times
rbufsize defined in line 69; used 2 times
read_interrupted defined in line 66; used 2 times
sccsid defined in line 2; never used
streamq defined in line 71; used 20 times

Defined macros

FD_CLR defined in line 53; used 1 times
FD_ISSET defined in line 54; used 3 times
FD_SET defined in line 52; used 5 times
FD_SETSIZE defined in line 51; used 1 times
FD_ZERO defined in line 55; used 1 times
NFDBITS defined in line 50; used 6 times
Last modified: 1986-05-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1669
Valid CSS Valid XHTML 1.0 Strict