home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * GSQL - a Mosaic gateway to SQL applications.
- *
- * Jason Ng, NCSA,
- * University of Illinois Urbana-Champaign
- * 1994
- *
- * This is public domain software. There is one requirement: if you use this
- * software, you should include a link in your forms or documents that
- * would mention GSQL and NCSA, and would point to the Tutorial on GSQL,
- * ie http://www.ncsa.uiuc.edu/SDG/People/jason/pub/gsql/starthere.html
- *
- * */
-
-
- #include <string.h>
- #include <stdio.h>
-
- #define SELECTKEYWORD "SELECT"
-
- static int dbg = 0;
- static int dd = 0;
-
- static char *sqlprogram = NULL;
-
- static FILE * fstream = NULL; /* procfile file descriptor */
-
- #define NM 101
- #define NITEMS 2010
- static int nmenus = 0;
- static char *menuvname[NM];
- static char *menutitle[NM];
- static char *mitem[NITEMS][NM];
- static int nitems[NM];
- static int menutype[NM];
-
- #define M_BUTTON 0
- #define M_FIELD 1
- #define M_SCROLL 2
- #define M_PULLDOWN 3
- #define M_RADIO 4
- #define M_BUTTONSET 5
-
- static int g_widgettypes[] =
- { M_FIELD, M_BUTTON, M_SCROLL, M_PULLDOWN, M_RADIO, M_BUTTONSET };
- static char *g_widgetnames[] =
- { "FIELD", "BUTTON", "SCROLL", "PULLDOWN", "RADIO", "BUTTONSET" };
- #define g_ndefwidtypes (sizeof(g_widgettypes)/sizeof(int))
-
- #define LLEN 5000
- newmenu(title, vname,type) char *title, *vname; char *type;
- {
- int i,t, id;
- char mtype[50];
- /* fprintf(stderr, "NEWMENU [%s] [%s] type [%s]\n", title, vname, type); */
-
- sscanf(type,"%s", mtype);
- for(t=-1, i=0;i<g_ndefwidtypes;i++)
- if(!strcmp(mtype,g_widgetnames[i])) { t = g_widgettypes[i]; break; }
-
- if(t==-1) return(-1);
-
- menuvname[nmenus] = strdup(vname);
- menutitle[nmenus] = strdup(title);
- menutype[nmenus] = t;
- nitems[nmenus] = 0;
- id = nmenus; nmenus++;
- return(id);
- }
-
- addmenuitem(id, itemname) int id; char *itemname;
- {
- int n = nitems[id];
- /* fprintf(stderr,"added [%s] ",itemname); */
- mitem[n][id] = strdup(itemname);
- nitems[id]++;
- }
-
- makeform () {
- int a;
- char buf[LLEN];
-
- printf("<H1> New Mosaic-SQL interface </H1> <HR>\n");
- if (getdirective("HEADING", buf))
- printf("%s\n",buf);
- else
- printf("<H1> Type-2 SQL Forms <H2>\n",buf);
-
- printf("<FORM>\n");
- for (a=0; a< (int) getitemcount(); a++) {
- int itemid;
- char type[10];
- fetchitem (a , type, &itemid);
- if (!strcmp(type,"TEXT"))
- displaytext(itemid);
- else if (!strcmp(type,"MENU"))
- displaymenu(itemid);
- else if (!strcmp(type,"EXEC")) {
- getscript(itemid, buf);
- execscript (buf);
- }
- }
- printf(" <p> <INPUT TYPE=\"submit\" VALUE=\"Doit!\"> <P>\n");
- printf("</FORM>\n");
-
- if (dbg) showmenus();
- }
-
- /* displays the menu specified by id - index into the menu structure */
- displaymenu(id) int id;
- {
- int j, maxsize;
- printf("<p> %s ", menutitle[id]);
- if (menutype[id]==M_FIELD ) { /* input field */
- printf(" <INPUT NAME=\"%s\">\n", menuvname[id]);
- }
- else if (menutype[id]==M_BUTTON) { /* toggle button */
- printf("<INPUT TYPE=\"checkbox\" NAME=\"%s\" > \n",
- menuvname[id]);
- }
- else if (menutype[id]==M_BUTTONSET || menutype[id]==M_RADIO) { /* buttons */
- for(j=0;j<nitems[id];j++) {
- if(menutype[id]==M_BUTTONSET)
- printf("<INPUT TYPE=\"checkbox\" NAME=\"%s\" VALUE=\"%s\"> %s\n",
- menuvname[id], mitem[j][id] , mitem[j][id]);
- else if(menutype[id]==M_RADIO)
- printf("<INPUT TYPE=\"radio\" NAME=\"%s\" VALUE=\"%s\"> %s\n",
- menuvname[id], mitem[j][id] , mitem[j][id]);
- }
- }
- else if (menutype[id]==M_SCROLL || menutype[id]==M_PULLDOWN) { /* menus */
- maxsize = nitems[id] -1 ; if (maxsize<2) maxsize=2;
- if(menutype[id]==M_SCROLL)
- printf("<SELECT NAME=\"%s\" MULTIPLE>\n", menuvname[id], maxsize);
- else if(menutype[id]==M_PULLDOWN)
- printf("<SELECT NAME=\"%s\">\n", menuvname[id]);
- for(j=0;j<nitems[id];j++) {
- if(j==0)
- printf(" <OPTION SELECTED> %s\n", mitem[j][id]);
- else
- printf(" <OPTION> %s\n", mitem[j][id]);
- }
- printf("</SELECT><p>\n");
- }
- }
-
- showmenus() {
- int i,j;
- fprintf(stderr,"SHOWALL\n");
- for(i=0;i<nmenus;i++) {
- fprintf(stderr, "MENU title [%s] [%s][%d]\n",
- menutitle[i],menuvname[i], menutype[i]);
- for(j=0;j<nitems[i];j++) {
- fprintf(stderr, "\t [%s]\n", mitem[j][i]);
- }
- }
- }
-
- /* ARGS: arg[1] = procfilename
- arg[2-..] user inputs from form output
- Minimally, procfilename is needed.
- */
- main(ac,av) int ac; char**av; {
-
- int i;
- char * procfilename;
-
- printf("Content-type: text/html \n\n");
-
- /*
- printf("NEW STUFF "); fflush(stdout);
- printf("NARGS %d \n", ac); if (ac>3) { printf(" SHOULD BE 3 <p>"); }
- for(i=0;i<ac;i++) { printf("<b>%d</b> [%s]\n", i,av[i]); } printf("<p>");
- */
-
- if(ac<2) {
- printf("Usage: %s procfilename user-inputs...\n",av[0]);
- exit(0);
- }
- else if(ac==2) {
- procfilename = av[1];
- parsefile1(procfilename);
- makeform();
- exit(0);
- }
- else {
- char buf[LLEN];
- procfilename = av[1];
- combineargs(ac,av,buf);
- /* printf("AFTER COMBINE args is <pre><tt> [%s]</tt></pre> \n", buf); */
- parseinputs(buf); /* buf: "v1=n1&v2=b2&...&vx=bx", b's can be empty */
-
- parsefile2(procfilename);
- mergeall();
- }
- }
-
-
- combineargs(ac,av,buf)
- int ac;
- char *av[], *buf;
- {
- int i;
-
- /* av[1] is the procfilename - skip over */
- if(ac<3) return;
- strcpy(buf,av[2]);
- for(i=3;i<ac;i++) {
- strcat(buf,av[i]);
- }
- }
-
- /* data structure to receive user inputs - conv to name-value pairs */
- #define NU 200
- static char *u_vname[NU];
- static char *u_vval[NU];
- static int u_vspecial[NU]; /* 1 if that varname starts with "_" */
- static int n_u = 0;
-
-
- parseinputs (inbuf) char *inbuf;
- {
- char *s, *s1=inbuf;
- char *headv, *tailv;
- int i;
-
- for(i=0;i<NU;i++) { /* init */
- u_vname[i] = u_vval[i] = NULL;
- u_vspecial[i] = 0;
- }
-
- i = 0;
- printf("<pre>");
- while(NULL!=( s = strtok(s1,"&"))) {
- {{
- char *b1, *b2;
- b1 = strchr(s,'='); if(b1==NULL) continue;
- *b1 = '\0';
- headv = strdup(s);
- b1++;
- if(b1) tailv = strdup(b1);
- }}
- if(headv[0]=='_') u_vspecial[i] = 1;
- u_vname[i] = strdup(headv);
- u_vval[i] = strdup(tailv);
- if(dd) { printf(" <li> userinput [%s] [%s]",u_vname[i], u_vval[i]);
- if (u_vspecial[i] ) printf(" <b> special </b>\n");
- }
- i++;
- s1=NULL;
- }
- n_u = i;
-
- printf("</pre>");
- }
-
- /* parses only display and exec directives */
- parsefile1 (filename) char *filename;
- {
- char buf[LLEN];
- char title[LLEN];
- char vname[LLEN];
- int id;
-
- if (NULL == (fstream= fopen(filename,"r"))) {
- printf("parsefile1: Cannot open procfile [%s]\n", filename);
- exit(0);
- }
-
- while( getword(buf)) {
- if (buf[0]=='#') { /* comment - ignore */
- flushline();
- }
- else if (!strcmp(buf,"TEXT")) {
- getline(buf);
- id = savetext(buf);
- registeritem ("TEXT", id);
- }
- else if (!strcmp(buf,"HEADING")) {
- getline(buf);
- savedirective("HEADING", buf);
- }
- else if (!strcmp(buf,"SHOW")) {
- getword(vname);
- if (dbg) fprintf(stderr,"VARIABLE [%s]\n", vname);
- getword(buf);
- getquotedline(title);
-
- getline(buf);
- id = newmenu(title,vname, buf);
- makemenu (id, buf);
- registeritem ("MENU", id);
-
- }
- else if (!strcmp(buf,"EXEC")) {
- getline(buf);
- id = savescript(buf);
- registeritem ("EXEC", id);
- }
- }
- fclose (fstream);
- }
-
- /* will scan to last semi-colon, and truncate the rest of line */
- getline(ss) char*ss;
- {
- char *sp, sbuf[LLEN];
-
- ss[0] ='\0';
- while(1) {
- if (NULL==fgets(sbuf,LLEN,fstream)) {
- return(0);
- }
- if(sbuf[0] =='#') {
- if(dbg) fprintf(stderr," found comment [%s]\n", sbuf);
- continue; /* ignore comment, get another line */
- }
- sp = strrchr(sbuf,';');
- if (sp) { /* found semicolon - concat and return */
- sp[0] = '\0'; /* chop off rest of line */
- strcat(ss,sbuf);
- return(1);
- }
- /* semicolon not found, concat and get more lines */
- strcat(ss,sbuf);
- }
- }
-
- /* look for and return the next quoted string "xxx" */
- getquotedline(ss) char*ss;
- {
- char sbuf[LLEN], *sp = sbuf;
- int c;
-
- ss[0] ='\0';
-
- while (EOF != (c = fgetc(fstream)) ) {
- if (c== '\"') /* opening quote */
- break;
- }
-
- while (EOF != (c = fgetc(fstream)) ) {
-
- if (c== '\"') { /* closing quote */
- *sp++ = '\0';
- strcpy(ss,sbuf);
- return(1);
- }
- else {
- *sp++ = c;
- }
- }
- }
-
- flushline() { /* throw away rst of line in input stream */
- char sbuf[LLEN];
- fgets(sbuf,LLEN,fstream);
- }
-
- getword(ss) char*ss;
- {
- char *sp;
- char sbuf[LLEN];
-
- if( EOF== fscanf(fstream,"%s",sbuf) ) return(0);
-
- if (sp = strrchr(sbuf,';')) { *sp = '\0'; } /* remove semicolon */
-
- sscanf(sbuf,"%s", ss);
- return(1);
- }
-
-
- /* for each item, need to remove leading and trailing blanks */
- /* Note that mline must have a first word of the menu type keyword */
- makemenu (menuid, mline ) int menuid; char *mline ; {
- #define PATTERN ","
-
- char *s, *s1;
- char *zz = mline;
-
- /* skip past first word */
- while( zz && isspace(*zz) ) { zz++; } if (zz==NULL) return;
- while( zz && !isspace(*zz) ) { zz++; } if (zz==NULL) return;
-
- if (dbg) fprintf(stderr,"DOIT rest ID %d[%s]\n", menuid, zz);
-
- if (NULL!=(s1 = strstr(zz,"EXEC"))) {
- FILE *f;
- char buf[LLEN];
- execcommand((s1+4), &f);
- while(NULL!=fgets(buf, LLEN, f)){
- addmenuitem(menuid, buf);
- }
- fclose(f);
- return;
- }
-
- s1=zz;
- while(NULL!=( s = strtok(s1,PATTERN))) {
- chopblanks(&s);
- addmenuitem(menuid, s);
- s1=NULL;
- }
-
- }
- chopblanks(ss) char **ss;
- {
- char *sp = *ss;
- int n;
- while(isspace(*sp) ) sp++;
- *ss = sp;
-
- sp = *ss;
- n = strlen(*ss);
- sp = *ss+(n-1);
- while(isspace(*sp)) { *sp = '\0'; sp--; }
-
- }
-
- /* ================================================================== */
- /* list of graphic objects */
- #define NOBJ 200
- static int obj_ref[NOBJ]; /* actually a unique reference int */
- static int obj_type[NOBJ]; /* t - text, m - menu, e -exec */
- static int n_obj = 0;
-
- /* rets its ordering , or -1 if error */
- int registeritem(type, ref) char *type; int ref;
- {
- int t , n;
-
- if (!strcmp(type,"TEXT")) {
- t = 't';
- }
- else if (!strcmp(type,"MENU")) {
- t = 'm';
- }
- else if (!strcmp(type,"EXEC")) {
- t = 'e';
- }
- else { return(-1); }
-
- n = n_obj;
- obj_ref[n] = ref;
- obj_type[n] = t;
- n_obj++;
- return (n);
- }
-
- getitemcount() { return (n_obj); }
-
- fetchitem (which, type, ref )
- int which; /* its ordering as ret from registeritem() */
- int *ref; /* output */
- char *type; /* output */
- {
- *ref = obj_ref[which];
- switch (obj_type[which]) {
- case 't': strcpy(type,"TEXT"); break;
- case 'm': strcpy(type,"MENU"); break;
- case 'e': strcpy(type,"EXEC"); break;
- default : strcpy(type,"NONE"); return(0); break;
- }
- return(1);
-
- }
-
- /* ================================================================== */
- /* storage for user's scripts and executables */
- #define NEX 80
- static char * d_ex[NEX];
- static int n_ex = 0;
-
- /* rets id of script , else -1 */
- int savescript(ex) char *ex;
- {
- int id;
- d_ex[n_ex] = strdup ( ex );
- id = n_ex; n_ex++;
- return (id);
- }
-
- getscript (id, ex) int id; char *ex;
- {
- strcpy(ex, d_ex[id] );
- }
- execscript (ex) char *ex;
- {
- char tfile[500];
- char buf[LLEN];
- FILE *f;
-
- tmpnam(tfile);
- sprintf(buf, "%s > %s ", ex, tfile);
-
- system( buf );
- f = fopen(tfile,"r");
- if(f==NULL) { printf("cannot open %s \n", tfile); return; }
-
- while(NULL!= fgets(buf, LLEN, f)) printf("%s",buf);
- fclose(f);
- }
-
- execcommand (ex,fhandle) char *ex; FILE **fhandle;
- {
- char tfile[500];
- char buf[LLEN];
- FILE *f;
-
-
- tmpnam(tfile);
- sprintf(buf, "%s > %s ", ex, tfile);
-
- system( buf );
- f = fopen(tfile,"r");
- if(f==NULL) { printf("cannot open %s \n", tfile); *fhandle = NULL; return; }
- *fhandle = f;
-
- }
-
- /* ================================================================== */
- /* storage for user's text */
- #define NTXT 80
- static char * d_text[NTXT];
- static int n_txt = 0;
-
- /* rets id of text, else -1 */
- int savetext(text) char *text;
- {
- int id;
- d_text[n_txt] = strdup ( text);
- id = n_txt; n_txt++;
- return (id);
- }
-
- gettext (id, text) int id; char *text;
- {
- strcpy(text, d_text[id] );
- }
- displaytext ( id) int id;
- {
- char text[LLEN];
- gettext(id, text);
- printf("%s", text);
- }
-
- /* ================================================================== */
- /* defines from DEFINE */
- /* sql directives and the expansion */
-
- /* general sql directives */
- static char * d_cmd[] = { "FROMLIST", "SELECTLIST", "WHERELIST", "SORTLIST", "HEADING" };
- #define NW ( sizeof(d_cmd)/sizeof(char *) )
- static char * d_mean[NW];
- static int n_cmd = NW;
-
- /* defines from DEFINE */
- #define MDEF 40
- static char * d_defvar[MDEF];
- static char * d_defval[MDEF];
- static int n_def = 0;
-
- /* variables from SUB */
- #define NV 200
- static char * var_name[NV];
- static char * var_mean[NV];
- static char * var_kind[NV]; /* what list it's part of eg SELECT or WHERE */
- static char * var_fmt[NV]; /* string to format output as */
- static int var_used[NV]; /* 1 if has user input */
- static int n_var = 0;
-
- parsefile2 (filename) char *filename;
- {
- char buf[LLEN], tbuf[LLEN];
- char vname[LLEN];
- int id, i;
-
- if (NULL == (fstream= fopen(filename,"r"))) {
- printf("parsefile2: Cannot open procfile [%s]\n", filename);
- exit(0);
- }
-
- for(i=0;i<NW;i++) { d_mean[i] = NULL; }
-
- for(i=0;i<NV;i++) { /* init */
- var_name[i] = var_mean[i] = var_kind[i] = NULL;
- var_used[i] = 0;
- var_fmt[i] = NULL;
- }
-
- printf("<PRE>");
- while( getword(buf)) {
- if (buf[0]=='#') {
- if(dbg) fprintf(stderr,"comment word [%s]\n", buf);
- flushline();
- }
- else if (!strcmp(buf,"HEADING")) {
- getline(buf);
- savedirective("HEADING", buf);
- }
- else if (!strcmp(buf,"SUB")) {
- getword(vname);
- var_name[n_var] = strdup(vname);
- getword(buf); /* kind */
- var_kind[n_var] = strdup(buf);
- getword(buf); /* AS */
- getline(buf); /* meaning */
- var_mean[n_var] = strdup(buf);
- if(dd) printf("<li> FILE VAR [%s] [%s] [%s] \n",
- var_name[n_var], var_kind[n_var], var_mean[n_var]);
- n_var++;
- }
- else if (!strcmp(buf,"SQLPROG")) {
- getline(tbuf);
- sqlprogram = strdup(tbuf);
- }
- else if (!strcmp(buf,"DEFINE")) {
- getword(tbuf);
- sscanf(tbuf,"%s",buf);
- d_defvar[n_def] = strdup(buf);
- getline(tbuf);
- sscanf(tbuf,"%s",buf);
- d_defval[n_def] = strdup(buf);
- if(dd) printf("<li> usrdefine [%s] [%s]\n", d_defvar[n_def], d_defval[n_def]);
- n_def++;
- }
- else { /* save if is a sql directive */
- getline(tbuf);
- savedirective (buf, tbuf);
-
- }
- }
- printf("</PRE>");
- fclose (fstream);
- }
-
- /* ------------------------------------------------------------------ */
- /* returns the meaning of a SUB variable */
- lookupmean (var, meaning) char *var, *meaning;
- {
- int i;
- for (i=0;i<n_var;i++)
- if (!strcmp(var, var_name[i])) {
- strcpy(meaning, var_mean[i]);
- return(1);
- }
- return(0);
- }
- /* ------------------------------------------------------------------ */
- /* updates the var_xxx structures with info from user */
- /* doesn't account for duplicate vars for now */
-
- mergeall()
- {
-
- int i, j, t, num;
- char *vname;
- char buf[LLEN]; /* contains all matches (comma-separated) for a variable */
- int match[200], nm;
- char sqlstr[LLEN];
-
- /* -- sub user inputs in the variables --- */
- /* some vars (arrays) can have multiple userinput values */
- for (i=0;i<n_var;i++) {
- vname = var_name[i];
- for (nm=0, t=0; t<n_u; t++) {
- if (!strcmp(vname, u_vname[t])) {
- if (strlen(u_vval[t])>0) { /* don't bother if empty value */
- var_used[i] = 1;
- match[nm] = t; nm++;
- }
- }
- }
- if (nm>0) { /* build the match string */
- buf[0]='\0';
- for (j=0;j<nm;j++) {
- t = match[j];
- if (u_vspecial[t]) { /* look up its meaning */
- char tbuf[LLEN];
- if (!lookupmean (u_vval[t], tbuf)) {
- strcpy(tbuf,"Undefined");
- printf("<li>UNDEFINED [%s]\n", u_vval[t]);
- }
- else {
- if (j!=0) strcat(buf, ",");
- strcat(buf, tbuf);
- }
- }
- else { /* just use the input */
- if (j!=0) strcat(buf, ",");
- strcat(buf, u_vval[t]);
- }
- }
- substitute(&var_mean[i], buf);
- }
- }
-
- /* --- build the sql string from the pieces --- */
-
- sqlstr[0] ='\0';
- strcat (sqlstr," \" " );
- strcat( sqlstr, SELECTKEYWORD);
-
- num = 0;
- if( getdirective("SELECTLIST", buf)) {
- strcat(sqlstr, buf );
- num = 1;
- }
- for (i=0;i<n_var;i++) {
- if (var_used[i]) {
- if (!strcmp(var_kind[i],"SELECTLIST")) {
- if(num>0) strcat(sqlstr, ", ");
- strcat(sqlstr, var_mean[i]);
- num++;
- }
- }
- }
- if (num==0) { /* yikes..no user-selected values, & no default select list */
- printf(" <H1> You must select field(s) to display. </H1> ");
- return;
- }
-
-
- if( getdirective("FROMLIST", buf)) {
- strcat(sqlstr, " FROM ");
- strcat(sqlstr, buf );
- }
-
- num = 0;
- strcat(sqlstr, " WHERE ");
- for (i=0;i<n_var;i++) {
- if (var_used[i]) {
- if (!strcmp(var_kind[i],"WHERELIST")) {
- if(num>0) strcat(sqlstr, " AND ");
- strcat(sqlstr, var_mean[i]);
- num++;
- }
- }
- }
- if( getdirective("WHERELIST", buf)) {
- if (num>0) strcat(sqlstr, " AND ");
- strcat(sqlstr, buf );
- }
-
- if( getdirective("SORTLIST", buf)) {
- strcat(sqlstr, buf );
- }
-
- strcat(sqlstr, " \" "); /* entire sql string is quoted */
-
- if(dd) printf("<b> SQL </b> <tt> %s </tt> <p> \n", sqlstr);
-
- stuffmenu("Here is the SQL Query ", sqlstr );
-
- strcat(sqlstr," ");
- for(i=0;i<n_def;i++) {
- char zz[LLEN];
- sprintf(zz," \"%s %s\" ",d_defvar[i], d_defval[i]);
- strcat(sqlstr,zz);
- }
-
- if (getdirective("HEADING", buf)) printf("%s\n",buf);
- printf("<P>");
-
- {{ char cmd[LLEN];
- if (sqlprogram==0) {
- printf("<H1> Sorry..I don't know what SQL program to run.");
- printf("<p>SQLPROG is not specified! </H1>");
- exit(0);
- }
- sprintf(cmd," %s %s ", sqlprogram, sqlstr);
- /* stuffmenu("Here is the cmd ", cmd); */
-
- fflush(stdout);
- system(cmd);
- }}
-
- }
-
- savedirective(cmd, meaning)
- char * cmd , *meaning;
- {
- int i;
-
- for(i=0;i<NW;i++)
- if (!strcmp(cmd , d_cmd[i])) {
- d_mean[i] = strdup(meaning);
- return(1);
- break;
- }
- return(0);
- }
-
- getdirective (cmd , meaning)
- char * cmd , *meaning;
- {
- int i;
- for (i=0;i<n_cmd;i++)
- if (!strcmp(d_cmd[i], cmd)) {
- if(NULL==d_mean[i]) return (0);
- strcpy(meaning, d_mean[i]);
- return(1);
- }
- return(0);
- }
-
-
- /* substitute all occurences of $ in x1 with x2 */
- /* this means reallocing the string at x1 */
- substitute(x1, x2) char **x1, *x2; {
- char buf[LLEN];
- char *orig = *x1;
- char *sp;
-
- /* printf("<p> sub [%s] inside [%s] ", x2, orig); */
- sp = strchr(orig,'$');
- if (sp==NULL) return;
-
- buf[0] = '\0';
-
- *sp ='\0';
- strcat(buf,orig); /* first portion */
-
- strcat(buf,x2); /* substituted portion */
-
- sp++;
- if(sp) { /* end portion */
- strcat(buf,sp);
- }
-
- *x1 = strdup(buf);
- /* printf("new string is [%s] ", *x1); */
- }
-
- /* stuff some text into a menu */
- stuffmenu(title, string) char *title, *string;
- {
- int n;
- char *stringbuf;
- char buf[LLEN];
- char *ss, *s2, *s1;
-
-
- stringbuf = strdup(string);
- /* remove quotes */
- s1 = strchr(stringbuf, '\"'); if(s1) *s1 = ' ';
- s1 = strrchr(stringbuf, '\"'); if(s1) *s1 = ' ';
-
- printf("<FORM>");
- printf("<SELECT NAME=\"sql-query\">\n" );
- printf(" <OPTION> %s \n", title);
-
- s1 = ss = stringbuf;
- while(1) {
- s2 = strchr(s1, ' ');
- if(s2==NULL) break;
- n = s2 - ss;
- if (n > 80) {
- strncpy(buf,ss,n); buf[n]='\0';
- printf(" <OPTION> %s\n", buf);
- ss = ++s2; if(ss==NULL) break;
- }
- else {
- s1 = s2+1;
- }
-
- }
- if (ss) printf(" <OPTION> %s\n", ss); /* trailing text */
- printf("</SELECT><p>\n");
- printf("</FORM>");
-
- fflush(stdout);
- }
-