Back to index

wims  3.65+svn20090927
common.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        /* Common routines in interfaces */
00019 
00020 #define ch_root "bin/ch..root"
00021 
00022 int mypid;
00023 int must_chroot=0;
00024 char inputfname[256], outputfname[256];
00025 char pidfname[256];
00026 char parmbuf[parmlim+16];
00027 char *inpf, *outpf, *errorf;
00028 char *parm;
00029 char *tmp_dir;
00030 char cmdbuf[1024];
00031 char inputbuf[inputlim];
00032 char *inputptr, *inputend;
00033 char stdinbuf[MAX_LINELEN+1];
00034 char *cmdparm;
00035 int isabout=0;
00036 char *multiexec_random;
00037 int multiexec=0, mxpid, notfirst;
00038 int pipe_in[2], pipe_out[2];
00039 int debug=0;
00040 FILE *goin;
00041 unsigned int seed;   /* random seed value */
00042 char aboutbuf[aboutlen];
00043        /* this is only a default. It should usually be reset. */
00044 char *tmpdir="/tmp";
00045 char startstring[256], endstring[256];
00046 char *obuf;
00047 
00048 void check_parm(char *p);
00049 void output(char *p);
00050 void about(void);
00051 char *dynsetup(char *p, char *end);
00052 
00053 void *xmalloc(size_t n)
00054 {
00055     void *p;
00056     p=malloc(n);
00057     if(p==NULL) {
00058        fprintf(stderr, "%s: Malloc failure.\n",progname);
00059        exit(1);
00060     }
00061     return p;
00062 }
00063 
00064        /* strip trailing spaces; return string end. */
00065 char *strip_trailing_spaces(char *p)
00066 {
00067     char *pp;
00068     if(*p==0) return p;
00069     for(pp=p+strlen(p)-1; pp>=p && isspace(*pp); *(pp--)=0);
00070     return pp;
00071 }
00072 
00073        /* Points to the end of the word */
00074 char *find_word_end(char *p)
00075 {
00076     int i;
00077     for(i=0;!isspace(*p) && *p!=0 && i<MAX_LINELEN; p++,i++);
00078     return p;
00079 }
00080 
00081        /* Strips leading spaces */
00082 char *find_word_start(char *p)
00083 {
00084     int i;
00085     for(i=0; isspace(*p) && i<MAX_LINELEN; p++,i++);
00086     return p;
00087 }
00088 
00089        /* Find first occurrence of word */
00090 char *wordchr(char *p, char *w)
00091 {
00092     char *r;
00093 
00094     if(*w==0) return NULL;
00095     for(r=strstr(p,w);r!=NULL && 
00096        ( (r>p && !isspace(*(r-1))) || (!isspace(*(r+strlen(w))) && *(r+strlen(w))!=0) );
00097        r=strstr(r+1,w));
00098     return r;
00099 }
00100 
00101          /* Returns the pointer or NULL. */
00102 char *varchr(char *p, char *v)
00103 {
00104         char *pp; int n=strlen(v);
00105         for(pp=strstr(p,v); pp!=NULL; pp=strstr(pp+1,v)) {
00106            if((pp==p || (!isalnum(*(pp-1)) && *(pp-1)!='_')) &&
00107               ((!isalnum(*(pp+n)) && *(pp+n)!='_') || *(pp+n)==0)) break;
00108        }
00109         return pp;
00110 }
00111 
00112        /* find matching parenthesis */
00113 char *find_matching(char *p, char c)
00114 {
00115     char *pp;
00116     int parenth, brak, brace;
00117     parenth=brak=brace=0;
00118     for(pp=p; *pp!=0; pp++) {
00119        switch(*pp) {
00120            case '[': brak++; break;
00121            case ']': brak--; break;
00122            case '(': parenth++; break;
00123            case ')': parenth--; break;
00124            case '{': brace++; break;
00125            case '}': brace--; break;
00126            default: continue;
00127        }
00128        if(parenth<0 || brak<0 || brace<0) {
00129            if(*pp!=c || parenth>0 || brak>0 || brace>0) return NULL;
00130            else break;
00131        }
00132     }
00133     if(*pp!=c) return NULL;
00134     return pp;
00135 }
00136 
00137        /* searches a list. Returns index if found, -1 if nomatch. 
00138         * Uses binary search, list must be sorted. */
00139 int search_list(void *list, int items, size_t item_size, const char *str)
00140 {
00141     int i1,i2,j,k;
00142     char **p;
00143     char c;
00144     
00145     if(items<=0) return -1;
00146     j=0; c=*str;
00147     p=list;
00148     k=**p-c; if(k==0) k=strcmp(*p,str);
00149     if(k==0) return k; if(k>0) return -1;
00150     p=list+(items-1)*item_size; 
00151     k=**p-c; if(k==0) k=strcmp(*p,str);
00152     if(k==0) return items-1; if(k<0) return -1;
00153     for(i1=0,i2=items-1;i2>i1+1;) {
00154        j=i1+(i2-i1)/2;
00155        p=list+(j*item_size);
00156        k=**p-c; if(k==0) k=strcmp(*p,str);
00157        if(k==0) return j;
00158        if(k>0) {i2=j; continue;}
00159        if(k<0) {i1=j; continue;}   
00160     }
00161     return -1;
00162 }
00163 
00164        /* Read/write to a file with variable parms to print filename */
00165 void accessfile(char *content, char *type, char *s,...)
00166 {
00167     va_list vp;
00168     char buf[MAX_LINELEN+1];
00169     FILE *f;
00170     int l;
00171 
00172     va_start(vp,s);
00173     vsnprintf(buf,sizeof(buf),s,vp);
00174     va_end(vp);
00175     f=fopen(buf,type); if(f==NULL) {
00176        if(*type=='r') content[0]=0; return;
00177     }
00178     switch(*type) {
00179        case 'a':
00180        case 'w': {
00181            l=strlen(content); fwrite(content,1,l,f); break;
00182        }
00183        case 'r': {
00184            l=fread(content,1,MAX_LINELEN-1,f);
00185            if(l>0 && l<MAX_LINELEN) content[l]=0;
00186            else content[0]=0;
00187            break;
00188        }
00189        default: {
00190            content[0]=0; break;
00191        }
00192     }
00193     fclose(f);
00194 }
00195 
00196 void getstdin(void)
00197 {
00198     char *p;
00199     int i,j,k;
00200     i=0; k=MAX_LINELEN; stdinbuf[0]=0;
00201     do {
00202        j=read(0,stdinbuf+i,k);
00203        if(j<0 || j>k) exit(1);
00204        i+=j; k-=j; stdinbuf[i]=0;
00205        p=strstr(stdinbuf,multiexec_random);
00206        if(p) {*p=0; break;}
00207     }
00208     while(k>0);
00209 }
00210 
00211        /* add a pid to the list of running childs */
00212 void addpid(int pid)
00213 {
00214     char buf[MAX_LINELEN+1], pidbuf[32];
00215     int l;
00216     snprintf(pidbuf,sizeof(pidbuf),"%u",pid);
00217     accessfile(buf,"r",pidfname); l=strlen(buf);
00218     if(l>=MAX_LINELEN-64) return;
00219     if(wordchr(buf,pidbuf)==NULL) {
00220        snprintf(buf+l,sizeof(buf)-l," %s",pidbuf);
00221        accessfile(buf,"w",pidfname);
00222     }
00223 }
00224 
00225        /* Remove a pidname to the list of running childs */
00226 void rmpid(int pid)
00227 {
00228     char buf[MAX_LINELEN+1], pidbuf[32], *p;
00229     snprintf(pidbuf,sizeof(pidbuf),"%u",pid);
00230     accessfile(buf,"r",pidfname);
00231     p=wordchr(buf,pidbuf);
00232     if(p!=NULL) {
00233        strcpy(p,find_word_start(find_word_end(p)));
00234        accessfile(buf,"w",pidfname);
00235     }
00236 }
00237 
00238 int execredirected(char *cmdf, char *inf, char *outf, char *errf,
00239                  char *args)
00240 {
00241     pid_t pid;
00242     int i;
00243     struct stat st;
00244     char *cm, *p, *p2, abuf[MAX_LINELEN+1];
00245     char *arg[1024];
00246 
00247     for(cm=cmdf; isspace(*cm); cm++); if(*cmdf==0) return -1;
00248     fflush(NULL);    /* flush all output streams before forking
00249                       * otherwise they will be doubled */
00250     pid=fork(); if(pid==-1) return -1;
00251     if(!pid) {       /* child */
00252        if(!inf) {
00253            dup2(pipe_in[0],0); close(pipe_in[1]);
00254        }
00255        else freopen(inf,"r",stdin);
00256        if(!outf) {
00257            dup2(pipe_out[1],1); close(pipe_out[0]);
00258        }
00259        else freopen(outf,"w",stdout);
00260        if(errf) freopen(errf,"w",stderr);
00261        snprintf(abuf,sizeof(abuf),"%s",find_word_start(args));
00262        if(stat("../chroot/tmp/sessions/.chroot",&st)==0 || must_chroot) {
00263            arg[0]=ch_root; i=1;
00264        }
00265        else {
00266            i=0;
00267            setreuid(getuid(),getuid());setregid(getgid(),getgid());
00268        }
00269        arg[i++]=cmdf;
00270        for(p=abuf; *p && i<1000; i++, p=find_word_start(p2)) {
00271            arg[i]=p; p2=find_word_end(p); if(*p2) *p2++=0;
00272        }
00273        arg[i]=NULL;
00274        if(strchr(arg[0],'/')) execv(arg[0],arg);
00275        else execvp(arg[0],arg);
00276        fprintf(stderr,"%s not_INStalled",progname);
00277        exit(127);
00278     }
00279     else {    /* parent */
00280        addpid(pid); mxpid=pid;
00281        if(outf) {
00282            int status;
00283            close(pipe_in[1]);
00284            if(waitpid(pid,&status,0)==pid) {
00285               rmpid(pid); mxpid=-1;
00286            }
00287        }
00288     }
00289     return 0;
00290 }
00291 
00292        /* verify illegal strings in parms. */
00293 void find_illegal(char *p)
00294 {
00295     char *pp, *pe;
00296     int i, l;
00297     for(pp=p;*pp;pp++) {
00298        if((*pp<' ' && *pp!='\n' && *pp!=' ') || *pp>=127) *pp=' ';
00299     }
00300     for(i=0;i<illpart_no;i++) {
00301        pe=illpart[i]; l=strlen(pe);
00302        for(pp=strstr(p,pe); pp; pp=strstr(pp+1,pe)) {
00303            if(!isupper(pe[0]) || !islower(*(pp+l))) {
00304               if(pp[1]!='j' && pp[1]!='J') pp[1]='J';
00305               else pp[1]='Z';
00306            }
00307        }
00308     }
00309     for(i=0;i<illegal_no;i++) {
00310        pe=illegal[i]; l=strlen(pe);
00311        for(pp=strstr(p,pe); pp; pp=strstr(pp+1,pe)) {
00312            if((pp==p || !isalnum(*(pp-1))) && !isalnum(*(pp+l))) {
00313               if(pp[1]!='j' && pp[1]!='J') pp[1]='J';
00314               else pp[1]='Z';
00315            }
00316        }
00317     }
00318 }
00319 
00320        /* strip trailing zeros */
00321 void strip_zeros(char *p)
00322 {
00323     char *pp, *p2, *numend, *ee;
00324     int i;
00325     for(pp=p;*pp!=0;pp++) {
00326        if(!isdigit(*pp)) continue;
00327        i=0;
00328        for(numend=pp;isdigit(*numend) || *numend=='.';numend++)
00329          if(*numend=='.') i=1;
00330        if(i==0) {
00331            pp=numend-1;continue;
00332        }
00333        for(p2=numend;p2>pp && *(p2-1)=='0';p2--);
00334        for(ee=numend;isspace(*ee);ee++);
00335        if(*(pp+1)=='.' && (*ee=='E' || *ee=='e') 
00336           && *(ee+1)=='-') {
00337            int k=0;
00338            char *pt=ee+2;
00339            while(isdigit(*pt)) {
00340               k*=10;k+=*pt-'0';pt++;
00341            }
00342            if(precision>8 && (k>precision*2 || (k>precision && *pp=='0'))) {
00343               
00344               sprintf(pp,"0.0%s",pt);
00345               
00346               pp+=strlen("0.0")-1;
00347               continue;
00348            }
00349        }
00350        
00351        if(*(p2-1)=='.' && p2<numend) p2++; 
00352        
00353        if(p2<numend) {
00354            strcpy(p2,numend);numend=p2;
00355        }
00356        pp=numend-1;
00357     }
00358 }
00359 
00360 char *hname[]={"", "_1","_2","_3","_4","_5","_6","_7","_8"};
00361 #define hnameno (sizeof(hname)/sizeof(hname[0]))
00362 
00363 void putheader(void)
00364 {
00365     char hbuf[64];
00366     char *p;
00367     int i;
00368     
00369     inputptr=dynsetup(inputptr,inputend);
00370     snprintf(inputptr,inputend-inputptr,"%s",header);
00371     inputptr+=strlen(inputptr);
00372     for(i=0;i<hnameno;i++) {
00373        snprintf(hbuf,sizeof(hbuf),"w_%s_header%s",progname,hname[i]);
00374        p=getenv(hbuf); if(p!=NULL && *p!=0) {
00375            snprintf(parmbuf,parmlim,"%s",p);
00376            check_parm(parmbuf); 
00377            snprintf(inputptr,inputend-inputptr,"%s\n",parmbuf);
00378            inputptr+=strlen(inputptr);
00379        }
00380     }
00381 }
00382 
00383 void putparm(void)
00384 {
00385     snprintf(parmbuf,parmlim,"%s",parm); check_parm(parmbuf);
00386     snprintf(inputptr,inputend-inputptr,stringprinter,startstring);
00387     inputptr+=strlen(inputptr);
00388     snprintf(inputptr,inputend-inputptr,"%s",parmbuf);
00389     inputptr+=strlen(inputptr);
00390     if(inputptr<inputend && inputptr>inputbuf && inputptr[-1]!='\n')
00391       *inputptr++='\n';
00392     snprintf(inputptr,inputend-inputptr,stringprinter,endstring);
00393     inputptr+=strlen(inputptr);
00394     *inputptr=0;
00395 }
00396 
00397        /* general first preparation */
00398 void prepare1(void)
00399 {
00400     char *p, buf[256];
00401     int i;
00402     unsigned int r[4];
00403     struct timeval t;
00404 
00405     parm=getenv("wims_exec_parm");
00406        /* nothing to do if no calling parameter */
00407     if(parm==NULL || *parm==0) exit(0);
00408     inputptr=inputbuf; inputend=inputbuf+inputlim-1;
00409     multiexec_random=getenv("multiexec_random");
00410     if(multiexec_random==NULL) multiexec_random="";
00411     if(*parm && strcmp(parm,multiexec_random)==0) {
00412        multiexec=1;
00413        getstdin(); parm=stdinbuf;
00414        if(parm[0]==0) exit(0);
00415     }
00416     if(pipe(pipe_in)<0 || pipe(pipe_out)<0) {
00417        fprintf(stderr,"%s: unable to create pipe.\n",progname);
00418        exit(1);
00419     }
00420 /*    i=fcntl(pipe_in[1],F_GETFL); if(i>=0) fcntl(pipe_in[1],F_SETFL,i|O_NONBLOCK);
00421     i=fcntl(pipe_out[0],F_GETFL); if(i>=0) fcntl(pipe_out[0],F_SETFL,i|O_NONBLOCK);
00422 */    tmp_dir=getenv("tmp_dir"); if(tmp_dir==NULL || *tmp_dir==0) tmp_dir=tmpdir;
00423     setenv("TMPDIR",tmp_dir,1);
00424     mypid=getpid();
00425     gettimeofday(&t,NULL); seed=t.tv_usec*t.tv_sec+mypid;
00426     srandom(seed);
00427     for(i=0;i<4;i++) r[i]=random();
00428     snprintf(startstring,sizeof(startstring),
00429             "Start line %s %u %u %u %u",progname,r[0],r[1],r[2],r[3]);
00430     snprintf(endstring,sizeof(endstring),
00431             "End line %s %u %u %u %u",progname,r[0],r[1],r[2],r[3]);
00432     snprintf(buf,sizeof(buf),"%s_command",progname); p=getenv(buf);
00433     if(p!=NULL && *find_word_start(p)!=0) nameofcmd=find_word_start(p);
00434     snprintf(cmdbuf,sizeof(cmdbuf),"%s",nameofcmd); nameofcmd=cmdbuf;
00435     cmdparm=find_word_end(nameofcmd); if(*cmdparm) *cmdparm++=0;
00436     cmdparm=find_word_start(cmdparm);
00437     snprintf(pidfname,sizeof(pidfname),"%s/exec.pid",tmp_dir); addpid(mypid);
00438     snprintf(inputfname,sizeof(inputfname),"%s/%s_input.%d",tmp_dir,progname,mypid);
00439     snprintf(outputfname,sizeof(outputfname),"%s/%s_output.%d",tmp_dir,progname,mypid);
00440     errorf=NULL;
00441     inpf=inputfname; outpf=outputfname;
00442     isabout=0; p=find_word_start(parm); i=strlen("about");
00443     if(memcmp(p,"about",i)==0 && *find_word_start(p+i)==0) isabout=1;
00444     p=getenv("multiexec_debug"); if(p && strcmp(p,"yes")==0) debug=1;
00445 }
00446 
00447 void prepabout(char *cmd, char *outf, char *errf)
00448 {
00449     write(pipe_in[1],cmd,strlen(cmd));
00450     execredirected(nameofcmd,NULL,outf,errf,cmdparm);
00451 }
00452 
00453        /* read to aboutbuf. Returns content length. */
00454 int readabout(void)
00455 {
00456     FILE *ff;
00457     long int l;
00458     char *p;
00459     
00460     aboutbuf[0]=0; ff=fopen(outputfname,"r");
00461     if(ff!=NULL) {
00462        fseek(ff,0,SEEK_END); l=ftell(ff); fseek(ff,0,SEEK_SET);
00463        l=fread(aboutbuf,1,aboutlen-10,ff); fclose(ff);
00464        if(l>0 && l<aboutlen) aboutbuf[l]=0; else aboutbuf[0]=0;
00465        p=find_word_start(aboutbuf); if(p>aboutbuf) strcpy(aboutbuf,p);
00466     }
00467     return strlen(aboutbuf);
00468 }
00469 
00470        /* read result of execution */
00471 void readresult(void)
00472 {
00473     FILE *ff;
00474     char *p, *pp, *pe;
00475 
00476     if(debug) {
00477        ff=fopen(outputfname,"a"); if(ff) {
00478            fputs(obuf,ff); fclose(ff);
00479        }
00480     }
00481     pe=NULL;
00482     p=strstr(obuf,startstring);
00483     if(p) {
00484        p+=strlen(startstring);
00485        pe=strstr(p,endstring);
00486        if(pe) {
00487            for(pp=pe-1; pp>=p && pp>pe-64 && *pp!='\n'; pp--);
00488            if(pp>=p && *pp=='\n') pe=pp;
00489        }
00490     }
00491     if(pe) {
00492        *pe=0;
00493        while((pe=strstr(p,startstring))!=NULL) {
00494            p=pe+strlen(startstring);
00495        }
00496        output(p);
00497     }
00498     else {
00499        if(mxpid>=0) {
00500            if(kill(mxpid,0)<0 && errno==ESRCH) { /* this doesn't work */
00501               fprintf(stderr,"%s not_INStalled",progname);
00502            }
00503            else {
00504               fprintf(stderr,"%s: execution error or time out.\n",progname);
00505               kill(mxpid,SIGKILL);
00506            }
00507            rmpid(mxpid); mxpid=-1;
00508        }
00509        else {
00510            fprintf(stderr,"%s: aborted on earlier error.\n",progname);
00511        }
00512     }
00513     if(multiexec && *multiexec_random) printf("%s\n",multiexec_random);
00514     fflush(stdout);
00515 }
00516 
00517 #ifdef linebyline1
00518 
00519        /* this one is for maxima but not used */
00520 void dopipes(void)
00521 {
00522     long int i, l;
00523     char *outptr;
00524     char *p1, *p2, *pp, *pe;
00525     struct timeval t;
00526     fd_set rset;
00527 
00528     if(mxpid<0) {
00529        *obuf=0; return;
00530     }
00531     outptr=obuf; pp=pe=NULL;
00532     for(p1=ibuf; *p1; p1=p2) {
00533        p2=strchr(p1,'\n'); if(p2) p2++; else p2=p1+strlen(p1);
00534        write(pipe_in[1],p1,p2-p1);
00535        
00536        if(strstr(p1,startstring)!=NULL) iactive=1;
00537        reread:
00538        l=read(fifofd2,lp,MAX_LINELEN-(lp-lbuf));
00539        if(!iactive) continue;
00540        if(l<0 || l>MAX_LINELEN-(lp-lbuf)) l=0;
00541        lp+=l; *lp=0;
00542        if(active==0) {
00543            char *pp;
00544            pp=strstr(lbuf,startstring);
00545            if(pp!=NULL) {
00546               active=1; strcpy(lbuf,pp); lp=lbuf+strlen(lbuf);
00547            }
00548        }
00549        if(active!=0 && strstr(lbuf,linebyline)!=NULL) {
00550            fprintf(ff,"%s",lbuf); lp=lbuf;
00551            if(strstr(lbuf,endstring)!=NULL) {lbuf[0]=0; active=-1; break;}
00552            lbuf[0]=0; continue;
00553        }
00554        /* time out allowance between each silence */
00555        t.tv_sec=3; t.tv_usec=400000;
00556        i=select(fifofd2+1,&rset,NULL,NULL,&t);
00557        if(i>0) goto reread;
00558        else break; /* time out or error */
00559     }
00560 }
00561 
00562 #else
00563 
00564 void dopipes(void)
00565 {
00566     long int i, k, l;
00567     int interval=20000;     /* in microseconds */
00568     int timeout =300;       /* in intervals */
00569     char *outptr;
00570     char *p1, *p2, *inp, *pw;
00571     struct timeval t;
00572     fd_set rset, wset;
00573 
00574     *obuf=0; if(mxpid<0) return;
00575     outptr=obuf; inp=inputbuf; k=0; 
00576     while(inp<inputptr) {
00577        t.tv_sec=0; t.tv_usec=interval;
00578        FD_ZERO(&rset); FD_SET(pipe_out[0],&rset);
00579        FD_ZERO(&wset); FD_SET(pipe_in[1],&wset);
00580        i=pipe_out[0]; if(i<pipe_in[1]) i=pipe_in[1];
00581        i=select(i+1,&rset,&wset,NULL,&t);
00582        if(i<=0) {
00583            k++; if(k>=timeout) return;    /* time out */
00584        }
00585        if(FD_ISSET(pipe_in[1],&wset)) {
00586               /* Writing must be line by line, for otherwise
00587                * it will block when the input is large. */
00588            for(pw=inp; pw<inputptr && *pw!='\n'; pw++);
00589            if(pw<inputptr) pw++;
00590            l=write(pipe_in[1],inp,pw-inp);
00591            if(l<0 || l>inputptr-inp) return;
00592            inp+=l;
00593        }
00594        if(FD_ISSET(pipe_out[0],&rset)) {
00595            l=read(pipe_out[0],outptr,fsizelim-(outptr-obuf)-1);
00596            if(l<=0 || l>fsizelim-(outptr-obuf)-1) {
00597               *outptr=0; break;
00598            }
00599            outptr+=l; *outptr=0;
00600        }
00601     }
00602     p2=NULL;
00603     p1=strstr(obuf,startstring);
00604     if(p1) {
00605        p1+=strlen(startstring);
00606        p2=strstr(p1,endstring);
00607     }
00608     while(!p2) {
00609        t.tv_sec=0; t.tv_usec=interval;
00610        FD_ZERO(&rset); FD_SET(pipe_out[0],&rset);
00611        i=select(pipe_out[0]+1,&rset,NULL,NULL,&t);
00612        if(i>0) {
00613            l=read(pipe_out[0],outptr,fsizelim-(outptr-obuf)-1);
00614            if(l<=0 || l>fsizelim-(outptr-obuf)-1) {
00615               *outptr=0; break;
00616            }
00617            outptr+=l; *outptr=0;
00618        }
00619        else {
00620            k++; if(k>=timeout) break;
00621        }
00622        if(!p1) {
00623            p1=strstr(obuf,startstring);
00624            if(p1) p1+=strlen(startstring);
00625        }
00626        if(p1) p2=strstr(p1,endstring);
00627     }
00628 }
00629 
00630 #endif
00631 
00632 void run(void)
00633 {
00634     FILE *ff;
00635     
00636     if(isabout) {about(); goto end;}
00637     execredirected(nameofcmd,NULL,NULL,NULL,cmdparm);
00638     putheader();
00639     obuf=xmalloc(fsizelim); if(!obuf) return;
00640     rep:
00641     putparm();
00642     if(!multiexec) {
00643        snprintf(inputptr,inputend-inputptr,"%s",quitstring);
00644        inputptr+=strlen(inputptr);
00645     }
00646     if(debug) {
00647        ff=fopen(inputfname,"a"); if(ff) {
00648            fputs(inputbuf,ff); fclose(ff);
00649        }
00650     }
00651     dopipes();
00652     readresult();
00653     if(multiexec) {
00654        getstdin(); inputptr=inputbuf; inputbuf[0]=0;
00655        goto rep;
00656     }
00657     end: if(strstr(tmp_dir,"tmp/sessions/")==NULL) {
00658        unlink(inputfname); unlink(outputfname);
00659     }
00660     free(obuf); rmpid(mypid);
00661     if(mxpid>0) {kill(mxpid,SIGKILL); rmpid(mxpid);}
00662 }
00663