From 0eb16f9fa8de016fbe9378db5f975825cc9c5e48 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 12 Jan 1996 13:08:06 +0000 Subject: [PATCH] CGI script passes name of lock file to the shell. The server will not close the response FIFO until this file becomes unlocked. This method handles cancel operations much better. --- www/wcgi.c | 67 ++++++++++++++++++++++++++++++++++++++++++++-------------- www/wproto.c | 26 +++++++++++++++++------ www/wproto.h | 8 ++++++- 3 files changed, 77 insertions(+), 24 deletions(-) diff --git a/www/wcgi.c b/www/wcgi.c index 0aa0be0..540d23b 100644 --- a/www/wcgi.c +++ b/www/wcgi.c @@ -41,7 +41,12 @@ * USE OR PERFORMANCE OF THIS SOFTWARE. * * $Log: wcgi.c,v $ - * Revision 1.13 1996/01/12 10:05:17 adam + * Revision 1.14 1996/01/12 13:08:06 adam + * CGI script passes name of lock file to the shell. The server will not close + * the response FIFO until this file becomes unlocked. This method handles + * cancel operations much better. + * + * 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]. @@ -111,6 +116,7 @@ the server, please reload the server's 'front page'." static char *prog = "cgi"; static char serverp[256] = {'\0'}; +static char serverf[256] = {'\0'}; static GW_DB gw_db = NULL; static void fatal(char *p) @@ -120,7 +126,9 @@ static void fatal(char *p) if (gw_db) gw_db_close (gw_db); if (*serverp) - unlink(serverp); + unlink (serverp); + if (*serverf) + unlink (serverf); exit(0); } @@ -172,12 +180,14 @@ int main() { char clientp[256], tmp[256], *path_info, *p, *operation, *t; char combuf[COMBUF]; + int serverf_fd = -1; int linein = -1, lineout, data, gw_id; chdir ("/usr/local/etc/httpd/cgi-bin"); gw_log_init ("egw"); gw_log_file (GW_LOG_ALL, LOGDIR "/egwcgi_log"); gw_log_level (GW_LOG_ALL); + gw_log_session (getpid()); gw_log (GW_LOG_STAT, prog, "Europagate www cgi server"); sprintf(tmp, "%s/%s", FIFOROOT, FIFODIR); @@ -208,16 +218,35 @@ int main() gw_log (GW_LOG_FATAL, prog, "Must set PATH_INFO."); fatal("Internal error in server."); } + sprintf (serverf, "%s/srf%d", tmp, getpid ()); + gw_log (GW_LOG_DEBUG, prog, "open w %s", serverf); + serverf_fd = open (serverf, O_WRONLY|O_CREAT|O_TRUNC, 0666); + if (serverf_fd == -1) + { + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "open (%s)", serverf); + fatal("Internal error in server."); + } + else + { + struct flock area; + area.l_type = F_WRLCK; + area.l_whence = SEEK_SET; + area.l_start = 0L; + area.l_len = 0L; + fcntl (serverf_fd, F_SETLK, &area); + } operation = ++path_info; while (*path_info && *path_info != '/') path_info++; if (*path_info) *(path_info++) = '\0'; + gw_log (GW_LOG_DEBUG, prog, "www.db open"); if (!(gw_db = gw_db_open (EGWDIR "/www.db", 1, 1))) { gw_log (GW_LOG_FATAL, prog, "gw_db_open"); exit (1); } + gw_log (GW_LOG_DEBUG, prog, "www.db ok"); if ((gw_id = atoi(operation)) <= 0) { int r; @@ -238,7 +267,7 @@ int main() 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 %s", serverp); + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "open r %s", serverp); fatal("Internal error in server."); } if (read(linein, combuf, 2) < 2 || strcmp(combuf, "OK")) @@ -249,7 +278,7 @@ int main() gw_log (GW_LOG_DEBUG, prog, "Synchronized"); } sprintf(clientp, "%s/clt%d", tmp, gw_id); - gw_log (GW_LOG_DEBUG, prog, "Opening %s", clientp); + gw_log (GW_LOG_DEBUG, prog, "open w %s", clientp); if ((lineout = open(clientp, O_WRONLY)) < 0) { char gw_id_str[16]; @@ -265,7 +294,7 @@ int main() 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); + gw_log (GW_LOG_DEBUG|GW_LOG_ERRNO, prog, "open r %s restart", clientp); spawn (sprog, gw_id); gw_log (GW_LOG_DEBUG, prog, "Synchronizing with client"); if ((linein = open(serverp, O_RDONLY)) < 0) @@ -288,9 +317,11 @@ int main() gw_db_close (gw_db); gw_log (GW_LOG_DEBUG, prog, "Decoding user data"); p = combuf + sizeof(data); - strcpy(p, serverp); - p += strlen(p) + 1; - strcpy(p, path_info); + strcpy (p, serverp); + p += strlen (p) + 1; + strcpy (p, serverf); + 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 */ @@ -332,7 +363,7 @@ int main() } if (linein < 0) { - gw_log (GW_LOG_DEBUG, prog, "open %s", serverp); + gw_log (GW_LOG_DEBUG, prog, "open r %s", serverp); if ((linein = open(serverp, O_RDONLY)) < 0) { gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "open %s", serverp); @@ -359,17 +390,21 @@ int main() } if (data > 0) { - --data; - if (write(1, combuf, data) < data) + if (close (serverf_fd)) { - gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "write"); - exit (1); + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "close %s", serverf); + } + if (--data > 0) + { + if (write(1, combuf, data) < 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"); } gw_log (GW_LOG_DEBUG, prog, "Cleaning up."); + unlink (serverf); close(linein); unlink(serverp); close(lineout); diff --git a/www/wproto.c b/www/wproto.c index 799a4d2..51130f9 100644 --- a/www/wproto.c +++ b/www/wproto.c @@ -41,7 +41,12 @@ * USE OR PERFORMANCE OF THIS SOFTWARE. * * $Log: wproto.c,v $ - * Revision 1.13 1996/01/12 10:05:20 adam + * Revision 1.14 1996/01/12 13:08:07 adam + * CGI script passes name of lock file to the shell. The server will not close + * the response FIFO until this file becomes unlocked. This method handles + * cancel operations much better. + * + * Revision 1.13 1996/01/12 10:05:20 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]. @@ -219,19 +224,24 @@ int wo_overflow(WCLIENT wc, char ch) int wo_finish(WCLIENT wc) { - char buf[4]; + int fd; gw_log (GW_LOG_DEBUG, mod, "wo_finish"); wo_putc (wc, 0); if (wo_flush(wc) < 0) return -1; -#if 1 - gw_log (GW_LOG_DEBUG, mod, "reading ack"); - if (read(wc->linein, buf, 2) != 2) + + fd = open (wc->wf_serverf, O_RDONLY); + if (fd != -1) { - gw_log (GW_LOG_DEBUG, mod, "read ack"); + struct flock area; + area.l_type = F_RDLCK; + area.l_whence = SEEK_SET; + area.l_start = 0L; + area.l_len = 0L; + fcntl (fd, F_SETLKW, &area); + close (fd); } -#endif close(wc->lineout); wc->lineout = -1; if (wc->cache_fd >= 0) @@ -357,6 +367,8 @@ int wproto_process(WCLIENT wc, int timeout) p = combuf; for (t = wc->wf_serverp; (*t = *p); t++, p++); p++; + for (t = wc->wf_serverf; (*t = *p); t++, p++); + p++; for (t = wc->wf_parms; (*t = *p); t++, p++); p++; p++; /* we don't deal with envvars yet */ diff --git a/www/wproto.h b/www/wproto.h index ec71a80..bfa6893 100644 --- a/www/wproto.h +++ b/www/wproto.h @@ -41,7 +41,12 @@ * USE OR PERFORMANCE OF THIS SOFTWARE. * * $Log: wproto.h,v $ - * Revision 1.5 1996/01/12 10:05:21 adam + * Revision 1.6 1996/01/12 13:08:07 adam + * CGI script passes name of lock file to the shell. The server will not close + * the response FIFO until this file becomes unlocked. This method handles + * cancel operations much better. + * + * Revision 1.5 1996/01/12 10:05:21 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]. @@ -102,6 +107,7 @@ typedef struct wclient_data wform_data wf_data[100]; char wf_parms[512]; char wf_serverp[512]; + char wf_serverf[512]; char path[512]; int linein; int lineout; -- 1.7.10.4