From a53cbcbde38442cd0ba104c84ea23187450d843e Mon Sep 17 00:00:00 2001 From: simon <> Date: Wed, 15 Oct 1997 20:16:08 +0000 Subject: [PATCH] Very nearly a useful tool. Still generating zombies, however; much work in wrapper to get this far, but still no bananas! --- Makefile | 8 +++--- config.c | 2 ++ gild.c | 14 +++++----- gild.conf | 7 ++--- gild.h | 1 - handlers/http | 4 +-- log.c | 4 +++ wrapper.c | 71 +++++++++++++++++++++++++++++++++++++-------------- 8 files changed, 77 insertions(+), 34 deletions(-) diff --git a/Makefile b/Makefile index 2f117a4..c6ed310 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ CC= gcc CFLAGS= -g LD= gcc LDFLAGS= -g -BINDIR= /usr/local/bin +HOMEDIR= /usr/local/etc/gild TARGETS= gild COMPONENTS = gild.o wrapper.o config.o log.o @@ -21,7 +21,9 @@ clean: rm core *.o $(TARGETS) install: $(TARGETS) - install --strip $(TARGETS) $(BINDIR) + install --strip $(TARGETS) gild.conf $(HOMEDIR) + install handlers/* $(HOMEDIR)/handlers version: $(TARGETS) - cvs commit gild.c wrapper.c config.c log.c Makefile gild.h gild.conf \ No newline at end of file + cvs commit gild.c wrapper.c config.c log.c Makefile gild.h \ + gild.conf handlers \ No newline at end of file diff --git a/config.c b/config.c index 73cf0dc..563a331 100644 --- a/config.c +++ b/config.c @@ -12,6 +12,8 @@ * * \**************************************************************************/ +/* $Header$ */ + #include "gild.h" extern char errorBuff[]; /* where I assemble logging messages */ diff --git a/gild.c b/gild.c index 738dd2a..6d4417e 100644 --- a/gild.c +++ b/gild.c @@ -23,8 +23,6 @@ int port = DEFAULT_PORT_NO; /* the port I shall listen on */ char errorBuff[ 1024]; /* somewhere to assemble error messages */ extern handler * handlers; /* the list of handlers I support */ -FILE * logstream = stderr; /* where I stick log messages */ - void error( int severity) /* log the current contents of errorBuff and then if severity is bad die */ @@ -49,8 +47,6 @@ int main( int argc, char * argv[]) ( struct sockaddr_in *)malloc( sizeof( struct sockaddr_in)); /* the address I bind the keyhole to */ - fprintf( stderr, "%s starting...", GILD_ID); - for ( arg = 1; argc > arg; arg ++) { /* process arguments */ switch ( argv[ arg][ 0]) @@ -115,8 +111,11 @@ int main( int argc, char * argv[]) #ifndef DEBUG /* we become a real class one daemon */ - if ( fork() != 0) exit(0); - /* the parent exits */ + if ( fork() != 0) /* we're the parent */ + { + exit(0); /* so die */ + } + /* otherwise (we're the child)... */ setsid(); /* release the controlling tty */ #endif @@ -171,12 +170,15 @@ int main( int argc, char * argv[]) wrapper( conversation, client_addr); /* wrapper (q.v.) handles the conversation */ + + exit( 0); /* after completing wrapper, die */ break; default: /* I'm the parent */ close( conversation); free( client); /* prevent memory bloat */ if ( client_addr != null) free( client_addr); + break; } } } diff --git a/gild.conf b/gild.conf index e77757e..ac056f2 100644 --- a/gild.conf +++ b/gild.conf @@ -1,5 +1,6 @@ # Sample GILD configuration file # $Header$ -# protocol pattern handler timeout -http ^.*HTTP/[0-1] handlers/http 5 -crp CRP/1 handlers/crp 10 +# protocol pattern handler timeout + +http ^.*HTTP/[0-1] handlers/http 5 +crp CRP/1 handlers/crp 10 diff --git a/gild.h b/gild.h index 450e639..d7dd3cf 100644 --- a/gild.h +++ b/gild.h @@ -40,7 +40,6 @@ #define STDOUT_FILENO 1 #define STDERR_FILENO 2 - #define ever (;;) #define null (((void *) 0)) diff --git a/handlers/http b/handlers/http index 0c01d76..a6915cd 100755 --- a/handlers/http +++ b/handlers/http @@ -73,14 +73,14 @@ then case $command in "HEAD"|"Head"|"head") exit 0;; "GET"|"Get"|"get" ) cat $file;; - * ) echo "Whoops! Unexpected error!";; esac echo "$now: $REMOTE_HOST: $command: $rq_file" \ >> $SERVER_ROOT/logs/access_log - else + else # didn't find it; report and log cat $SERVER_ROOT/error/404.html echo "$now: $REMOTE_HOST: No such file [$rq_file]" \ >> $SERVER_ROOT/logs/error_log fi fi +exit 0 # yes, I know it _shouldn't_ be necessary diff --git a/log.c b/log.c index e2ddb45..c3d405c 100644 --- a/log.c +++ b/log.c @@ -21,8 +21,12 @@ int log( int level, char *message) /* hand this message over to the syslog daemon for recording */ { +#ifdef DEBUG + fprintf( stderr, "%s: DEBUG: %s\n", GILD_ID, message); +#else openlog( GILD_NAME, 0, LOG_DAEMON); syslog( level, message); closelog(); +#endif } diff --git a/wrapper.c b/wrapper.c index 8d0e358..17d71a3 100644 --- a/wrapper.c +++ b/wrapper.c @@ -16,26 +16,27 @@ #include "gild.h" -char errorBuff[ 1024]; +extern char errorBuff[ 1024]; +extern char **environ; -void die( void) /* inherited from cgi-lib; a way of - getting rid of errant programs */ +void die( void) +/* inherited from cgi-lib; a way of getting rid of errant programs */ { sprintf( errorBuff, "potentially serious: handler over-ran alloted time"); error( LOG_ERR); + exit( 1); /* belt and braces; should never be called */ } void wrapper( int conversation, char * client_id) /* conversation is the handle on an open socket communicating with a - client. What I want to do is quite simple, and there must be a - straightforward way of doing it: attach the conversation to both - the standard input and the standard output of a process, and then - exec the handler within that process... I can't (at present) find - an easy way of doing that, however */ + client. */ { char firstln[ 1024]; + char * exec_args[1]; /* 'arguments' to pass to execve */ handler * command = null; + pid_t child_pid; /* the process number of the spawned child */ + int child_status; /* the status returned by wait() */ recv( conversation, firstln, 80, MSG_PEEK); /* get the first thing the client @@ -67,25 +68,58 @@ void wrapper( int conversation, char * client_id) } else /* did find one */ { - sprintf( errorBuff, - "using handler '%s' to handle %s request from %s", - command->command, command->protocol, client_id); - error( LOG_NOTICE); - /* log the request */ + setenv( "REMOTE_HOST", client_id, 1); + /* set up the handler environment */ if ( command->timeout != 0) /* prevent runaway processes; if a - timeout has been specified for this - handler, enforce it */ + timeout has been specified for this + handler, enforce it */ { signal( SIGALRM,(void (*)())die); alarm( command->timeout); } - setenv( "REMOTE_HOST", client_id, 1); - /* set up the handler environment */ + child_pid = fork(); - system( command->command); + switch ( child_pid) + { + case -1: /* blew it; whinge and die */ + sprintf( errorBuff, "failed to fork in wrapper()"); + error( LOG_ERR); + break; + case 0: /* we're the child process */ + sprintf( errorBuff, + "using handler '%s' [%d] to handle %s request from %s", + command->command, ( int)getpid(), command->protocol, + client_id); + error( LOG_NOTICE); + /* log the request, and... */ + + exec_args[ 0] = command->command; + exec_args[ 1] = null; + /* set up the dummy arguments */ + + if ( execve( command->command, + exec_args, environ) == -1) + /* ...execute the command (shouldn't return) */ + { /* if it did we've got an error */ + sprintf( errorBuff, + "error [errno %d] whislt execing handler '%s' [%d]\n", + errno, command->command, child_pid), + error( LOG_ERR); + } + break; + + default: /* we're the parent */ + wait( &child_status); + /* hang around for the child to die */ + sprintf( errorBuff, + "handler '%s' [%d] completed; wrapper exiting normally", + command->command, child_pid), + error( LOG_NOTICE); + break; + } } exit( 0); @@ -94,4 +128,3 @@ void wrapper( int conversation, char * client_id) -