* USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Log: wcgi.c,v $
- * Revision 1.6 1995/11/06 17:44:22 adam
+ * Revision 1.13 1996/01/12 10:05:17 adam
+ * If script name ends with ';' HTTP/GET/Expires will be defined.
+ * The cgi interface only reads final handshake if response from
+ * server (shell) was zero-terminated [If it isn't it probably died].
+ *
+ * Revision 1.12 1996/01/09 10:46:49 adam
+ * New defines: LOGDIR/EGWDIR/CGIDIR set in Makefile.
+ *
+ * Revision 1.11 1996/01/08 08:42:19 adam
+ * Handles method GET.
+ *
+ * Revision 1.10 1996/01/05 16:21:20 adam
+ * Bug fix: shell (wproto) sometimes closed server FIFO before cgi
+ * program opened it - solution: cgi sends OK when response has been read.
+ *
+ * Revision 1.9 1995/12/20 16:31:33 adam
+ * Bug fix: shell might terminate even though new request was initiated
+ * by the cgi interface program.
+ * Work on more simple user interface and Europagate buttons.
+ *
+ * Revision 1.8 1995/11/08 16:14:35 adam
+ * Many improvements and bug fixes.
+ * First version that ran on dtbsun.
+ *
+ * Revision 1.7 1995/11/08 12:42:18 adam
+ * Added descriptive text field in target info.
+ * Added authentication field in target info.
+ *
+ * Revision 1.6 1995/11/06 17:44:22 adam
* State reestablised when shell restarts. History of previous
* result sets.
*
#include <gw-db.h>
#include "wproto.h"
-#define CGIDIR "/usr/local/etc/httpd/cgi-bin"
-
static char *prog = "cgi";
static char serverp[256] = {'\0'};
case 0:
close (0);
close (1);
+ close (2);
gw_log (GW_LOG_DEBUG, prog, "execl %s", path);
execl (path, sprog, 0);
gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "execl %s", path);
}
}
+#if 0
+static void print_environ (void)
+{
+ extern char **environ;
+ int i;
+
+ for (i = 0; environ[i]; i++)
+ gw_log (GW_LOG_DEBUG, prog, "e: %s", environ[i]);
+}
+#endif
+
/*
* NOTE: In the (perhaps odd) terminology used within this software,
* the 'server' is the present program, which is executed by the httpd
char combuf[COMBUF];
int linein = -1, lineout, data, gw_id;
+ chdir ("/usr/local/etc/httpd/cgi-bin");
gw_log_init ("egw");
- gw_log_file (GW_LOG_ALL, "/usr/local/etc/httpd/logs/egwcgi_log");
+ gw_log_file (GW_LOG_ALL, LOGDIR "/egwcgi_log");
gw_log_level (GW_LOG_ALL);
gw_log (GW_LOG_STAT, prog, "Europagate www cgi server");
path_info++;
if (*path_info)
*(path_info++) = '\0';
- if (!(gw_db = gw_db_open ("user.db", 1)))
+ if (!(gw_db = gw_db_open (EGWDIR "/www.db", 1, 1)))
{
gw_log (GW_LOG_FATAL, prog, "gw_db_open");
exit (1);
strcpy(p, serverp);
p += strlen(p) + 1;
strcpy(p, path_info);
+ gw_log (GW_LOG_DEBUG, prog, "P:%s", p);
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");
+ int j, i = 0;
+ while (i < data)
+ {
+ j = read(0, p + i, data - i);
+ if (j == -1)
+ {
+ gw_log (GW_LOG_ERRNO|GW_LOG_FATAL, prog,
+ "Failed to read input");
+ fatal("Internal error in server");
+ }
+ else if (j == 0)
+ {
+ gw_log (GW_LOG_ERRNO, prog, "Failed to read input");
+ fatal("Internal error in server");
+ }
+ i += j;
}
}
- p += data;
- *(p++) = '\0';
+ else if ((t = getenv("QUERY_STRING")))
+ {
+ strcpy (p, t);
+ data = strlen(p);
+ }
+ p[data] = '\0';
+ gw_log (GW_LOG_DEBUG, prog, "C:%s", p);
+ p += data+1;
data = (p - combuf);
memcpy(combuf, &data, sizeof(data));
gw_log (GW_LOG_DEBUG, prog, "Writing data");
gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "write");
fatal("Internal server error");
}
- if (linein < 0 && (linein = open(serverp, O_RDONLY)) < 0)
+ if (linein < 0)
{
- gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "open %s", serverp);
- fatal("Internal error in server");
+ gw_log (GW_LOG_DEBUG, prog, "open %s", serverp);
+ if ((linein = open(serverp, O_RDONLY)) < 0)
+ {
+ gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "open %s", serverp);
+ fatal("Internal error in server");
+ }
}
gw_log (GW_LOG_DEBUG, prog, "Reading response");
-#if 0
while ((data = read(linein, combuf, COMBUF)) > 0)
{
gw_log (GW_LOG_DEBUG, prog, "Got %d bytes", data);
+ if (combuf[data-1] == '\0')
+ break;
if (write(1, combuf, data) < data)
{
gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "write");
gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "read");
exit (1);
}
-#else
-# if 0
- fcntl (linein, F_SETFL, O_NONBLOCK);
-# endif
- while (1)
+ if (data > 0)
{
- fd_set s_input;
- struct timeval t;
- int r, eof_flag = 0;
-
- t.tv_sec = 10;
- t.tv_usec = 0;
- FD_ZERO(&s_input);
- FD_SET(linein, &s_input);
-# if 0
- FD_SET(1, &s_input);
-# endif
- gw_log (GW_LOG_DEBUG, prog, "select");
- r = select (linein + 1, &s_input, NULL, NULL, &t);
- if (r < 0)
- {
- gw_log (GW_LOG_ERRNO|GW_LOG_FATAL, prog, "select");
- exit(1);
- }
- if (r == 0 || FD_ISSET (linein, &s_input))
- {
- if (r == 0)
- gw_log (GW_LOG_DEBUG, prog, "poll");
- if ((data = read (linein, combuf, COMBUF)) > 0)
- {
- if (combuf[data-1] == '\0')
- {
- --data;
- eof_flag = 1;
- }
- gw_log (GW_LOG_DEBUG, prog, "Got %d bytes", data);
- if (data > 0 && write(1, combuf, data) < data)
- {
- gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "write");
- exit (1);
- }
- }
- else if (data == -1)
- {
- if (r > 0)
- {
- gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "read");
- exit (1);
- }
- gw_log (GW_LOG_DEBUG, prog, "poll read");
- }
- else
- break;
- }
- if (eof_flag)
- break;
- if (r > 0 && FD_ISSET (1, &s_input))
+ --data;
+ if (write(1, combuf, data) < data)
{
- data = read (1, combuf, COMBUF);
- if (data == -1)
- {
- gw_log (GW_LOG_DEBUG|GW_LOG_ERRNO, prog, "stdout closed");
- break;
- }
- if (data == 0)
- {
- gw_log (GW_LOG_DEBUG, prog, "stdout closed");
- break;
- }
- gw_log (GW_LOG_DEBUG, prog, "stdout got %d bytes", data);
+ gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "write");
+ exit (1);
}
+ gw_log (GW_LOG_DEBUG, prog, "writing ack");
+ if (write(lineout, "OK", 2) < 2)
+ gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "write");
}
-#endif
gw_log (GW_LOG_DEBUG, prog, "Cleaning up.");
close(linein);
unlink(serverp);