|
|
1.1 ! root 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.50 (Berkeley) 6/29/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 VOID onintr(), maint_alarm(), endxfer(); ! 178: extern VOID setdumpflg(), onhup(); ! 179: extern VOID setIncrDbgFlg(), setNoDbgFlg(), sigprof(); ! 180: extern VOID 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: VOID ! 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: VOID ! 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: VOID ! 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: VOID ! 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: VOID ! 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: VOID ! 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: VOID ! 1111: setstatsflg() ! 1112: { ! 1113: #if defined(SYSV) ! 1114: (void)signal(SIGIOT, setstatsflg); ! 1115: #endif SYSV ! 1116: needStatsDump = 1; ! 1117: } ! 1118: ! 1119: VOID ! 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: VOID ! 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.