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 >
Wrap
C/C++ Source or Header
|
1992-04-28
|
9KB
|
417 lines
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
#include "dixie.h"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/syslog.h>
#include <sys/wait.h>
#include <signal.h>
#ifndef FD_SET
#define NFDBITS 32
#define FD_SETSIZE 32
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
#endif
#define DAPUSER "c=US@o=University of Michigan@ou=Miscellaneous Servers@cn=Go500"
#define DEFAULT_BASE "c=US@o=University of Michigan@ou=People"
#define DEFAULT_DIXIEHOST "dixie.itd.umich.edu"
#define DEFAULT_GO500PORT 5555
int debug;
int dosyslog;
char *dixiehost = DEFAULT_DIXIEHOST;
char *base = DEFAULT_BASE;
int strip = 3;
int searchaliases = 1;
char *myhost = "totalrecall.rs.itd.umich.edu";
int myport;
static usage( name )
char *name;
{
fprintf( stderr, "usage: %s [-d debuglevel] [-p port] [-l] [-x dixiehost] [-b searchbase] [-a]\n" );
exit( 1 );
}
main (argc, argv)
int argc;
char **argv;
{
int s, ns, rc;
int port = -1;
int tblsize;
int i, pid;
char *myname;
fd_set readfds;
struct hostent *hp;
struct sockaddr_in from;
int fromlen;
int wait4child();
extern char *optarg;
while ( (i = getopt( argc, argv, "ab:d:lp:s:x:" )) != EOF ) {
switch( i ) {
case 'a':
searchaliases = 0;
break;
case 'b':
base = strdup( optarg );
break;
case 'd':
debug = atoi( optarg );
break;
case 'l':
dosyslog = 1;
break;
case 'p':
port = atoi( optarg );
break;
case 's':
strip = atoi( optarg );
break;
case 'x':
dixiehost = strdup( optarg );
break;
default:
usage( argv[0] );
}
}
/* detach if stderr is redirected or no debugging */
(void) detach( debug );
if ( (myname = strrchr( argv[0], '/' )) == NULL )
myname = strdup( argv[0] );
else
myname = strdup( myname + 1 );
if ( dosyslog && openlog( myname, LOG_PID | LOG_NOWAIT, LOG_LOCAL3 )
< 0 ) {
perror("openlog");
}
if ( dosyslog ) syslog( LOG_INFO, "initializing" );
/* set up the socket to listen on */
s = set_socket( port );
/* arrange to reap children */
(void) signal( SIGCHLD, wait4child );
tblsize = getdtablesize();
for ( ;; ) {
FD_ZERO( &readfds );
FD_SET( s, &readfds );
if ( (rc = select( tblsize, &readfds, 0, 0 ,0 )) == -1 ) {
if ( debug ) perror( "select" );
continue;
} else if ( rc == 0 ) {
continue;
}
if ( ! FD_ISSET( s, &readfds ) )
continue;
fromlen = sizeof(from);
if ( (ns = accept( s, &from, &fromlen )) == -1 ) {
if ( debug ) perror( "accept" );
exit( 1 );
}
hp = gethostbyaddr( (char *) &(from.sin_addr.s_addr),
sizeof(from.sin_addr.s_addr), AF_INET );
syslog( LOG_INFO, "TCP connection from %s (%s)",
(hp == NULL) ? "unknown" : hp->h_name,
inet_ntoa( from.sin_addr ) );
switch( pid = fork() ) {
case 0: /* child */
close( s );
do_queries( ns );
break;
case -1: /* failed */
perror( "fork" );
break;
default: /* parent */
close( ns );
if ( debug )
fprintf( stderr, "forked child %d\n", pid );
break;
}
}
/* NOT REACHED */
}
static set_socket( port )
int port;
{
int s;
struct sockaddr_in addr;
if ( port == -1 )
port = DEFAULT_GO500PORT;
myport = port;
if ( (s = socket( AF_INET, SOCK_STREAM, 0 )) == -1 ) {
perror( "socket" );
exit( 1 );
}
/* set option so clients can't keep us from coming back up */
if ( setsockopt( s, SOL_SOCKET, SO_REUSEADDR, 0, 0 ) < 0 ) {
perror( "setsockopt" );
exit( 1 );
}
/* bind to a name */
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons( port );
if ( bind( s, &addr, sizeof(addr) ) ) {
perror( "bind" );
exit( 1 );
}
/* listen for connections */
if ( listen( s, 5 ) == -1 ) {
perror( "listen" );
exit( 1 );
}
if ( debug ) printf("tcp socket allocated, bound, and listening\n");
return( s );
}
static wait4child()
{
#if defined(SunOS) && SunOS < 40
union wait status;
#else
int status;
#endif
if ( debug ) printf( "parent: catching child status\n" );
while ( wait3( &status, WNOHANG | WUNTRACED, 0 ) > 0 )
; /* NULL */
}
static char dixie_buffer[MAX_PKT_SIZE];
static do_queries( s )
int s;
{
char buf[256];
int len;
FILE *fp;
int rc, tblsize;
struct timeval timeout;
fd_set readfds;
if ( dxi_init( dixiehost, 0, 0 ) == -1 ) {
if ( debug ) perror( "dxi_init" );
exit( 1 );
}
if ( !searchaliases )
dxi_options |= DXI_OPT_DONTSEARCHALIASES;
if ( dxi_bind( DAPUSER, NULL ) == -1 ) {
if ( debug ) dxi_perror( "dxi_bind" );
exit( 1 );
}
dxi_not61 = 1;
if ( (fp = fdopen( s, "a+")) == NULL ) {
perror( "fdopen" );
exit( 1 );
}
tblsize = getdtablesize();
timeout.tv_sec = 300;
timeout.tv_usec = 0;
FD_ZERO( &readfds );
FD_SET( fileno( fp ), &readfds );
if ( (rc = select( tblsize, &readfds, 0, 0, &timeout )) <= 0 )
exit( 1 );
if ( fgets( buf, sizeof(buf), fp ) == NULL )
exit( 1 );
len = strlen( buf );
if ( debug ) {
fprintf( stderr, "got %d bytes\n", len );
dxi_bprint( buf, len );
}
/* strip of \r \n */
if ( buf[len - 1] == '\n' )
buf[len - 1] = '\0';
len--;
if ( buf[len - 1] == '\r' )
buf[len - 1] = '\0';
len--;
rewind(fp);
if ( strchr( buf, '=' ) )
do_read( fp, buf );
else
do_search( fp, buf );
fprintf( fp, ".\r\n" );
rewind(fp);
exit( 1 );
/* NOT REACHED */
}
static do_search( fp, buf )
FILE *fp;
char *buf;
{
char filter[1024];
char *dn, *e, *rdn;
char **title;
static char *attrs[] = { "title", 0 };
sprintf( filter, "uid=%s|sn=%s|cn=%s", buf, buf, buf );
if ( dxi_search( base, DXI_SRCH_SUBTREE, filter, attrs, dixie_buffer )
== -1 ) {
dxi_perror( "dxi_search" );
exit( 1 );
}
for ( e = dxi_firstentry( dixie_buffer ); e != NULL;
e = dxi_nextentry() ) {
dn = dxi_getdn( e );
rdn = dxi_lastdncomp( dn );
title = dxi_getvalues( e, "title" );
fprintf( fp, "0%-20s %s\t%s\t%s\t%d\r\n", rdn,
title ? title[0] : "", dn, myhost, myport );
dxi_valuefree( title );
free( dn );
}
}
static print_attr( fp, label, attr, e, multiline )
FILE *fp;
char *label;
char *attr;
char *e;
int multiline;
{
char **val;
int i, gotone = 0, firstline = 1;
if ( (val = dxi_getvalues( e, attr )) == NULL )
return;
fprintf( fp, "%-19s\r\n", label );
for ( i = 0; val[i] != NULL; i++ ) {
if ( multiline ) {
char *s, *p;
if ( gotone )
fprintf( fp, "%-19s\r\n", label );
p = s = val[i];
while ( s = strchr( s, '$' ) ) {
*s++ = '\0';
while ( isspace( *s ) )
s++;
if ( firstline ) {
fprintf( fp, " %s\r\n", p );
firstline = 0;
} else {
fprintf( fp, " %s\r\n", p );
}
p = s;
}
if ( firstline ) {
fprintf( fp, " %s\r\n", p );
} else {
fprintf( fp, " %s\r\n", p );
}
gotone = 1;
firstline = 1;
} else {
if ( firstline ) {
fprintf( fp, " %s\r\n", val[i] );
firstline = 0;
} else {
fprintf( fp, " %s\r\n", val[i] );
}
}
}
dxi_valuefree( val );
}
static do_read( fp, buf )
FILE *fp;
char *buf;
{
char *dn, *e, *ufn;
int i;
char *s;
char **cn, **paddr, **tnumber, **uid, **title, **mail;
static char *attrs[] = { "cn", "postalAddress", "uid", "title",
"mail", "telephoneNumber",
"facsimileTelephoneNumber", 0 };
if ( dxi_read( buf, attrs, dixie_buffer ) == -1 ) {
if ( debug ) dxi_perror( "dxi_read" );
exit( 1 );
}
e = dxi_getreadentry( dixie_buffer );
dn = dxi_getdn( e );
ufn = dxi_dn2ufn( dn );
for ( i = 0; i < strip; i++ ) {
if ( (s = strrchr( ufn, ',' )) == NULL )
break;
*s = '\0';
}
fprintf( fp, "\"%s\"\r\n", ufn );
print_attr( fp, " Also known as:", "cn", e, 0 );
print_attr( fp, " E-mail address:", "mail", e, 0 );
print_attr( fp, " Fax number:", "facsimileTelephoneNumber", e, 0 );
print_attr( fp, " Business phone:", "telephoneNumber", e, 0 );
print_attr( fp, " Business address:", "postalAddress", e, 1 );
print_attr( fp, " Title:", "title", e, 0 );
print_attr( fp, " Uniqname:", "uid", e, 0 );
free( dn );
}