1: /*
   2: ** identd.c                       A TCP/IP link identification protocol server
   3: **
   4: ** This program is in the public domain and may be used freely by anyone
   5: ** who wants to.
   6: **
   7: ** Last update: 7 Oct 1993
   8: **
   9: ** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
  10: */
  11: 
  12: #if !defined(__STDC__)
  13: #define void int
  14: #endif
  15: 
  16: #if defined(IRIX) || defined(SVR4) || defined(NeXT) || (defined(sco) && sco >= 42) || defined(_AIX4) || defined(__FreeBSD__) || defined(ultrix)
  17: #  define SIGRETURN_TYPE void
  18: #  define SIGRETURN_TYPE_IS_VOID
  19: #else
  20: #  define SIGRETURN_TYPE int
  21: #endif
  22: 
  23: #ifdef SVR4
  24: #  define STRNET
  25: #endif
  26: 
  27: #ifdef NeXT31
  28: #  include <libc.h>
  29: #endif
  30: 
  31: #ifdef sco
  32: #  define USE_SIGALARM
  33: #endif
  34: 
  35: #include <stdio.h>
  36: #include <ctype.h>
  37: #include <errno.h>
  38: #include <netdb.h>
  39: #include <signal.h>
  40: #include <fcntl.h>
  41: 
  42: #include <sys/types.h>
  43: #include <sys/param.h>
  44: #include <sys/ioctl.h>
  45: #include <sys/socket.h>
  46: #ifndef _AUX_SOURCE
  47: #  include <sys/file.h>
  48: #endif
  49: #include <sys/time.h>
  50: #include <sys/wait.h>
  51: 
  52: #include <pwd.h>
  53: #include <grp.h>
  54: 
  55: #include <netinet/in.h>
  56: 
  57: #ifndef HPUX7
  58: #  include <arpa/inet.h>
  59: #endif
  60: 
  61: #ifdef _AIX32
  62: # include <sys/select.h>
  63: #endif
  64: 
  65: #if defined(MIPS) || defined(BSD43)
  66: extern int errno;
  67: #endif
  68: 
  69: #if defined(SOLARIS) || defined(__FreeBSD__)
  70: #  include <unistd.h>
  71: #  include <stdlib.h>
  72: #  include <string.h>
  73: #endif
  74: 
  75: #include "identd.h"
  76: #include "error.h"
  77: #include "paths.h"
  78: #include "crypto.h"
  79: 
  80: /* Antique unixes do not have these things defined... */
  81: #ifndef FD_SETSIZE
  82: #  define FD_SETSIZE 256
  83: #endif
  84: 
  85: #ifndef FD_SET
  86: #  ifndef NFDBITS
  87: #    define NFDBITS     (sizeof(int) * NBBY)  /* bits per mask */
  88: #  endif
  89: #  define FD_SET(n, p)  ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
  90: #endif
  91: 
  92: #ifndef FD_ZERO
  93: #  define FD_ZERO(p)        bzero((char *)(p), sizeof(*(p)))
  94: #endif
  95: 
  96: 
  97: extern void *calloc();
  98: extern void *malloc();
  99: 
 100: 
 101: char *path_unix = NULL;
 102: char *path_kmem = NULL;
 103: 
 104: int verbose_flag = 0;
 105: int debug_flag   = 0;
 106: int syslog_flag  = 0;
 107: int multi_flag   = 0;
 108: int other_flag   = 0;
 109: int unknown_flag = 0;
 110: int noident_flag = 0;
 111: int crypto_flag  = 0;
 112: 
 113: int lport = 0;
 114: int fport = 0;
 115: 
 116: char *charset_name = NULL;
 117: char *indirect_host = NULL;
 118: char *indirect_password = NULL;
 119: 
 120: #ifdef ALLOW_FORMAT
 121:     int format_flag = 0;
 122:     char *format = "%u";
 123: #endif
 124: 
 125: static int child_pid;
 126: 
 127: #ifdef LOG_DAEMON
 128: static int syslog_facility = LOG_DAEMON;
 129: #endif
 130: 
 131: /*
 132: ** The structure passing convention for GCC is incompatible with
 133: ** Suns own C compiler, so we define our own inet_ntoa() function.
 134: ** (This should only affect GCC version 1 I think, a well, this works
 135: ** for version 2 also so why bother.. :-)
 136: */
 137: #if defined(__GNUC__) && defined(__sparc__) && !defined(NeXT)
 138: 
 139: #ifdef inet_ntoa
 140: #undef inet_ntoa
 141: #endif
 142: 
 143: char *inet_ntoa(ad)
 144:     struct in_addr ad;
 145: {
 146:     unsigned long int s_ad;
 147:     int a, b, c, d;
 148:     static char addr[20];
 149: 
 150:     s_ad = ad.s_addr;
 151:     d = s_ad % 256;
 152:     s_ad /= 256;
 153:     c = s_ad % 256;
 154:     s_ad /= 256;
 155:     b = s_ad % 256;
 156:     a = s_ad / 256;
 157:     sprintf(addr, "%d.%d.%d.%d", a, b, c, d);
 158: 
 159:     return addr;
 160: }
 161: #endif
 162: 
 163: static int comparemem(vp1, vp2, len)
 164:      void *vp1;
 165:      void *vp2;
 166:      int len;
 167: {
 168:     unsigned char *p1 = (unsigned char *) vp1;
 169:     unsigned char *p2 = (unsigned char *) vp2;
 170:     int c;
 171: 
 172:     while (len-- > 0)
 173:     if ((c = (int) *p1++ - (int) *p2++) != 0)
 174:         return c;
 175: 
 176:     return 0;
 177: }
 178: 
 179: /*
 180: ** Return the name of the connecting host, or the IP number as a string.
 181: */
 182: char *gethost(addr)
 183:     struct in_addr *addr;
 184: {
 185:     int i;
 186:     struct hostent *hp;
 187: 
 188: 
 189:     hp = gethostbyaddr((char *) addr, sizeof(struct in_addr), AF_INET);
 190:     if (hp)
 191:     {
 192:     /* Found a IP -> Name match, now try the reverse for security reasons */
 193:     hp = gethostbyname(hp->h_name);
 194:     if (hp)
 195: #ifdef h_addr
 196:         for (i = 0; hp->h_addr_list[i]; i++)
 197:         if (comparemem(hp->h_addr_list[i],
 198:                    (unsigned char *) addr,
 199:                    sizeof(struct in_addr)) == 0)
 200:             return (char *) hp->h_name;
 201: #else
 202:     if (comparemem(hp->h_addr, addr, sizeof(struct in_addr)) == 0)
 203:         return hp->h_name;
 204: #endif
 205:   }
 206: 
 207:   return inet_ntoa(*addr);
 208: }
 209: 
 210: #ifdef USE_SIGALARM
 211: /*
 212: ** Exit cleanly after our time's up.
 213: */
 214: static SIGRETURN_TYPE
 215: alarm_handler(int s)
 216: {
 217:     if (syslog_flag)
 218:     syslog(LOG_DEBUG, "SIGALRM triggered, exiting");
 219: 
 220:     exit(0);
 221: }
 222: #endif
 223: 
 224: 
 225: #if !defined(hpux) && !defined(__hpux) && !defined(SVR4) && \
 226:     !defined(_CRAY) && !defined(sco) && !defined(LINUX)
 227: /*
 228: ** This is used to clean up zombie child processes
 229: ** if the -w or -b options are used.
 230: */
 231: static SIGRETURN_TYPE
 232: child_handler()
 233: {
 234: #if defined(NeXT) || (defined(__sgi) && defined(__SVR3))
 235:     union wait status;
 236: #else
 237:     int status;
 238: #endif
 239: 
 240:     while (wait3(&status, WNOHANG, NULL) > 0)
 241:     ;
 242: 
 243: #ifndef SIGRETURN_TYPE_IS_VOID
 244:     return 0;
 245: #endif
 246: }
 247: #endif
 248: 
 249: 
 250: char *clearmem(vbp, len)
 251:      void *vbp;
 252:      int len;
 253: {
 254:     char *bp = (char *) vbp;
 255:     char *cp;
 256: 
 257:     cp = bp;
 258:     while (len-- > 0)
 259:     *cp++ = 0;
 260: 
 261:     return bp;
 262: }
 263: 
 264: 
 265: /*
 266: ** Main entry point into this daemon
 267: */
 268: int main(argc,argv)
 269:     int argc;
 270:     char *argv[];
 271: {
 272:     int i, len;
 273:     struct sockaddr_in sin;
 274:     struct in_addr laddr, faddr;
 275: #ifndef USE_SIGALARM
 276:     struct timeval tv;
 277: #endif
 278:     int one = 1;
 279: 
 280:     int background_flag = 0;
 281:     int timeout = 0;
 282:     char *portno = "113";
 283:     char *bind_address = NULL;
 284:     int set_uid = 0;
 285:     int set_gid = 0;
 286:     int inhibit_default_config = 0;
 287:     int opt_count = 0;      /* Count of option flags */
 288: 
 289: #ifdef __convex__
 290:     argc--;    /* get rid of extra argument passed by inetd */
 291: #endif
 292: 
 293: 
 294:     if (isatty(0))
 295:     background_flag = 1;
 296: 
 297:     /*
 298:     ** Prescan the arguments for "-f<config-file>" switches
 299:     */
 300:     inhibit_default_config = 0;
 301:     for (i = 1; i < argc && argv[i][0] == '-'; i++)
 302:     if (argv[i][1] == 'f')
 303:         inhibit_default_config = 1;
 304: 
 305:     /*
 306:     ** Parse the default config file - if it exists
 307:     */
 308:     if (!inhibit_default_config)
 309:     parse_config(NULL, 1);
 310: 
 311:     /*
 312:     ** Parse the command line arguments
 313:     */
 314:     for (i = 1; i < argc && argv[i][0] == '-'; i++) {
 315:     opt_count++;
 316:     switch (argv[i][1])
 317:     {
 318:       case 'b':    /* Start as standalone daemon */
 319:         background_flag = 1;
 320:         break;
 321: 
 322:       case 'w':    /* Start from Inetd, wait mode */
 323:         background_flag = 2;
 324:         break;
 325: 
 326:       case 'i':    /* Start from Inetd, nowait mode */
 327:         background_flag = 0;
 328:         break;
 329: 
 330:       case 't':
 331:         timeout = atoi(argv[i]+2);
 332:         break;
 333: 
 334:       case 'p':
 335:         portno = argv[i]+2;
 336:         break;
 337: 
 338:       case 'a':
 339:         bind_address = argv[i]+2;
 340:         break;
 341: 
 342:       case 'u':
 343:         if (isdigit(argv[i][2]))
 344:         set_uid = atoi(argv[i]+2);
 345:         else
 346:         {
 347:         struct passwd *pwd;
 348: 
 349:         pwd = getpwnam(argv[i]+2);
 350:         if (!pwd)
 351:             ERROR1("no such user (%s) for -u option", argv[i]+2);
 352:         else
 353:         {
 354:             set_uid = pwd->pw_uid;
 355:             set_gid = pwd->pw_gid;
 356:         }
 357:         }
 358:         break;
 359: 
 360:       case 'g':
 361:         if (isdigit(argv[i][2]))
 362:         set_gid = atoi(argv[i]+2);
 363:         else
 364:         {
 365:         struct group *grp;
 366: 
 367:         grp = getgrnam(argv[i]+2);
 368:         if (!grp)
 369:             ERROR1("no such group (%s) for -g option", argv[i]+2);
 370:         else
 371:             set_gid = grp->gr_gid;
 372:         }
 373:         break;
 374: 
 375:       case 'c':
 376:         charset_name = argv[i]+2;
 377:         break;
 378: 
 379:       case 'r':
 380:         indirect_host = argv[i]+2;
 381:         break;
 382: 
 383:       case 'l':    /* Use the Syslog daemon for logging */
 384:         syslog_flag++;
 385:         break;
 386: 
 387:       case 'o':
 388:         other_flag = 1;
 389:         break;
 390: 
 391:       case 'e':
 392:         unknown_flag = 1;
 393:         break;
 394: 
 395:       case 'V':    /* Give version of this daemon */
 396:         printf("[in.identd, version %s]\r\n", version);
 397:         exit(0);
 398:         break;
 399: 
 400:       case 'v':    /* Be verbose */
 401:         verbose_flag++;
 402:         break;
 403: 
 404:       case 'd':    /* Enable debugging */
 405:         debug_flag++;
 406:         break;
 407: 
 408:       case 'm':    /* Enable multiline queries */
 409:         multi_flag++;
 410:         break;
 411: 
 412:       case 'N':    /* Enable users ".noident" files */
 413:         noident_flag++;
 414:         break;
 415: 
 416: #ifdef INCLUDE_CRYPT
 417:           case 'C':    /* Enable encryption. */
 418:         {
 419:         FILE *keyfile;
 420: 
 421:         if (argv[i][2])
 422:             keyfile = fopen(argv[i]+2, "r");
 423:         else
 424:             keyfile = fopen(PATH_DESKEY, "r");
 425: 
 426:         if (keyfile == NULL)
 427:         {
 428:             ERROR("cannot open key file for option -C");
 429:         }
 430:         else
 431:         {
 432:             char buf[1024];
 433: 
 434:             if (fgets(buf, 1024, keyfile) == NULL)
 435:             {
 436:             ERROR("cannot read key file for option -C");
 437:             }
 438:             else
 439:             {
 440:             init_encryption(buf);
 441:             crypto_flag++;
 442:             }
 443:             fclose(keyfile);
 444:         }
 445:         }
 446:             break;
 447: #endif
 448: 
 449: #ifdef ALLOW_FORMAT
 450:       case 'n': /* Compatibility flag - just send the user number */
 451:         format_flag = 1;
 452:         format = "%U";
 453:         break;
 454: 
 455:           case 'F':    /* Output format */
 456:         format_flag = 1;
 457:         format = argv[i]+2;
 458:         break;
 459: #endif
 460: 
 461:       default:
 462:         ERROR1("Bad option %s", argv[i]);
 463:         break;
 464:     }
 465:     }
 466: 
 467: #if defined(_AUX_SOURCE) || defined (SUNOS35)
 468:     /* A/UX 2.0* & SunOS 3.5 calls us with an argument XXXXXXXX.YYYY
 469:     ** where XXXXXXXXX is the hexadecimal version of the callers
 470:     ** IP number, and YYYY is the port/socket or something.
 471:     ** It seems to be impossible to pass arguments to a daemon started
 472:     ** by inetd.
 473:     **
 474:     ** Just in case it is started from something else, then we only
 475:     ** skip the argument if no option flags have been seen.
 476:     */
 477:     if (opt_count == 0)
 478:     argc--;
 479: #endif
 480: 
 481:     /*
 482:     ** Path to kernel namelist file specified on command line
 483:     */
 484:     if (i < argc)
 485:     path_unix = argv[i++];
 486: 
 487:     /*
 488:     ** Path to kernel memory device specified on command line
 489:     */
 490:     if (i < argc)
 491:     path_kmem = argv[i++];
 492: 
 493: 
 494:     if (i < argc)
 495:     ERROR1("Too many arguments: ignored from %s", argv[i]);
 496: 
 497: 
 498:     /*
 499:     ** We used to call k_open here. But then the file descriptor
 500:     ** kd->fd open on /dev/kmem is shared by all child processes.
 501:     ** From the fork(2) man page:
 502:     **      o  The child process has its own copy of the parent's descriptors.  These
 503:     **         descriptors reference the same underlying objects.  For instance, file
 504:     **         pointers in file objects are shared between the child and the parent
 505:     **         so that an lseek(2) on a descriptor in the child process can affect a
 506:     **         subsequent read(2) or write(2) by the parent.
 507:     ** Thus with concurrent (simultaneous) identd client processes,
 508:     ** they step on each other's toes when they use kvm_read.
 509:     **
 510:     ** Calling k_open here was a mistake for another reason too: we
 511:     ** did not yet honor -u and -g options. Presumably we are
 512:     ** running as root (unless the in.identd file is setuid), and
 513:     ** then we can open kmem regardless of -u and -g values.
 514:     **
 515:     **
 516:     ** Open the kernel memory device and read the nlist table
 517:     **
 518:     **     if (k_open() < 0)
 519:     ** 		ERROR("main: k_open");
 520:     */
 521: 
 522:     /*
 523:     ** Do the special handling needed for the "-b" flag
 524:     */
 525:     if (background_flag == 1)
 526:     {
 527:     struct sockaddr_in addr;
 528:     struct servent *sp;
 529:     int fd;
 530: 
 531: 
 532:     if (!debug_flag)
 533:     {
 534:         if (fork())
 535:         exit(0);
 536: 
 537:         close(0);
 538:         close(1);
 539:         close(2);
 540: 
 541:         if (fork())
 542:         exit(0);
 543:     }
 544: 
 545:     fd = socket(AF_INET, SOCK_STREAM, 0);
 546:     if (fd == -1)
 547:         ERROR("main: socket");
 548: 
 549:     if (fd != 0)
 550:         dup2(fd, 0);
 551: 
 552:     clearmem(&addr, sizeof(addr));
 553: 
 554:     addr.sin_family = AF_INET;
 555:     if (bind_address == NULL)
 556:         addr.sin_addr.s_addr = htonl(INADDR_ANY);
 557:     else
 558:     {
 559:         if (isdigit(bind_address[0]))
 560:         addr.sin_addr.s_addr = inet_addr(bind_address);
 561:         else
 562:         {
 563:         struct hostent *hp;
 564: 
 565:         hp = gethostbyname(bind_address);
 566:         if (!hp)
 567:             ERROR1("no such address (%s) for -a switch", bind_address);
 568: 
 569:         /* This is ugly, should use memcpy() or bcopy() but... */
 570:         addr.sin_addr.s_addr = * (unsigned long *) (hp->h_addr);
 571:         }
 572:     }
 573: 
 574:     if (isdigit(portno[0]))
 575:         addr.sin_port = htons(atoi(portno));
 576:     else
 577:     {
 578:         sp = getservbyname(portno, "tcp");
 579:         if (sp == NULL)
 580:         ERROR1("main: getservbyname: %s", portno);
 581:         addr.sin_port = sp->s_port;
 582:     }
 583: 
 584: #ifdef SO_REUSEADDR
 585:     setsockopt(0, SOL_SOCKET, SO_REUSEADDR, (void *) &one, sizeof(one));
 586: #endif
 587: 
 588:     if (bind(0, (struct sockaddr *) &addr, sizeof(addr)) < 0)
 589:         ERROR("main: bind");
 590:     }
 591: 
 592:     if (background_flag)
 593:     {
 594:       if (listen(0, 3) < 0)
 595:     ERROR("main: listen");
 596:     }
 597: 
 598:     if (set_gid)
 599:     {
 600:     if (setgid(set_gid) == -1)
 601:         ERROR("main: setgid");
 602:     /* Call me paranoid... PSz */
 603:     if (getgid() != set_gid)
 604:         ERROR2("main: setgid failed: wanted %d, got GID %d", set_gid, getgid());
 605:     if (getegid() != set_gid)
 606:         ERROR2("main: setgid failed: wanted %d, got EGID %d", set_gid, getegid());
 607:     }
 608: 
 609:     if (set_uid)
 610:     {
 611:     if (setuid(set_uid) == -1)
 612:         ERROR("main: setuid");
 613:     /* Call me paranoid... PSz */
 614:     if (getuid() != set_uid)
 615:         ERROR2("main: setuid failed: wanted %d, got UID %d", set_uid, getuid());
 616:     if (geteuid() != set_uid)
 617:         ERROR2("main: setuid failed: wanted %d, got EUID %d", set_uid, geteuid());
 618:     }
 619: 
 620:     /*
 621:     ** Do some special handling if the "-b" or "-w" flags are used
 622:     */
 623:     if (background_flag)
 624:     {
 625:     int nfds, fd;
 626:     fd_set read_set;
 627:     struct sockaddr sad;
 628:     int sadlen;
 629: 
 630: 
 631:     /*
 632: 	** Set up the SIGCHLD signal child termination handler so
 633: 	** that we can avoid zombie processes hanging around and
 634: 	** handle childs terminating before being able to complete the
 635: 	** handshake.
 636: 	*/
 637: #if (defined(SVR4) || defined(hpux) || defined(__hpux) || defined(IRIX) || \
 638:      defined(_CRAY) || defined(_AUX_SOURCE)) || defined(sco) || defined(LINUX)
 639:     signal(SIGCHLD, SIG_IGN);
 640: #else
 641:     signal(SIGCHLD, (SIGRETURN_TYPE (*)()) child_handler);
 642: #endif
 643: 
 644:     /*
 645: 	** Loop and dispatch client handling processes
 646: 	*/
 647:     do
 648:     {
 649: #ifdef USE_SIGALARM
 650:         /*
 651: 	    ** Terminate if we've been idle for 'timeout' seconds
 652: 	    */
 653:         if (background_flag == 2 && timeout)
 654:         {
 655:         signal(SIGALRM, alarm_handler);
 656:         alarm(timeout);
 657:         }
 658: #endif
 659: 
 660:         /*
 661: 	    ** Wait for a connection request to occur.
 662: 	    ** Ignore EINTR (Interrupted System Call).
 663: 	    */
 664:         do
 665:         {
 666:         FD_ZERO(&read_set);
 667:         FD_SET(0, &read_set);
 668: 
 669: #ifndef USE_SIGALARM
 670:         if (timeout)
 671:         {
 672:             tv.tv_sec = timeout;
 673:             tv.tv_usec = 0;
 674: #ifdef __hpux
 675:             nfds = select(FD_SETSIZE,
 676:                   (int *) &read_set, NULL, NULL, &tv);
 677: #else
 678:             nfds = select(FD_SETSIZE, &read_set, NULL, NULL, &tv);
 679: #endif
 680:         }
 681:         else
 682: #endif
 683: 
 684: #ifdef __hpux
 685:         nfds = select(FD_SETSIZE, (int *) &read_set, NULL, NULL, NULL);
 686: #else
 687:         nfds = select(FD_SETSIZE, &read_set, NULL, NULL, NULL);
 688: #endif
 689:         } while (nfds < 0  && errno == EINTR);
 690: 
 691:         /*
 692: 	    ** An error occured in select? Just die
 693: 	    */
 694:         if (nfds < 0)
 695:         ERROR("main: select");
 696: 
 697:         /*
 698: 	    ** Timeout limit reached. Exit nicely
 699: 	    */
 700:         if (nfds == 0)
 701:         exit(0);
 702: 
 703: #ifdef USE_SIGALARM
 704:         /*
 705: 	    ** Disable the alarm timeout
 706: 	    */
 707:         alarm(0);
 708: #endif
 709: 
 710:         /*
 711: 	    ** Accept the new client
 712: 	    */
 713:         sadlen = sizeof(sad);
 714:         errno = 0;
 715:         fd = accept(0, &sad, &sadlen);
 716:         if (fd == -1)
 717:         ERROR1("main: accept. errno = %d", errno);
 718: 
 719:         /*
 720: 	    ** And fork, then close the fd if we are the parent.
 721: 	    */
 722:         child_pid = fork();
 723:     } while (child_pid && (close(fd), 1));
 724: 
 725:     /*
 726: 	** We are now in child, the parent has returned to "do" above.
 727: 	*/
 728:     if (dup2(fd, 0) == -1)
 729:         ERROR("main: dup2: failed fd 0");
 730: 
 731:     if (dup2(fd, 1) == -1)
 732:         ERROR("main: dup2: failed fd 1");
 733: 
 734:     if (dup2(fd, 2) == -1)
 735:         ERROR("main: dup2: failed fd 2");
 736:     }
 737: 
 738:     /*
 739:     ** Get foreign internet address
 740:     */
 741:     len = sizeof(sin);
 742:     if (getpeername(0, (struct sockaddr *) &sin, &len) == -1)
 743:     {
 744:     /*
 745: 	** A user has tried to start us from the command line or
 746: 	** the network link died, in which case this message won't
 747: 	** reach to other end anyway, so lets give the poor user some
 748: 	** errors.
 749: 	*/
 750:     perror("in.identd: getpeername()");
 751:     exit(1);
 752:     }
 753: 
 754:     faddr = sin.sin_addr;
 755: 
 756: 
 757:     /*
 758:     ** Open the connection to the Syslog daemon if requested
 759:     */
 760:     if (syslog_flag)
 761:     {
 762: #ifdef LOG_DAEMON
 763:     openlog("identd", LOG_PID, syslog_facility);
 764: #else
 765:     openlog("identd", LOG_PID);
 766: #endif
 767: 
 768: #ifndef STRONG_LOG
 769:     syslog(LOG_INFO, "Connection from %s", gethost(&faddr));
 770: #endif
 771:     }
 772: 
 773: 
 774:     /*
 775:     ** Get local internet address
 776:     */
 777:     len = sizeof(sin);
 778: #ifdef ATTSVR4
 779:     if (t_getsockname(0, (struct sockaddr *) &sin, &len) == -1)
 780: #else
 781:     if (getsockname(0, (struct sockaddr *) &sin, &len) == -1)
 782: #endif
 783:     {
 784:     /*
 785: 	** We can just die here, because if this fails then the
 786: 	** network has died and we haven't got anyone to return
 787: 	** errors to.
 788: 	*/
 789:     exit(1);
 790:     }
 791:     laddr = sin.sin_addr;
 792: 
 793: 
 794:     /*
 795:     ** Get the local/foreign port pair from the luser
 796:     */
 797:     parse(stdin, &laddr, &faddr);
 798: 
 799:     exit(0);
 800: }

