X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=www%2Fwcgi.c;fp=www%2Fwcgi.c;h=3fb3cec5f26bffc628b45c21572cefa9b3548f86;hb=1938b1fd36e774fa9b6d11a4eb5edfcdaee0267b;hp=0000000000000000000000000000000000000000;hpb=f7782074f0b95181a9fe5b04453f42c643ed0844;p=egate.git diff --git a/www/wcgi.c b/www/wcgi.c new file mode 100644 index 0000000..3fb3cec --- /dev/null +++ b/www/wcgi.c @@ -0,0 +1,222 @@ +/* + * Copyright (c) 1995, the EUROPAGATE consortium (see below). + * + * The EUROPAGATE consortium members are: + * + * University College Dublin + * Danmarks Teknologiske Videnscenter + * An Chomhairle Leabharlanna + * Consejo Superior de Investigaciones Cientificas + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation, in whole or in part, for any purpose, is hereby granted, + * provided that: + * + * 1. This copyright and permission notice appear in all copies of the + * software and its documentation. Notices of copyright or attribution + * which appear at the beginning of any file must remain unchanged. + * + * 2. The names of EUROPAGATE or the project partners may not be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * 3. Users of this software (implementors and gateway operators) agree to + * inform the EUROPAGATE consortium of their use of the software. This + * information will be used to evaluate the EUROPAGATE project and the + * software, and to plan further developments. The consortium may use + * the information in later publications. + * + * 4. Users of this software agree to make their best efforts, when + * documenting their use of the software, to acknowledge the EUROPAGATE + * consortium, and the role played by the software in their work. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * IN NO EVENT SHALL THE EUROPAGATE CONSORTIUM OR ITS MEMBERS BE LIABLE + * FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF + * ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA + * OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND + * ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE + * USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Log: wcgi.c,v $ + * Revision 1.1 1995/10/20 11:49:25 adam + * First version of www gateway. + * + */ + +#include +#include +#include +#include +#include +#include + +#define DEADSTRING "Your database server has terminated. To reactivate \ +the server, please reload the server's 'front page'." + +#include "wproto.h" + +#define CGIDIR "/usr/local/etc/httpd/cgi-bin" + +static char *prog = "cgi"; + +static char serverp[256] = {'\0'}; + +static void fatal(char *p) +{ + printf("Content-type: text/html\n\nServer Failure\n"); + printf("%s\n", p); + if (*serverp) + unlink(serverp); + exit(0); +} + +static int spawn(char *sprog) +{ + int r; + char path[256]; + + sprintf(path, "%s/%s", CGIDIR, sprog); + switch(r = fork()) + { + case -1: + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "fork"); + exit(1); + case 0: + close (0); + close (1); + execl (path, sprog, 0); + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "execl %s", path); + exit(0); + default: + return r; + } +} + + +/* + * NOTE: In the (perhaps odd) terminology used within this software, + * the 'server' is the present program, which is executed by the httpd + * server. The 'client' is the process running outside. + * Protocol is long(len)\0\0\0\0 + */ +int main() +{ + char clientp[256], tmp[256], *path_info, *p, *operation, *t; + char combuf[COMBUF]; + int linein = -1, lineout, data, childpid; + + gw_log_init ("egw"); + gw_log_file (GW_LOG_ALL, "/usr/local/etc/httpd/logs/egwcgi_log"); + gw_log_level (GW_LOG_ALL); + gw_log (GW_LOG_STAT, prog, "Europagate www cgi server"); + + sprintf(tmp, "%s/%s", FIFOROOT, FIFODIR); + if (access(tmp, R_OK|W_OK) < 0 && mkdir(tmp, 0777) < 0) + { + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "Failed to create %s", tmp); + fatal("Internal error in server."); + } + sprintf(serverp, "%s/srv%d", tmp, getpid()); + if (access(serverp, R_OK|W_OK) == 0) + { + if (unlink(serverp) < 0) + { + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, + "Failed to delete stale fifo."); + fatal("Internal error in server."); + } + else + gw_log (GW_LOG_WARN, prog, "Removed stale server fifo."); + } + if (mkfifo(serverp, 0666 | S_IFIFO) < 0) + { + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "mkfifo(%s)", serverp); + fatal("Internal error in server."); + } + if (!(path_info = getenv("PATH_INFO"))) + { + gw_log (GW_LOG_FATAL, prog, "Must set PATH_INFO."); + fatal("Internal error in server."); + } + operation = ++path_info; + while (*path_info && *path_info != '/') + path_info++; + if (*path_info) + *(path_info++) = '\0'; + if ((childpid = atoi(operation)) <= 0) + { + childpid = spawn(operation); + /* synchronize with client. */ + gw_log (GW_LOG_DEBUG, prog, "Synchronizing with client."); + if ((linein = open(serverp, O_RDONLY)) < 0) + { + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "open server %s", serverp); + fatal("Internal error in server."); + } + if (read(linein, combuf, 2) < 2 || strcmp(combuf, "OK")) + { + gw_log (GW_LOG_FATAL, prog, "Failed to synchronize with client."); + fatal("Internal error in server"); + } + gw_log (GW_LOG_DEBUG, prog, "Synchronized."); + } + sprintf(clientp, "%s/clt%d", tmp, childpid); + gw_log (GW_LOG_DEBUG, prog, "Opening %s", clientp); + if ((lineout = open(clientp, O_WRONLY)) < 0) + { + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "%s", clientp); + fatal(DEADSTRING); + } + gw_log (GW_LOG_DEBUG, prog, "Decoding user data."); + p = combuf + sizeof(data); + strcpy(p, serverp); + p += strlen(p) + 1; + strcpy(p, path_info); + p += strlen(p) + 1; + *(p++) = '\0'; /* no envvars tranferred at present */ + if ((t = getenv("CONTENT_LENGTH")) && (data = atoi(t)) > 0) + { + if (read(0, p, data) < data) + { + gw_log (GW_LOG_FATAL, prog, "Failed to read input."); + fatal("Internal error in server."); + } + } + p += data; + *(p++) = '\0'; + data = (p - combuf); + memcpy(combuf, &data, sizeof(data)); + gw_log (GW_LOG_DEBUG, prog, "Writing data."); + if (write(lineout, combuf, data) < data) + { + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "write"); + fatal("Internal server error."); + } + if (linein < 0 && (linein = open(serverp, O_RDONLY)) < 0) + { + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "open server %s", serverp); + fatal("Internal error in server."); + } + gw_log (GW_LOG_DEBUG, prog, "Reading response."); + while ((data = read(linein, combuf, COMBUF)) > 0) + { + if (write(1, combuf, data) < data) + { + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "write"); + fatal("Internal server error."); + } + } + if (data < 0) + { + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "read"); + fatal("Internal server error."); + } + gw_log (GW_LOG_DEBUG, prog, "Cleaning up."); + close(linein); + unlink(serverp); + close(lineout); + return 0; +}