/**************************************************************************** * server.c * * * * LocalGate Local Filesystem -> WWW Gateway * * * * LocalGate allows a user to access HTML files on the local filesystem * * as if they had a web server to access the files. * * * * server.c: server core for LocalGate. * * * * Copyright (C) 1997 Michael Chu * * This file is part of the LocalGate local filesystem -> WWW gateway. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * * Contact information: Michael Chu * * mmchu@pobox.com * ****************************************************************************/ /*********************************** INCLUDES *******************************/ #include #include #include #include #include #include #include "netutils.h" #include "miscutils.h" #include "server.h" /********************************** FUNCTIONS *******************************/ /**************************************************************************** * main: * * * * Summary: Main function that is the body of the server. * * * * Input: argc: number of command-line arguments. * * argv: list of command-line arguments. * * * * Returns: Error code: 0 (zero) if execution ended okay. * * Non-zero if execution ended incorrectly. * * * * Global State Affected: * * Server is started. * ****************************************************************************/ int main(int argc, char *argv[]) { int serverPort = 0; /* server port to connect to. */ int mainSocketId = 0; /* main server socket id. */ int newSocketId = 0; /* new connection socket id. */ int childPID = 0; /* child process id. */ char *localFileRequest = NULL; /* stores local filename requested. */ /* set default server TCP port. */ serverPort = DEFAULT_SERVER_TCP_PORT; /* check arguments. */ if (argc > 2) { /* show usage. */ fprintf(stderr, "USAGE: %s [TCP_PORT_TO_USE]\n", argv[0]); /* return error. */ return(1); } else if (argc == 2) { /* if the second argument is not an unsigned integer, then error. */ if (!(isUnsignedInteger(argv[1]))) { /* show error. */ fprintf(stderr, "TCP port MUST BE NON-NEGATIVE!\n"); /* exit with error. */ exit(1); } /* get the server port from the command-line argument. */ serverPort = atoi(argv[1]); /* make sure that port is greater than reserved boundary. */ if (serverPort <= IPPORT_USERRESERVED) { /* show error. */ fprintf(stderr, "TCP port MUST BE GREATER THAN %d!\n", IPPORT_USERRESERVED); /* exit with error. */ exit(1); } } /* let system know we do not care about exit status of our children to prevent zombie processes from forming. */ signal(SIGCLD, SIG_IGN); /* initialize the socket. */ mainSocketId = socketInit(serverPort); /* make sure socket was setup correctly. */ if (mainSocketId < 0) { /* exit with error. */ exit(1); } /* continuously iterate to accept socket connections. */ for (;;) { /* accept incoming connection. */ newSocketId = getIncomingConnection(mainSocketId); /* make sure socket was connected correctly. */ if (newSocketId >= 0) { /* fork off another child to handle this connection. */ childPID = fork(); /* if this the PID returned is negative, then we have an error. */ /* if it is zero, then we are the child. */ if (childPID < 0) { /* show error. */ fprintf(stderr, "Error forking off child! (errno = %d)\n", errno); } else if (childPID == 0) { /* get local file request. */ localFileRequest = getLocalFileRequest(newSocketId); /* if we got back an actual valid filename, then try to send the file through the socket. */ if (localFileRequest != NULL) { /* write file to socket. */ writeFileToSocket(newSocketId, localFileRequest); /* free local file request name. */ free(localFileRequest); localFileRequest = NULL; } /* close the new socket. */ close(newSocketId); /* exit correctly. */ exit(0); } /* close the new socket. */ close(newSocketId); } } }