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