home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.sbin / named / ns_main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-30  |  30.5 KB  |  1,303 lines

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