Back to index

wims  3.65+svn20090927
exec.c
Go to the documentation of this file.
00001 /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
00002  *
00003  *  This program is free software; you can redistribute it and/or modify
00004  *  it under the terms of the GNU General Public License as published by
00005  *  the Free Software Foundation; either version 2 of the License, or
00006  *  (at your option) any later version.
00007  *
00008  *  This program is distributed in the hope that it will be useful,
00009  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  *  GNU General Public License for more details.
00012  *
00013  *  You should have received a copy of the GNU General Public License
00014  *  along with this program; if not, write to the Free Software
00015  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00016  */
00017 
00018        /* this is part of wims server source.
00019         * This file does execution commands. */
00020 
00021 static void _skip_contents(int isif);
00022 
00023        /* common routine for the two if's. */
00024 static void _exec_if_while(char *p, int numerical, int isif)
00025 {
00026     if(compare(p,numerical,0)==0) _skip_contents(isif); /* skip if false */
00027     else if(!isif) m_file.for_idx++;
00028     return;
00029 }
00030 
00031        /* 'if' non-numerical (unless comparisons are < or >, etc.) */
00032 void exec_if(char *p)
00033 {
00034     _exec_if_while(p,0,1);
00035 }
00036 
00037        /* 'if' numerical. */
00038 void exec_ifval(char *p)
00039 {
00040     _exec_if_while(p,1,1);    
00041 }
00042 
00043 void _exec_while(char *p, int numerical)
00044 {
00045     FOR_STACK *stk;
00046     if(m_file.for_idx>=MAX_FOR_LEVEL) module_error("too_many_fors");
00047     stk=&(m_file.for_stack[m_file.for_idx]);
00048     stk->lineno=m_file.l;
00049     memmove(stk->varname,"?",2);
00050     _exec_if_while(p,numerical,0);
00051 }
00052 
00053        /* 'while' non-numerical (unless comparisons are < or >, etc.) */
00054 void exec_while(char *p)
00055 {
00056     _exec_while(p,0);
00057 }
00058 
00059        /* 'while' numerical. */
00060 void exec_whileval(char *p)
00061 {
00062     _exec_while(p,1);
00063 }
00064 
00065 void exec_endwhile(char *p)
00066 {
00067     FOR_STACK *stk;
00068     if(m_file.for_idx<=0) module_error("next_without_for");
00069     stk=&(m_file.for_stack[m_file.for_idx-1]);
00070     if(stk->varname[0]!='?') module_error("next_without_for");
00071     m_file.for_idx--; *p=0;
00072     m_file.linepointer=stk->lineno;
00073     executed_gotos++;
00074     if(executed_gotos>=GOTO_LIMIT) module_error("too_many_gotos");
00075 }
00076 
00077        /* Should provide a method to stop infinite loop. */
00078 void exec_goto(char *p)
00079 {
00080     char lbuf[MAX_NAMELEN+17];
00081     char *label_start, *line_start;
00082     int old_line;
00083     int i;
00084     executed_gotos++;
00085     if(executed_gotos>=GOTO_LIMIT) module_error("too_many_gotos");
00086     old_line=m_file.l;
00087     label_start=find_word_start(p);
00088     *find_word_end(label_start)=0;
00089     m_file.l=m_file.linepointer=0;
00090     for(i=0;i<m_file.linecnt;i++) {
00091        if(((m_file.lines[i].isstart)&4)==0) continue;
00092        line_start=find_word_start((m_file.lines[i]).address);
00093        if(line_start>(m_file.lines[i+1]).address && i<m_file.linecnt)
00094          continue;
00095        m_file.linepointer=i;
00096        wgetline(lbuf,MAX_NAMELEN+8,&m_file);
00097        line_start=find_word_start(lbuf);
00098        if(*line_start!=label_prefix_char) continue;
00099        line_start++;*find_word_end(line_start)=0;
00100        if(line_start[0]!='*' && strcmp(line_start,label_start)!=0) continue;
00101        *p=0; i++; return;
00102     }
00103     m_file.l=old_line;
00104     setvar(error_data_string,label_start); module_error("label_not_found");    
00105 /*    m_file.linepointer=m_file.linecnt; *p=0;
00106     return;
00107 */}
00108 
00109        /* 'else' with or without 'if'. 
00110         * Philosophy: we implement a loosely checked grammar.
00111         * We cannot check 'if' grammar if we want to use 'goto' 
00112         * together with 'if'. */
00113 void exec_else(char *p)
00114 {
00115     _skip_contents(1); return;    
00116 }
00117 
00118        /* 'endif': nothing needs to be done here. */
00119 void exec_endif(char *p)
00120 {
00121     return;
00122 }
00123 
00124        /* find out the end of a for loop */
00125 void goto_for_end(void)
00126 {
00127     int inner;
00128     char buf[16];
00129     inner=0;
00130     while(m_file.linepointer<m_file.linecnt) {
00131        if((m_file.lines[m_file.linepointer].isstart&2)==0) {
00132            m_file.linepointer++; continue;
00133        }
00134        if(wgetline(buf,8,&m_file)==EOF) break;
00135        *find_word_end(buf)=0;
00136        if(strcmp(buf,"!for")==0) {
00137            inner++; continue;
00138        }
00139        if(strcmp(buf,"!next")==0) {
00140            if(inner>0) {
00141               inner--; continue;
00142            }
00143            else break;
00144        }
00145     }
00146 }
00147 
00148        /* for */
00149 void exec_for(char *p)
00150 {
00151     char *p1, *p2, *p3;
00152     double v1, v2, step;
00153     char buf[MAX_LINELEN+1];
00154     FOR_STACK *stk;
00155 
00156     if(m_file.for_idx>=MAX_FOR_LEVEL) module_error("too_many_fors");
00157     stk=&(m_file.for_stack[m_file.for_idx]);
00158     stk->lineno=m_file.l;
00159     p1=find_word_start(p); 
00160     for(p2=p1; !isspace(*p2) && *p2!=0 && *p2!='=' ; p2++);
00161     if(*p2==0) syntax: module_error("for_syntax");
00162     if(p2-p1>MAX_NAMELEN) module_error("name_too_long");
00163     memmove(stk->varname,p1,p2-p1);
00164     stk->varname[p2-p1]=0;
00165     p1=find_word_start(p2); if(*p1==0) goto syntax;
00166     if(*p1=='=') {
00167        p1++;
00168   assign:
00169        stk->from=0;
00170        p2=wordchr(p1,"to"); 
00171        if(p2==NULL) p2=strstr(p1,"..");
00172        if(p2==NULL) goto syntax;
00173        *p2=0; p2+=2;
00174        p3=wordchr(p2,"step");
00175        if(p3!=NULL) {
00176            *p3=0; p3+=strlen("step");
00177            step=evalue(p3);
00178            if(step==0) module_error("zero_step");
00179        }
00180        else step=1;
00181        v1=evalue(p1); v2=evalue(p2);
00182        float2str(v1,buf); setvar(stk->varname, buf);
00183        if((step>0 && v1>v2) || (step<0 && v1<v2) ) {  /* condition not met */
00184   loop_out:
00185            goto_for_end();
00186        }
00187        else {
00188            stk->varval=v1; stk->varend=v2; stk->step=step;
00189            stk->lineno=m_file.linepointer;
00190            m_file.for_idx++;
00191        }
00192        *p=0; return;
00193     }
00194     if(memcmp(p1,"from",strlen("from"))==0 && isspace(*(p1+strlen("from")))) {
00195        p1+=strlen("from"); goto assign;
00196     }
00197     if(memcmp(p1,"in",strlen("in"))==0 && isspace(*(p1+strlen("in")))) {
00198        stk->from=1; p1+=strlen("in");
00199        p1=find_word_start(p1); if(*p1==0) goto loop_out;
00200        p2=xmalloc(MAX_LINELEN+1);
00201        mystrncpy(p2,p1,MAX_LINELEN);
00202        substit(p2);
00203        strip_trailing_spaces(p2);
00204        if(*p2==0) goto loop_out;
00205        p1=strparchr(p2,','); stk->bufpt=p2;
00206        if(p1!=NULL) {
00207            *p1=0; stk->list_pt=find_word_start(p1+1);
00208        }
00209        else stk->list_pt=NULL;
00210        strip_trailing_spaces(p2); setvar(stk->varname,p2);
00211        stk->lineno=m_file.linepointer;
00212        m_file.for_idx++; *p=0; return;
00213     }
00214     goto syntax;
00215 }
00216 
00217        /* break a for loop */
00218 void exec_break(char *p)
00219 {
00220     FOR_STACK *stk;
00221     if(m_file.for_idx>0) {
00222        stk=&(m_file.for_stack[m_file.for_idx-1]);
00223        if(stk->varname[0]=='?') _skip_contents(0);
00224        else goto_for_end();
00225        m_file.for_idx--;
00226     }
00227     *p=0; return;
00228 }
00229 
00230        /* next */
00231 void exec_next(char *p)
00232 {
00233     double v1, v2, step;
00234     char *p1, *p2;
00235     char buf[MAX_LINELEN+1];
00236     FOR_STACK *stk;
00237     if(m_file.for_idx<=0) module_error("next_without_for");
00238     stk=&(m_file.for_stack[m_file.for_idx-1]);
00239     if(stk->varname[0]=='?') module_error("next_without_for");
00240     if(stk->from) { /* list style */
00241        if(stk->list_pt==NULL) {
00242            free(stk->bufpt);
00243            m_file.for_idx--;
00244            *p=0; return;
00245        }
00246        p1=strchr(stk->list_pt,',');
00247        if(p1!=NULL) {
00248            *p1=0; p2=find_word_start(p1+1);
00249        }
00250        else p2=NULL;
00251        strip_trailing_spaces(stk->list_pt);
00252        setvar(stk->varname,stk->list_pt);
00253        stk->list_pt=p2; goto loop_back;
00254     }
00255     v1=stk->varval; v2=stk->varend; step=stk->step;
00256     v1+=step; stk->varval=v1;
00257     float2str(v1,buf);
00258     setvar(stk->varname, buf);
00259     if((step>0 && v1<=v2) || (step<0 && v1>=v2)) { /* loop */
00260   loop_back:  
00261        m_file.linepointer=stk->lineno;
00262        executed_gotos++;
00263        if(executed_gotos>=GOTO_LIMIT) module_error("too_many_gotos");
00264     }
00265     else m_file.for_idx--;
00266     *p=0; return;
00267 }
00268 
00269        /* Execution of a file in the module directory,
00270         * only for trusted modules. */
00271 void exec_mexec(char *p)
00272 {
00273     direct_exec=1;
00274     calc_mexec(p);
00275     direct_exec=0;
00276 }
00277 
00278        /* call shell. */
00279 void _exec_ex(char *p, char *arg0, char *arg1, int n)
00280 {
00281     char *abuf[8];
00282     char errorfname[MAX_FNAME+1];
00283 
00284     if(robot_access) {
00285        *p=0; return;
00286     }
00287     if(!noout || !trusted_module() || is_class_module) {
00288        _calc_exec(p,arg0,arg1,n); if(outputing) output0(p);
00289        return;
00290     }
00291     mkfname(errorfname,"%s/exec.err",tmp_dir);
00292     abuf[0]=arg0; abuf[1]=arg1; abuf[n]=p; abuf[n+1]=NULL;
00293     wrapexec=1; exportall();
00294     execredirected(abuf[0],NULL,NULL,errorfname,abuf);
00295 }
00296 
00297        /* call shell. */
00298 void exec_sh(char *p)
00299 {
00300     _exec_ex(p,"sh","-c",2);
00301 }
00302 
00303        /* call perl. */
00304 void exec_perl(char *p)
00305 {
00306     _exec_ex(p,"perl","-e",2);
00307 }
00308 
00309        /* file should not be cached */
00310 void exec_nocache(char *p)
00311 {    m_file.nocache|=1; *p=0; }
00312 
00313        /* Read another file. */
00314 void exec_read(char *p)
00315 {
00316     WORKING_FILE save;
00317     char parmsave[MAX_LINELEN+1];
00318     char *pp,*ps;
00319     int t,cache;
00320     
00321     strip_trailing_spaces(p);p=find_word_start(p);
00322     if(*p==0) return;
00323     pp=find_word_end(p); if(*pp) *pp++=0;
00324     pp=find_word_start(pp);
00325     ps=getvar("wims_read_parm"); if(ps==NULL) ps="";
00326     mystrncpy(parmsave,ps,sizeof(parmsave));
00327     setvar("wims_read_parm",pp);
00328     memmove(&save,&m_file,sizeof(WORKING_FILE));
00329     cache=1; if(p[0]=='.' && p[1]=='/') {p+=2; cache=0;}
00330     t=untrust;
00331     if(strncmp(p,"wimshome/",9)==0) {
00332        if((untrust&255)!=0 && 
00333           (m_file.name[0]=='/' || strncmp(m_file.name,"wimshome/",9)==0))
00334          module_error("Illegal_file_access");
00335        untrust|=0x200;
00336     }
00337     if((untrust&0x202)!=0) {
00338        pp=getvar("wims_trustfile");
00339        if(pp!=NULL && *pp!=0 && wordchr(pp,p)!=NULL)
00340          untrust&=0xfdfd;
00341     }
00342     readnest++; if(readnest>MAX_READNEST) module_error("too_many_nested_read");
00343     if(outputing) phtml_put(p,cache); else var_proc(p,cache);
00344     readnest--; untrust=t;
00345     memmove(&m_file,&save,sizeof(WORKING_FILE));
00346     setvar("wims_read_parm",parmsave);
00347 }
00348 
00349        /* read a variable processing file */
00350 void exec_readproc(char *p)
00351 {
00352     int o=outputing; outputing=0; exec_read(p); outputing=o;
00353 }
00354 
00355 void exec_defread(char *p)
00356 {
00357     int t,o;
00358     secure_exec();
00359     t=untrust; untrust|=0x400;
00360     o=outputing; outputing=0;
00361     exec_read(p); untrust=t; outputing=o;
00362 }
00363 
00364        /* Change to another file (no return) */
00365 void exec_changeto(char *p)
00366 {
00367     m_file.linepointer=m_file.linecnt;
00368     exec_read(p);
00369 }
00370 
00371 int header_executed=0, tail_executed=0;
00372 
00373        /* internal routine: get other language versions */
00374 void other_langs(void)
00375 {
00376     int i,j,k;
00377     char *p, lbuf[4], pbuf[MAX_FNAME+1], *phtml;
00378     char namebuf[MAX_FNAME+1], listbuf[4*MAX_LANGUAGES];
00379     static int otherlangs_got=0;
00380 
00381     if(otherlangs_got) return;
00382     mystrncpy(namebuf,module_prefix,sizeof(namebuf));
00383     listbuf[0]=0;j=strlen(namebuf)-3; p=listbuf;
00384     if(j>=2 && strcmp("light",namebuf+j-2)==0) {
00385        setvar("wims_light_module","yes");
00386        phtml=getvar("phtml");
00387        if(phtml==NULL || *phtml==0) return;
00388        mystrncpy(pbuf,phtml,sizeof(pbuf));
00389        j=strlen(pbuf)-3;
00390        if(pbuf[j]!='.') return;
00391        j++; strcpy(lbuf,pbuf+j); pbuf[j]=0;
00392        j=strlen(namebuf);
00393        snprintf(namebuf+j,MAX_FNAME-j-10,"/pages/%s",pbuf);
00394        j=strlen(namebuf);
00395        for(i=k=0;i<available_lang_no;i++) {
00396            if(strcmp(lbuf,available_lang[i])==0) continue;
00397            mystrncpy(namebuf+j,available_lang[i],MAX_FNAME-j);
00398            if(ftest(namebuf)<0) continue;
00399            if(k>0) *p++=',';
00400            mystrncpy(p,available_lang[i],sizeof(listbuf)-4-(p-listbuf));
00401            p+=strlen(p);
00402            k++;          
00403        }
00404        goto end;
00405     }
00406     if(j>0 && namebuf[j]=='.') {
00407        setvar("wims_light_module","");
00408        j++; strcpy(lbuf,namebuf+j); namebuf[j]=0;
00409        for(i=k=0;i<available_lang_no;i++) {
00410            if(strcmp(lbuf,available_lang[i])==0) continue;
00411            snprintf(namebuf+j,MAX_FNAME-j,"%s/main.phtml",
00412                    available_lang[i]);
00413            if(ftest(namebuf)<0) continue;
00414            if(k>0) *p++=',';
00415            mystrncpy(p,available_lang[i],sizeof(listbuf)-4-(p-listbuf));
00416            p+=strlen(p);
00417            k++;          
00418        }
00419     }
00420     end: setvar("wims_otherlangs",listbuf); otherlangs_got=1;
00421 }
00422 
00423        /* Standardised reference to wims home */
00424 void exec_homeref(char *p)
00425 {
00426     char *ref, *user;
00427     
00428     if(ismhelp || tail_executed) return;
00429     setvar("wims_homeref_parm",p); *p=0;
00430     user=getvar("wims_user");
00431     if(user==NULL) user="";
00432     if(*user==0 || robot_access) ref=home_referer;
00433     else {
00434        if(strcmp(user,"supervisor")==0) ref=home_referer_supervisor;
00435        else ref=home_referer_user;
00436     }
00437     if(user[0]==0 && !robot_access) other_langs();
00438     phtml_put_base(ref,0); tail_executed=1;
00439 }
00440 
00441        /* Standardised header menu */
00442 void exec_headmenu(char *p)
00443 {
00444     char *ref, *user;
00445     
00446     if(header_executed) return;
00447     setvar("wims_headmenu_parm",p); *p=0;
00448     user=getvar("wims_user");
00449     if(user==NULL) user="";
00450     if(*user==0 || robot_access) ref=header_menu;
00451     else {
00452        if(strcmp(user,"supervisor")==0) ref=header_menu_supervisor;
00453        else ref=header_menu_user;
00454     }
00455     if(user[0]==0 && !robot_access) other_langs();
00456     phtml_put_base(ref,0); header_executed=1;
00457 }
00458 
00459        /* uniformized title */
00460 void exec_title(char *p)
00461 {
00462     char *s;
00463     *p=0;
00464     if(!outputing) return;
00465     s=getvar("wims_title_title");
00466     if(s==NULL || *s==0) {
00467        s=getvar("module_title");
00468        if(s==NULL || *s==0) return;
00469        force_setvar("wims_title_title",s);
00470     }
00471     phtml_put_base(title_page,0);
00472 }
00473 
00474        /* standardized html tail */
00475 void exec_tail(char *p)
00476 {
00477     if(!outputing || tail_executed) {
00478        *p=0; return;
00479     }
00480     if(!ismhelp) exec_homeref(p); *p=0;
00481     _output_("</body></html>");
00482     tail_executed=1;
00483 }
00484 
00485 void determine_font(char *l);
00486 
00487        /* standardized header */
00488 void _header(char *p, int option)
00489 {
00490     char *s1, *s2, hbuf[MAX_LINELEN+1], *ws="", *ws2="", *bo, *ol;
00491     char wsbuf[MAX_LINELEN+1],wsbuf2[MAX_LINELEN+1];
00492     setvar("wims_header_parm",p); *p=0;
00493     if(!outputing || header_executed) return;
00494     s1=getvar("wims_window");
00495     if(mode==mode_popup) {
00496        if(s1!=NULL && *s1!=0) {
00497            char *p1, *p2;
00498            int t1,t2/*,t3,t4*/;
00499            p1=find_word_start(s1);
00500            for(p2=p1; myisdigit(*p2); p2++);
00501            *p2=0; t1=atoi(p1); p1=p2+1;
00502            while(!myisdigit(*p1) && *p1) p1++;
00503            for(p2=p1; myisdigit(*p2); p2++);
00504            *p2=0; t2=atoi(p1); p1=p2+1;
00505 /*         while(!myisdigit(*p1) && *p1) p1++;
00506            for(p2=p1; myisdigit(*p2); p2++);
00507            *p2=0; t3=atoi(p1); p1=p2+1;
00508            while(!myisdigit(*p1) && *p1) p1++;
00509            for(p2=p1; myisdigit(*p2); p2++);
00510            *p2=0; t4=atoi(p1); p1=p2+1;
00511            while(!myisdigit(*p1) && *p1) p1++;
00512            for(p2=p1; myisdigit(*p2); p2++);
00513            if(t3<5) t3=5; if(t4<20) t4=20;
00514 */         snprintf(wsbuf,sizeof(wsbuf),
00515                    "window.focus();window.resizeTo(%d,%d);",
00516                    t1,t2); ws=wsbuf;
00517 /*         snprintf(wsbuf,sizeof(wsbuf),
00518                    "window.focus();window.resizeTo(%d,%d);window.moveTo(%d,%d);",
00519                    t1,t2,t3,t4); ws=wsbuf;
00520 */     }
00521     }
00522     else {
00523        if(s1!=NULL && strcmp(s1,"new")==0)
00524          ws="window.focus();window.resizeTo(800,640);window.moveTo(15,35);";
00525     }
00526     if(strstr(session_prefix,"_exam")!=NULL) {
00527 /*     char buf[64]; */
00528        if(*ws==0) ws="window.focus();";
00529        else ws= "window.focus();window.moveTo(5,70);";
00530 /*     snprintf(buf,sizeof(buf),"name.phtml.%s",lang);
00531        phtml_put_base(buf);
00532        phtml_put_base("jsclock.phtml"); */
00533     }
00534     s1=getvar("wims_html_header"); if(s1==NULL) s1="";
00535     determine_font(getvar("module_language"));
00536     s2=getvar("module_title"); if(s2!=NULL && *s2!=0) {
00537        mystrncpy(hbuf,s2,sizeof(hbuf)); calc_detag(hbuf);
00538        setvar("module_title2",hbuf);
00539     }
00540     mystrncpy(hbuf,s1,sizeof(hbuf)); substit(hbuf);
00541     s2=getvar("wims_htmlbody"); if(s2==NULL) s2="";
00542     bo=getvar("wims_html_bodyoption"); if(bo==NULL) bo="";
00543     ws2=getvar("wims_html_onload"); if(ws2==NULL) ws2="";
00544     snprintf(wsbuf2,sizeof(wsbuf2),"%s%s",ws,ws2);
00545     setvar("wims_html_onload",wsbuf2);
00546     if(wsbuf2[0]) ol=" onload="; else ol="";
00547 /*    output("<html xmlns=\"http://www.w3.org/1999/xhtml\"><head>%s\n\
00548 </head><body %s %s%s %s>\n", */
00549 /*    output("<html>\n\
00550 <head>%s\n\
00551 </head><body %s %s%s %s>\n",
00552           hbuf,s2,ol,wsbuf2,bo);*/
00553         if(ol[0]) {
00554            output("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\
00555            \n<html><head>%s\n\
00556      </head>\n<body %s %s\"%s\" %s>\n",
00557           hbuf,s2,ol,wsbuf2,bo);}
00558           else {
00559           output("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\
00560            \n<html><head>%s\n\
00561      </head>\n<body %s %s%s %s>\n",
00562           hbuf,s2,ol,wsbuf2,bo);
00563           }
00564     exec_headmenu(p);
00565     if(option) exec_title(p);
00566     if(cmd_type==cmd_help) {
00567        char *s=getvar("special_parm");
00568        if(s==NULL) s="";
00569        m_file.linepointer=m_file.linecnt;
00570        if(strcmp(s,"about")==0) strcpy(hbuf,"about.phtml");
00571        else strcpy(hbuf,"help.phtml");
00572        exec_read(hbuf); exec_tail(p); /* param of exec_...() must be readable */
00573        return;
00574     }
00575     header_executed=1;
00576 }
00577 
00578 void exec_header(char *p) { _header(p,1);}
00579 void exec_header1(char *p) { _header(p,0);}
00580 
00581 char href_target[128];
00582 char jsbuf[512];
00583 #define jsstr " onClick=\"%s=window.open('','%s','status=no,toolbar=no,location=no,menubar=no,scrollbars=yes,resizable=yes')\""
00584 int ref_mhelp=0;
00585 int follow_list[]={
00586     ro_session, ro_lang, ro_useropts, ro_module
00587 };
00588 #define follow_no (sizeof(follow_list)/sizeof(follow_list[0]))
00589 
00590 void _httpfollow(char b1[], char *wn, int new)
00591 {
00592     int i;
00593     char *p1, *s, *ss, sb[MAX_LINELEN+1], qbuf[MAX_LINELEN+1];
00594 
00595     sb[0]=0;
00596     for(i=0;i<follow_no;i++) {
00597        if(robot_access && follow_list[i]==ro_session) continue;
00598        if(!new && follow_list[i]!=ro_session 
00599           && follow_list[i]!=ro_module && follow_list[i]!=ro_lang)
00600          continue;
00601        if(follow_list[i]==ro_module) {
00602            char *pp;
00603            if(new) continue;
00604            pp=strstr(b1,"cmd="); 
00605            if(pp==NULL) continue;
00606            pp+=strlen("cmd=");
00607            if(memcmp(pp,"intro",strlen("intro"))==0 ||
00608               memcmp(pp,"new",strlen("new"))==0) continue;      
00609        }
00610        s=getvar(ro_name[follow_list[i]]);
00611        ss=strstr(b1,ro_name[follow_list[i]]);
00612        if(s!=NULL && *s!=0 &&
00613           (ss==NULL || (ss>b1 && *(ss-1)!='&')
00614            || *(ss+strlen(ro_name[follow_list[i]]))!='=')) {
00615            if(follow_list[i]==ro_session && memcmp(href_target,"wims_",5)==0) {
00616               char st[MAX_LINELEN+1];
00617               char *s1;
00618               s1=getvar("wims_session");
00619               if(s1==NULL) internal_error("exec_href() error.\n");
00620               if(ref_mhelp) {
00621                   if(strstr(s1,"_mhelp")!=0)
00622                     snprintf(st,sizeof(st),"%s",s1);
00623                   else
00624                     snprintf(st,sizeof(st),"%s_mhelp",s1);
00625               }
00626               else snprintf(st,sizeof(st),"%.10s%s",s1,href_target+4);
00627               s=st;
00628            }
00629            snprintf(sb+strlen(sb),MAX_LINELEN-strlen(sb),"%s=%s&",
00630                    ro_name[follow_list[i]],s);
00631            if(ismhelp && follow_list[i]==ro_session &&
00632               strstr(sb,"_mhelp")==NULL) 
00633              snprintf(sb+strlen(sb)-1,MAX_LINELEN-strlen(sb)+1,"_mhelp&");
00634        }
00635     }
00636     snprintf(qbuf,MAX_LINELEN,"%s%s%s",wn,sb,b1);
00637        /* cleaning up query string */
00638     for(p1=qbuf;*p1;p1++) {
00639        if(*p1=='"') string_modify(qbuf,p1,p1+1,"%22");
00640        if(*p1=='&' && isalpha(*(p1+1))) {
00641            p1++; string_modify(qbuf,p1,p1,"+");
00642        }
00643     }
00644     mystrncpy(b1,qbuf,MAX_LINELEN);
00645 }
00646 
00647        /* Restart with a new module, using http code 302. */
00648 void exec_restart(char *p)
00649 {
00650     char buf[MAX_LINELEN+1], *rfn, buf2[MAX_LINELEN+1];
00651 /*    long int t; */
00652     
00653     if(robot_access || outputing || !trusted_module() || is_class_module) return;
00654 /*    accessfile(buf,"r","%s/restart.time",s2_prefix);
00655     t=atoi(buf); if(t==nowtime) return;   */ /* possible looping */
00656     mystrncpy(buf,find_word_start(p),sizeof(buf));
00657     *find_word_end(buf)=0;
00658     _httpfollow(buf,"",0);
00659     nph_header(301);
00660     rfn=strchr(ref_name,':'); if(rfn==NULL) {
00661        usual: snprintf(buf2,sizeof(buf2),"%s?%s",ref_name,buf);
00662     }
00663     else {
00664        char *p;
00665        p=getvar("wims_protocol");
00666        if(p!=NULL && strcmp(p,"https")==0) {
00667            snprintf(buf2,sizeof(buf2),"https%s?%s",rfn,buf);
00668        }
00669        else goto usual;
00670     }
00671     printf("Location: %s\r\n\r\n\
00672 <!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\
00673 <html><body><a href=\"%s\">%s</a></body></html>",buf2,buf2,buf2);
00674     close_working_file(&m_file,0); write_logs();
00675     snprintf(buf,sizeof(buf),"%ld",nowtime);
00676 /*    accessfile(buf,"w","%s/restart.time",s2_prefix);
00677 */    delete_pid(); exit(0);
00678 }
00679 
00680        /* extract target tag from parm string. */
00681 void href_find_target(char *p)
00682 {
00683     char *pp, *pe,buf1[MAX_LINELEN+1];
00684     href_target[0]=0; jsbuf[0]=0; ref_mhelp=0;
00685     for(pp=find_word_start(p);*pp!=0;pp=find_word_start(pe)) {
00686        pe=find_word_end(pp);
00687        if(strncasecmp(pp,"target=wims_",strlen("target=wims_"))!=0) continue;
00688        memmove(buf1,pp,pe-pp); buf1[pe-pp]=0; substit(buf1);
00689        if(strncasecmp(buf1,"target=wims_mhelp",strlen("target=wims_mhelp"))==0) {
00690            if(*pe!=0) *pe++=0; strcpy(href_target,"wims_help");
00691            ref_mhelp=1;
00692        }
00693        else {
00694            if(*pe!=0) *pe++=0;
00695            mystrncpy(href_target,buf1+strlen("target="),sizeof(href_target));
00696        }
00697        snprintf(jsbuf,sizeof(jsbuf),jsstr,href_target,href_target);
00698        strcpy(pp,pe);return;
00699     }
00700     pp=getvar("module_help");
00701     if(href_target[0]==0 && pp!=NULL && strcmp(pp,"popup")==0 &&
00702        (pe=strstr(p,"cmd=help"))!=NULL) {
00703        if(pe==p || *(pe-1)=='&') {
00704            strcpy(href_target,"wims_help"); ref_mhelp=1;
00705            snprintf(jsbuf,sizeof(jsbuf),jsstr,href_target,href_target);
00706        }
00707     }
00708 }
00709 
00710 void _href_getdef(char src[], char vname[], char buf[], int buflen)
00711 {
00712     char *p1, *p2, *p3;
00713     buf[0]=0;
00714     for(p1=strstr(src,vname); p1; p1=strstr(p2,vname)) {
00715        p2=p1+strlen(vname); if(*p2!='=') continue;
00716        if(p1>src && *(p1-1)!='&') continue;
00717        p2++; p3=strchr(p2,'&'); if(p3==NULL) p3=p2+strlen(p2);
00718        if(p3-p2>=buflen) return; /* too long */
00719        memmove(buf,p2, p3-p2); buf[p3-p2]=0; return;
00720     }
00721 }
00722 
00723        /* Create href to wims requests. subst() is not done. */
00724 void exec_href(char *p)
00725 {
00726     char *s, st[128], sti[128], stc[128], *p1, *p2, *p3, *wn="";
00727     char *U="<u><font color=\"#A0A0C0\">%s</font></u>";
00728     char b1[MAX_LINELEN+1], b2[MAX_LINELEN+1];
00729     int new=0;
00730     if(!outputing) return;
00731     href_find_target(p);
00732     p1=find_word_start(p);
00733     p2=find_word_end(p1); if(*p2) *(p2++)=0;
00734     mystrncpy(b1,p1,sizeof(b1));
00735     mystrncpy(b2,find_word_start(p2),sizeof(b2));
00736     substit(b1); substit(b2);
00737        /* standard reference */
00738     if(*b2==0 && strchr(b1,'=')==NULL) {
00739        char b[MAX_LINELEN+1], *ll;
00740        p1=find_word_start(b1); *find_word_end(p1)=0;
00741        if(*p1==0 || strlen(p1)>64) return;
00742        ll=getvar("module_language"); 
00743        if(ll==NULL || *ll==0 || *(ll+1)==0 || *(ll+2)!=0) ll=lang;
00744        accessfile(b,"r","html/href.%s",ll);
00745        memmove(p1+1,p1,64); *p1='\n'; strcat(p1,"       ");
00746        p2=strstr(b,p1); if(p2==NULL) return;
00747        p1=find_word_start(p2+strlen(p1)); p2=find_word_end(p1);
00748        if(*p2) *(p2++)=0;
00749        p3=strchr(p2,'\n'); if(p3!=NULL) *p3=0;
00750        mystrncpy(b1,p1,sizeof(b1));
00751        mystrncpy(b2,find_word_start(p2),sizeof(b2));
00752        substit(b1); substit(b2);
00753     }
00754        /* for robots: only references without defining cmd. */
00755     if(robot_access && strstr(b1,"cmd=")!=NULL &&
00756        strstr(b1,"module=adm/doc")==NULL) {
00757        _output_(b2); return;
00758     }
00759     if(robot_access && strstr(aliased_cgi,"yes")!=NULL) {
00760        char mbuf[256], lbuf[16];
00761        _href_getdef(b1,"module",mbuf,sizeof(mbuf));
00762        if(mbuf[0]==0) mystrncpy(mbuf,home_module,sizeof(mbuf));
00763        _href_getdef(b1,"lang",lbuf,sizeof(lbuf));
00764        if(strlen(lbuf)!=2) {mystrncpy(lbuf,lang,4);lbuf[2]=0;}
00765        if(strncmp(mbuf,"adm/doc",strlen("adm/doc"))==0) {
00766            char dbuf[256], bbuf[256];
00767            _href_getdef(b1,"doc",dbuf,sizeof(dbuf));
00768            _href_getdef(b1,"block",bbuf,sizeof(bbuf));
00769            if(!myisdigit(dbuf[0])) dbuf[0]=0;
00770            if(dbuf[0]!=0 && bbuf[0]==0) snprintf(bbuf,sizeof(bbuf),"main");
00771            if(dbuf[0]==0)
00772              output("<a href=\"%s%s_doc~.html\">%s</a>", ref_base,lbuf,b2);
00773            else
00774              output("<a href=\"%s%s_doc~%s~%s.html\">%s</a>",
00775                    ref_base,lbuf,dbuf,bbuf,b2);
00776        }
00777        else {
00778            for(s=strchr(mbuf,'/'); s!=NULL; s=strchr(s+1,'/')) *s='~';
00779            output("<a href=\"%s%s_%s.html\">%s</a>", ref_base,lbuf,mbuf,b2);
00780        }
00781        return;
00782     }
00783     s=getvar("wims_ref_id");
00784     if(s!=NULL && *s!=0 && !isspace(*s)) {
00785        snprintf(sti,sizeof(sti)," id=\"%s\"",s);
00786     }
00787     else sti[0]=0;
00788     
00789     s=getvar("wims_ref_class");
00790     if(s!=NULL && *s!=0 && !isspace(*s)) {
00791        snprintf(stc,sizeof(stc)," class=\"%s\"",s);
00792     }
00793     else stc[0]=0;
00794     
00795     s=getvar("wims_ref_target");
00796     if(href_target[0]!=0) s=href_target;
00797     if(s!=NULL && *s!=0 && !isspace(*s)) {
00798        snprintf(st,sizeof(st)," target=\"%s\"",s);
00799        if(strcmp(s,"_parent")!=0) {
00800            new=1; wn="wims_window=new&";
00801        }
00802     }
00803     else st[0]=0;
00804     _httpfollow(b1,wn,new);
00805     tohttpquery(b1);
00806     if(strstr(session_prefix,"_check")!=NULL) {
00807        if(*b2) output(U,b2);
00808        else _output_("<a name=\"0\">");
00809        return;
00810     }
00811     if(jsbuf[0]==0 && st[0]==0 && strstr(session_prefix,"_exam")!=NULL) {
00812        p1=strstr(b1,"cmd="); if(p1!=NULL) {
00813            p1+=strlen("cmd=");
00814            if(strncmp(p1,"new",3)==0 || strncmp(p1,"renew",5)==0 ||
00815               strncmp(p1,"intro",5)==0) {
00816               if(*b2) output(U,b2);
00817               else _output_("<a name=\"#\">");
00818               return;
00819            }
00820        }
00821     }
00822     if(*b2)
00823       output("<a href=\"%s?%s\"%s%s %s %s>%s</a>",
00824             ref_name, b1, st, jsbuf,sti,stc, b2);
00825     else
00826       output("<a href=\"%s?%s\"%s%s %s %s>",ref_name, b1, st, jsbuf,sti,stc);
00827     setvar("wims_ref_id"," ");
00828     setvar("wims_ref_class"," ");
00829 }
00830 
00831        /* Create form refering to the page. */
00832 void exec_form(char *p)
00833 {
00834     char *s, *p1, *p2, *a, *m, *opt, st[128], *wn="";
00835     char abuf[128];
00836     int i, new=0;
00837     if(!outputing) return;
00838     href_find_target(p);
00839     s=getvar("wims_ref_target");
00840     if(href_target[0]!=0) s=href_target;
00841     if(s!=NULL && *s!=0 && !isspace(*s)) {
00842        snprintf(st,sizeof(st)," target=\"%s\"",s);
00843        if(strcmp(s,"_parent")!=0) {
00844            new=1; wn="<input type=hidden name=wims_window value=yes>\n";
00845        }
00846     }
00847     else st[0]=0;
00848     a=getvar("wims_ref_anchor"); if(a==NULL) a="";
00849     opt=find_word_start(find_word_end(find_word_start(p)));
00850     m=getvar("wims_form_method");
00851     if(m!=NULL) {
00852        m=find_word_start(m);
00853        if(strncasecmp(m,"post",4)==0) m="post";
00854        else if(strncasecmp(m,"get",3)==0) m="get";
00855        else if(strncasecmp(m,"file",4)==0) {
00856            m="post\" enctype=\"multipart/form-data";
00857            snprintf(abuf,sizeof(abuf),"?form-data%ld%s",random(),a); a=abuf;
00858            force_setvar("wims_form_method","");
00859        }
00860        else m=default_form_method;
00861     }
00862     else m=default_form_method;
00863     if(strstr(session_prefix,"_check")!=NULL) {
00864        output("<p><form action=\"NON_EXISTING_PAGE\" onsubmit=\"window.close();\" %s>\n",
00865               opt);
00866        return;
00867     }
00868     output("<p><form action=\"%s%s\"%s method=\"%s\" %s>\n%s",ref_name,a,st,m,opt,wn);
00869     if(a!=abuf && a[0]) force_setvar("wims_ref_anchor","");
00870     for(i=0;i<follow_no;i++) {
00871        if(robot_access && follow_list[i]==ro_session) continue;
00872        if(!new && follow_list[i]!=ro_session 
00873           && follow_list[i]!=ro_module && follow_list[i]!=ro_lang)
00874          continue;
00875        if(follow_list[i]==ro_module) continue;
00876        s=getvar(ro_name[follow_list[i]]);
00877        if(s!=NULL && *s!=0) {
00878            if(follow_list[i]==ro_session && memcmp(href_target,"wims_",5)==0) {
00879               char st[MAX_LINELEN+1];
00880               char *s1;
00881               s1=getvar("wims_session");
00882               if(s1==NULL) internal_error("exec_form() error.\n");
00883               snprintf(st,sizeof(st),"%.10s%s",s1,href_target+4);
00884               s=st;
00885            }
00886            output("<input type=hidden name=%s value=\"%s\">\n",
00887                  ro_name[follow_list[i]],s);
00888        }
00889     }
00890     p1=find_word_start(p);p2=find_word_end(p1);
00891     if(p2>p1) {
00892        char buf[64];
00893        int i;
00894        i=p2-p1; if(i>60) i=60;
00895        memmove(buf,p1,i);buf[i]=0;
00896        for(i=0;i<CMD_NO && strcmp(buf,commands[i]);i++);
00897        if(i<CMD_NO) {
00898            output("<input type=hidden name=cmd value=\"%s\">\n",buf);
00899            if(i!=cmd_intro && i!=cmd_new)
00900              output("<input type=hidden name=module value=\"%s\">\n",
00901                    getvar(ro_name[ro_module]));
00902        }
00903     }
00904 }
00905 
00906        /* Creat link to trap robot access, an internal command
00907         * which should not be documented */
00908 void exec_robottrap(char *p)
00909 {
00910     char buf[MAX_LINELEN+1];
00911     if(robot_access) return;
00912     strcpy(buf,"session=$wims_session.1&module=adm/trap");
00913     _output_("<!-- >"); exec_href(buf);
00914     _output_("Robot trapper, do not click!</a> < -->");
00915     exec_href(buf); _output_("<font></font></a>");
00916 }
00917 
00918        /* set definitions in a file. Trusted modules only. */
00919 void exec_setdef(char *p)
00920 {
00921     char *p1, *pp;
00922     char nbuf[MAX_LINELEN+1], fbuf[MAX_LINELEN+1], tbuf[MAX_LINELEN+1];
00923     if(robot_access || !trusted_module() || is_class_module) return;
00924     p1=wordchr(p,"in"); if(p1==NULL) module_error("syntax_error");
00925     *p1=0; p1=find_word_start(p1+strlen("in"));
00926     strcpy(nbuf,p);
00927     mystrncpy(tbuf,p1,sizeof(tbuf));
00928     substit(nbuf); substit(tbuf);
00929     if(find_module_file(tbuf,fbuf,1)) return;
00930     pp=find_word_start(nbuf); p1=find_word_start(fbuf); *find_word_end(p1)=0;
00931     strip_trailing_spaces(pp);
00932     setdef(p1,pp);
00933 }
00934 
00935        /* Set a variable. */
00936 void exec_set(char *name)
00937 {
00938     char *p, *defn, *parm;
00939     char tbuf2[MAX_LINELEN+1], namebuf[MAX_LINELEN+1];
00940     int i;
00941 
00942     p=strchr(name,'=');
00943     if(p==NULL) return; /* warning or error! */
00944     *p=0; defn=find_word_start(p+1);
00945     *find_word_end(name)=0;
00946     mystrncpy(namebuf,find_word_start(name),sizeof(namebuf));
00947        /* we allow substit in names, to implement array */
00948     substit(namebuf); *find_word_end(namebuf)=0;    
00949     if(*defn!=calc_prefix_char) {
00950        /* substitute by default */
00951        mystrncpy(tbuf2,defn,sizeof(tbuf2));
00952        substit(tbuf2); setvar(namebuf,tbuf2); return;
00953     }
00954        /* called from !readdef */
00955     if((untrust&4)!=0) module_error("not_trusted");
00956        /* definition is a command  */
00957     parm=find_word_end(defn+1); 
00958     if( *parm != 0 ) { *parm=0; parm=find_word_start(parm+1); }
00959     i=m_file.lines[m_file.l].varcode;
00960     if(i<0) {
00961        i=search_list(calc_routine,CALC_FN_NO,sizeof(calc_routine[0]),defn+1);
00962        m_file.lines[m_file.l].varcode=i;
00963     }
00964     if(i<0) {
00965            /* replace by warning? */
00966        setvar(error_data_string,defn+1); module_error("bad_cmd");
00967        return;
00968     }
00969     mystrncpy(tbuf2,parm,sizeof(tbuf2)); execnt++;
00970     if(calc_routine[i].tag==0) substit(tbuf2);
00971     tbuf2[sizeof(tbuf2)-1]=0; calc_routine[i].routine(tbuf2);
00972               /* remove trailing new line */
00973     tbuf2[sizeof(tbuf2)-1]=0;
00974     if(tbuf2[strlen(tbuf2)-1]=='\n') tbuf2[strlen(tbuf2)-1]=0;
00975     setvar(namebuf,tbuf2);
00976 }
00977 
00978        /* set but do not overwrite. */
00979 void exec_default(char *p)
00980 {
00981     char *start, *end, c, *pp;
00982     char namebuf[MAX_LINELEN+1];
00983     start=find_word_start(p);
00984     for(end=start;*end!=0 && !isspace(*end) && *end!='='; end++);
00985     c=*end; *end=0;
00986     if(end-start<=MAX_LINELEN-1) {
00987        memmove(namebuf,start,end-start+1); substit(namebuf);
00988        pp=getvar(namebuf);
00989        if(pp!=NULL && *pp!=0) return;
00990     }
00991     *end=c; exec_set(p);
00992 }
00993 
00994        /* Does nothing; just a comment. */
00995 void exec_comment(char *p)
00996 {
00997     return;
00998 }
00999 
01000        /* Exit the file under interpretation */
01001 void exec_exit(char *p)
01002 {
01003     m_file.linepointer=m_file.linecnt;
01004     return;
01005 }
01006 
01007        /* output a file. Undocumented. Aliases:
01008         * getfile, outfile, fileout */
01009 void exec_getfile(char *p)
01010 {
01011     char *s, *p1, url[MAX_LINELEN+1];
01012     char *prompt;
01013     
01014     p=find_word_start(p); prompt=find_word_end(p);
01015     if(*prompt!=0) *prompt++=0;
01016     prompt=find_word_start(prompt);
01017     if(*p==0 || !outputing) return;
01018     if(!trusted_module() || is_class_module) return;
01019     s=getvar(ro_name[ro_session]);
01020     if(s==NULL || *s==0 || strstr(s,"robot")!=NULL) return;
01021     mystrncpy(url,ref_name,sizeof(url));
01022     for(p1=url+strlen(url);p1>url && *(p1-1)!='/'; p1--);
01023     if(good_httpd) snprintf(p1,sizeof(url)+p1-url,
01024                          "getfile/%s?&+session=%s&+modif=%ld",
01025                          p,s,nowtime);
01026     else snprintf(url,sizeof(url),
01027                 "%s?cmd=getfile&+session=%s&+special_parm=%s&+modif=%ld",
01028                 ref_name,s,p,nowtime);
01029     snprintf(jsbuf,sizeof(jsbuf),jsstr,"wims_file","wims_file");
01030     if(*prompt) output("<a href=\"%s\">%s</a>\n", url,prompt);
01031     else output("<a href=\"%s\"></a>",url);
01032 }
01033 
01034        /* internal */
01035 void count_insert(void)
01036 {
01037     insert_no++;
01038     if(insert_no>=INS_LIMIT) module_error("too_many_ins");
01039 }
01040 
01041 int animated_ins=0;
01042 int grouped_ins=0;
01043 
01044        /* generic insertion */
01045 void _exec_ins(char *p, char *script_name,char *format)
01046 {
01047     char *s, *b, *at, *tag, *tag2, *al, *fmt, *mh;
01048     char *p1, *pt;
01049     char buf[1024],buf2[1024],url[MAX_LINELEN+1],altbuf[1024];
01050     char outbuf[1024];
01051     int border, middle, vspace;
01052     long int tel;
01053 
01054     if(robot_access) return;
01055     count_insert(); outbuf[0]=0;
01056     setenv("ins_source",p,1); /* value kept from user tamper */
01057     if(animated_ins) fmt=getvar("anim_format"); else fmt=format;
01058     if(fmt==NULL) fmt="gif";
01059     if(ismhelp) mh="mh"; else mh="";
01060     snprintf(buf,sizeof(buf),"%s/insert%s-%d.%s",s2_prefix,mh,insert_no,fmt);
01061     if(grouped_ins) {unlink(buf); goto grouped;}
01062     exportall();
01063     call_ssh("%s/%s %d %s >%s/ins.out 2>%s/ins.err",
01064            bin_dir,script_name,insert_no,tmp_dir,tmp_dir,tmp_dir);
01065     unlink(buf); wrapexec=1;
01066     if(trusted_module()) setenv("trusted_module","yes",1);
01067     else if(untrust) setenv("trusted_module","no",1);
01068     call_ssh("mv %s/insert%s-%d.%s %s >/dev/null 2>/dev/null",
01069             tmp_dir,mh,insert_no,fmt,s2_prefix);
01070     tel=filelength("%s", buf);
01071     if(tel<=5) {
01072        char bbuf[MAX_LINELEN+1];
01073        accessfile(bbuf,"r","%s/ins.err",tmp_dir);
01074        snprintf(url,sizeof(url),"gifs/badins.gif");
01075        for(p1=bbuf;p1<bbuf+512 && *p1;p1++)
01076          if(*p1=='<' || *p1=='>') *p1='?';
01077        *p1=0;
01078        if(bbuf[0]==0) snprintf(bbuf,sizeof(bbuf),"Fail");
01079        snprintf(outbuf+strlen(outbuf),sizeof(outbuf)-strlen(outbuf),
01080                " <img src=\"%s\" alt=Error> <p><small><pre>%s</pre></small> <p> ",
01081                url,bbuf);
01082        setvar("ins_warn","fail");
01083        setvar("ins_cnt","0");
01084        goto reset;
01085     }
01086     grouped:
01087     s=getvar(ro_name[ro_session]);
01088     b=getvar("ins_border"); at=getvar("ins_attr");
01089     tag=getvar("ins_tag");  al=getvar("ins_align");
01090     if(at==NULL) at="";
01091     if(tag==NULL) tag="";
01092     if(al==NULL) al="";al=find_word_start(al);
01093     if(*al!=0) snprintf(buf2,sizeof(buf2),"align=%s",al); else buf2[0]=0;
01094     if(strcasecmp(al,"middle")==0) middle=1; else middle=0;
01095     tag2=""; vspace=0;
01096     if(*tag!=0) {
01097        mystrncpy(buf,tag,sizeof(buf)); tag=find_word_start(buf);
01098        tag2=find_word_end(tag);
01099        if(*tag2!=0) *tag2++=0;
01100        tag2=find_word_start(tag2);
01101     }
01102     if(b==NULL || *b==0) border=0;
01103     else border=atoi(b);
01104     if(border<0) border=0; if(border>100) border=100;
01105     if(middle) {
01106        snprintf(outbuf+strlen(outbuf),
01107                sizeof(outbuf)-strlen(outbuf),mathalign_sup1);
01108        vspace=2;
01109     }
01110     mystrncpy(url,ref_name,sizeof(url));
01111     for(p1=url+strlen(url);p1>url && *(p1-1)!='/'; p1--);
01112     snprintf(p1,sizeof(url)+p1-url,
01113             "wims.%s?cmd=getins&+session=%s&+special_parm=insert%s-%d.%s&+modif=%ld",
01114             fmt,s,mh,insert_no,fmt,nowtime);
01115     if(strchr(ins_alt,'"')!=NULL || strlen(ins_alt)>256) ins_alt[0]=0;
01116     pt=getvar("wims_ins_alt"); if(pt==NULL) pt="";
01117     if(ins_alt[0] && strcmp(pt,"none")!=0)
01118       snprintf(altbuf,sizeof(altbuf)," alt=\"%s \"",ins_alt);
01119     else altbuf[0]=0;
01120     if(strcasecmp(tag,"form")!=0) {
01121        snprintf(outbuf+strlen(outbuf),sizeof(outbuf)-strlen(outbuf),
01122                "<img src=\"%s\" border=%d vspace=%d %s %s%s>",
01123                url, border, vspace, at, buf2, altbuf);
01124     }
01125     else {
01126        char *n;
01127        if(*tag2!=0) n="name="; else n="";
01128        snprintf(outbuf+strlen(outbuf),sizeof(outbuf)-strlen(outbuf),
01129                "<input type=image %s%s src=\"%s\" border=%d vspace=%d %s %s%s>",
01130                n,tag2,url,border,vspace, at,buf2, altbuf);
01131     }
01132     if(middle) snprintf(outbuf+strlen(outbuf),
01133                      sizeof(outbuf)-strlen(outbuf),mathalign_sup2);
01134     setvar("ins_warn",""); ins_alt[0]=0;
01135     setvar("ins_cnt",int2str(insert_no));
01136     reset:
01137     if(outputing) _output_(outbuf);
01138     setvar("ins_out",outbuf);
01139     setvar("ins_attr",""); setvar("ins_tag","");
01140     setvar("ins_url",url);
01141     snprintf(buf2,sizeof(buf2),"insert%s-%d.%s",mh,insert_no,fmt);
01142     setvar("ins_filename",buf2);
01143     animated_ins=0;
01144 }
01145 
01146        /* instex: dynamically insert tex outputs */
01147 void exec_instex(char *p)
01148 {
01149     char *ts, *tc, *f, *mh, buf[MAX_FNAME+1];
01150     
01151     if(robot_access) {
01152        *p=0; return;
01153     }
01154     f=instex_check_static(p); substit(p);
01155     if(f==NULL) {
01156        /* Use static instex if there is no real substitution
01157         * and the source file is not in sessions directory. */
01158        calc_instexst(p); if(outputing) _output_(p);
01159        return;
01160     }
01161     if(ismhelp) mh="mh"; else mh="";
01162     fix_tex_size(); f="gif";
01163     setenv("texgif_style",instex_style,1);
01164     setenv("texgif_tmpdir",tmp_dir,1);
01165     setenv("texgif_src",p,1);
01166     if(ins_alt[0]==0) mystrncpy(ins_alt,p,sizeof(ins_alt));
01167     mkfname(buf,"%s/insert%s-%d.gif",tmp_dir,mh,insert_no+1);
01168     setenv("texgif_outfile",buf,1);
01169     ts=getvar("wims_texsize"); tc=getvar("instex_color");
01170     if(lastout_file!=-1 && (tc==NULL || *tc==0) &&       
01171        (ts==NULL || *ts==0 || strcmp(ts,"0")==0) &&
01172        strstr(p,"\\begin{")==NULL) {
01173        int ls, ln;
01174        char *pagebreak;
01175        ls=strlen(instex_src); ln=strlen(instex_fname);
01176        if(ls+strlen(p)>=MAX_LINELEN-256 || 
01177           ln+strlen(buf)>=MAX_LINELEN-16) {
01178            instex_flush(); ls=ln=0;
01179        }
01180        if(instex_cnt>0) pagebreak="\\pagebreak\n"; else pagebreak="";
01181        snprintf(instex_src+ls,MAX_LINELEN-ls,"%s %s %s %s\n",
01182                pagebreak,instex_style,p,instex_style);
01183        snprintf(instex_fname+ln,MAX_LINELEN-ln,"%s\n",buf);
01184        grouped_ins=1;
01185     }
01186     mkfname(buf,"%s/texgif.dvi",tmp_dir); unlink(buf);
01187     wrapexec=0; _exec_ins(p,instex_processor,f);
01188     if(grouped_ins) instex_cnt++;
01189     grouped_ins=0;
01190 }
01191 
01192        /* patches the gnuplot integer division (mis)feature. */
01193 void gnuplot_patch(char *p,int oneline)
01194 {
01195     char *pp;
01196     for(pp=strchr(p,'/');pp!=NULL;pp=strchr(pp+1,'/')) {
01197        char *p1;
01198        if(pp<=p || !myisdigit(*(pp-1)) || !myisdigit(*(pp+1))) continue;
01199        for(p1=pp-2;p1>=p && myisdigit(*p1);p1--);
01200        if(p1>=p && *p1=='.') continue;
01201        for(p1=pp+2;*p1 && myisdigit(*p1);p1++);
01202        if(*p1=='.') continue;
01203        string_modify(p,p1,p1,".0");
01204     }
01205     for(pp=strchr(p,'^');pp!=NULL;pp=strchr(pp+1,'^'))
01206       string_modify(p,pp,pp+1,"**");
01207        /* disallow new lines and ';' */
01208     if(oneline)
01209       for(pp=p;*pp!=0;pp++) if(*pp==';' || *pp=='\n') *pp=' ';
01210 }
01211 
01212        /* This is to disable pipe in the gnuplot plotting function.
01213         * We do not allow ' followed by < . */
01214 void prepare_insplot_parm(char *p)
01215 {
01216     int i,j,multanim; char *pp, *s;
01217     double d;
01218     char setbuf[MAX_LINELEN+10],buf[MAX_LINELEN+1];
01219     
01220     j=strlen(p);
01221       /* pipe in plot command */
01222     for(i=0;i<j;i++) {
01223        if(*(p+i)!='\'' && *(p+i)!='"') continue;
01224        pp=find_word_start(p+i+1); if(*pp=='<') module_error("illegal_plot_cmd");
01225     }
01226     gnuplot_patch(p,1);
01227        /* multiplot */
01228     multanim=0;
01229     pp=getvar("insplot_split");
01230     if(pp!=NULL) i=linenum(pp); else i=0;
01231        /* arbitrary limit: 16 multiplots */
01232     if(i>16) i=16;
01233     if(i>1) {
01234        char tbuf[MAX_LINELEN*(i+1)+100], bbuf[MAX_LINELEN+1];
01235        tbuf[0]=0;
01236        if(*p!=0) snprintf(tbuf,sizeof(tbuf),"%s\n",p);
01237        snprintf(buf,sizeof(buf),"%d",i); setenv("multiplot",buf,1);
01238        for(j=1;j<=i;j++) {
01239            snprintf(buf,sizeof(buf),"insplot_parm_%d",j);
01240            pp=getvar(buf);
01241            if(pp==NULL || *pp==0) {
01242               if(j==1 && *p!=0) continue;
01243               pp="";
01244            }
01245            else {
01246               mystrncpy(bbuf,pp,sizeof(bbuf));
01247               gnuplot_patch(bbuf,1);
01248            }
01249            strcat(tbuf,bbuf);strcat(tbuf,"\n");
01250        }
01251        setenv("insplot_source",tbuf,1);
01252        if(varchr(tbuf,"s")!=NULL) multanim=1;
01253     }
01254        /* no illegal chaining */
01255     pp=getvar("insplot_font"); if(pp!=NULL) {
01256        for(s=pp;s<pp+MAX_LINELEN && *s;s++) 
01257          if(*s==';' || *s=='\n' || *s==' ') *s=0;
01258        if(s>=pp+MAX_LINELEN) *s=0;
01259        setvar("insplot_font",pp);
01260     }
01261     pp=getvar("insplot_set"); if(pp!=NULL) {
01262        char tbuf[MAX_LINELEN+1];
01263        mystrncpy(tbuf,pp,sizeof(tbuf));
01264        i=strlen(tbuf)-1;
01265        while(i>0 && isspace(tbuf[i])) i--;
01266        if(tbuf[i]==';') tbuf[i]=0;
01267        gnuplot_patch(tbuf,0);pp=tbuf;
01268        strcpy(setbuf,"set "); j=strlen("set ");
01269        for(i=0; *(pp+i)!=0 && j<MAX_LINELEN; i++) {
01270            if(*(pp+i)=='\n') {setbuf[j++]=' '; continue;}
01271            if(*(pp+i)!=';') {setbuf[j++]=*(pp+i); continue;}
01272            strcpy(setbuf+j,"\nset "); j+=strlen("\nset ");
01273        }
01274        setbuf[j]=0;
01275        setenv("insplot_set",setbuf,1);
01276     }
01277     else setenv("insplot_set","",1);
01278       /* frames of animation */
01279     pp=getvar("ins_anim_frames");
01280     if(pp!=NULL) i=evalue(pp); else i=1;
01281     if(i>=ANIM_LIMIT) i=ANIM_LIMIT-1; if(i<1) i=1;
01282     if(strstr(setbuf,"step")==NULL && strstr(p,"step")==NULL
01283        && varchr(setbuf,"s")==NULL && varchr(p,"s")==NULL && !multanim) i=1;
01284     setenv("ins_anim_frames",int2str(i),1);
01285     setvar("ins_anim_frames","");
01286     if(i>1) {setvar("ins_animation","yes");animated_ins=1;}
01287     else setvar("ins_animation","no");
01288       /* delay of animation */
01289     pp=getvar("ins_anim_delay");
01290     if(pp!=NULL) d=evalue(pp); else d=0;
01291     if(d>=10) d=10; if(d<0) d=0;
01292     setenv("ins_anim_delay",int2str(d*100),1);
01293 }
01294 
01295        /* Insert dynamic 2d plot */
01296 void exec_insplot(char *p)
01297 {
01298     char *fmt;
01299     if(robot_access) {
01300        *p=0; return;
01301     }
01302     fmt=getvar("ins_format"); if(fmt==NULL || *fmt==0) fmt=DEFAULT_INS_FORMAT;
01303     prepare_insplot_parm(p); setenv("insplot_method","2D",1);
01304     _exec_ins(p,insplot_processor,fmt);
01305     wrapexec=1;
01306 /*    call_ssh("mv %s/insplot_cmd %s 2>/dev/null",tmp_dir,s2_prefix); */
01307     unsetenv("multiplot"); setvar("insplot_split","");
01308 }
01309 
01310        /* Insert dynamic 3d plot */
01311 void exec_insplot3d(char *p)
01312 {
01313     char *fmt;
01314     if(robot_access) {
01315        *p=0; return;
01316     }
01317     fmt=getvar("ins_format"); if(fmt==NULL || *fmt==0) fmt=DEFAULT_INS_FORMAT;
01318     prepare_insplot_parm(p); setenv("insplot_method","3D",1);
01319     _exec_ins(p,insplot_processor,fmt);
01320     wrapexec=1;
01321 /*     call_ssh("mv %s/insplot_cmd %s 2>/dev/null",tmp_dir,s2_prefix); */
01322     unsetenv("multiplot");setvar("insplot_split","");
01323 }
01324 
01325        /* Insert dynamic gif draw. The parm preparation is specific to fly. */
01326 void exec_insdraw(char *p)
01327 {
01328     char *pp, *fmt;
01329     int i;
01330     double d;
01331     
01332     if(robot_access) {
01333        *p=0; return;
01334     }
01335 /*    calc_tolower(p);      */
01336     fmt=getvar("ins_format"); if(fmt==NULL || *fmt==0) fmt=DEFAULT_INS_FORMAT;
01337     while((pp=wordchr(p,"output"))!=NULL) memmove(pp,"zqkwfx",6);
01338       /* frames of animation */
01339     pp=getvar("ins_anim_frames");
01340     if(pp!=NULL) i=evalue(pp); else i=1;
01341     if(i>=ANIM_LIMIT) i=ANIM_LIMIT-1; if(i<1) i=1;
01342     if(i>1 && varchr(p,"s")==NULL && varchr(p,"animstep")==NULL
01343        && varchr(p,"step")==NULL) i=1;
01344     setenv("ins_anim_frames",int2str(i),1);
01345     setvar("ins_anim_frames","");
01346     if(i>1) {setvar("ins_animation","yes");animated_ins=1;}
01347     else setvar("ins_animation","no");
01348       /* delay of animation */
01349     pp=getvar("ins_anim_delay");
01350     if(pp!=NULL) d=evalue(pp); else d=0;
01351     if(d>=10) d=10; if(d<0) d=0;
01352     setenv("ins_anim_delay",int2str(d*100),1);
01353     pp=getvar("insdraw_filebase");
01354     if(pp!=NULL && strstr(pp,parent_dir_string)!=NULL)
01355       setvar("insdraw_filebase","");
01356     _exec_ins(p,insdraw_processor,fmt);
01357 }
01358 
01359 void exec_increase(char *p)
01360 {
01361     char *p1, *p2;
01362     p1=find_word_start(p); p2=find_word_end(p1);
01363     if(p2<=p1) {
01364        *p=0; return;
01365     }
01366     *p2=0;p2=getvar(p1);
01367     if(p2==NULL) p2="";
01368     setvar(p1,int2str(atoi(p2)+1)); *p=0;
01369 }
01370 
01371        /* bound a variable */
01372 void exec_bound(char *p)
01373 {
01374     char *p1, *p2, *p3;
01375     int doub,i,bcnt,defaulted;
01376     double d1,d2,dd,val;
01377     char nbuf[MAX_LINELEN+1],lbuf[MAX_LINELEN+1],dbuf[MAX_LINELEN+1];
01378     char vbuf[MAX_LINELEN+1];
01379     char *blist[2048];
01380     
01381     p1=find_word_start(p); p2=find_word_end(p1);
01382     if(*p2==0) {
01383        syntax: module_error("syntax_error");
01384     }
01385     *p2=0; strcpy(nbuf,p1);substit(nbuf); p1=find_word_start(p2+1);
01386     p2=getvar(nbuf);if(p2==NULL) p2="";
01387     mystrncpy(vbuf,find_word_start(p2),sizeof(vbuf));
01388     strip_trailing_spaces(vbuf);
01389     p2=find_word_end(p1); if(*p2==0) goto syntax;
01390     *p2=0;p2++;
01391     p3=wordchr(p2,"default");
01392     if(p3!=NULL) {
01393        *p3=0; defaulted=1;
01394        p3=find_word_start(p3+strlen("default"));
01395        strcpy(dbuf,p3); substit(dbuf);
01396     }
01397     else defaulted=0;
01398     if(strcmp(p1,"between")==0) {
01399        p1=find_word_start(p2);
01400        i=strlen("integer");
01401        if(strncmp(p1,"integer",i)==0 &&
01402           (isspace(*(p1+i)) || (*(p1+i)=='s' && isspace(*(p1+i+1))))) {
01403            doub=0; p1=find_word_start(find_word_end(p1));
01404            val=rint(evalue(vbuf)); 
01405            if(vbuf[0]) float2str(val,vbuf);
01406        }
01407        else {
01408            doub=1;val=evalue(vbuf);
01409        }
01410        p2=wordchr(p1,"and"); p3=p2+strlen("and");
01411        if(p2==NULL) {
01412          p2=strchr(p1,','); p3=p2+1;
01413        }
01414        if(p2==NULL) goto syntax;
01415        *p2=0;p2=find_word_start(p3);
01416        if(*p1==0 || *p2==0) goto syntax;
01417        d1=evalue(p1);d2=evalue(p2);
01418        if(!finite(d1) || !finite(d2) || 
01419           abs(d1)>(double)(1E10) || abs(d2)>(double)(1E10)) goto syntax;
01420        if(d1>d2) {
01421            dd=d1;d1=d2;d2=dd;
01422        }
01423        if(vbuf[0] && val<=d2 && val>=d1) {
01424            if(!doub) setvar(nbuf,vbuf);
01425            *p=0; return;
01426        }
01427        if(defaulted) strcpy(p,dbuf);
01428        else {
01429            if(!doub) {
01430               d1=ceil(d1);d2=floor(d2);
01431            }
01432            if(vbuf[0]==0 || val<d1) val=d1;
01433            else val=d2;
01434            float2str(val,p);
01435        }
01436        setvar(nbuf,p); *p=0; return;
01437     }
01438     else {
01439        if(strcmp(p1,"within")==0 || strcmp(p1,"among")==0) {
01440            strcpy(lbuf,p2);substit(lbuf);
01441            bcnt=cutitems(lbuf,blist,2048);
01442            if(bcnt<=0) {
01443               *p=0; return;
01444            }
01445            for(i=0;i<bcnt;i++) {
01446               if(strcmp(blist[i],vbuf)==0) {
01447                   *p=0; return;
01448               }
01449            }
01450            if(defaulted) strcpy(p,dbuf); else strcpy(p,blist[0]);
01451            setvar(nbuf,p); *p=0;
01452            return;
01453        }
01454        else goto syntax;
01455     }
01456 }
01457 
01458        /* detrust the module. */
01459 void exec_detrust(char *p)
01460 {      untrust|=1; *p=0; }
01461 
01462 void exec_warn(char *p)
01463 {
01464     char *p1,*p2;
01465     char buf[MAX_FNAME+1];
01466     WORKING_FILE save;
01467 
01468     if(!outputing) goto end;
01469     p1=find_word_start(p);p2=find_word_end(p1);
01470     if(p2<=p1) goto end;
01471     *p2=0;
01472     snprintf(buf,sizeof(buf),"wims_warn_%s",p1);
01473     p2=getvar(buf);
01474     if(p2==NULL || *p2==0) goto end;
01475     p2=getvar("module_language");if(p2==NULL) p2="en";
01476     mkfname(buf,"msg/warn_%s.phtml.%s",p1,p2);
01477     memmove(&save,&m_file,sizeof(WORKING_FILE));
01478     if(open_working_file(&m_file,buf)==0) phtml_put(NULL,0);
01479     memmove(&m_file,&save,sizeof(WORKING_FILE));
01480     end:
01481     *p=0; return;
01482 }
01483 
01484        /* write an error message. */
01485 void exec_msg(char *p)
01486 {
01487     char *p1,*p2, buf[64], *l;
01488     secure_exec();
01489     p1=find_word_start(p); p2=find_word_end(p1);
01490     if(*p2) {
01491        *p2=0; p2=find_word_start(p2+1);
01492     }
01493     force_setvar("wims_error",p1); force_setvar("wims_error_parm",p2);
01494     l=getvar("module_language");
01495     if(l!=NULL && strlen(l)==2) {
01496        snprintf(buf,sizeof(buf),"msg.phtml.%s",l);
01497        phtml_put_base(buf,0);
01498     }
01499     *p=0;
01500 }
01501 
01502 struct {
01503     char *name;
01504     int (*routine) (char *p, char *list[], int max);
01505 } distr_cmd[]={
01506       {"char",              NULL},
01507       {"charof",     NULL},
01508       {"chars",             NULL},
01509       {"charsof",    NULL},
01510       {"item",              cutitems},
01511       {"itemof",     cutitems},
01512       {"items",             cutitems},
01513       {"itemsof",    cutitems},
01514       {"line",              cutlines},
01515       {"lineof",     cutlines},
01516       {"lines",             cutlines},
01517       {"linesof",    cutlines},
01518       {"list",              cutitems},
01519       {"word",              cutwords},
01520       {"wordof",     cutwords},
01521       {"words",             cutwords},
01522       {"wordsof",    cutwords}
01523 };
01524 
01525 #define distr_cmd_no (sizeof(distr_cmd)/sizeof(distr_cmd[0]))
01526 
01527        /* distribute a number of lines, items, etc. into a list of vars. */
01528 void exec_distribute(char *p)
01529 {
01530     int i,k,n;
01531     char *p1, *p2;
01532     char bf1[MAX_LINELEN+1],bf2[MAX_LINELEN+1];
01533     char *names[4096],*vals[4096];
01534     p1=find_word_start(p); p2=find_word_end(p1);
01535     if(p2<=p1 || *p2==0) module_error("syntax_error");
01536     *p2++=0;
01537     i=search_list(distr_cmd,distr_cmd_no,sizeof(distr_cmd[0]),p1);
01538     if(i<0) module_error("syntax_error");
01539     p2=find_word_start(p2); p1=wordchr(p2,"into");
01540     if(p1==NULL) module_error("syntax_error");
01541     *p1=0;mystrncpy(bf1,p2,sizeof(bf1));
01542     p1=find_word_start(p1+strlen("into"));
01543     mystrncpy(bf2,p1,sizeof(bf2));
01544     substit(bf1);substit(bf2);
01545     strip_trailing_spaces(bf1);
01546     items2words(bf2); n=cutwords(bf2,names,4096);
01547     if(distr_cmd[i].routine!=NULL) {
01548        k=distr_cmd[i].routine(bf1,vals,n);
01549        for(i=0;i<k;i++) setvar(names[i],vals[i]);
01550        for(;i<n;i++) setvar(names[i],"");
01551     }
01552     else {
01553        char buf[2];
01554        buf[1]=0;
01555        for(p1=bf1,i=0;i<n;i++) {
01556            buf[0]=*p1; if(*p1) p1++;
01557            setvar(names[i],buf);
01558        }
01559     }
01560 }
01561 
01562        /* reset variables */
01563 void exec_reset(char *p)
01564 {
01565     char *p1, *p2;
01566 
01567     items2words(p);
01568     for(p1=find_word_start(p); *p1; p1=find_word_start(p2)) {
01569        p2=find_word_end(p1); if(*p2) *p2++=0;
01570        setvar(p1,"");
01571     }
01572 }
01573 
01574        /* exchange the values of two variables */
01575 void exec_exchange(char *p)
01576 {
01577     char buf[MAX_LINELEN+1],b1[MAX_LINELEN+1],b2[MAX_LINELEN+1];
01578     char *p1,*p2,*pb;
01579     p1=wordchr(p,"and");
01580     if(p1!=NULL) {
01581        *p1=0; p2=find_word_start(p1+strlen("and"));
01582     }
01583     else {
01584        p1=strchr(p,',');
01585        if(p1==NULL) module_error("syntax_error");
01586        *p1=0; p2=find_word_start(p1+1);
01587     }
01588     p1=find_word_start(p);
01589     mystrncpy(b1,p1,sizeof(b1)); substit(b1); *find_word_end(b1)=0;
01590     mystrncpy(b2,p2,sizeof(b2)); substit(b2); *find_word_end(b2)=0;
01591     if(*b1==0 || *b2==0) module_error("syntax_error");
01592     pb=getvar(b1);if(pb==NULL) pb="";
01593     mystrncpy(buf,pb,sizeof(buf));
01594     pb=getvar(b2);if(pb==NULL) pb="";
01595     setvar(b1,pb); setvar(b2,buf);
01596 }
01597 
01598        /* Send a mail */
01599 void exec_mailto(char *p)
01600 {
01601     char *p1,*p2,*pp;
01602 
01603     if(!trusted_module() || is_class_module) return;
01604     p1=strchr(p,'\n'); if(p1==NULL) return;
01605     *p1++=0; p=find_word_start(p);
01606     if(*p==0) return;
01607     p2=strchr(p1,'\n'); if(p2==NULL) return;
01608     *p2++=0;
01609     for(pp=p1;*pp;pp++) if(*pp=='"' || *pp=='\n') *pp=' ';
01610     accessfile(p2,"w","%s/mail.body",tmp_dir);
01611     wrapexec=1;
01612     call_sh("mail %s -s \" %s \" %s <%s/mail.body; chmod og-rwx %s/mail.body",
01613            mail_opt, p1,p,tmp_dir,tmp_dir);
01614     mail_log(p);
01615     *p=0;
01616 }
01617 
01618        /* Generates a user error. Internal and undocumented. */
01619 void exec_usererror(char *p)
01620 {
01621     if(trusted_module()) user_error(p);
01622 }
01623 
01624        /* stop output. */
01625 void exec_directout(char *p)
01626 {
01627     if(outputing || !trusted_module()) return;
01628     printf("%s",p);
01629     noout=1;
01630 }
01631 
01632 enum {
01633       EXEC_IF, EXEC_JUMP, EXEC_ELSE, EXEC_ENDIF, EXEC_EXEC,
01634       EXEC_WHILE, EXEC_ENDWHILE,
01635       EXEC_FOR, EXEC_VAR, EXEC_DEBUG, EXEC_DAEMON,
01636       EXEC_SET, EXEC_DEFAULT, EXEC_COMMENT, EXEC_READ, EXEC_HREF,
01637       EXEC_INS, EXEC_STRING, EXEC_PEDIA, EXEC_DIR,
01638       EXEC_TRUST, EXEC_WARN, EXEC_ERROR, EXEC_SQL, EXEC_SCORE,
01639       EXEC_MAIL, EXEC_OTHER
01640 } EXEC_TYPES;
01641 #define EXEC_SUBST 0x1000
01642 #define EXEC_USECALC 0x2000
01643 #define EXEC_PROCTOO 0x4000
01644 MYFUNCTION exec_routine[]={
01645       {"!",          EXEC_COMMENT,        exec_comment},
01646       {"TeXmath",    EXEC_STRING|EXEC_SUBST|EXEC_USECALC,texmath},
01647       {"add",        EXEC_STRING|EXEC_USECALC,calc_sum},
01648       {"advance",    EXEC_VAR|EXEC_SUBST, exec_increase},
01649       {"append",     EXEC_STRING|EXEC_USECALC,calc_append},
01650       {"appendfile", EXEC_DIR|EXEC_SUBST, fileappend},
01651       {"bound",             EXEC_STRING,         exec_bound},
01652       {"break",             EXEC_FOR,            exec_break},
01653       {"call",              EXEC_EXEC|EXEC_SUBST|EXEC_PROCTOO|EXEC_USECALC,  calc_exec},
01654       {"changeto",   EXEC_READ|EXEC_SUBST,       exec_changeto},
01655       {"char",              EXEC_STRING|EXEC_USECALC,calc_charof},
01656       {"chars",             EXEC_STRING|EXEC_USECALC,calc_charof},
01657       {"checkhost",  EXEC_STRING|EXEC_USECALC|EXEC_SUBST,calc_checkhost},
01658       {"column",     EXEC_STRING|EXEC_USECALC,calc_columnof},
01659       {"columns",    EXEC_STRING|EXEC_USECALC,calc_columnof},
01660       {"comment",    EXEC_COMMENT,        exec_comment},
01661       {"daemon",     EXEC_DAEMON|EXEC_USECALC|EXEC_SUBST,calc_daemon},
01662       {"date",              EXEC_STRING|EXEC_USECALC|EXEC_SUBST,calc_date},
01663       {"deaccent",   EXEC_STRING|EXEC_USECALC|EXEC_SUBST,deaccent},
01664       {"debug",             EXEC_DEBUG,          calc_debug},
01665       {"declosing",  EXEC_STRING|EXEC_USECALC|EXEC_SUBST,calc_declosing},
01666       {"def",        EXEC_SET,            exec_set},
01667       {"default",    EXEC_SET,            exec_default},
01668       {"define",     EXEC_SET,            exec_set},
01669       {"definitionof",      EXEC_SCORE|EXEC_USECALC,calc_defof},
01670       {"defof",             EXEC_SCORE|EXEC_USECALC,calc_defof},
01671       {"defread",    EXEC_READ|EXEC_SUBST,       exec_defread},
01672       {"detag",             EXEC_STRING|EXEC_USECALC|EXEC_SUBST,calc_detag},
01673       {"detrust",    EXEC_TRUST,          exec_detrust},
01674 /*      {"dictionary",      EXEC_STRING|EXEC_USECALC,calc_dictionary},       */
01675       {"dir",        EXEC_DIR|EXEC_SUBST|EXEC_USECALC,calc_listfile},
01676       {"distribute", EXEC_STRING,         exec_distribute},
01677       {"distrust",   EXEC_TRUST,          exec_detrust},
01678       {"else",              EXEC_ELSE,           exec_else},
01679       {"embraced",   EXEC_STRING|EXEC_USECALC,calc_embraced},
01680       {"encyclo",    EXEC_PEDIA|EXEC_SUBST|EXEC_USECALC,pedia},
01681       {"encyclopedia",      EXEC_PEDIA|EXEC_SUBST|EXEC_USECALC,pedia},
01682       {"endif",             EXEC_ENDIF,          exec_endif},
01683       {"endwhile",   EXEC_ENDWHILE,              exec_endwhile},
01684       {"evalsubst",  EXEC_STRING|EXEC_USECALC,calc_evalsubst},
01685       {"evalsubstit",       EXEC_STRING|EXEC_USECALC,calc_evalsubst},
01686       {"evalsubstitute",EXEC_STRING|EXEC_USECALC,calc_evalsubst},
01687       {"evaluesubst",       EXEC_STRING|EXEC_USECALC,calc_evalsubst},
01688       {"evaluesubstit",     EXEC_STRING|EXEC_USECALC,calc_evalsubst},
01689       {"evaluesubstitute",EXEC_STRING|EXEC_USECALC,calc_evalsubst},
01690       {"examscore",  EXEC_SCORE|EXEC_SUBST|EXEC_USECALC,calc_examscore},
01691       {"exchange",   EXEC_STRING,         exec_exchange},
01692       {"exec",              EXEC_EXEC|EXEC_SUBST|EXEC_PROCTOO|EXEC_USECALC,  calc_exec},
01693       {"execute",    EXEC_EXEC|EXEC_SUBST|EXEC_PROCTOO|EXEC_USECALC,  calc_exec},
01694       {"exit",              EXEC_JUMP,           exec_exit},
01695       {"fileappend", EXEC_DIR|EXEC_SUBST, fileappend},
01696       {"filelist",   EXEC_DIR|EXEC_SUBST|EXEC_USECALC,calc_listfile},
01697       {"fileout",    EXEC_HREF|EXEC_SUBST,       exec_getfile},
01698       {"filewrite",  EXEC_DIR|EXEC_SUBST, filewrite},
01699       {"for",        EXEC_FOR,            exec_for},
01700       {"form",              EXEC_HREF|EXEC_SUBST,       exec_form},
01701       {"formbar",    EXEC_HREF,           exec_formbar},
01702       {"formcheckbox",      EXEC_HREF,           exec_formcheckbox},
01703       {"formradio",  EXEC_HREF,           exec_formradio},
01704       {"formradiobar",      EXEC_HREF,           exec_formbar},
01705       {"formselect", EXEC_HREF,           exec_formselect},
01706       {"getdef",     EXEC_SCORE|EXEC_USECALC,calc_defof},
01707       {"getfile",    EXEC_HREF|EXEC_SUBST,       exec_getfile},
01708       {"getscore",   EXEC_SCORE|EXEC_SUBST|EXEC_USECALC,calc_getscore},
01709       {"getscoremean",      EXEC_SCORE|EXEC_SUBST|EXEC_USECALC,calc_getscoremean},
01710       {"getscorepercent",EXEC_SCORE|EXEC_SUBST|EXEC_USECALC,calc_getscorepercent},
01711       {"getscoreremain",EXEC_SCORE|EXEC_SUBST|EXEC_USECALC,calc_getscoreremain},
01712       {"getscorerequire",EXEC_SCORE|EXEC_SUBST|EXEC_USECALC,calc_getscorerequire},
01713       {"getscoreweight",EXEC_SCORE|EXEC_SUBST|EXEC_USECALC,calc_getscoreweight},
01714       {"goto",              EXEC_JUMP|EXEC_SUBST,       exec_goto},
01715       {"header",     EXEC_HREF,           exec_header},
01716       {"header1",    EXEC_HREF,           exec_header1},
01717       {"headmenu",   EXEC_HREF,           exec_headmenu},
01718       {"hex",        EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_hex},
01719       {"homeref",    EXEC_HREF,           exec_homeref},
01720       {"href",              EXEC_HREF,           exec_href},
01721       {"htmlbar",    EXEC_HREF,           exec_formbar},
01722       {"htmlcheckbox",      EXEC_HREF,           exec_formcheckbox},
01723       {"htmlheader", EXEC_HREF,           exec_header},
01724       {"htmlmath",   EXEC_STRING|EXEC_SUBST|EXEC_USECALC,htmlmath},
01725       {"htmlradio",  EXEC_HREF,           exec_formradio},
01726       {"htmlradiobar",      EXEC_HREF,           exec_formbar},
01727       {"htmlselect", EXEC_HREF,           exec_formselect},
01728       {"htmltail",   EXEC_HREF,           exec_tail},
01729       {"htmltitle",  EXEC_HREF,           exec_title},
01730       {"if",         EXEC_IF,             exec_if},
01731       {"ifval",             EXEC_IF,             exec_ifval},
01732       {"ifvalue",    EXEC_IF,             exec_ifval},
01733       {"imgrename",  EXEC_STRING|EXEC_USECALC|EXEC_SUBST,calc_imgrename},
01734       {"include",    EXEC_READ|EXEC_SUBST,       exec_read},
01735       {"increase",   EXEC_VAR|EXEC_SUBST, exec_increase},
01736       {"input",             EXEC_READ|EXEC_SUBST,       exec_read},
01737       {"insdraw",    EXEC_INS|EXEC_SUBST, exec_insdraw},
01738       {"insmath",    EXEC_INS,            insmath},
01739       {"inspaint",   EXEC_INS|EXEC_SUBST, exec_insdraw},
01740       {"insplot",    EXEC_INS|EXEC_SUBST, exec_insplot},
01741       {"insplot3d",  EXEC_INS|EXEC_SUBST, exec_insplot3d},
01742       {"instex",     EXEC_INS,            exec_instex},
01743       {"instexst",   EXEC_INS|EXEC_USECALC,      calc_instexst},
01744       {"instexstatic",      EXEC_INS|EXEC_USECALC,      calc_instexst},
01745       {"item",              EXEC_STRING|EXEC_USECALC,calc_itemof},
01746       {"items",             EXEC_STRING|EXEC_USECALC,calc_itemof},
01747       {"items2lines",       EXEC_STRING|EXEC_SUBST|EXEC_USECALC,items2lines},
01748       {"items2words",       EXEC_STRING|EXEC_SUBST|EXEC_USECALC,items2words},
01749       {"itemstolines",      EXEC_STRING|EXEC_SUBST|EXEC_USECALC,items2lines},
01750       {"itemstowords",      EXEC_STRING|EXEC_SUBST|EXEC_USECALC,items2words},
01751       {"let",        EXEC_SET,            exec_set},
01752       {"leveldata",  EXEC_STRING|EXEC_USECALC,calc_leveldata},
01753       {"levelpoints",       EXEC_STRING|EXEC_USECALC,calc_leveldata},
01754       {"line",              EXEC_STRING|EXEC_USECALC,calc_lineof},
01755       {"lines",             EXEC_STRING|EXEC_USECALC,calc_lineof},
01756       {"lines2items",       EXEC_STRING|EXEC_SUBST|EXEC_USECALC,lines2items},
01757       {"lines2list", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,lines2items},
01758       {"lines2words",       EXEC_STRING|EXEC_SUBST|EXEC_USECALC,lines2words},
01759       {"linestoitems",      EXEC_STRING|EXEC_SUBST|EXEC_USECALC,lines2items},
01760       {"linestolist",       EXEC_STRING|EXEC_SUBST|EXEC_USECALC,lines2items},
01761       {"linestowords",      EXEC_STRING|EXEC_SUBST|EXEC_USECALC,lines2words},
01762       {"list2lines", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,items2lines},
01763       {"list2words", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,items2words},
01764       {"listfile",   EXEC_DIR|EXEC_SUBST|EXEC_USECALC,calc_listfile},
01765       {"listfiles",  EXEC_DIR|EXEC_SUBST|EXEC_USECALC,calc_listfile},
01766       {"listintersect",     EXEC_STRING|EXEC_USECALC,calc_listintersect},
01767       {"listintersection", EXEC_STRING|EXEC_USECALC,calc_listintersect},
01768       {"listtolines",       EXEC_STRING|EXEC_SUBST|EXEC_USECALC,items2lines},
01769       {"listtowords",       EXEC_STRING|EXEC_SUBST|EXEC_USECALC,items2words},
01770       {"listunion",  EXEC_STRING|EXEC_USECALC,calc_listunion},
01771       {"listuniq",   EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_listuniq},
01772       {"listunique", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_listuniq},
01773       {"listvar",    EXEC_STRING|EXEC_SUBST|EXEC_USECALC,mathvarlist},
01774       {"lookup",     EXEC_STRING|EXEC_USECALC,   calc_lookup},
01775       {"lower",             EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_tolower},
01776       {"lowercase",  EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_tolower},
01777       {"ls",         EXEC_DIR|EXEC_SUBST|EXEC_USECALC,calc_listfile},
01778       {"mailto",     EXEC_MAIL|EXEC_SUBST,       exec_mailto},
01779       {"mailurl",    EXEC_MAIL|EXEC_SUBST|EXEC_USECALC,calc_mailurl},
01780       {"makelist",   EXEC_STRING|EXEC_USECALC,calc_makelist},
01781       {"mathsubst",  EXEC_STRING|EXEC_USECALC,calc_mathsubst},
01782       {"mathsubstit",       EXEC_STRING|EXEC_USECALC,calc_mathsubst},
01783       {"mathsubstitute",EXEC_STRING|EXEC_USECALC,calc_mathsubst},
01784       {"mexec",             EXEC_EXEC|EXEC_SUBST,       exec_mexec},
01785       {"module",     EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_module},
01786       {"msg",        EXEC_EXEC|EXEC_SUBST ,exec_msg},
01787       {"multiply",   EXEC_STRING|EXEC_USECALC,calc_product},
01788       {"next",              EXEC_FOR,            exec_next},
01789       {"nocache",    EXEC_READ,           exec_nocache},
01790       {"non_empty",  EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_nonempty},
01791       {"nonempty",   EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_nonempty},
01792       {"nospace",    EXEC_STRING|EXEC_SUBST|EXEC_USECALC,nospace},
01793       {"outfile",    EXEC_HREF|EXEC_SUBST,       exec_getfile},
01794       {"pedia",             EXEC_PEDIA|EXEC_SUBST|EXEC_USECALC,pedia},
01795       {"perl",              EXEC_EXEC|EXEC_PROCTOO|EXEC_SUBST,exec_perl},
01796       {"position",   EXEC_STRING|EXEC_USECALC,calc_pos},
01797       {"positionof", EXEC_STRING|EXEC_USECALC,calc_pos},
01798       {"positions",  EXEC_STRING|EXEC_USECALC,calc_pos},
01799       {"prod",              EXEC_STRING|EXEC_USECALC,calc_product},
01800       {"product",    EXEC_STRING|EXEC_USECALC,calc_product},
01801       {"rawmath",    EXEC_STRING|EXEC_SUBST|EXEC_USECALC,rawmath},
01802       {"rawmatrix",  EXEC_STRING|EXEC_SUBST|EXEC_USECALC,rawmatrix},
01803       {"reaccent",   EXEC_STRING|EXEC_USECALC|EXEC_SUBST,reaccent},
01804       {"read",              EXEC_READ|EXEC_SUBST,       exec_read},
01805       {"readdef",    EXEC_READ|EXEC_SUBST,       exec_defread},
01806       {"readproc",   EXEC_READ|EXEC_SUBST,       exec_readproc},
01807       {"record",     EXEC_STRING|EXEC_USECALC,calc_recordof},
01808       {"records",    EXEC_STRING|EXEC_USECALC,calc_recordof},
01809       {"recursion",  EXEC_STRING|EXEC_USECALC,calc_recursion},
01810       {"reinput",    EXEC_STRING|EXEC_USECALC|EXEC_SUBST,calc_reinput},
01811       {"rem",        EXEC_COMMENT,        exec_comment},
01812       {"remark",     EXEC_COMMENT,        exec_comment},
01813       {"replace",    EXEC_STRING|EXEC_USECALC,calc_replace},
01814       {"reset",             EXEC_SET|EXEC_SUBST, exec_reset},
01815       {"restart",    EXEC_JUMP|EXEC_SUBST,       exec_restart},
01816       {"return",     EXEC_JUMP,           exec_exit},
01817       {"robotrap",   EXEC_HREF|EXEC_SUBST,       exec_robottrap},
01818       {"robottrap",  EXEC_HREF|EXEC_SUBST,       exec_robottrap},
01819       {"rootof",     EXEC_STRING|EXEC_USECALC,calc_solve},
01820       {"row",        EXEC_STRING|EXEC_USECALC,calc_rowof},
01821       {"rows",              EXEC_STRING|EXEC_USECALC,calc_rowof},
01822       {"rows2lines", EXEC_STRING|EXEC_USECALC|EXEC_SUBST,calc_rows2lines},
01823       {"run",        EXEC_EXEC|EXEC_SUBST|EXEC_PROCTOO|EXEC_USECALC,  calc_exec},
01824       {"select",     EXEC_STRING|EXEC_USECALC,calc_select},
01825       {"set",        EXEC_SET,            exec_set},
01826       {"setdef",     EXEC_OTHER,          exec_setdef},
01827       {"sh",         EXEC_EXEC|EXEC_PROCTOO|EXEC_SUBST,exec_sh},
01828       {"shortout",   EXEC_JUMP|EXEC_SUBST,       exec_directout},
01829       {"singlespace",       EXEC_STRING|EXEC_SUBST|EXEC_USECALC,singlespace},
01830       {"solve",             EXEC_STRING|EXEC_USECALC,calc_solve},
01831       {"sort",              EXEC_STRING|EXEC_USECALC, calc_sort},
01832 /*      {"sql",             EXEC_SQL|EXEC_SUBST|EXEC_USECALC, calc_sql}, */
01833       {"staticinstex",      EXEC_INS|EXEC_USECALC,      calc_instexst},
01834       {"stinstex",   EXEC_INS|EXEC_USECALC,      calc_instexst},
01835       {"sum",        EXEC_STRING|EXEC_USECALC,calc_sum},
01836       {"system",     EXEC_EXEC|EXEC_PROCTOO|EXEC_SUBST,exec_sh},
01837       {"tail",              EXEC_HREF,           exec_tail},
01838       {"test",              EXEC_DEBUG,          exec_test},
01839       {"texmath",    EXEC_STRING|EXEC_SUBST|EXEC_USECALC,texmath},
01840       {"text",              EXEC_STRING|EXEC_USECALC,text},
01841       {"title",             EXEC_HREF,           exec_title},
01842       {"tohex",             EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_hex},
01843       {"tolower",    EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_tolower},
01844       {"toupper",    EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_toupper},
01845       {"translate",  EXEC_STRING|EXEC_USECALC,calc_translate},
01846       {"trim",              EXEC_STRING|EXEC_USECALC,calc_trim},
01847       {"upper",             EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_toupper},
01848       {"uppercase",  EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_toupper},
01849       {"usererror",  EXEC_WARN|EXEC_SUBST,       exec_usererror},
01850       {"values",     EXEC_STRING|EXEC_USECALC,calc_values},
01851       {"varlist",    EXEC_STRING|EXEC_SUBST|EXEC_USECALC,mathvarlist},
01852       {"warn",              EXEC_WARN|EXEC_SUBST,       exec_warn},
01853       {"warning",    EXEC_WARN|EXEC_SUBST,       exec_warn},
01854       {"while",             EXEC_WHILE,          exec_while},
01855       {"whileval",   EXEC_WHILE,          exec_whileval},
01856       {"whilevalue", EXEC_WHILE,          exec_whileval},
01857       {"wimsheader", EXEC_HREF,           exec_header},
01858       {"wimsref",    EXEC_HREF,           exec_homeref},
01859       {"wimstail",   EXEC_HREF,           exec_tail},
01860       {"wimstitle",  EXEC_HREF,           exec_title},
01861       {"word",              EXEC_STRING|EXEC_USECALC,calc_wordof},
01862       {"words",             EXEC_STRING|EXEC_USECALC,calc_wordof},
01863       {"words2items",       EXEC_STRING|EXEC_SUBST|EXEC_USECALC,words2items},
01864       {"words2lines",       EXEC_STRING|EXEC_SUBST|EXEC_USECALC,words2lines},
01865       {"words2list", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,words2items},
01866       {"wordstoitems",      EXEC_STRING|EXEC_SUBST|EXEC_USECALC,words2items},
01867       {"wordstolines",      EXEC_STRING|EXEC_SUBST|EXEC_USECALC,words2lines},
01868       {"wordstolist",       EXEC_STRING|EXEC_SUBST|EXEC_USECALC,words2items},
01869       {"writefile",  EXEC_DIR|EXEC_SUBST, filewrite},
01870 };
01871 #define EXEC_FN_NO (sizeof(exec_routine)/sizeof(exec_routine[0]))
01872 
01873        /* internal: to skip the content of a false if/while. */
01874 static void _skip_contents(int isif)
01875 {
01876     char buf[MAX_NAMELEN+8], *p1;
01877     int i,j,loop;
01878     loop=0;
01879     while(m_file.linepointer<m_file.linecnt) {
01880        j=m_file.linepointer;
01881        if((m_file.lines[j].isstart&2)==0) {
01882            m_file.linepointer++; continue;
01883        }
01884        i=m_file.lines[j].execcode; if(i<0) {
01885            if(wgetline(buf,MAX_NAMELEN+4,&m_file)==EOF) return;
01886            p1=buf+1; if(*p1!='i' && *p1!='e' && *p1!='w') continue;
01887            *find_word_end(p1)=0;
01888            i=search_list(exec_routine,EXEC_FN_NO,sizeof(exec_routine[0]),p1);
01889            if(i>=0) m_file.lines[j].execcode=i;
01890        }
01891        else m_file.linepointer++;
01892        if(i<0) continue;
01893        switch(exec_routine[i].tag & 0xffff) {
01894            case EXEC_WHILE:
01895               if(!isif) loop++; break;
01896            case EXEC_IF:
01897               if(isif) loop++; break;
01898            case EXEC_ELSE: {
01899               if(!isif) break;
01900               if(loop<=0) return; else break;
01901            }
01902            case EXEC_ENDIF: {
01903               if(!isif) break;
01904               if(loop>0) {
01905                   loop--; break;
01906               }
01907               else return;
01908            }
01909            case EXEC_ENDWHILE: {
01910               if(isif) break;
01911               if(loop>0) {
01912                   loop--; break;
01913               }
01914               else return;
01915            }
01916            default: break;
01917        }
01918     }
01919 }
01920 
01921        /* Execute a command defined by !. Returns 0 if OK. */
01922 void exec_main(char *p)
01923 {
01924     int i,j;
01925     char *pp;
01926     char tbuf2[MAX_LINELEN+1];
01927 
01928     pp=find_word_end(p); 
01929     if(*pp!=0) {
01930        *(pp++)=0; pp=find_word_start(pp);
01931     }
01932     i=m_file.lines[m_file.l].execcode;
01933     if(i<0) {
01934        i=search_list(exec_routine,EXEC_FN_NO,sizeof(exec_routine[0]),p);
01935        m_file.lines[m_file.l].execcode=i;
01936     }
01937     if(i<0) {
01938        setvar(error_data_string,p); module_error("bad_cmd");
01939     }
01940        /* called from !readdef, no right other than set; bail out */
01941     execnt++;
01942     if((untrust&4)!=0 && (j=(exec_routine[i].tag&0xffff))!=EXEC_SET) {
01943        tbuf2[0]=0; exec_exit(tbuf2);
01944     }
01945     strcpy(tbuf2,pp); j=exec_routine[i].tag;
01946     if(j&EXEC_SUBST) substit(tbuf2);
01947     if(j&EXEC_USECALC) {
01948        if(!outputing && (j&EXEC_PROCTOO)==0) return;
01949        exec_routine[i].routine(tbuf2); if(outputing) output0(tbuf2);
01950     }
01951     else exec_routine[i].routine(tbuf2);
01952     return;
01953 }
01954