From 71b5b2cf0d923cf64e9353c9250bd2912e446e0a Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Mon, 6 Nov 1995 10:51:14 +0000 Subject: [PATCH] End of response marker in response from wsh/wproto to wcgi. Shells are respawned when necessary. --- www/Makefile | 8 +++- www/wcgi.c | 146 +++++++++++++++++++++++++++++++++++++++------------------- www/wproto.c | 48 +++++++++++++------ www/wproto.h | 8 +++- www/wsh.c | 8 +++- 5 files changed, 151 insertions(+), 67 deletions(-) diff --git a/www/Makefile b/www/Makefile index be88fa7..98c0843 100644 --- a/www/Makefile +++ b/www/Makefile @@ -2,7 +2,11 @@ # Europagate, 1995 # # $Log: Makefile,v $ -# Revision 1.7 1995/10/31 16:56:23 adam +# Revision 1.8 1995/11/06 10:51:14 adam +# End of response marker in response from wsh/wproto to wcgi. +# Shells are respawned when necessary. +# +# Revision 1.7 1995/10/31 16:56:23 adam # Record presentation. # # Revision 1.6 1995/10/27 17:30:15 adam @@ -33,7 +37,7 @@ ZLIB=../../yaz/lib/libyaz.a MOSILIB=../../xtimosi/src/libmosi.a ../../yaz/lib/librfc.a LIBIRTCL=/usr/local/lib/libirtcl.a $(ZLIB) $(MOSILIB) # -OLIB=../lib/libres+log.a +OLIB=../lib/util.a ../lib/libres+log.a TCLLIB=/usr/local/lib/libtcl7.4.a # WSCRIPTS=egwscript targets.egw query.egw search.egw showfull.egw diff --git a/www/wcgi.c b/www/wcgi.c index 28f388e..d2b915d 100644 --- a/www/wcgi.c +++ b/www/wcgi.c @@ -41,7 +41,11 @@ * USE OR PERFORMANCE OF THIS SOFTWARE. * * $Log: wcgi.c,v $ - * Revision 1.4 1995/11/02 16:35:37 adam + * Revision 1.5 1995/11/06 10:51:15 adam + * End of response marker in response from wsh/wproto to wcgi. + * Shells are respawned when necessary. + * + * Revision 1.4 1995/11/02 16:35:37 adam * Bug fixes and select on FIFOs in wcgi - doesn't really work! * * Revision 1.3 1995/10/31 16:56:24 adam @@ -69,6 +73,7 @@ #define DEADSTRING "Your database server has terminated. To reactivate \ the server, please reload the server's 'front page'." +#include #include "wproto.h" #define CGIDIR "/usr/local/etc/httpd/cgi-bin" @@ -76,21 +81,27 @@ the server, please reload the server's 'front page'." static char *prog = "cgi"; static char serverp[256] = {'\0'}; +static GW_DB gw_db = NULL; static void fatal(char *p) { printf("Content-type: text/html\n\nServer Failure\n"); printf("%s\n", p); + if (gw_db) + gw_db_close (gw_db); if (*serverp) unlink(serverp); exit(0); } -static int spawn(char *sprog) +static int spawn (char *sprog, int id) { int r; char path[256]; + char envstr[80]; + sprintf (envstr, "GWID=%d", id); + putenv (envstr); sprintf(path, "%s/%s", CGIDIR, sprog); switch(r = fork()) { @@ -109,7 +120,6 @@ static int spawn(char *sprog) } } - /* * NOTE: In the (perhaps odd) terminology used within this software, * the 'server' is the present program, which is executed by the httpd @@ -120,7 +130,7 @@ int main() { char clientp[256], tmp[256], *path_info, *p, *operation, *t; char combuf[COMBUF]; - int linein = -1, lineout, data, childpid; + int linein = -1, lineout, data, gw_id; gw_log_init ("egw"); gw_log_file (GW_LOG_ALL, "/usr/local/etc/httpd/logs/egwcgi_log"); @@ -160,11 +170,29 @@ int main() path_info++; if (*path_info) *(path_info++) = '\0'; - if ((childpid = atoi(operation)) <= 0) + if (!(gw_db = gw_db_open ("user.db", 1))) { - childpid = spawn(operation); - /* synchronize with client. */ - gw_log (GW_LOG_DEBUG, prog, "Synchronizing with client."); + gw_log (GW_LOG_FATAL, prog, "gw_db_open"); + exit (1); + } + if ((gw_id = atoi(operation)) <= 0) + { + int r; + char gw_id_str[16]; + + gw_id = gw_db_seq_no (gw_db); + sprintf (gw_id_str, "%d", gw_id); + + spawn(operation, gw_id); + r = gw_db_insert (gw_db, gw_id_str, strlen(gw_id_str)+1, + operation, strlen(operation)+1); + if (r) + { + gw_log (GW_LOG_FATAL, prog, "gw_db_insert: %d", r); + gw_db_close (gw_db); + exit (1); + } + 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); @@ -177,13 +205,45 @@ int main() } gw_log (GW_LOG_DEBUG, prog, "Synchronized."); } - sprintf(clientp, "%s/clt%d", tmp, childpid); + sprintf(clientp, "%s/clt%d", tmp, gw_id); 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); + char gw_id_str[16]; + void *sprog; + size_t sprog_size; + int r; + + sprintf (gw_id_str, "%d", gw_id); + r = gw_db_lookup (gw_db, gw_id_str, strlen(gw_id_str)+1, + &sprog, &sprog_size); + if (r != 1) + { + gw_log (GW_LOG_FATAL, prog, "gw_db_lookup %s", gw_id_str); + fatal("Internal error in server"); + } + gw_log (GW_LOG_DEBUG|GW_LOG_ERRNO, prog, "open %s restart", clientp); + spawn (sprog, gw_id); + 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."); + if ((lineout = open(clientp, O_WRONLY)) < 0) + { + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "%s", clientp); + gw_db_close (gw_db); + exit (1); + } } + gw_db_close (gw_db); gw_log (GW_LOG_DEBUG, prog, "Decoding user data."); p = combuf + sizeof(data); strcpy(p, serverp); @@ -226,37 +286,48 @@ int main() exit (1); } } + if (data < 0) + { + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "read"); + exit (1); + } #else -# if 1 +# if 0 fcntl (linein, F_SETFL, O_NONBLOCK); # endif while (1) { fd_set s_input; struct timeval t; - int r; + int r, eof_flag = 0; - t.tv_sec = 5; + t.tv_sec = 10; t.tv_usec = 0; FD_ZERO(&s_input); FD_SET(linein, &s_input); # if 0 - FD_SET(1, &s_output); + FD_SET(1, &s_input); # endif gw_log (GW_LOG_DEBUG, prog, "select"); - r = select (linein + 1, &s_input, NULL, NULL, NULL); + 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) + if (r == 0 || FD_ISSET (linein, &s_input)) { - gw_log (GW_LOG_DEBUG, prog, "poll"); + 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 (write(1, combuf, data) < data) + if (data > 0 && write(1, combuf, data) < data) { gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "write"); exit (1); @@ -264,44 +335,25 @@ int main() } else if (data == -1) { - gw_log (GW_LOG_DEBUG, prog, "No data"); + if (r > 0) + { + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "read"); + exit (1); + } + gw_log (GW_LOG_DEBUG, prog, "poll read"); } else - { - gw_log (GW_LOG_DEBUG, prog, "No more"); break; - } - continue; - } - if (FD_ISSET (linein, &s_input)) - { - data = read (linein, combuf, COMBUF); - if (data == 0) - break; - else if (data < 0) - { - gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "read"); - exit (1); - } - gw_log (GW_LOG_DEBUG, prog, "Got %d bytes", data); - if (write(1, combuf, data) < data) - { - gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "write"); - exit (1); - } } - if (FD_ISSET (1, &s_input)) + if (eof_flag) + break; + if (r > 0 && FD_ISSET (1, &s_input)) { gw_log (GW_LOG_DEBUG, prog, "stdout closed"); break; } } #endif - if (data < 0) - { - gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "read"); - exit (1); - } gw_log (GW_LOG_DEBUG, prog, "Cleaning up."); close(linein); unlink(serverp); diff --git a/www/wproto.c b/www/wproto.c index 49b82b7..bc46653 100644 --- a/www/wproto.c +++ b/www/wproto.c @@ -41,7 +41,11 @@ * USE OR PERFORMANCE OF THIS SOFTWARE. * * $Log: wproto.c,v $ - * Revision 1.5 1995/11/02 16:35:37 adam + * Revision 1.6 1995/11/06 10:51:17 adam + * End of response marker in response from wsh/wproto to wcgi. + * Shells are respawned when necessary. + * + * Revision 1.5 1995/11/02 16:35:37 adam * Bug fixes and select on FIFOs in wcgi - doesn't really work! * * Revision 1.4 1995/10/31 16:56:25 adam @@ -79,18 +83,21 @@ static void wproto_uncache(WCLIENT wc, int level); static char *mod = "wproto"; -void wo_puts(WCLIENT wc, char *s) +void wo_write (WCLIENT wc, const char *s, size_t len) { - int len; - - if (wc->outbuffer_offset + (len = strlen(s)) + 1 > wc->outbuffer_size) + if (wc->outbuffer_offset + len >= wc->outbuffer_size) wc->outbuffer = realloc(wc->outbuffer, wc->outbuffer_size += OUTBUFFER_CHUNK); - memcpy(wc->outbuffer + wc->outbuffer_offset, s, len + 1); + memcpy(wc->outbuffer + wc->outbuffer_offset, s, len); wc->outbuffer_offset += len; } -void wo_printf(WCLIENT wc, const char *fmt, ...) +void wo_puts (WCLIENT wc, const char *s) +{ + wo_write (wc, s, strlen(s)); +} + +void wo_printf (WCLIENT wc, const char *fmt, ...) { va_list ap; char tmpbuf[4048]; @@ -101,7 +108,7 @@ void wo_printf(WCLIENT wc, const char *fmt, ...) va_end(ap); } -void wo_clear(WCLIENT wc, char *type) +void wo_clear (WCLIENT wc, char *type) { if (!wc->outbuffer) wc->outbuffer = malloc(wc->outbuffer_size = OUTBUFFER_CHUNK); @@ -109,7 +116,7 @@ void wo_clear(WCLIENT wc, char *type) wo_printf(wc, "Content-type: %s\n\n", type); } -int wo_puthtml(WCLIENT wc, char *name) +int wo_puthtml (WCLIENT wc, char *name) { FILE *f; char ch; @@ -142,8 +149,11 @@ int wo_flush(WCLIENT wc) wc->outbuffer_offset = 0; for (;;) { + int w_chunk; + + w_chunk = towrite; wrote = write(wc->lineout, wc->outbuffer + wc->outbuffer_offset, - towrite); + w_chunk); if (wrote <= 0) { gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, mod, "write response"); @@ -177,6 +187,8 @@ int wo_overflow(WCLIENT wc, char ch) int wo_finish(WCLIENT wc) { gw_log (GW_LOG_DEBUG, mod, "wo_finish"); + + wo_putc (wc, 0); if (wo_flush(wc) < 0) return -1; close(wc->lineout); @@ -312,7 +324,6 @@ int wproto_process(WCLIENT wc, int timeout) } else { - unlink (wc->wf_serverp); return 1; } } @@ -320,13 +331,22 @@ int wproto_process(WCLIENT wc, int timeout) WCLIENT wproto_init(void) { - char path2[256]; + char *val, path2[256]; wclient_data *new; gw_log (GW_LOG_DEBUG, mod, "wproto_init"); close(1); /* release us from the wserver */ - new = malloc(sizeof(*new)); - new->id = getpid(); + if (!(new = malloc(sizeof(*new)))) + { + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, mod, "malloc"); + exit (1); + } + if (!(val = getenv ("GWID"))) + { + gw_log (GW_LOG_FATAL, mod, "GWID not set"); + exit (1); + } + new->id = atoi (val); sprintf(new->path, "%s/%s/clt%d", FIFOROOT, FIFODIR, new->id); if (mkfifo(new->path, 0666 | S_IFIFO) < 0) { diff --git a/www/wproto.h b/www/wproto.h index 8f35e3a..8b203a9 100644 --- a/www/wproto.h +++ b/www/wproto.h @@ -41,7 +41,11 @@ * USE OR PERFORMANCE OF THIS SOFTWARE. * * $Log: wproto.h,v $ - * Revision 1.3 1995/10/27 15:12:11 adam + * Revision 1.4 1995/11/06 10:51:18 adam + * End of response marker in response from wsh/wproto to wcgi. + * Shells are respawned when necessary. + * + * Revision 1.3 1995/10/27 15:12:11 adam * IrTcl incorporated in the gateway. * Better separation of script types. * Z39.50 gateway scripts entered. @@ -120,6 +124,6 @@ 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); +void wo_puts(WCLIENT wc, const char *s); #endif diff --git a/www/wsh.c b/www/wsh.c index 2927715..20213df 100644 --- a/www/wsh.c +++ b/www/wsh.c @@ -41,7 +41,11 @@ * USE OR PERFORMANCE OF THIS SOFTWARE. * * $Log: wsh.c,v $ - * Revision 1.5 1995/11/01 16:15:48 adam + * Revision 1.6 1995/11/06 10:51:19 adam + * End of response marker in response from wsh/wproto to wcgi. + * Shells are respawned when necessary. + * + * Revision 1.5 1995/11/01 16:15:48 adam * Better presentation of records. Query/set number persistent. * * Revision 1.4 1995/10/27 15:12:12 adam @@ -71,7 +75,7 @@ #include "wtcl.h" #include "wirtcl.h" -#define TIMEOUT_SHORT 180 +#define TIMEOUT_SHORT 120 #define TIMEOUT_MEDIUM 1800 #define TIMEOUT_LONG 7200 -- 1.7.10.4