Annotation of 43BSDTahoe/etc/named/ns_main.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1986 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted
        !             6:  * provided that the above copyright notice and this paragraph are
        !             7:  * duplicated in all such forms and that any documentation,
        !             8:  * advertising materials, and other materials related to such
        !             9:  * distribution and use acknowledge that the software was developed
        !            10:  * by the University of California, Berkeley.  The name of the
        !            11:  * University may not be used to endorse or promote products derived
        !            12:  * from this software without specific prior written permission.
        !            13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            15:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            16:  */
        !            17: 
        !            18: #ifndef lint
        !            19: char copyright[] =
        !            20: "@(#) Copyright (c) 1986 Regents of the University of California.\n\
        !            21:  All rights reserved.\n";
        !            22: #endif /* not lint */
        !            23: 
        !            24: #ifndef lint
        !            25: static char sccsid[] = "@(#)ns_main.c  4.31 (Berkeley) 7/9/88";
        !            26: #endif /* not lint */
        !            27: 
        !            28: /*
        !            29: * Internet Name server (see rfc883 & others).
        !            30: */
        !            31: 
        !            32: #include <sys/param.h>
        !            33: #if defined(SYSV)
        !            34: #include <fcntl.h>
        !            35: #endif SYSV
        !            36: #include <sys/file.h>
        !            37: #include <sys/time.h>
        !            38: #if !defined(SYSV)
        !            39: #include <sys/wait.h>
        !            40: #endif !SYSV
        !            41: #include <sys/resource.h>
        !            42: #include <sys/ioctl.h>
        !            43: #include <sys/socket.h>
        !            44: #include <netinet/in.h>
        !            45: #include <net/if.h>
        !            46: #include <stdio.h>
        !            47: #include <syslog.h>
        !            48: #include <errno.h>
        !            49: #include <signal.h>
        !            50: #include <netdb.h>
        !            51: #include <arpa/nameser.h>
        !            52: #include <arpa/inet.h>
        !            53: #include <resolv.h>
        !            54: #undef nsaddr                          /* XXX */
        !            55: #include "ns.h"
        !            56: #include "db.h"
        !            57: 
        !            58: #ifdef BOOTFILE                        /* default boot file */
        !            59: char   *bootfile = BOOTFILE;
        !            60: #else
        !            61: char   *bootfile = "/etc/named.boot";
        !            62: #endif
        !            63: 
        !            64: #ifdef DEBUGFILE                       /* default debug output file */
        !            65: char   *debugfile = DEBUGFILE;
        !            66: #else
        !            67: char   *debugfile = "/usr/tmp/named.run";
        !            68: #endif
        !            69: 
        !            70: #ifdef PIDFILE                                 /* file to store current named PID */
        !            71: char   *PidFile = PIDFILE;
        !            72: #else
        !            73: char   *PidFile = "/etc/named.pid";    
        !            74: #endif
        !            75: 
        !            76: #ifndef FD_SET
        !            77: #define        NFDBITS         32
        !            78: #define        FD_SETSIZE      32
        !            79: #define        FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
        !            80: #define        FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
        !            81: #define        FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
        !            82: #define FD_ZERO(p)     bzero((char *)(p), sizeof(*(p)))
        !            83: #endif
        !            84: 
        !            85: FILE   *fp;                            /* file descriptor for pid file */
        !            86: 
        !            87: #ifdef DEBUG
        !            88: FILE   *ddt;
        !            89: #endif
        !            90: 
        !            91: int    debug = 0;                      /* debugging flag */
        !            92: int    ds;                             /* datagram socket */
        !            93: int    read_interrupted = 0;           /* flag for read timer */
        !            94: int    needreload = 0;                 /* received SIGHUP, need to reload db */
        !            95: int    needmaint = 0;                  /* need to call ns_maint()*/
        !            96: int     needToDoadump = 0;              /* need to dump database */
        !            97: int     needToChkpt = 0;               /* need to checkpoint cache */
        !            98: int    needStatsDump = 0;              /* need to dump statistics */
        !            99: #ifdef ALLOW_UPDATES
        !           100: int     needToExit = 0;                 /* need to exit (may need to doadump
        !           101:                                         * first, if database has changed since
        !           102:                                         * it was last dumped/booted). Gets
        !           103:                                         * set by shutdown signal handler
        !           104:                                         *  (onintr)
        !           105:                                         */
        !           106: #endif ALLOW_UPDATES
        !           107: int    priming = 0;                    /* is cache being primed */
        !           108: 
        !           109: #ifdef SO_RCVBUF
        !           110: int    rbufsize = 8 * 1024;            /* UDP recive buffer size */
        !           111: #endif
        !           112: 
        !           113: struct qstream *streamq = QSTREAM_NULL; /* list of open streams */
        !           114: struct qdatagram *datagramq = QDATAGRAM_NULL; /* list of datagram interfaces */
        !           115: struct qdatagram *dqp, *sqp;
        !           116: struct sockaddr_in nsaddr;
        !           117: struct timeval tt;
        !           118: struct netinfo *nettab = NULL;
        !           119: struct netinfo *fnettab = NULL;
        !           120: struct netinfo *onettab = NULL;
        !           121: struct netinfo netloop;
        !           122: short  ns_port;
        !           123: struct sockaddr_in from_addr;          /* Source addr of last packet */
        !           124: int    from_len;                       /* Source addr size of last packet */
        !           125: time_t boottime, resettime;            /* Used by ns_stats */
        !           126: fd_set mask;                           /* select mask of open descriptors */
        !           127: 
        !           128: char           **Argv = NULL;          /* pointer to argument vector */
        !           129: char           *LastArg = NULL;        /* end of argv */
        !           130: 
        !           131: extern int errno;
        !           132: 
        !           133: #if defined(SYSV)
        !           134: getdtablesize()
        !           135: {
        !           136:        return(FD_SETSIZE);
        !           137: }
        !           138: #endif SYSV
        !           139: 
        !           140: main(argc, argv, envp)
        !           141:        int argc;
        !           142:        char *argv[], *envp[];
        !           143: {
        !           144:        register int n, udpcnt;
        !           145:        register char *arg;
        !           146:        register struct qstream *sp;
        !           147:        int vs;
        !           148:        int nfds;
        !           149:        int on = 1;
        !           150:        int rfd, size;
        !           151:        u_long lasttime, maxctime;
        !           152:        u_long nnn, nm;
        !           153:        char buf[BUFSIZ];
        !           154: 
        !           155:        fd_set tmpmask;
        !           156: 
        !           157:        struct timeval t, *tp;
        !           158:        struct qstream *candidate = QSTREAM_NULL;
        !           159:        struct ifconf ifc;
        !           160:        struct ifreq ifreq, *ifr;
        !           161:        struct netinfo *ntp;
        !           162:        struct netinfo *ntip;
        !           163:        struct netinfo *ontp;
        !           164:        struct netinfo *ontip;
        !           165:        extern int onintr(), maint_alarm(), reapchild(), setdumpflg(), onhup();
        !           166:        extern int setIncrDbgFlg(), setNoDbgFlg(), sigprof();
        !           167:        extern int setchkptflg(), setstatsflg();
        !           168:        extern struct qstream *sqadd();
        !           169:        extern struct qinfo *qhead; 
        !           170:        extern char Version[];
        !           171: 
        !           172:        ns_port = htons(NAMESERVER_PORT);
        !           173: 
        !           174:        /*
        !           175:        **  Save start and extent of argv for setproctitle.
        !           176:        */
        !           177: 
        !           178:        Argv = argv;
        !           179:        if (envp == 0 || *envp == 0)
        !           180:                envp = argv;
        !           181:        while (*envp)
        !           182:                envp++;
        !           183:        LastArg = envp[-1] + strlen(envp[-1]);
        !           184: 
        !           185:        (void) umask(022);
        !           186:        while (--argc > 0) {
        !           187:                arg = *++argv;
        !           188:                if (*arg == '-') {
        !           189:                        while (*++arg)
        !           190:                                switch (*arg) {
        !           191:                                case 'b':
        !           192:                                        if (--argc <= 0)
        !           193:                                                usage();
        !           194:                                        bootfile = *++argv;
        !           195:                                        break;
        !           196: 
        !           197:                                case 'd':
        !           198:                                        ++argv;
        !           199: 
        !           200:                                        if (*argv != 0) {
        !           201:                                            if (**argv == '-') {
        !           202:                                                argv--;
        !           203:                                                break;
        !           204:                                            }
        !           205:                                            debug = atoi(*argv);
        !           206:                                            --argc;
        !           207:                                        }
        !           208:                                        if (debug <= 0)
        !           209:                                                debug = 1;
        !           210:                                        setdebug(1);
        !           211:                                        break;
        !           212: 
        !           213:                                case 'p':
        !           214:                                        if (--argc <= 0)
        !           215:                                                usage();
        !           216:                                        ns_port = htons((u_short)atoi(*++argv));
        !           217:                                        break;
        !           218: 
        !           219:                                default:
        !           220:                                        usage();
        !           221:                                }
        !           222:                } else
        !           223:                        bootfile = *argv;
        !           224:        }
        !           225: 
        !           226:        if (!debug) {
        !           227:                if (fork())
        !           228:                        exit(0);
        !           229:                for (n = getdtablesize() - 1; n >= 0; n--)
        !           230:                        (void) close(n);
        !           231:                (void) open("/dev/null", O_RDONLY);
        !           232:                (void) dup2(0, 1);
        !           233:                (void) dup2(0, 2);
        !           234:                n = open("/dev/tty", O_RDWR);
        !           235:                if (n > 0) {
        !           236: #ifndef SYSV
        !           237:                        (void) ioctl(n, TIOCNOTTY, (char *)NULL);
        !           238: #else
        !           239:                        setpgrp();
        !           240: #endif
        !           241:                        (void) close(n);
        !           242:                }
        !           243:        }
        !           244: #ifdef DEBUG
        !           245:        else {
        !           246:                fprintf(ddt,"Debug turned ON, Level %d\n",debug);
        !           247:                fprintf(ddt,"Version = %s\t",Version);
        !           248:                fprintf(ddt,"bootfile = %s\n",bootfile);
        !           249:        }               
        !           250: #endif
        !           251: 
        !           252: #ifdef LOG_DAEMON
        !           253:        openlog("named", LOG_PID|LOG_CONS|LOG_NDELAY, LOG_DAEMON);
        !           254: #else
        !           255:        openlog("named", LOG_PID);
        !           256: #endif
        !           257: 
        !           258:        /* tuck my process id away */
        !           259:        fp = fopen(PidFile, "w");
        !           260:        if (fp != NULL) {
        !           261:                fprintf(fp, "%d\n", getpid());
        !           262:                (void) fclose(fp);
        !           263:        }
        !           264:        syslog(LOG_NOTICE, "restarted\n");
        !           265: 
        !           266:        _res.options &= ~(RES_DEFNAMES | RES_DNSRCH | RES_RECURSE);
        !           267: 
        !           268:        nsaddr.sin_family = AF_INET;
        !           269:        nsaddr.sin_addr.s_addr = INADDR_ANY;
        !           270:        nsaddr.sin_port = ns_port;
        !           271:        /*
        !           272:        ** Initialize and load database.
        !           273:        */
        !           274:        gettime(&tt);
        !           275:        buildservicelist();
        !           276:        buildprotolist();
        !           277:        ns_init(bootfile);
        !           278:        time(&boottime);
        !           279:        resettime = boottime;
        !           280: 
        !           281:        (void) signal(SIGALRM, maint_alarm);
        !           282:        (void) signal(SIGHUP, onhup);
        !           283: #if defined(SYSV)
        !           284:        (void) signal(SIGCLD, reapchild);
        !           285: #else
        !           286:        (void) signal(SIGCHLD, reapchild);
        !           287: #endif SYSV
        !           288:        (void) signal(SIGPIPE, SIG_IGN);
        !           289:        (void) signal(SIGSYS, sigprof);
        !           290:        (void) signal(SIGINT, setdumpflg);
        !           291:        (void) signal(SIGQUIT, setchkptflg);
        !           292:        (void) signal(SIGIOT, setstatsflg);
        !           293: 
        !           294: #ifdef ALLOW_UPDATES
        !           295:         /* Catch SIGTERM so we can dump the database upon shutdown if it
        !           296:            has changed since it was last dumped/booted */
        !           297:         (void) signal(SIGTERM, onintr);
        !           298: #endif ALLOW_UPDATES
        !           299: 
        !           300: #if defined(SIGUSR1) && defined(SIGUSR2)
        !           301:        (void) signal(SIGUSR1, setIncrDbgFlg);
        !           302:        (void) signal(SIGUSR2, setNoDbgFlg);
        !           303: #else  SIGUSR1&&SIGUSR2
        !           304:        (void) signal(SIGEMT, setIncrDbgFlg);
        !           305:        (void) signal(SIGFPE, setNoDbgFlg);
        !           306: #endif SIGUSR1&&SIGUSR2
        !           307: 
        !           308: #ifdef DEBUG
        !           309:        if (debug) {
        !           310:                fprintf(ddt,"database initialized\n");
        !           311:        }
        !           312: #endif
        !           313:        /*
        !           314:        ** Open stream port.
        !           315:        */
        !           316:        if ((vs = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        !           317:                syslog(LOG_ERR, "socket(SOCK_STREAM): %m");
        !           318:                exit(1);
        !           319:        }       
        !           320:        (void)setsockopt(vs, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
        !           321:        if (bind(vs, (struct sockaddr *)&nsaddr, sizeof(nsaddr))) {
        !           322:                syslog(LOG_ERR, "bind(vs, %s[%d]): %m",
        !           323:                        inet_ntoa(nsaddr.sin_addr), ntohs(nsaddr.sin_port));
        !           324:                exit(1);
        !           325:        }
        !           326:        ifc.ifc_len = sizeof(buf);
        !           327:        ifc.ifc_buf = buf;
        !           328:        if (ioctl(vs, SIOCGIFCONF, (char *)&ifc) < 0) {
        !           329:                syslog(LOG_ERR, "get interface configuration: %m");
        !           330:                exit(1);
        !           331:        }
        !           332:        n = ifc.ifc_len/sizeof(struct ifreq);
        !           333:        ntp = NULL;
        !           334:        for (ifr = ifc.ifc_req; n > 0; n--, ifr++) {
        !           335:                int dup_addr;
        !           336: 
        !           337:                if (ifr->ifr_addr.sa_family != AF_INET)
        !           338:                        continue;
        !           339:                ifreq = *ifr;
        !           340:                if (ioctl(vs, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
        !           341:                        syslog(LOG_ERR, "get interface flags: %m");
        !           342:                        continue;
        !           343:                }
        !           344:                if ((ifreq.ifr_flags & IFF_UP) == 0)
        !           345:                        continue;
        !           346:                if (ioctl(vs, SIOCGIFADDR, (char *)&ifreq) < 0) {
        !           347:                        syslog(LOG_ERR, "get interface addr: %m");
        !           348:                        continue;
        !           349:                }
        !           350:                /* build datagram queue */
        !           351:                if ((dqp = (struct qdatagram *)calloc(1,
        !           352:                    sizeof(struct qdatagram))) == NULL) {
        !           353: #ifdef DEBUG
        !           354:                        if (debug >= 5)
        !           355:                                fprintf(ddt,"main: malloc error\n");
        !           356: #endif
        !           357:                        syslog(LOG_ERR, "main: Out Of Memory");
        !           358:                        exit(12);
        !           359:                }
        !           360:                dqp->dq_next = datagramq;
        !           361:                dqp->dq_addr = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr;
        !           362:                /* 
        !           363:                 * look for an already existing source interface address.  If
        !           364:                 * the machine has multiple point to point interfaces, then 
        !           365:                 * the local address may appear more than once.
        !           366:                 */                
        !           367:                dup_addr = 0;
        !           368:                for (sqp=datagramq; sqp != NULL; sqp = sqp->dq_next)
        !           369:                  if (dqp->dq_addr.s_addr == sqp->dq_addr.s_addr) {
        !           370:                    dup_addr = 1;
        !           371:                    break;
        !           372:                  }
        !           373:                if (!dup_addr)
        !           374:                      datagramq = dqp;
        !           375:                else {
        !           376: #ifdef DEBUG
        !           377:                  if (debug)
        !           378:                    fprintf(ddt, "main: dup interface address %s on %s\n",
        !           379:                            inet_ntoa(dqp->dq_addr), ifreq.ifr_name);
        !           380: #endif               
        !           381:                  free((char *) dqp);
        !           382:                }
        !           383: 
        !           384:                if (ntp == NULL)
        !           385:                        ntp = (struct netinfo *)malloc(sizeof(struct netinfo));
        !           386:                ntp->my_addr = 
        !           387:                    ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr;
        !           388: #ifdef SIOCGIFNETMASK
        !           389:                if (ioctl(vs, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
        !           390:                    syslog(LOG_ERR, "get netmask: %m");
        !           391:                    continue;
        !           392:                }
        !           393:                ntp->mask = ((struct sockaddr_in *)
        !           394:                    &ifreq.ifr_addr)->sin_addr.s_addr;
        !           395: #else
        !           396:                /* 4.2 does not support subnets */
        !           397:                ntp->mask = net_mask(ntp->my_addr);
        !           398: #endif
        !           399:                if (ioctl(vs, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
        !           400:                        syslog(LOG_ERR, "get interface flags: %m");
        !           401:                        continue;
        !           402:                }
        !           403: #ifdef IFF_LOOPBACK
        !           404:                if ((ifreq.ifr_flags & IFF_LOOPBACK))
        !           405: #else
        !           406:                /* test against 127.0.0.1 (yuck!!) */
        !           407:                if (ntp->my_addr.s_addr == htonl(0x7F000001))
        !           408: #endif
        !           409:                {
        !           410:                    netloop.my_addr = ntp->my_addr;
        !           411:                    netloop.mask = 0xffffffff;
        !           412:                    netloop.net = ntp->my_addr.s_addr;
        !           413:                    netloop.next = NULL;
        !           414: #ifdef DEBUG
        !           415:                    if (debug) 
        !           416:                        fprintf(ddt,"loopback address: x%lx\n",
        !           417:                                netloop.my_addr.s_addr);
        !           418: #endif DEBUG
        !           419:                    continue;
        !           420:                } else if ((ifreq.ifr_flags & IFF_POINTOPOINT)) {
        !           421:                        if (ioctl(vs, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {
        !           422:                            syslog(LOG_ERR, "get dst addr: %m");
        !           423:                            continue;
        !           424:                        }
        !           425:                        ntp->mask = 0xffffffff;
        !           426:                        ntp->net = ((struct sockaddr_in *)
        !           427:                            &ifreq.ifr_addr)->sin_addr.s_addr;
        !           428:                } else {
        !           429:                        ntp->net = ntp->mask & ntp->my_addr.s_addr;
        !           430:                }
        !           431:                ntp->next = NULL;
        !           432:                if (nettab == NULL)
        !           433:                        nettab = ntip = ntp;
        !           434:                else {
        !           435:                        ntip->next = ntp;
        !           436:                        ntip = ntp;
        !           437:                }
        !           438:                ntp = NULL;
        !           439:        }
        !           440:        if (ntp)
        !           441:                (void) free((char *)ntp);
        !           442: 
        !           443:        /*
        !           444:         * Create separate qdatagram structure for socket
        !           445:         * wildcard address.
        !           446:         */
        !           447:        if ((dqp = (struct qdatagram *)calloc(1, sizeof(struct qdatagram)))
        !           448:             == NULL) {
        !           449: #ifdef DEBUG
        !           450:                if (debug >= 5)
        !           451:                        fprintf(ddt,"main: malloc error\n");
        !           452: #endif
        !           453:                syslog(LOG_ERR, "main: Out Of Memory");
        !           454:                exit(12);
        !           455:        }
        !           456:        dqp->dq_next = datagramq;
        !           457:        datagramq = dqp;
        !           458:        dqp->dq_addr.s_addr = INADDR_ANY;
        !           459: 
        !           460:        /*
        !           461:         * Compute other networks for sorting based on network configuration
        !           462:         */
        !           463:        ontp = NULL;
        !           464:        for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
        !           465:                nm = net_mask(ntp->my_addr);
        !           466:                if (nm != ntp->mask) {
        !           467:                        nnn = ntp->my_addr.s_addr & nm;
        !           468:                        for (ontp=onettab; ontp != NULL; ontp=ontp->next) {
        !           469:                                if ((ontp->net == nnn) &&
        !           470:                                    (ontp->mask == nm))
        !           471:                                        goto outerloop;
        !           472:                                ontip = ontp;
        !           473:                        }
        !           474:                        ontp = (struct netinfo *) 
        !           475:                                malloc(sizeof(struct netinfo));
        !           476:                        ontp->net = nnn;
        !           477:                        ontp->mask = nm;
        !           478:                        ontp->my_addr = ntp->my_addr;
        !           479:                        ontp->next = NULL;
        !           480:                        if (onettab == NULL )
        !           481:                                onettab = ontp;
        !           482:                        else
        !           483:                                ontip->next = ontp;
        !           484:                }
        !           485: outerloop:
        !           486:                ;
        !           487:        }
        !           488:        /*
        !           489:         * Merge sort list from network configuration
        !           490:         * with list we computed from network configuration
        !           491:         */
        !           492:        for (ntp = nettab; ntp != NULL; ntp = ntp->next){
        !           493:                if (ntp->next == NULL) {
        !           494:                        ntp->next = onettab;
        !           495:                        break;
        !           496:                }
        !           497:        }
        !           498:        /* 
        !           499:         * Merge sort list from boot file with list from 
        !           500:         * network configuration
        !           501:         */
        !           502:        for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
        !           503:            for (ontp = fnettab; ontp != NULL; ontp = ontp->next) {
        !           504:                if ((ontp->mask == ntp->mask) && (ontp->net == ntp->net)) {
        !           505:                    if( fnettab == ontp )  {
        !           506:                        ontip = ontp;
        !           507:                        fnettab = ontp->next;
        !           508:                        free((char *)ontip);
        !           509:                        break;
        !           510:                    } else {
        !           511:                        for (ontip = fnettab; ontip != NULL;ontip = ontip->next)
        !           512:                           if (ontip->next == ontp) break;
        !           513:                        ontip->next = ontp->next;
        !           514:                        free((char *)ontp);
        !           515:                        ontp = ontip;
        !           516:                        break;
        !           517:                    }
        !           518:                }
        !           519:            }
        !           520:            if (ntp->next == NULL)
        !           521:                break;
        !           522:        }
        !           523:        ntp->next = fnettab;
        !           524: #ifdef DEBUG
        !           525:        if (debug)
        !           526:                for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
        !           527:                        fprintf(ddt,"net x%lx mask x%lx", ntp->net, ntp->mask);
        !           528:                        fprintf(ddt," my_addr x%lx", ntp->my_addr.s_addr);
        !           529:                        fprintf(ddt," %s\n", inet_ntoa(ntp->my_addr));
        !           530:                }
        !           531: #endif DEBUG
        !           532:        (void) listen(vs, 5);
        !           533: 
        !           534:        /*
        !           535:         * Open datagram ports for each interface
        !           536:         * (the first is un-addressed datagram port).
        !           537:         */
        !           538:        for (dqp = datagramq; dqp != QDATAGRAM_NULL; dqp = dqp->dq_next) {
        !           539:                nsaddr.sin_addr = dqp->dq_addr;
        !           540:                if ((dqp->dq_dfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        !           541:                        syslog(LOG_ERR, "socket(SOCK_DGRAM): %m");
        !           542:                        exit(1);
        !           543:                }       
        !           544: #ifdef DEBUG
        !           545:                if (debug)
        !           546:                        fprintf(ddt,"dqp->dq_addr %s d_dfd %d\n",
        !           547:                            inet_ntoa(dqp->dq_addr), dqp->dq_dfd);
        !           548: #endif DEBUG
        !           549:                (void)setsockopt(dqp->dq_dfd, SOL_SOCKET, SO_REUSEADDR,
        !           550:                    (char *)&on, sizeof(on));
        !           551: #ifdef SO_RCVBUF
        !           552:                (void)setsockopt(dqp->dq_dfd, SOL_SOCKET, SO_RCVBUF,
        !           553:                    (char *)&rbufsize, sizeof(rbufsize));
        !           554: #endif SO_RCVBUF
        !           555:                (void) fcntl(dqp->dq_dfd, F_SETFL, FNDELAY);
        !           556: /*
        !           557:  *   NOTE: Some versions of SunOS have problems with the following
        !           558:  *   call to bind.  Bind still seems to function on these systems
        !           559:  *   if you comment out the exit inside the if.  This may cause
        !           560:  *   Suns with multiple interfaces to reply strangely.
        !           561:  */
        !           562:                if (bind(dqp->dq_dfd, (struct sockaddr *)&nsaddr, sizeof(nsaddr))) {
        !           563:                        syslog(LOG_ERR, "bind(dfd %d, %s[%d]): %m",
        !           564:                                dqp->dq_dfd, inet_ntoa(nsaddr.sin_addr),
        !           565:                                ntohs(nsaddr.sin_port));
        !           566: #if !defined(sun)
        !           567:                        exit(1);
        !           568: #endif
        !           569:                }
        !           570:        }
        !           571:        ds = datagramq->dq_dfd;
        !           572: 
        !           573:        t.tv_usec = 0;
        !           574: 
        !           575: #ifdef DEBUG
        !           576:        if (debug)
        !           577:                fprintf(ddt,"Ready to answer queries.\n");
        !           578: #endif
        !           579:        prime_cache();
        !           580:        nfds = getdtablesize();       /* get the number of file descriptors */
        !           581:        if (nfds > FD_SETSIZE) {
        !           582:                nfds = FD_SETSIZE;      /* Bulletproofing */
        !           583:                syslog(LOG_ERR, "Return from getdtablesize() > FD_SETSIZE");
        !           584: #ifdef DEBUG
        !           585:                if (debug)
        !           586:                      fprintf(ddt,"Return from getdtablesize() > FD_SETSIZE\n");
        !           587: #endif
        !           588:        }
        !           589:        FD_ZERO(&mask);
        !           590:        FD_SET(vs, &mask);
        !           591:        FD_SET(ds, &mask);
        !           592:        for (dqp = datagramq; dqp != QDATAGRAM_NULL; dqp = dqp->dq_next)
        !           593:                FD_SET(dqp->dq_dfd, &mask);
        !           594:        for (;;) {
        !           595: #ifdef ALLOW_UPDATES
        !           596:                 if (needToExit) {
        !           597:                        struct zoneinfo *zp;
        !           598:                        sigblock(~0);   /*
        !           599:                                         * Block all blockable signals
        !           600:                                         * to ensure a consistant
        !           601:                                         * state during final dump
        !           602:                                         */
        !           603: #ifdef DEBUG
        !           604:                        if (debug)
        !           605:                                fprintf(ddt, "Received shutdown signal\n");                     
        !           606: #endif DEBUG
        !           607:                        for (zp = zones; zp < &zones[nzones]; zp++) {
        !           608:                                if (zp->hasChanged)
        !           609:                                        zonedump(zp);
        !           610:                         }
        !           611:                         exit(0);
        !           612:                 }        
        !           613: #endif ALLOW_UPDATES
        !           614:                if(needreload) {
        !           615:                        needreload = 0;
        !           616:                        db_reload();
        !           617:                }
        !           618: #ifdef STATS
        !           619:                if(needStatsDump) {
        !           620:                        needStatsDump = 0;
        !           621:                        ns_stats();
        !           622:                }
        !           623: #endif STATS
        !           624:                if(needmaint) {
        !           625:                         needmaint = 0;
        !           626:                         ns_maint();
        !           627:                 }
        !           628:                if(needToChkpt) {
        !           629:                         needToChkpt = 0;
        !           630:                         doachkpt();
        !           631:                }
        !           632:                 if(needToDoadump) {
        !           633:                         needToDoadump = 0;
        !           634:                         doadump();
        !           635:                 }
        !           636:                /*
        !           637:                ** Wait until a query arrives
        !           638:                */
        !           639:                if (retryqp != NULL) {
        !           640:                        gettime(&tt);
        !           641:                        t.tv_sec = (long) retryqp->q_time - tt.tv_sec;
        !           642:                        if (t.tv_sec <= 0) {
        !           643:                                retry(retryqp);
        !           644:                                continue;
        !           645:                        }
        !           646:                        tp = &t;
        !           647:                } else
        !           648:                        tp = NULL;
        !           649:                tmpmask = mask;
        !           650:                n = select(nfds, &tmpmask, (fd_set *)NULL, (fd_set *)NULL, tp);
        !           651:                if (n < 0) {
        !           652:                        if (errno == EINTR)
        !           653:                                continue;
        !           654:                        syslog(LOG_ERR, "select: %m");
        !           655: #ifdef DEBUG
        !           656:                        if (debug)
        !           657:                                fprintf(ddt,"select error\n");
        !           658: #endif
        !           659:                        ;
        !           660:                }
        !           661:                if (n == 0)
        !           662:                        continue;
        !           663: 
        !           664:                for (dqp = datagramq; dqp != QDATAGRAM_NULL;
        !           665:                    dqp = dqp->dq_next) {
        !           666:                    if (FD_ISSET(dqp->dq_dfd, &tmpmask))
        !           667:                        for(udpcnt = 0; udpcnt < 25; udpcnt++) {
        !           668:                            from_len = sizeof(from_addr);
        !           669:                            if ((n = recvfrom(dqp->dq_dfd, buf, sizeof(buf), 0,
        !           670:                                (struct sockaddr *)&from_addr, &from_len)) < 0)
        !           671:                            {
        !           672:                                if ((n == -1) && (errno == EWOULDBLOCK))
        !           673:                                        break;
        !           674:                                syslog(LOG_WARNING, "recvfrom: %m");
        !           675:                                break;
        !           676:                            }
        !           677: #ifdef STATS
        !           678:                            stats[S_INPKTS].cnt++;
        !           679: #endif
        !           680: #ifdef DEBUG
        !           681:                            if (debug)
        !           682:                                fprintf(ddt,
        !           683:                                  "\ndatagram from %s port %d, fd %d, len %d\n",
        !           684:                                    inet_ntoa(from_addr.sin_addr),
        !           685:                                    ntohs(from_addr.sin_port), ds, n);
        !           686:                            if (debug >= 10)
        !           687:                                fp_query(buf, ddt);
        !           688: #endif
        !           689:                            /*
        !           690:                             * Consult database to get the answer.
        !           691:                             */
        !           692:                            gettime(&tt);
        !           693:                            ns_req(buf, n, PACKETSZ, QSTREAM_NULL, &from_addr,
        !           694:                                    dqp->dq_dfd);
        !           695:                        }
        !           696:                }
        !           697:                /*
        !           698:                ** Process stream connection
        !           699:                */
        !           700:                if (FD_ISSET(vs, &tmpmask)) {
        !           701:                        from_len = sizeof(from_addr);
        !           702:                        rfd = accept(vs, (struct sockaddr *)&from_addr, &from_len);
        !           703:                        gettime(&tt);
        !           704:                        if (rfd < 0 && errno == EMFILE && streamq != NULL) {
        !           705:                                maxctime = 0;
        !           706:                                candidate = QSTREAM_NULL;
        !           707:                                for (sp = streamq; sp != QSTREAM_NULL;
        !           708:                                   sp = sp->s_next) {
        !           709:                                        if (sp->s_refcnt != 0)
        !           710:                                            continue;
        !           711:                                        lasttime = tt.tv_sec - sp->s_time;
        !           712:                                        if (lasttime >= 900)
        !           713:                                            sqrm(sp, &mask);
        !           714:                                        else if (lasttime > maxctime) {
        !           715:                                            candidate = sp;
        !           716:                                            maxctime = lasttime;
        !           717:                                        }
        !           718:                                }
        !           719:                                rfd = accept(vs, (struct sockaddr *)&from_addr, &from_len);
        !           720:                                if ((rfd < 0) && (errno == EMFILE) &&
        !           721:                                    candidate != QSTREAM_NULL) {
        !           722:                                        sqrm(candidate, &mask);
        !           723:                                        rfd = accept(vs, (struct sockaddr *)&from_addr, &from_len);
        !           724:                                }
        !           725:                        }
        !           726:                        if (rfd < 0) {
        !           727:                                syslog(LOG_WARNING, "accept: %m");
        !           728:                                continue;
        !           729:                        }
        !           730:                        (void) fcntl(rfd, F_SETFL, FNDELAY);
        !           731:                        (void) setsockopt(rfd, SOL_SOCKET, SO_KEEPALIVE,
        !           732:                                (char *)&on, sizeof(on));
        !           733:                        if ((sp = sqadd()) == QSTREAM_NULL) {
        !           734:                                (void) close(rfd);
        !           735:                                continue;
        !           736:                        }
        !           737:                        sp->s_rfd = rfd;        /* stream file descriptor */
        !           738:                        sp->s_size = -1;        /* amount of data to receive */
        !           739:                        gettime(&tt);
        !           740:                        sp->s_time = tt.tv_sec; /* last transaction time */
        !           741:                        sp->s_from = from_addr; /* address to respond to */
        !           742:                        sp->s_bufsize = 0;
        !           743:                        sp->s_bufp = (char *)&sp->s_tempsize;
        !           744:                        sp->s_refcnt = 0;
        !           745:                        FD_SET(rfd, &mask);
        !           746:                        FD_SET(rfd, &tmpmask);
        !           747: #ifdef DEBUG
        !           748:                        if (debug) {
        !           749:                                fprintf(ddt,
        !           750:                                   "\nTCP connection from %s port %d (fd %d)\n",
        !           751:                                        inet_ntoa(sp->s_from.sin_addr),
        !           752:                                        ntohs(sp->s_from.sin_port), rfd);
        !           753:                        }
        !           754: #endif
        !           755:                }
        !           756: #ifdef DEBUG
        !           757:                if (debug > 2 && streamq)
        !           758:                        fprintf(ddt,"streamq  = x%x\n",streamq);
        !           759: #endif
        !           760:                if (streamq != NULL) {
        !           761:                        for (sp = streamq; sp != QSTREAM_NULL; sp = sp->s_next)
        !           762:                            if (FD_ISSET(sp->s_rfd, &tmpmask)) {
        !           763: #ifdef DEBUG
        !           764:                                if (debug > 5) {
        !           765:                                    fprintf(ddt,
        !           766:                                        "sp x%x rfd %d size %d time %d ",
        !           767:                                        sp, sp->s_rfd, sp->s_size,
        !           768:                                        sp->s_time );
        !           769:                                    fprintf(ddt," next x%x \n", sp->s_next );
        !           770:                                    fprintf(ddt,"\tbufsize %d",sp->s_bufsize);
        !           771:                                    fprintf(ddt," buf x%x ",sp->s_buf);
        !           772:                                    fprintf(ddt," bufp x%x\n",sp->s_bufp);
        !           773:                                }
        !           774: #endif DEBUG
        !           775:                            if (sp->s_size < 0) {
        !           776:                                size = sizeof(u_short) -
        !           777:                                   (sp->s_bufp - (char *)&sp->s_tempsize);
        !           778:                                while (size > 0 &&
        !           779:                                   (n = read(sp->s_rfd, sp->s_bufp, size)) > 0){
        !           780:                                            sp->s_bufp += n;
        !           781:                                            size -= n;
        !           782:                                }
        !           783:                                if ((n == -1) && (errno == EWOULDBLOCK))
        !           784:                                            continue;
        !           785:                                if (n <= 0) {
        !           786:                                            sp->s_refcnt = 0;
        !           787:                                            sqrm(sp, &mask);
        !           788:                                            continue;
        !           789:                                }
        !           790:                                if ((sp->s_bufp - (char *)&sp->s_tempsize) ==
        !           791:                                        sizeof(u_short)) {
        !           792:                                        sp->s_size = htons(sp->s_tempsize);
        !           793:                                        if (sp->s_bufsize == 0) {
        !           794:                                            if ( (sp->s_buf = malloc(BUFSIZ))
        !           795:                                                == NULL) {
        !           796:                                                    sp->s_buf = buf;
        !           797:                                                    sp->s_size  = sizeof(buf);
        !           798:                                            } else {
        !           799:                                                    sp->s_bufsize = BUFSIZ;
        !           800:                                            }
        !           801:                                        }
        !           802:                                        if (sp->s_size > sp->s_bufsize &&
        !           803:                                          sp->s_bufsize != 0) {
        !           804:                                            if ((sp->s_buf = realloc(
        !           805:                                                (char *)sp->s_buf,
        !           806:                                                (unsigned)sp->s_size)) == NULL){
        !           807:                                                    sp->s_buf = buf;
        !           808:                                                    sp->s_bufsize = 0;
        !           809:                                                    sp->s_size  = sizeof(buf);
        !           810:                                           } else {
        !           811:                                                    sp->s_bufsize = sp->s_size;
        !           812:                                           }
        !           813:                                        }
        !           814:                                        sp->s_bufp = sp->s_buf; 
        !           815:                                    }
        !           816:                            }
        !           817:                            gettime(&tt);
        !           818:                            sp->s_time = tt.tv_sec;
        !           819:                            while (sp->s_size > 0 &&
        !           820:                              (n = read(sp->s_rfd, sp->s_bufp, sp->s_size)) > 0)
        !           821:                            {
        !           822:                                    sp->s_bufp += n;
        !           823:                                    sp->s_size -= n;
        !           824:                            }
        !           825:                            /*
        !           826:                             * we don't have enough memory for the query.
        !           827:                             * if we have a query id, then we will send an
        !           828:                             * error back to the user.
        !           829:                             */
        !           830:                            if (sp->s_bufsize == 0 &&
        !           831:                                (sp->s_bufp - sp->s_buf > sizeof(u_short))) {
        !           832:                                    HEADER *hp;
        !           833: 
        !           834:                                    hp = (HEADER *)sp->s_buf;
        !           835:                                    hp->qr = 1;
        !           836:                                    hp->ra = 1;
        !           837:                                    hp->ancount = 0;
        !           838:                                    hp->qdcount = 0;
        !           839:                                    hp->nscount = 0;
        !           840:                                    hp->arcount = 0;
        !           841:                                    hp->rcode = SERVFAIL;
        !           842:                                    (void) writemsg(sp->s_rfd, sp->s_buf,
        !           843:                                        sizeof(HEADER));
        !           844:                                    continue;
        !           845:                            }
        !           846:                            if ((n == -1) && (errno == EWOULDBLOCK))
        !           847:                                    continue;
        !           848:                            if (n <= 0) {
        !           849:                                    sp->s_refcnt = 0;
        !           850:                                    sqrm(sp, &mask);
        !           851:                                    continue;
        !           852:                            }
        !           853:                            /*
        !           854:                             * Consult database to get the answer.
        !           855:                             */
        !           856:                            if (sp->s_size == 0) {
        !           857:                                    sp->s_refcnt++;
        !           858:                                    ns_req(sp->s_buf,
        !           859:                                        sp->s_bufp - sp->s_buf,
        !           860:                                        sp->s_bufsize, sp,
        !           861:                                        &sp->s_from, -1);
        !           862:                                    sp->s_bufp = (char *)&sp->s_tempsize;
        !           863:                                    sp->s_size = -1;
        !           864:                                    continue;
        !           865:                            }
        !           866:                    }
        !           867:                }
        !           868:        }
        !           869:        /* NOTREACHED */
        !           870: }
        !           871: 
        !           872: usage()
        !           873: {
        !           874:        fprintf(stderr, "Usage: named [-d #] [-p port] [{-b} bootfile]\n");
        !           875:        exit(1);
        !           876: }
        !           877: 
        !           878: /*
        !           879: ** Set flag saying to reload database upon receiving SIGHUP.
        !           880: ** Must make sure that someone isn't walking through a data
        !           881: ** structure at the time.
        !           882: */
        !           883: 
        !           884: onhup()
        !           885: {
        !           886: #if defined(SYSV)
        !           887:        (void)signal(SIGHUP, onhup);
        !           888: #endif SYSV
        !           889:        needreload = 1;
        !           890: }
        !           891: 
        !           892: /*
        !           893: ** Set flag saying to call ns_maint()
        !           894: ** Must make sure that someone isn't walking through a data
        !           895: ** structure at the time.
        !           896: */
        !           897: 
        !           898: maint_alarm()
        !           899: {
        !           900: #if defined(SYSV)
        !           901:        (void)signal(SIGALRM, maint_alarm);
        !           902: #endif SYSV
        !           903:        needmaint = 1;
        !           904: }
        !           905: 
        !           906: #ifdef ALLOW_UPDATES
        !           907: /*
        !           908:  * Signal handler to schedule shutdown.  Just set flag, to ensure a consistent
        !           909:  * state during dump.
        !           910:  */
        !           911: onintr()
        !           912: {
        !           913:         needToExit = 1;
        !           914: }
        !           915: #endif ALLOW_UPDATES
        !           916: 
        !           917: /*
        !           918:  * Signal handler to schedule a data base dump.  Do this instead of dumping the
        !           919:  * data base immediately, to avoid seeing it in a possibly inconsistent state
        !           920:  * (due to updates), and to avoid long disk I/O delays at signal-handler
        !           921:  * level
        !           922:  */
        !           923: int setdumpflg()
        !           924: {
        !           925: #if defined(SYSV)
        !           926:        (void)signal(SIGINT, setdumpflg);
        !           927: #endif SYSV
        !           928:         needToDoadump = 1;
        !           929: }
        !           930: 
        !           931: /*
        !           932: ** Set flag saying to read was interrupted
        !           933: ** used for a read timer
        !           934: */
        !           935: 
        !           936: read_alarm()
        !           937: {
        !           938:        extern int read_interrupted;
        !           939:        read_interrupted = 1;
        !           940: }
        !           941: 
        !           942: reapchild()
        !           943: {
        !           944: #if defined(SYSV)
        !           945:        (void)wait(0);
        !           946:        (void)signal(SIGCLD, reapchild);
        !           947: #else
        !           948:        union wait status;
        !           949: 
        !           950:        while ((wait3(&status, WNOHANG, (struct rusage *)NULL)) > 0)
        !           951:                ;
        !           952: #endif SYSV
        !           953: }
        !           954: 
        !           955: /*
        !           956: ** Turn on or off debuging by open or closeing the debug file
        !           957: */
        !           958: 
        !           959: setdebug(code)
        !           960: int code;
        !           961: {
        !           962: #if defined(lint) && !defined(DEBUG)
        !           963:        code = code;
        !           964: #endif
        !           965: #ifdef DEBUG
        !           966: 
        !           967:        if (code) {
        !           968:                ddt = freopen(debugfile, "w+", stderr);
        !           969:                if ( ddt == NULL)
        !           970:                        syslog(LOG_WARNING, "can't open debug file: %m");
        !           971:                else {
        !           972: #if defined(SYSV)
        !           973:                        setvbuf(ddt, NULL, _IOLBF, BUFSIZ);
        !           974: #else
        !           975:                        setlinebuf(ddt);
        !           976: #endif
        !           977:                        (void) fcntl(fileno(ddt), F_SETFL, FAPPEND);
        !           978:                }
        !           979:        }
        !           980:        else {
        !           981:                if (ddt) {
        !           982:                        fprintf(ddt,"Debug turned OFF, Level %d\n",debug);
        !           983:                        (void) fclose(ddt);
        !           984:                }
        !           985:                debug = 0;
        !           986:        }
        !           987: #endif
        !           988: }
        !           989: 
        !           990: /*
        !           991: ** Catch a special signal and set debug level.
        !           992: **
        !           993: **  If debuging is off then turn on debuging else increment the level.
        !           994: **
        !           995: ** Handy for looking in on long running name servers.
        !           996: */
        !           997: 
        !           998: setIncrDbgFlg()
        !           999: {
        !          1000: #if defined(SYSV)
        !          1001:        (void)signal(SIGUSR1, setIncrDbgFlg);
        !          1002: #endif SYSV
        !          1003: #ifdef DEBUG
        !          1004:        if (debug == 0) {
        !          1005:                debug++;
        !          1006:                setdebug(1);
        !          1007:        }
        !          1008:        else {
        !          1009:                debug++;
        !          1010:        }
        !          1011:        fprintf(ddt,"Debug turned ON, Level %d\n",debug);
        !          1012: #endif
        !          1013: }
        !          1014: 
        !          1015: /*
        !          1016: ** Catch a special signal to turn off debugging
        !          1017: */
        !          1018: 
        !          1019: setNoDbgFlg()
        !          1020: {
        !          1021: #if defined(SYSV)
        !          1022:        (void)signal(SIGUSR2, setNoDbgFlg);
        !          1023: #endif SYSV
        !          1024:        setdebug(0);
        !          1025: }
        !          1026: 
        !          1027: /*
        !          1028: ** Set flag for statistics dump
        !          1029: */
        !          1030: setstatsflg()
        !          1031: {
        !          1032: #if defined(SYSV)
        !          1033:        (void)signal(SIGIOT, setstatsflg);
        !          1034: #endif SYSV
        !          1035:        needStatsDump = 1;
        !          1036: }
        !          1037: 
        !          1038: int setchkptflg()
        !          1039: {
        !          1040: #if defined(SYSV)
        !          1041:        (void)signal(SIGQUIT, setchkptflg);
        !          1042: #endif SYSV
        !          1043:        needToChkpt = 1;
        !          1044: }
        !          1045: 
        !          1046: /*
        !          1047: ** Catch a special signal SIGSYS
        !          1048: **
        !          1049: **  this is setup to fork and exit to drop to /usr/tmp/gmon.out
        !          1050: **   and keep the server running
        !          1051: */
        !          1052: 
        !          1053: sigprof()
        !          1054: {
        !          1055: #if defined(SYSV)
        !          1056:        (void)signal(SIGSYS, sigprof);
        !          1057: #endif SYSV
        !          1058: #ifdef DEBUG
        !          1059:        if (debug)
        !          1060:                fprintf(ddt,"sigprof()\n");
        !          1061: #endif
        !          1062:        if ( fork() == 0)
        !          1063:        {
        !          1064:                (void) chdir("/usr/tmp");
        !          1065:                exit(1);
        !          1066:        }
        !          1067: }
        !          1068: 
        !          1069: /*
        !          1070: ** Routines for managing stream queue
        !          1071: */
        !          1072: 
        !          1073: struct qstream *
        !          1074: sqadd()
        !          1075: {
        !          1076:        register struct qstream *sqp;
        !          1077: 
        !          1078:        if ((sqp = (struct qstream *)calloc(1, sizeof(struct qstream)))
        !          1079:            == NULL ) {
        !          1080: #ifdef DEBUG
        !          1081:                if (debug >= 5)
        !          1082:                        fprintf(ddt,"sqadd: malloc error\n");
        !          1083: #endif
        !          1084:                syslog(LOG_ERR, "sqadd: Out Of Memory");
        !          1085:                return(QSTREAM_NULL);
        !          1086:        }
        !          1087: #ifdef DEBUG
        !          1088:        if (debug > 3)
        !          1089:                fprintf(ddt,"sqadd(x%x)\n", sqp);
        !          1090: #endif
        !          1091: 
        !          1092:        sqp->s_next = streamq;
        !          1093:        streamq = sqp;
        !          1094:        return(sqp);
        !          1095: }
        !          1096: 
        !          1097: sqrm(qp, mask)
        !          1098:        register struct qstream *qp;
        !          1099:        fd_set *mask;
        !          1100: {
        !          1101:        register struct qstream *qsp;
        !          1102: 
        !          1103: #ifdef DEBUG
        !          1104:        if (debug > 1) {
        !          1105:                fprintf(ddt,"sqrm(%#x, %d ) rfcnt=%d\n",
        !          1106:                    qp, qp->s_rfd, qp->s_refcnt);
        !          1107:        }
        !          1108: #endif
        !          1109:        if (qp->s_refcnt != 0)
        !          1110:                return;
        !          1111: 
        !          1112:        if (qp->s_bufsize != 0)
        !          1113:                (void) free(qp->s_buf);
        !          1114:        FD_CLR(qp->s_rfd, mask);
        !          1115:        (void) close(qp->s_rfd);
        !          1116:        if (qp == streamq) {
        !          1117:                streamq = qp->s_next;
        !          1118:        } else {
        !          1119:                for (qsp = streamq; qsp->s_next != qp; qsp = qsp->s_next)
        !          1120:                        ;
        !          1121:                qsp->s_next = qp->s_next;
        !          1122:        }
        !          1123:        (void)free((char *)qp);
        !          1124: }
        !          1125: 
        !          1126: sqflush()
        !          1127: {
        !          1128:        register struct qstream *sp, *spnext;
        !          1129: 
        !          1130:        for (sp = streamq; sp != QSTREAM_NULL; sp = spnext) {
        !          1131:                sp->s_refcnt = 0;
        !          1132:                spnext = sp->s_next;
        !          1133:                sqrm(sp, &mask);
        !          1134:        }
        !          1135: }
        !          1136: 
        !          1137: setproctitle(a, s)
        !          1138:        char *a;
        !          1139:        int s;
        !          1140: {
        !          1141:        int size;
        !          1142:        register char *cp;
        !          1143:        struct sockaddr_in sin;
        !          1144:        char buf[80];
        !          1145: 
        !          1146:        cp = Argv[0];
        !          1147:        size = sizeof(sin);
        !          1148:        if (getpeername(s, (struct sockaddr *)&sin, &size) == 0)
        !          1149:                (void) sprintf(buf, "-%s [%s]", a, inet_ntoa(sin.sin_addr));
        !          1150:        else {
        !          1151:                syslog(LOG_DEBUG, "getpeername: %m");
        !          1152:                (void) sprintf(buf, "-%s", a);
        !          1153:        }
        !          1154:        (void) strncpy(cp, buf, LastArg - cp);
        !          1155:        cp += strlen(cp);
        !          1156:        while (cp < LastArg)
        !          1157:                *cp++ = ' ';
        !          1158: }
        !          1159: 
        !          1160: net_mask(in)
        !          1161: struct in_addr in;
        !          1162: {
        !          1163:        register u_long i = ntohl(in.s_addr);
        !          1164: 
        !          1165:        if (IN_CLASSA(i))
        !          1166:                return (htonl(IN_CLASSA_NET));
        !          1167:        else if (IN_CLASSB(i))
        !          1168:                return (htonl(IN_CLASSB_NET));
        !          1169:        else
        !          1170:                return (htonl(IN_CLASSC_NET));
        !          1171: }
        !          1172: 
        !          1173: gettime(ttp)
        !          1174: struct timeval *ttp;
        !          1175: {
        !          1176:        if (gettimeofday(ttp, (struct timezone *)0) < 0)
        !          1177:                syslog(LOG_ERR, "gettimeofday failed: %m");
        !          1178:        return;
        !          1179: }

unix.superglobalmegacorp.com

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