home *** CD-ROM | disk | FTP | other *** search
/ ftp.muug.mb.ca / 2014.06.ftp.muug.mb.ca.tar / ftp.muug.mb.ca / pub / src / gopher / gopher1.01 / misc / go500 / main.c < prev    next >
C/C++ Source or Header  |  1992-04-28  |  9KB  |  417 lines

  1. /*
  2.  * Copyright (c) 1990 Regents of the University of Michigan.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that this notice is preserved and that due credit is given
  7.  * to the University of Michigan at Ann Arbor. The name of the University
  8.  * may not be used to endorse or promote products derived from this
  9.  * software without specific prior written permission. This software
  10.  * is provided ``as is'' without express or implied warranty.
  11.  */
  12.  
  13. #include "dixie.h"
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <sys/types.h>
  17. #include <sys/time.h>
  18. #include <sys/socket.h>
  19. #include <netinet/in.h>
  20. #include <arpa/inet.h>
  21. #include <netdb.h>
  22. #include <sys/syslog.h>
  23. #include <sys/wait.h>
  24. #include <signal.h>
  25.  
  26. #ifndef FD_SET
  27. #define NFDBITS         32
  28. #define FD_SETSIZE      32
  29. #define FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
  30. #define FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
  31. #define FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
  32. #define FD_ZERO(p)      bzero((char *)(p), sizeof(*(p)))
  33. #endif
  34.  
  35. #define DAPUSER            "c=US@o=University of Michigan@ou=Miscellaneous Servers@cn=Go500"
  36. #define DEFAULT_BASE        "c=US@o=University of Michigan@ou=People"
  37. #define DEFAULT_DIXIEHOST    "dixie.itd.umich.edu"
  38. #define DEFAULT_GO500PORT    5555
  39.  
  40. int    debug;
  41. int    dosyslog;
  42.  
  43. char    *dixiehost = DEFAULT_DIXIEHOST;
  44. char    *base = DEFAULT_BASE;
  45. int    strip = 3;
  46. int    searchaliases = 1;
  47.  
  48. char    *myhost = "totalrecall.rs.itd.umich.edu";
  49. int    myport;
  50.  
  51. static usage( name )
  52. char    *name;
  53. {
  54.     fprintf( stderr, "usage: %s [-d debuglevel] [-p port] [-l] [-x dixiehost] [-b searchbase] [-a]\n" );
  55.     exit( 1 );
  56. }
  57.  
  58. main (argc, argv)
  59. int    argc;
  60. char    **argv;
  61. {
  62.     int            s, ns, rc;
  63.     int            port = -1;
  64.     int            tblsize;
  65.     int            i, pid;
  66.     char            *myname;
  67.     fd_set            readfds;
  68.     struct hostent        *hp;
  69.     struct sockaddr_in    from;
  70.     int            fromlen;
  71.     int            wait4child();
  72.     extern char        *optarg;
  73.  
  74.     while ( (i = getopt( argc, argv, "ab:d:lp:s:x:" )) != EOF ) {
  75.         switch( i ) {
  76.         case 'a':
  77.             searchaliases = 0;
  78.             break;
  79.  
  80.         case 'b':
  81.             base = strdup( optarg );
  82.             break;
  83.  
  84.         case 'd':
  85.             debug = atoi( optarg );
  86.             break;
  87.  
  88.         case 'l':
  89.             dosyslog = 1;
  90.             break;
  91.  
  92.         case 'p':
  93.             port = atoi( optarg );
  94.             break;
  95.  
  96.         case 's':
  97.             strip = atoi( optarg );
  98.             break;
  99.  
  100.         case 'x':
  101.             dixiehost = strdup( optarg );
  102.             break;
  103.  
  104.         default:
  105.             usage( argv[0] );
  106.         }
  107.     }
  108.  
  109.     /* detach if stderr is redirected or no debugging */
  110.     (void) detach( debug );
  111.  
  112.     if ( (myname = strrchr( argv[0], '/' )) == NULL )
  113.         myname = strdup( argv[0] );
  114.     else
  115.         myname = strdup( myname + 1 );
  116.  
  117.     if ( dosyslog && openlog( myname, LOG_PID | LOG_NOWAIT, LOG_LOCAL3 )
  118.         < 0 ) {
  119.         perror("openlog");
  120.     }
  121.     if ( dosyslog ) syslog( LOG_INFO, "initializing" );
  122.  
  123.     /* set up the socket to listen on */
  124.     s = set_socket( port );
  125.  
  126.     /* arrange to reap children */
  127.     (void) signal( SIGCHLD, wait4child );
  128.  
  129.     tblsize = getdtablesize();
  130.     for ( ;; ) {
  131.         FD_ZERO( &readfds );
  132.         FD_SET( s, &readfds );
  133.  
  134.         if ( (rc = select( tblsize, &readfds, 0, 0 ,0 )) == -1 ) {
  135.             if ( debug ) perror( "select" );
  136.             continue;
  137.         } else if ( rc == 0 ) {
  138.             continue;
  139.         }
  140.  
  141.         if ( ! FD_ISSET( s, &readfds ) )
  142.             continue;
  143.  
  144.         fromlen = sizeof(from);
  145.         if ( (ns = accept( s, &from, &fromlen )) == -1 ) {
  146.             if ( debug ) perror( "accept" );
  147.             exit( 1 );
  148.         }
  149.  
  150.         hp = gethostbyaddr( (char *) &(from.sin_addr.s_addr),
  151.             sizeof(from.sin_addr.s_addr), AF_INET );
  152.         syslog( LOG_INFO, "TCP connection from %s (%s)",
  153.             (hp == NULL) ? "unknown" : hp->h_name,
  154.             inet_ntoa( from.sin_addr ) );
  155.  
  156.         switch( pid = fork() ) {
  157.         case 0:        /* child */
  158.             close( s );
  159.             do_queries( ns );
  160.             break;
  161.  
  162.         case -1:    /* failed */
  163.             perror( "fork" );
  164.             break;
  165.  
  166.         default:    /* parent */
  167.             close( ns );
  168.             if ( debug )
  169.                 fprintf( stderr, "forked child %d\n", pid );
  170.             break;
  171.         }
  172.     }
  173.     /* NOT REACHED */
  174. }
  175.  
  176. static set_socket( port )
  177. int    port;
  178. {
  179.     int            s;
  180.     struct sockaddr_in    addr;
  181.  
  182.     if ( port == -1 )
  183.         port = DEFAULT_GO500PORT;
  184.     myport = port;
  185.  
  186.     if ( (s = socket( AF_INET, SOCK_STREAM, 0 )) == -1 ) {
  187.                 perror( "socket" );
  188.                 exit( 1 );
  189.         }
  190.  
  191.         /* set option so clients can't keep us from coming back up */
  192.         if ( setsockopt( s, SOL_SOCKET, SO_REUSEADDR, 0, 0 ) < 0 ) {
  193.                 perror( "setsockopt" );
  194.                 exit( 1 );
  195.         }
  196.  
  197.         /* bind to a name */
  198.         addr.sin_family = AF_INET;
  199.         addr.sin_addr.s_addr = INADDR_ANY;
  200.         addr.sin_port = htons( port );
  201.         if ( bind( s, &addr, sizeof(addr) ) ) {
  202.                 perror( "bind" );
  203.                 exit( 1 );
  204.         }
  205.  
  206.     /* listen for connections */
  207.         if ( listen( s, 5 ) == -1 ) {
  208.                 perror( "listen" );
  209.                 exit( 1 );
  210.         }
  211.  
  212.         if ( debug ) printf("tcp socket allocated, bound, and listening\n");
  213.  
  214.     return( s );
  215. }
  216.  
  217. static wait4child()
  218. {
  219. #if defined(SunOS) && SunOS < 40
  220.         union wait status;
  221. #else
  222.         int     status;
  223. #endif
  224.  
  225.         if ( debug ) printf( "parent: catching child status\n" );
  226.         while ( wait3( &status, WNOHANG | WUNTRACED, 0 ) > 0 )
  227.                 ;       /* NULL */
  228. }
  229.  
  230. static char    dixie_buffer[MAX_PKT_SIZE];
  231.  
  232. static do_queries( s )
  233. int    s;
  234. {
  235.     char        buf[256];
  236.     int        len;
  237.     FILE        *fp;
  238.     int        rc, tblsize;
  239.     struct timeval    timeout;
  240.     fd_set        readfds;
  241.  
  242.     if ( dxi_init( dixiehost, 0, 0 ) == -1 ) {
  243.         if ( debug ) perror( "dxi_init" );
  244.         exit( 1 );
  245.     }
  246.     if ( !searchaliases )
  247.         dxi_options |= DXI_OPT_DONTSEARCHALIASES;
  248.  
  249.     if ( dxi_bind( DAPUSER, NULL ) == -1 ) {
  250.         if ( debug ) dxi_perror( "dxi_bind" );
  251.         exit( 1 );
  252.     }
  253.     dxi_not61 = 1;
  254.  
  255.     if ( (fp = fdopen( s, "a+")) == NULL ) {
  256.         perror( "fdopen" );
  257.         exit( 1 );
  258.     }
  259.  
  260.     tblsize = getdtablesize();
  261.     timeout.tv_sec = 300;
  262.     timeout.tv_usec = 0;
  263.     FD_ZERO( &readfds );
  264.     FD_SET( fileno( fp ), &readfds );
  265.  
  266.     if ( (rc = select( tblsize, &readfds, 0, 0, &timeout )) <= 0 )
  267.         exit( 1 );
  268.  
  269.     if ( fgets( buf, sizeof(buf), fp ) == NULL )
  270.         exit( 1 );
  271.  
  272.     len = strlen( buf );
  273.     if ( debug ) {
  274.         fprintf( stderr, "got %d bytes\n", len );
  275.         dxi_bprint( buf, len );
  276.     }
  277.  
  278.     /* strip of \r \n */
  279.     if ( buf[len - 1] == '\n' )
  280.         buf[len - 1] = '\0';
  281.     len--;
  282.     if ( buf[len - 1] == '\r' )
  283.         buf[len - 1] = '\0';
  284.     len--;
  285.  
  286.     rewind(fp);
  287.     if ( strchr( buf, '=' ) )
  288.         do_read( fp, buf );
  289.     else
  290.         do_search( fp, buf );
  291.     fprintf( fp, ".\r\n" );
  292.     rewind(fp);
  293.  
  294.     exit( 1 );
  295.     /* NOT REACHED */
  296. }
  297.  
  298. static do_search( fp, buf )
  299. FILE    *fp;
  300. char    *buf;
  301. {
  302.     char    filter[1024];
  303.     char    *dn, *e, *rdn;
  304.     char    **title;
  305.     static char    *attrs[] = { "title", 0 };
  306.  
  307.     sprintf( filter, "uid=%s|sn=%s|cn=%s", buf, buf, buf );
  308.  
  309.     if ( dxi_search( base, DXI_SRCH_SUBTREE, filter, attrs, dixie_buffer )
  310.         == -1 ) {
  311.         dxi_perror( "dxi_search" );
  312.         exit( 1 );
  313.     }
  314.  
  315.     for ( e = dxi_firstentry( dixie_buffer ); e != NULL;
  316.         e = dxi_nextentry() ) {
  317.         dn = dxi_getdn( e );
  318.         rdn = dxi_lastdncomp( dn );
  319.         title = dxi_getvalues( e, "title" );
  320.  
  321.         fprintf( fp, "0%-20s    %s\t%s\t%s\t%d\r\n", rdn,
  322.             title ? title[0] : "", dn, myhost, myport );
  323.  
  324.         dxi_valuefree( title );
  325.         free( dn );
  326.     }
  327. }
  328.  
  329. static print_attr( fp, label, attr, e, multiline )
  330. FILE    *fp;
  331. char    *label;
  332. char    *attr;
  333. char    *e;
  334. int    multiline;
  335. {
  336.     char    **val;
  337.     int    i, gotone = 0, firstline = 1;
  338.  
  339.     if ( (val = dxi_getvalues( e, attr )) == NULL )
  340.         return;
  341.  
  342.     fprintf( fp, "%-19s\r\n", label );
  343.     for ( i = 0; val[i] != NULL; i++ ) {
  344.         if ( multiline ) {
  345.             char    *s, *p;
  346.  
  347.             if ( gotone )
  348.                 fprintf( fp, "%-19s\r\n", label );
  349.             p = s = val[i];
  350.             while ( s = strchr( s, '$' ) ) {
  351.                 *s++ = '\0';
  352.                 while ( isspace( *s ) )
  353.                     s++;
  354.                 if ( firstline ) {
  355.                     fprintf( fp, "                    %s\r\n", p );
  356.                     firstline = 0;
  357.                 } else {
  358.                     fprintf( fp, "                    %s\r\n", p );
  359.                 }
  360.                 p = s;
  361.             }
  362.             if ( firstline ) {
  363.                 fprintf( fp, "                    %s\r\n", p );
  364.             } else {
  365.                 fprintf( fp, "                    %s\r\n", p );
  366.             }
  367.             gotone = 1;
  368.             firstline = 1;
  369.         } else {
  370.             if ( firstline ) {
  371.                 fprintf( fp, "                    %s\r\n", val[i] );
  372.                 firstline = 0;
  373.             } else {
  374.                 fprintf( fp, "                    %s\r\n", val[i] );
  375.             }
  376.         }
  377.     }
  378.     dxi_valuefree( val );
  379. }
  380.  
  381. static do_read( fp, buf )
  382. FILE    *fp;
  383. char    *buf;
  384. {
  385.     char        *dn, *e, *ufn;
  386.     int        i;
  387.     char        *s;
  388.     char        **cn, **paddr, **tnumber, **uid, **title, **mail;
  389.     static char    *attrs[] = { "cn", "postalAddress", "uid", "title",
  390.                      "mail", "telephoneNumber",
  391.                      "facsimileTelephoneNumber", 0 };
  392.  
  393.     if ( dxi_read( buf, attrs, dixie_buffer ) == -1 ) {
  394.         if ( debug ) dxi_perror( "dxi_read" );
  395.         exit( 1 );
  396.     }
  397.  
  398.     e = dxi_getreadentry( dixie_buffer );
  399.     dn = dxi_getdn( e );
  400.     ufn = dxi_dn2ufn( dn );
  401.     for ( i = 0; i < strip; i++ ) {
  402.         if ( (s = strrchr( ufn, ',' )) == NULL )
  403.             break;
  404.         *s = '\0';
  405.     }
  406.     fprintf( fp, "\"%s\"\r\n", ufn );
  407.     print_attr( fp, "  Also known as:", "cn", e, 0 );
  408.     print_attr( fp, "  E-mail address:", "mail", e, 0 );
  409.     print_attr( fp, "  Fax number:", "facsimileTelephoneNumber", e, 0 );
  410.     print_attr( fp, "  Business phone:", "telephoneNumber", e, 0 );
  411.     print_attr( fp, "  Business address:", "postalAddress", e, 1 );
  412.     print_attr( fp, "  Title:", "title", e, 0 );
  413.     print_attr( fp, "  Uniqname:", "uid", e, 0 );
  414.  
  415.     free( dn );
  416. }
  417.