X-Git-Url: http://jsfdemo.indexdata.com/?a=blobdiff_plain;f=www%2Fwcgi.c;h=be3cb9654936ec9098943162c241d1cae0c32fdd;hb=6c6f3deb01675917b3c73cca50dd20d738593a47;hp=4ab8aa056d31bf276ee38f8bc716c061fa766526;hpb=5414eafed41a60ef3625cfc6770184b36016186e;p=egate.git diff --git a/www/wcgi.c b/www/wcgi.c index 4ab8aa0..be3cb96 100644 --- a/www/wcgi.c +++ b/www/wcgi.c @@ -41,7 +41,29 @@ * USE OR PERFORMANCE OF THIS SOFTWARE. * * $Log: wcgi.c,v $ - * Revision 1.2 1995/10/23 16:55:36 adam + * 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. + * + * 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 + * Record presentation. + * + * Revision 1.2 1995/10/23 16:55:36 adam * A lot of changes - really. * * Revision 1.1 1995/10/20 11:49:25 adam @@ -52,13 +74,18 @@ #include #include #include -#include #include #include +#include +#include +#ifdef AIX +#include +#endif #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" @@ -66,21 +93,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()) { @@ -90,6 +123,7 @@ static int spawn(char *sprog) 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); @@ -99,7 +133,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 @@ -110,8 +143,9 @@ 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; + 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_level (GW_LOG_ALL); @@ -150,31 +184,80 @@ 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); + gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "open %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."); + gw_log (GW_LOG_FATAL, prog, "Failed to synchronize with client"); fatal("Internal error in server"); } - gw_log (GW_LOG_DEBUG, prog, "Synchronized."); + 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 %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); + fatal("Internal error in server"); + } } - gw_log (GW_LOG_DEBUG, prog, "Decoding user data."); + 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; @@ -183,41 +266,129 @@ int main() *(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'; data = (p - combuf); memcpy(combuf, &data, sizeof(data)); - gw_log (GW_LOG_DEBUG, prog, "Writing 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."); + 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_FATAL|GW_LOG_ERRNO, prog, "open %s", serverp); + fatal("Internal error in server"); } - gw_log (GW_LOG_DEBUG, prog, "Reading response."); + gw_log (GW_LOG_DEBUG, prog, "Reading response"); + +#if 1 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."); - } + 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 (data < 0) { gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, prog, "read"); - fatal("Internal server error."); + exit (1); + } +#else +# if 1 + fcntl (linein, F_SETFL, O_NONBLOCK); +# endif + while (1) + { + 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 = 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); + } } +#endif gw_log (GW_LOG_DEBUG, prog, "Cleaning up."); close(linein); unlink(serverp);