First version of www gateway.
authorAdam Dickmeiss <adam@indexdata.dk>
Fri, 20 Oct 1995 11:49:24 +0000 (11:49 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Fri, 20 Oct 1995 11:49:24 +0000 (11:49 +0000)
www/Makefile [new file with mode: 0644]
www/wcgi.c [new file with mode: 0644]
www/wproto.c [new file with mode: 0644]
www/wproto.h [new file with mode: 0644]
www/wsh.c [new file with mode: 0644]
www/wtest.c [new file with mode: 0644]

diff --git a/www/Makefile b/www/Makefile
new file mode 100644 (file)
index 0000000..36772bd
--- /dev/null
@@ -0,0 +1,65 @@
+# Makefile for www gateway utility
+# Europagate, 1995
+#
+# $Log: Makefile,v $
+# Revision 1.1  1995/10/20 11:49:24  adam
+# First version of www gateway.
+#
+SHELL=/bin/sh
+INCLUDE=-I../include
+#CFLAGS=-g -Wall -pedantic -ansi
+OLIB=../lib/libres+log.a
+TPROG1=egwcgi
+TPROG2=egwsh
+TPROG3=wtest
+P1=wcgi.o
+P2=wproto.o wsh.o
+P3=wproto.o wtest.o
+CPP=$(CC) -E
+DEFS=$(INCLUDE)
+
+HTTPDDIR=/usr/local/etc/httpd
+CGIBIN=$(HTTPDDIR)/cgi-bin
+HTDOCS=$(HTTPDDIR)/htdocs
+
+all: $(TPROG1) $(TPROG2) $(TPROG3)
+
+$(TPROG1): $(P1)
+       $(CC) $(CFLAGS) -o $(TPROG1) $(P1) $(OLIB)
+
+$(TPROG2): $(P2)
+       $(CC) $(CFLAGS) -o $(TPROG2) $(P2) $(OLIB)
+
+$(TPROG3): $(P3)
+       $(CC) $(CFLAGS) -o $(TPROG3) $(P3) $(OLIB)
+
+install: $(TPROG1) $(TPROG2) $(TPROG3)
+       @for x in $(TPROG1) $(TPROG2) $(TPROG3); do \
+               echo Installing $$x; \
+               cp $$x $(CGIBIN); \
+               chmod +x $(CGIBIN)/$$x; \
+       done
+
+.c.o:
+       $(CC) -c $(DEFS) $(CFLAGS) $<
+
+clean:
+       rm -f *.log *.[oa] $(TPROG1) $(TPROG2) $(TPROG3) 
+       rm -f core mon.out gmon.out errlist *~
+
+depend: depend2
+
+depend1:
+       sed '/^#Depend/q' <Makefile >Makefile.tmp
+       $(CPP) $(DEFS) -M *.c >>Makefile.tmp
+       mv -f Makefile.tmp Makefile
+
+depend2:
+       $(CPP) $(DEFS) -M *.c >.depend  
+
+#GNU make style depend
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
+
+#Depend --- DOT NOT DELETE THIS LINE
diff --git a/www/wcgi.c b/www/wcgi.c
new file mode 100644 (file)
index 0000000..3fb3cec
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#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\n<HTML><HEAD><TITLE>Server Failure</TITLE></HEAD>\n");
+    printf("<BODY>%s</BODY>\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)<serverfifo>\0<extrapath>\0<envvars>\0<INFO>\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;
+}
diff --git a/www/wproto.c b/www/wproto.c
new file mode 100644 (file)
index 0000000..6bc7cb0
--- /dev/null
@@ -0,0 +1,412 @@
+/*
+ * 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: wproto.c,v $
+ * Revision 1.1  1995/10/20 11:49:26  adam
+ * First version of www gateway.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include "wproto.h"
+
+static int wproto_dumpcache(WCLIENT wc, int level);
+static int wproto_findcache(WCLIENT wc, char *name);
+static void wproto_uncache(WCLIENT wc, int level);
+
+static char *mod = "wproto";
+
+void wo_puts(WCLIENT wc, char *s)
+{
+    int len;
+
+    if (wc->outbuffer_offset + (len = strlen(s)) + 1 > wc->outbuffer_size)
+       wc->outbuffer = realloc(wc->outbuffer, wc->outbuffer_size +=
+       OUTBUFFER_CHUNK);
+    memcpy(wc->outbuffer + wc->outbuffer_offset, s, len + 1);
+    wc->outbuffer_offset += len;
+}
+
+void wo_printf(WCLIENT wc, const char *fmt, ...)
+{
+    va_list ap;
+    char tmpbuf[4048];
+
+    va_start(ap, fmt);
+    vsprintf(tmpbuf, fmt, ap);
+    wo_puts(wc, tmpbuf);
+    va_end(ap);
+}
+
+void wo_clear(WCLIENT wc, char *type)
+{
+    if (!wc->outbuffer)
+       wc->outbuffer = malloc(wc->outbuffer_size = OUTBUFFER_CHUNK);
+    wc->outbuffer_offset = 0;
+    wo_printf(wc, "Content-type: %s\n\n", type);
+}
+
+int wo_puthtml(WCLIENT wc, char *name)
+{
+    FILE *f; 
+    char ch;
+
+    wo_clear(wc, "text/html");
+    if (!(f = fopen(name, "r")))
+    {
+       wo_printf(wc, "<BR>Failed to open file: %s<BR>", name);
+       return 0;
+    }
+    while (ch = getc(f), !feof(f))
+    {
+       if (wo_putc(wc, ch) < 0)
+       {
+           fclose(f);
+           return -1;
+       }
+    }
+    fclose(f);
+    return 0;
+}
+
+int wo_flush(WCLIENT wc)
+{
+    int wrote, towrite;
+
+    if (!(wc->outbuffer_offset))
+       return 0;
+    towrite = wc->outbuffer_offset;
+    wc->outbuffer_offset = 0;
+    for (;;)
+    {
+       wrote = write(wc->lineout, wc->outbuffer + wc->outbuffer_offset,
+           towrite);
+       if (wrote <= 0)
+       {
+           gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, mod, "write response");
+           return -1;
+       }
+       if (wc->cache_fd >= 0)
+           if (write(wc->cache_fd, wc->outbuffer + wc->outbuffer_offset,
+               towrite) < 0)
+           {   
+               gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, mod, "write cache");
+               return -1;
+           }
+       towrite -= wrote;
+       if (!towrite)
+           break;
+       wc->outbuffer_offset += wrote;
+    }
+    wc->outbuffer_offset = 0;
+    return 0;
+}
+
+int wo_overflow(WCLIENT wc, char ch)
+{
+    gw_log (GW_LOG_DEBUG, mod, "wo_overflow");
+    if (wo_flush(wc) < 0)
+       return -1;
+    return wo_putc(wc, ch);
+}
+
+int wo_finish(WCLIENT wc)
+{
+    gw_log (GW_LOG_DEBUG, mod, "wo_finish");
+    if (wo_flush(wc) < 0)
+       return -1;
+    close(wc->lineout);
+    wc->lineout = -1;
+    if (wc->cache_fd >= 0)
+    {
+       close(wc->cache_fd);
+       wc->cache_fd = -1;
+    }
+    return 0;
+}
+
+static void descramble(char *t, const char *o)
+{
+    unsigned int v;
+
+    while (*o)
+    {
+       if (*o == '%' && isxdigit(*(o + 1)) && isxdigit(*(o + 2)))
+       {
+           sscanf(o + 1, "%2x", &v);
+           o += 3;
+           *(t++) = (char) v;
+       }
+       else
+           *(t++) = *(o++);
+    }
+    *t = '\0';
+}
+
+static void decode_form(wform_data *form, char *buf)
+{
+    int i = 0;
+    char *p;
+    char tmp[512];
+
+    while (*buf)
+    {
+       for (p = form[i].name; *buf && *buf != '='; buf++)
+           *(p++) = *buf;
+       *p = '\0';
+       if (*buf)
+           buf++;
+       for (p = tmp; *buf && *buf != '&'; buf++)
+           *(p++) = *buf;
+       *p = '\0';
+       descramble(form[i].value, tmp);
+       if (*buf)
+           buf++;
+       i++;
+    }
+    *form[i].name = '\0';
+}
+
+char *wgetval(WCLIENT wc, char *name)
+{
+    int i;
+
+    for (i = 0; *wc->wf_data[i].name; i++)
+       if (!strcmp(name, wc->wf_data[i].name))
+           return wc->wf_data[i].value;
+    return 0;
+}
+
+int wproto_process(WCLIENT wc, int timeout)
+{
+    int toread, rs, level;
+    char combuf[COMBUF], *p,*t;
+    fd_set input;
+    struct timeval to, *top;
+
+    for (;;)
+    {
+       gw_log (GW_LOG_DEBUG, mod, "process waiting for input.");
+       if (timeout > 0)
+       {
+           to.tv_usec = 0;
+           to.tv_sec = timeout;
+           top = &to;
+       }
+       else
+           top = 0;
+       FD_ZERO(&input);
+       FD_SET(wc->linein, &input);
+       while ((rs = select(wc->linein + 1, &input, 0, 0, top)) < 0 &&
+           errno == EINTR)
+           ;
+       if (rs < 0)
+       {
+           gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, mod, "select");
+           return -1;
+       }
+       if (rs == 0)
+       {
+           gw_log (GW_LOG_STAT, mod, 
+                    "wproto_process returning 0 after %d second timeout.",
+                   timeout);
+           return 0;
+       }
+       if (read(wc->linein, &toread, sizeof(toread)) < sizeof(toread))
+       {
+           gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, mod, "wp_proc:len read failed");
+           exit(1);
+       }
+       toread -= sizeof(toread);
+       if (read(wc->linein, combuf, toread) < toread)
+       {
+           gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, mod, "wp_proc: data read failed");
+           exit(1);
+       }
+       p = combuf;
+       for (t = wc->wf_serverp; (*t = *p); t++, p++);
+       p++;
+       for (t = wc->wf_parms; (*t = *p); t++, p++);
+       p++;
+       p++;         /* we don't deal with envvars yet */
+       decode_form(wc->wf_data, p);
+       if (wc->lineout < 0 && (wc->lineout = open(wc->wf_serverp, O_WRONLY))
+           < 0)
+       {
+           gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, mod, "open %s", wc->wf_serverp);
+           exit(1);
+       }
+       /* look in cache only if request carries no forms data. */
+       if (!*wc->wf_data[0].name && (level = wproto_findcache(wc,
+           wc->wf_parms)) >= 0)
+       {
+           wproto_dumpcache(wc, level);
+           wo_finish(wc);
+       }
+       else
+           return 1;
+    }
+}
+
+WCLIENT wproto_init(void)
+{
+    char path2[256];
+    wclient_data *new;
+
+    gw_log (GW_LOG_DEBUG, mod, "wproto_init");
+    close(1);    /* release us from the wserver */
+    new = malloc(sizeof(*new));
+    sprintf(new->path, "%s/%s/clt%d", FIFOROOT, FIFODIR, getpid());
+    if (mkfifo(new->path, 0666 | S_IFIFO) < 0)
+    {
+       gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, mod, "mkfifo(%s)", new->path);
+       exit(1);
+    }
+    gw_log (GW_LOG_DEBUG, mod, "Synchronizing with server.");
+    sprintf(path2, "%s/%s/srv%d", FIFOROOT, FIFODIR, getppid());
+    if ((new->lineout = open(path2, O_WRONLY)) < 0)
+    {
+       gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, mod, "open %s", path2);
+       exit(1);
+    }
+    if (write(new->lineout, "OK", 2) < 2)
+    {
+       gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, mod, "write");
+       exit(1);
+    }
+    gw_log (GW_LOG_DEBUG, mod, "Synchronized.");
+    if ((new->linein = open(new->path, O_RDONLY)) < 0)
+    {
+       gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, mod, "open input handle %s", new->path);
+       exit(1);
+    }
+    /* we put a handle on this so we get a blocking read when no peer */
+    if (open(new->path, O_WRONLY | O_NDELAY) < 0)
+    {
+       gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, mod, "open dummy %s", new->path);
+       exit(1);
+    }
+    new->outbuffer = 0;
+    new->cache_level = -1;
+    new->cache_fd = -1;
+    return new;
+}
+
+static void wproto_uncache(WCLIENT wc, int level)
+{
+    for (;wc->cache_level >= level; wc->cache_level--)
+       unlink(wc->cache[wc->cache_level].path);
+}
+
+void wproto_terminate(WCLIENT wc)
+{
+    close(wc->linein);
+    unlink(wc->path);
+    wproto_uncache(wc, 0);
+    free(wc);
+}
+
+int wproto_cache(WCLIENT wc, int level)
+{
+    cache_data *p;
+
+    if (level > wc->cache_level + 1)
+    {
+       gw_log (GW_LOG_FATAL, mod, "Illegal cache level increment.");
+       exit(1);
+    }
+    wproto_uncache(wc, level);
+    p = &wc->cache[++wc->cache_level];
+    sprintf(p->path, "%s/%s/csh%d.%d", FIFOROOT, FIFODIR, getpid(), level);
+    if ((wc->cache_fd = open(p->path, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0)
+    {
+       gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, mod, "open %s", p->path);
+       return -1;
+    }
+    strcpy(p->name, wc->wf_parms);
+    return 0;
+}
+
+static int wproto_findcache(WCLIENT wc, char *name)
+{
+    int i;
+
+    for (i = 0; i <= wc->cache_level; i++)
+       if (!strcmp(wc->cache[i].name, name))
+           return i;
+    return -1;
+}
+
+static int wproto_dumpcache(WCLIENT wc, int level)
+{
+    int fd, rd;
+
+    gw_log (GW_LOG_STAT, mod, "Using Cache: %s", wc->cache[level].name);
+    if ((fd = open(wc->cache[level].path, O_RDONLY)) < 0)
+    {
+       gw_log (GW_LOG_FATAL, mod, "open (R) %s", wc->cache[level].path);
+       return -1;
+    }
+    while ((rd = read(fd, wc->outbuffer, OUTBUFFER_CHUNK)) > 0)
+       if (write(wc->lineout, wc->outbuffer, rd) < rd)
+       {
+           gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, mod, "write toline");
+           return -1;
+       }
+    if (rd < 0)
+    {
+       gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, mod, "read");
+       return -1;
+    }
+    wproto_uncache(wc, level + 1);
+    return 0;
+}
diff --git a/www/wproto.h b/www/wproto.h
new file mode 100644 (file)
index 0000000..fef0d48
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * 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: wproto.h,v $
+ * Revision 1.1  1995/10/20 11:49:27  adam
+ * First version of www gateway.
+ *
+ */
+
+#ifndef WPROTO_H
+#define WPROTO_H
+
+#include <gw-log.h>
+#include <gw-res.h>
+
+#define COMBUF 4096
+#define OUTBUFFER_CHUNK 4096
+
+#define FIFOROOT "/tmp"
+#define FIFODIR "egw"
+
+typedef struct wform_data
+{
+    char name[20];
+    char value[512];
+} wform_data;
+
+typedef struct cache_data
+{
+    char name[256];
+    char path[256];
+} cache_data;
+
+typedef struct wclient_data
+{
+    wform_data wf_data[100];
+    char wf_parms[512];
+    char wf_serverp[512];
+    char path[512];
+    int linein;
+    int lineout;
+    char *outbuffer;
+    int outbuffer_size;
+    int outbuffer_offset;
+    int cache_level;
+    cache_data cache[20];
+    int cache_fd;
+} *WCLIENT, wclient_data;
+
+#define wo_putc(wc, ch)   \
+    ((wc)->outbuffer_offset >= OUTBUFFER_CHUNK ? wo_overflow((wc), (ch)) :  \
+    (*((wc)->outbuffer + (wc)->outbuffer_offset++) = (char) (ch)), 0)
+
+char *wgetval(WCLIENT wc, char *name);
+int wproto_process(WCLIENT wc, int timeout);
+WCLIENT wproto_init(void);
+void wo_printf(WCLIENT wc, const char *fmt, ...);
+void wo_clear(WCLIENT wc, char *type);
+int wo_finish(WCLIENT wc);
+int wo_flush(WCLIENT wc);
+int wo_overflow(WCLIENT wc, char ch);
+void wproto_terminate(WCLIENT wc);
+int wproto_cache(WCLIENT wc, int level);
+int wo_puthtml(WCLIENT wc, char *name);
+void wo_puts(WCLIENT wc, char *s);
+
+#endif
diff --git a/www/wsh.c b/www/wsh.c
new file mode 100644 (file)
index 0000000..f36d42e
--- /dev/null
+++ b/www/wsh.c
@@ -0,0 +1,97 @@
+/*
+ * 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: wsh.c,v $
+ * Revision 1.1  1995/10/20 11:49:28  adam
+ * First version of www gateway.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <assert.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include "wproto.h"
+
+#define TIMEOUT_SHORT 300
+#define TIMEOUT_MEDIUM 1800
+#define TIMEOUT_LONG 7200
+
+static WCLIENT wcl;
+static char *mod = "wsh";
+
+int main (int argc, char **argv)
+{
+    char *argument, *p, parms[512];
+    int timeout = TIMEOUT_SHORT;
+
+    chdir("/usr/local/etc/httpd/cgi-bin");
+    gw_log_init ("egw");
+    gw_log_file (GW_LOG_ALL, "/usr/local/etc/httpd/logs/egwsh_log");
+    gw_log_level (GW_LOG_ALL);
+    gw_log (GW_LOG_STAT, mod, "Europagate www shell");
+
+    if (!(wcl = wproto_init()))
+    {
+       gw_log (GW_LOG_FATAL, mod, "init");
+       exit(1);
+    }
+    while (wproto_process(wcl, timeout) > 0)
+    {
+       wo_clear(wcl, "text/html");
+       wo_printf(wcl, "<HTML><TITLE>INDEX</TITLE>\n");
+       strcpy(parms, wcl->wf_parms);
+       argument = p = parms;
+       while (*p && *p != '/')
+           p++;
+       if (*p == '/')
+           *(p++) = '\0';
+       gw_log (GW_LOG_DEBUG, mod, "command: %s", argument);
+        wo_printf (wcl, "<BODY>hej - %s</BODY>\n", argument);
+       wo_finish(wcl);
+    }
+    wproto_terminate(wcl);
+    return 0;
+}
diff --git a/www/wtest.c b/www/wtest.c
new file mode 100644 (file)
index 0000000..77dc438
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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: wtest.c,v $
+ * Revision 1.1  1995/10/20 11:49:28  adam
+ * First version of www gateway.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "wproto.h"
+
+static WCLIENT wcl;
+static char *mod = "wtest";
+
+int main()
+{
+    int timeout = 60;
+    int counter = 0;
+    int i;
+
+    chdir ("/usr/local/etc/httpd/cgi-bin");
+    gw_log_init ("egw");
+    gw_log_level (GW_LOG_ALL);
+    gw_log_file (GW_LOG_ALL, "/usr/local/etc/httpd/logs/wtest_log");
+    gw_log (GW_LOG_STAT, mod, "Europagate www test");
+
+    if (!(wcl = wproto_init ()))
+    {
+        gw_log (GW_LOG_FATAL, mod, "init");
+        exit (1);
+    }
+    while (wproto_process(wcl, timeout) > 0)
+    {
+        gw_log (GW_LOG_DEBUG, mod, "Process input");
+       wo_clear (wcl, "text/html");
+       wo_printf (wcl, "<HTML><TITLE>Test page</TITLE>\n");
+       wo_printf (wcl, "Hello from the test program.<BR>\n");
+       wo_printf (wcl, "This is #%d time that you call me!!<BR>\n", ++counter);
+       wo_printf (wcl, "My parameters are '%s'<BR>\n", wcl->wf_parms);
+       wo_printf (wcl, "My server FIFO is '%s'<BR>\n", wcl->wf_serverp);
+       for (i = 0; *wcl->wf_data[i].name; i++)
+       {
+           wo_printf (wcl, "%s = %s<BR>\n", wcl->wf_data[i].name, 
+                                             wcl->wf_data[i].value);
+       }
+       wo_printf (wcl, "Here is a button which references ");
+       wo_printf (wcl, "<A HREF=\"http://localhost/cgi-bin/egwcgi/%d/%d\">me</A> "
+                 "again.\n", getpid(), counter);
+        wo_printf (wcl, "</HTML>\n");
+        wo_finish (wcl);
+        gw_log (GW_LOG_DEBUG, mod, "Process end");
+    }
+    wproto_terminate (wcl);
+    return 0;
+}