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