X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=www%2Fwirtcl.c;h=f70cbcbac8621323672be138793c0b0bd9db9d83;hb=7c2d86a77557592c7dd8d5415d8345f9bb74661c;hp=c6548ce9673036bd789a5da9ca004e6ecddb0030;hpb=a6f3beb071fe8c894ee6c846c86296c84f48e3d4;p=egate.git diff --git a/www/wirtcl.c b/www/wirtcl.c index c6548ce..f70cbcb 100644 --- a/www/wirtcl.c +++ b/www/wirtcl.c @@ -41,7 +41,53 @@ * USE OR PERFORMANCE OF THIS SOFTWARE. * * $Log: wirtcl.c,v $ - * Revision 1.1 1995/10/27 15:12:08 adam + * Revision 1.14 1996/02/12 10:10:31 adam + * Resource/config system used by the gateway. + * + * Revision 1.13 1996/01/24 08:26:54 adam + * All tcl commands prefixed with egw_ (except the html command). + * + * Revision 1.12 1996/01/12 10:05:18 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.11 1996/01/09 16:16:49 adam + * Port to OSF/1. Gif references moved from /gif/ to /egwgif/. + * + * Revision 1.10 1996/01/09 10:46:50 adam + * New defines: LOGDIR/EGWDIR/CGIDIR set in Makefile. + * + * Revision 1.9 1995/11/07 14:56:59 adam + * Work on search in multiple targets. + * New wtcl command: wlog. + * Optional timeout parameter to zwait. + * + * Revision 1.8 1995/11/06 17:44:22 adam + * State reestablised when shell restarts. History of previous + * result sets. + * + * Revision 1.7 1995/11/02 16:35:37 adam + * Bug fixes and select on FIFOs in wcgi - doesn't really work! + * + * Revision 1.6 1995/11/01 16:15:47 adam + * Better presentation of records. Query/set number persistent. + * + * Revision 1.5 1995/10/31 16:56:24 adam + * Record presentation. + * + * Revision 1.4 1995/10/31 10:03:53 adam + * Work on queries. + * New command implemented - aborts script. + * + * Revision 1.3 1995/10/30 17:35:18 adam + * New function zwait that waits for a variable change - due to i/o events + * that invoke callback routines. + * + * Revision 1.2 1995/10/27 17:30:16 adam + * First search request/response that works. + * + * Revision 1.1 1995/10/27 15:12:08 adam * IrTcl incorporated in the gateway. * Better separation of script types. * Z39.50 gateway scripts entered. @@ -60,16 +106,21 @@ #include #include +#include #include "wtcl.h" #include "wirtcl.h" static void *do_create (WCLIENT wcl, void *args); static int do_exec (const char *fname, char *parms, void *mydata); +static int do_load (char *parms, void *mydata); +static int do_save (char *parms, void *mydata); static struct w_interp_type w_interp_t = { "irtcl", do_create, - do_exec + do_exec, + do_load, + do_save }; W_Interp_Type w_interp_irtcl = &w_interp_t; @@ -83,9 +134,37 @@ struct tcl_info { WCLIENT wcl; }; + +static int events (struct tcl_info *p, char *waitVar, int tout); + +static int proc_zwait_invoke (ClientData clientData, Tcl_Interp *interp, + int argc, char **argv) +{ + struct tcl_info *p = (struct tcl_info*) clientData; + + if (argc < 2) + return TCL_OK; + return events (p, argv[1], (argc == 3) ? atoi(argv[2]) : 0); +} + + + +/* select(2) callbacks */ +struct callback { + void (*r_handle)(ClientData); + void (*w_handle)(ClientData); + void (*x_handle)(ClientData); + void *obj; +}; +#define MAX_CALLBACK 200 + +static struct callback callback_table[MAX_CALLBACK]; +static int max_fd = 3; /* don't worry: it will grow... */ + static void *do_create (WCLIENT wcl, void *args) { struct tcl_info *p; + int i; if (!(p = malloc (sizeof(*p)))) { @@ -104,45 +183,82 @@ static void *do_create (WCLIENT wcl, void *args) gw_log (GW_LOG_FATAL, mod, "Cannot make Irtcl_Interp"); exit (1); } + log_init(LOG_ALL, "irtcl", "irtcl_log"); /* initialize irtcl */ + Tcl_CreateCommand (p->interp, "egw_wait", proc_zwait_invoke, p, NULL); + for (i=0; iw_interp, fname, parms))) + return r; + return 0; +} + + +static int events (struct tcl_info *p, char *waitVar, int tout) +{ + int r, i; + char *cp; + char *waitVarVal; static fd_set fdset_tcl_r; static fd_set fdset_tcl_w; static fd_set fdset_tcl_x; + int fifo_in = p->wcl->linein; + if (fifo_in > max_fd) + max_fd = fifo_in; - for (i=0; iinterp, waitVar, 0))) { - callback_table[i].r_handle = NULL; - callback_table[i].w_handle = NULL; - callback_table[i].x_handle = NULL; + waitVarVal = malloc (strlen(cp)+1); + strcpy (waitVarVal, cp); } - if ((r = w_interp_exec (p->w_interp, fname, parms))) - return r; + else + { + char msg[128]; + + sprintf (msg, "Variable %s doesn't exist", waitVar); + gw_log (GW_LOG_WARN, mod, "%s", msg); + Tcl_AppendResult (p->interp, msg, NULL); + return TCL_ERROR; + } + gw_log (GW_LOG_DEBUG, mod, "Waiting %s=%s", waitVar, waitVarVal); while (1) { + struct timeval to, *top; + if (tout > 0) + { + to.tv_usec = 0; + to.tv_sec = tout; + top = &to; + } + else + top = 0; + + if (!(cp = Tcl_GetVar (p->interp, waitVar, 0)) || + strcmp (cp, waitVarVal)) + { + gw_log (GW_LOG_DEBUG, mod, "Changed to %s", cp); + Tcl_AppendResult (p->interp, cp, NULL); + free (waitVarVal); + return TCL_OK; + } FD_ZERO (&fdset_tcl_r); FD_ZERO (&fdset_tcl_w); FD_ZERO (&fdset_tcl_x); - for (r=0, i=min_fd; i<=max_fd; i++) + + for (r=0, i=0; i<=max_fd; i++) { if (callback_table[i].w_handle) { @@ -161,37 +277,50 @@ static int do_exec (const char *fname, char *parms, void *mydata) } } if (!r) - return 0; + break; +#if 1 + gw_log (GW_LOG_DEBUG, mod, "fifo select %d", fifo_in); + FD_SET (fifo_in, &fdset_tcl_r); +#endif if ((r = select(max_fd+1, &fdset_tcl_r, &fdset_tcl_w, - &fdset_tcl_x, 0)) < 0) + &fdset_tcl_x, top)) < 0) { - perror("select"); + gw_log (GW_LOG_ERRNO|GW_LOG_FATAL, mod, "select"); exit(1); } if (!r) - continue; - for (i=min_fd; i<=max_fd; i++) + { + gw_log (GW_LOG_DEBUG, mod, "timeout"); + free (waitVarVal); + return TCL_ERROR; + } + if (FD_ISSET (fifo_in, &fdset_tcl_r)) + { + gw_log (GW_LOG_DEBUG, mod, "FIFO closed"); + free (waitVarVal); + return TCL_ERROR; + } + for (i=0; i<=max_fd; i++) { if (FD_ISSET (i, &fdset_tcl_r)) { - assert (callback_table[i].r_handle); - (*callback_table[i].r_handle) (callback_table[i].obj); + if (callback_table[i].r_handle) + (*callback_table[i].r_handle) (callback_table[i].obj); } if (FD_ISSET (i, &fdset_tcl_w)) { - assert (callback_table[i].w_handle); - (*callback_table[i].w_handle) (callback_table[i].obj); + if (callback_table[i].w_handle) + (*callback_table[i].w_handle) (callback_table[i].obj); } if (FD_ISSET (i, &fdset_tcl_x)) { - assert (callback_table[i].x_handle); - (*callback_table[i].x_handle) (callback_table[i].obj); + if (callback_table[i].x_handle) + (*callback_table[i].x_handle) (callback_table[i].obj); } } - if ((cp=Tcl_GetVar (p->interp, "sessionWait", 0)) && !strcmp (cp, "0")) - return 0; } - return 0; + free (waitVarVal); + return TCL_OK; } void ir_select_add (int fd, void *obj) @@ -222,3 +351,18 @@ void ir_select_remove (int fd, void *obj) callback_table[fd].w_handle = NULL; callback_table[fd].x_handle = NULL; } + +static int do_load (char *parms, void *mydata) +{ + struct tcl_info *p = mydata; + + return w_interp_load_state (p->w_interp, parms); +} + +static int do_save (char *parms, void *mydata) +{ + struct tcl_info *p = mydata; + + return w_interp_save_state (p->w_interp, parms); +} +