Very nearly a useful tool. Still generating zombies, however; much work in

wrapper to get this far, but still no bananas!
This commit is contained in:
simon 1997-10-15 20:16:08 +00:00
parent 98b634bc9d
commit a53cbcbde3
8 changed files with 77 additions and 34 deletions

View file

@ -5,7 +5,7 @@ CC= gcc
CFLAGS= -g CFLAGS= -g
LD= gcc LD= gcc
LDFLAGS= -g LDFLAGS= -g
BINDIR= /usr/local/bin HOMEDIR= /usr/local/etc/gild
TARGETS= gild TARGETS= gild
COMPONENTS = gild.o wrapper.o config.o log.o COMPONENTS = gild.o wrapper.o config.o log.o
@ -21,7 +21,9 @@ clean:
rm core *.o $(TARGETS) rm core *.o $(TARGETS)
install: $(TARGETS) install: $(TARGETS)
install --strip $(TARGETS) $(BINDIR) install --strip $(TARGETS) gild.conf $(HOMEDIR)
install handlers/* $(HOMEDIR)/handlers
version: $(TARGETS) version: $(TARGETS)
cvs commit gild.c wrapper.c config.c log.c Makefile gild.h gild.conf cvs commit gild.c wrapper.c config.c log.c Makefile gild.h \
gild.conf handlers

View file

@ -12,6 +12,8 @@
* * * *
\**************************************************************************/ \**************************************************************************/
/* $Header$ */
#include "gild.h" #include "gild.h"
extern char errorBuff[]; /* where I assemble logging messages */ extern char errorBuff[]; /* where I assemble logging messages */

14
gild.c
View file

@ -23,8 +23,6 @@ int port = DEFAULT_PORT_NO; /* the port I shall listen on */
char errorBuff[ 1024]; /* somewhere to assemble error messages */ char errorBuff[ 1024]; /* somewhere to assemble error messages */
extern handler * handlers; extern handler * handlers;
/* the list of handlers I support */ /* the list of handlers I support */
FILE * logstream = stderr; /* where I stick log messages */
void error( int severity) void error( int severity)
/* log the current contents of errorBuff and then if severity is bad die */ /* 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)); ( struct sockaddr_in *)malloc( sizeof( struct sockaddr_in));
/* the address I bind the keyhole to */ /* the address I bind the keyhole to */
fprintf( stderr, "%s starting...", GILD_ID);
for ( arg = 1; argc > arg; arg ++) for ( arg = 1; argc > arg; arg ++)
{ /* process arguments */ { /* process arguments */
switch ( argv[ arg][ 0]) switch ( argv[ arg][ 0])
@ -115,8 +111,11 @@ int main( int argc, char * argv[])
#ifndef DEBUG #ifndef DEBUG
/* we become a real class one daemon */ /* we become a real class one daemon */
if ( fork() != 0) exit(0); if ( fork() != 0) /* we're the parent */
/* the parent exits */ {
exit(0); /* so die */
}
/* otherwise (we're the child)... */
setsid(); /* release the controlling tty */ setsid(); /* release the controlling tty */
#endif #endif
@ -171,12 +170,15 @@ int main( int argc, char * argv[])
wrapper( conversation, client_addr); wrapper( conversation, client_addr);
/* wrapper (q.v.) handles the conversation */ /* wrapper (q.v.) handles the conversation */
exit( 0); /* after completing wrapper, die */
break; break;
default: /* I'm the parent */ default: /* I'm the parent */
close( conversation); close( conversation);
free( client); /* prevent memory bloat */ free( client); /* prevent memory bloat */
if ( client_addr != null) if ( client_addr != null)
free( client_addr); free( client_addr);
break;
} }
} }
} }

View file

@ -1,5 +1,6 @@
# Sample GILD configuration file # Sample GILD configuration file
# $Header$ # $Header$
# protocol pattern handler timeout # protocol pattern handler timeout
http ^.*HTTP/[0-1] handlers/http 5
crp CRP/1 handlers/crp 10 http ^.*HTTP/[0-1] handlers/http 5
crp CRP/1 handlers/crp 10