Defined functions

alarm_handler defined in line 214; used 1 times
child_handler defined in line 231; used 1 times
clearmem defined in line 250; used 1 times
comparemem defined in line 163; used 2 times
gethost defined in line 182; used 21 times
inet_ntoa defined in line 143; used 20 times
main defined in line 268; never used

Defined variables

charset_name defined in line 116; used 16 times
child_pid defined in line 125; used 2 times
crypto_flag defined in line 111; used 2 times
debug_flag defined in line 105; used 7 times
format defined in line 122; used 3 times
format_flag defined in line 121; used 3 times
fport defined in line 114; used 53 times
indirect_host defined in line 117; used 6 times
indirect_password defined in line 118; used 2 times
lport defined in line 113; used 54 times
multi_flag defined in line 107; used 2 times
noident_flag defined in line 110; used 2 times
other_flag defined in line 108; used 3 times
path_kmem defined in line 102; used 1 times
path_unix defined in line 101; used 1 times
syslog_facility defined in line 128; used 1 times
syslog_flag defined in line 106; used 29 times
unknown_flag defined in line 109; used 14 times
verbose_flag defined in line 104; used 1 times

Defined macros

FD_SET defined in line 89; used 2 times
FD_SETSIZE defined in line 82; used 5 times
FD_ZERO defined in line 93; used 2 times
NFDBITS defined in line 87; used 3 times
SIGRETURN_TYPE defined in line 20; used 3 times
SIGRETURN_TYPE_IS_VOID defined in line 18; used 1 times
STRNET defined in line 24; never used
USE_SIGALARM defined in line 32; used 5 times
void defined in line 13; never used
Last modified: 1996-10-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5946
Valid CSS Valid XHTML 1.0 Strict