1
gild.h
View file

@ -40,7 +40,6 @@
#define STDOUT_FILENO 1 #define STDOUT_FILENO 1
#define STDERR_FILENO 2 #define STDERR_FILENO 2
#define ever (;;) #define ever (;;)
#define null (((void *) 0)) #define null (((void *) 0))

View file

@ -73,14 +73,14 @@ then
case $command in case $command in
"HEAD"|"Head"|"head") exit 0;; "HEAD"|"Head"|"head") exit 0;;
"GET"|"Get"|"get" ) cat $file;; "GET"|"Get"|"get" ) cat $file;;
* ) echo "Whoops! Unexpected error!";;
esac esac
echo "$now: $REMOTE_HOST: $command: $rq_file" \ echo "$now: $REMOTE_HOST: $command: $rq_file" \
>> $SERVER_ROOT/logs/access_log >> $SERVER_ROOT/logs/access_log
else else # didn't find it; report and log
cat $SERVER_ROOT/error/404.html cat $SERVER_ROOT/error/404.html
echo "$now: $REMOTE_HOST: No such file [$rq_file]" \ echo "$now: $REMOTE_HOST: No such file [$rq_file]" \
>> $SERVER_ROOT/logs/error_log >> $SERVER_ROOT/logs/error_log
fi fi
fi fi
exit 0 # yes, I know it _shouldn't_ be necessary

4
log.c
View file

@ -21,8 +21,12 @@
int log( int level, char *message) int log( int level, char *message)
/* hand this message over to the syslog daemon for recording */ /* 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); openlog( GILD_NAME, 0, LOG_DAEMON);
syslog( level, message); syslog( level, message);
closelog(); closelog();
#endif
} }

View file

@ -16,26 +16,27 @@
#include "gild.h" #include "gild.h"
char errorBuff[ 1024]; extern char errorBuff[ 1024];
extern char **environ;
void die( void) /* inherited from cgi-lib; a way of void die( void)
getting rid of errant programs */ /* inherited from cgi-lib; a way of getting rid of errant programs */
{ {
sprintf( errorBuff, "potentially serious: handler over-ran alloted time"); sprintf( errorBuff, "potentially serious: handler over-ran alloted time");
error( LOG_ERR); error( LOG_ERR);
exit( 1); /* belt and braces; should never be called */
} }
void wrapper( int conversation, char * client_id) void wrapper( int conversation, char * client_id)
/* conversation is the handle on an open socket communicating with a /* 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 client. */
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 */
{ {
char firstln[ 1024]; char firstln[ 1024];
char * exec_args[1]; /* 'arguments' to pass to execve */
handler * command = null; 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); recv( conversation, firstln, 80, MSG_PEEK);
/* get the first thing the client /* get the first thing the client
@ -67,25 +68,58 @@ void wrapper( int conversation, char * client_id)
} }
else /* did find one */ else /* did find one */
{ {
sprintf( errorBuff, setenv( "REMOTE_HOST", client_id, 1);
"using handler '%s' to handle %s request from %s", /* set up the handler environment */
command->command, command->protocol, client_id);
error( LOG_NOTICE);
/* log the request */
if ( command->timeout != 0) if ( command->timeout != 0)
/* prevent runaway processes; if a /* prevent runaway processes; if a
timeout has been specified for this timeout has been specified for this
handler, enforce it */ handler, enforce it */
{ {
signal( SIGALRM,(void (*)())die); signal( SIGALRM,(void (*)())die);
alarm( command->timeout); alarm( command->timeout);
} }
setenv( "REMOTE_HOST", client_id, 1); child_pid = fork();
/* set up the handler environment */
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); exit( 0);
@ -94,4 +128,3 @@ void wrapper( int conversation, char * client_id)