Subversion Repositories wimsdev

Rev

Rev 3843 | Rev 7079 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
10 reyssat 1
/*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
2
 *
3
 *  This program is free software; you can redistribute it and/or modify
4
 *  it under the terms of the GNU General Public License as published by
5
 *  the Free Software Foundation; either version 2 of the License, or
6
 *  (at your option) any later version.
7
 *
8
 *  This program is distributed in the hope that it will be useful,
9
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 *  GNU General Public License for more details.
12
 *
13
 *  You should have received a copy of the GNU General Public License
14
 *  along with this program; if not, write to the Free Software
15
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
 */
17
 
18
        /* Common routines in interfaces */
3718 reyssat 19
#include "../Lib/basicstr.c"
10 reyssat 20
 
21
#define ch_root "bin/ch..root"
22
 
23
int mypid;
24
int must_chroot=0;
25
char inputfname[256], outputfname[256];
26
char pidfname[256];
27
char parmbuf[parmlim+16];
28
char *inpf, *outpf, *errorf;
29
char *parm;
30
char *tmp_dir;
31
char cmdbuf[1024];
32
char inputbuf[inputlim];
33
char *inputptr, *inputend;
34
char stdinbuf[MAX_LINELEN+1];
35
char *cmdparm;
36
int isabout=0;
37
char *multiexec_random;
38
int multiexec=0, mxpid, notfirst;
39
int pipe_in[2], pipe_out[2];
40
int debug=0;
41
FILE *goin;
42
unsigned int seed;      /* random seed value */
43
char aboutbuf[aboutlen];
44
        /* this is only a default. It should usually be reset. */
45
char *tmpdir="/tmp";
46
char startstring[256], endstring[256];
47
char *obuf;
48
 
49
void check_parm(char *p);
50
void output(char *p);
51
void about(void);
52
char *dynsetup(char *p, char *end);
53
 
54
void *xmalloc(size_t n)
55
{
56
    void *p;
57
    p=malloc(n);
58
    if(p==NULL) {
59
        fprintf(stderr, "%s: Malloc failure.\n",progname);
60
        exit(1);
61
    }
62
    return p;
63
}
64
 
65
        /* strip trailing spaces; return string end. */
66
char *strip_trailing_spaces(char *p)
67
{
68
    char *pp;
69
    if(*p==0) return p;
70
    for(pp=p+strlen(p)-1; pp>=p && isspace(*pp); *(pp--)=0);
71
    return pp;
72
}
73
 
74
        /* Points to the end of the word */
75
char *find_word_end(char *p)
76
{
77
    int i;
78
    for(i=0;!isspace(*p) && *p!=0 && i<MAX_LINELEN; p++,i++);
79
    return p;
80
}
81
 
82
        /* Strips leading spaces */
83
char *find_word_start(char *p)
84
{
85
    int i;
86
    for(i=0; isspace(*p) && i<MAX_LINELEN; p++,i++);
87
    return p;
88
}
89
 
90
        /* Find first occurrence of word */
91
char *wordchr(char *p, char *w)
92
{
93
    char *r;
94
 
95
    if(*w==0) return NULL;
96
    for(r=strstr(p,w);r!=NULL &&
97
        ( (r>p && !isspace(*(r-1))) || (!isspace(*(r+strlen(w))) && *(r+strlen(w))!=0) );
98
        r=strstr(r+1,w));
99
    return r;
100
}
101
 
102
         /* Returns the pointer or NULL. */
103
char *varchr(char *p, char *v)
104
{
105
        char *pp; int n=strlen(v);
106
        for(pp=strstr(p,v); pp!=NULL; pp=strstr(pp+1,v)) {
107
            if((pp==p || (!isalnum(*(pp-1)) && *(pp-1)!='_')) &&
108
               ((!isalnum(*(pp+n)) && *(pp+n)!='_') || *(pp+n)==0)) break;
109
        }
110
        return pp;
111
}
112
 
113
        /* find matching parenthesis */
114
char *find_matching(char *p, char c)
115
{
116
    char *pp;
117
    int parenth, brak, brace;
118
    parenth=brak=brace=0;
119
    for(pp=p; *pp!=0; pp++) {
120
        switch(*pp) {
121
            case '[': brak++; break;
122
            case ']': brak--; break;
123
            case '(': parenth++; break;
124
            case ')': parenth--; break;
125
            case '{': brace++; break;
126
            case '}': brace--; break;
127
            default: continue;
128
        }
129
        if(parenth<0 || brak<0 || brace<0) {
130
            if(*pp!=c || parenth>0 || brak>0 || brace>0) return NULL;
131
            else break;
132
        }
133
    }
134
    if(*pp!=c) return NULL;
135
    return pp;
136
}
137
 
138
        /* searches a list. Returns index if found, -1 if nomatch.
139
         * Uses binary search, list must be sorted. */
140
int search_list(void *list, int items, size_t item_size, const char *str)
141
{
142
    int i1,i2,j,k;
143
    char **p;
144
    char c;
145
 
146
    if(items<=0) return -1;
147
    j=0; c=*str;
148
    p=list;
149
    k=**p-c; if(k==0) k=strcmp(*p,str);
150
    if(k==0) return k; if(k>0) return -1;
151
    p=list+(items-1)*item_size;
152
    k=**p-c; if(k==0) k=strcmp(*p,str);
153
    if(k==0) return items-1; if(k<0) return -1;
154
    for(i1=0,i2=items-1;i2>i1+1;) {
155
        j=i1+(i2-i1)/2;
156
        p=list+(j*item_size);
157
        k=**p-c; if(k==0) k=strcmp(*p,str);
158
        if(k==0) return j;
159
        if(k>0) {i2=j; continue;}
160
        if(k<0) {i1=j; continue;}      
161
    }
162
    return -1;
163
}
164
 
165
        /* Read/write to a file with variable parms to print filename */
166
void accessfile(char *content, char *type, char *s,...)
167
{
168
    va_list vp;
169
    char buf[MAX_LINELEN+1];
170
    FILE *f;
171
    int l;
172
 
173
    va_start(vp,s);
174
    vsnprintf(buf,sizeof(buf),s,vp);
175
    va_end(vp);
176
    f=fopen(buf,type); if(f==NULL) {
177
        if(*type=='r') content[0]=0; return;
178
    }
179
    switch(*type) {
180
        case 'a':
181
        case 'w': {
182
            l=strlen(content); fwrite(content,1,l,f); break;
183
        }
184
        case 'r': {
185
            l=fread(content,1,MAX_LINELEN-1,f);
186
            if(l>0 && l<MAX_LINELEN) content[l]=0;
187
            else content[0]=0;
188
            break;
189
        }
190
        default: {
191
            content[0]=0; break;
192
        }
193
    }
194
    fclose(f);
195
}
196
 
197
void getstdin(void)
198
{
199
    char *p;
200
    int i,j,k;
201
    i=0; k=MAX_LINELEN; stdinbuf[0]=0;
202
    do {
203
        j=read(0,stdinbuf+i,k);
204
        if(j<0 || j>k) exit(1);
205
        i+=j; k-=j; stdinbuf[i]=0;
206
        p=strstr(stdinbuf,multiexec_random);
207
        if(p) {*p=0; break;}
208
    }
209
    while(k>0);
210
}
211
 
212
        /* add a pid to the list of running childs */
213
void addpid(int pid)
214
{
215
    char buf[MAX_LINELEN+1], pidbuf[32];
216
    int l;
217
    snprintf(pidbuf,sizeof(pidbuf),"%u",pid);
218
    accessfile(buf,"r",pidfname); l=strlen(buf);
219
    if(l>=MAX_LINELEN-64) return;
220
    if(wordchr(buf,pidbuf)==NULL) {
221
        snprintf(buf+l,sizeof(buf)-l," %s",pidbuf);
222
        accessfile(buf,"w",pidfname);
223
    }
224
}
225
 
226
        /* Remove a pidname to the list of running childs */
227
void rmpid(int pid)
228
{
229
    char buf[MAX_LINELEN+1], pidbuf[32], *p;
230
    snprintf(pidbuf,sizeof(pidbuf),"%u",pid);
231
    accessfile(buf,"r",pidfname);
232
    p=wordchr(buf,pidbuf);
233
    if(p!=NULL) {
3718 reyssat 234
        ovlstrcpy(p,find_word_start(find_word_end(p)));
10 reyssat 235
        accessfile(buf,"w",pidfname);
236
    }
237
}
238
 
239
int execredirected(char *cmdf, char *inf, char *outf, char *errf,
240
                   char *args)
241
{
242
    pid_t pid;
243
    int i;
244
    struct stat st;
245
    char *cm, *p, *p2, abuf[MAX_LINELEN+1];
246
    char *arg[1024];
247
 
7076 obado 248
    for(cm=cmdf; isspace(*cm); cm++);
249
    if(*cmdf==0) return -1;
10 reyssat 250
    fflush(NULL);       /* flush all output streams before forking
251
                         * otherwise they will be doubled */
252
    pid=fork(); if(pid==-1) return -1;
253
    if(!pid) {  /* child */
254
        if(!inf) {
255
            dup2(pipe_in[0],0); close(pipe_in[1]);
256
        }
3843 kbelabas 257
        else if (freopen(inf,"r",stdin) == NULL)
258
            fprintf(stderr,"freopen failed");
10 reyssat 259
        if(!outf) {
260
            dup2(pipe_out[1],1); close(pipe_out[0]);
261
        }
3843 kbelabas 262
        else if (freopen(outf,"w",stdout) == NULL)
263
            fprintf(stderr,"freopen failed");
264
        if(errf && freopen(errf,"w",stderr) == NULL)
265
            fprintf(stderr,"freopen failed");
10 reyssat 266
        snprintf(abuf,sizeof(abuf),"%s",find_word_start(args));
267
        if(stat("../chroot/tmp/sessions/.chroot",&st)==0 || must_chroot) {
268
            arg[0]=ch_root; i=1;
269
        }
270
        else {
271
            i=0;
272
            setreuid(getuid(),getuid());setregid(getgid(),getgid());
273
        }
274
        arg[i++]=cmdf;
275
        for(p=abuf; *p && i<1000; i++, p=find_word_start(p2)) {
276
            arg[i]=p; p2=find_word_end(p); if(*p2) *p2++=0;
277
        }
278
        arg[i]=NULL;
279
        if(strchr(arg[0],'/')) execv(arg[0],arg);
280
        else execvp(arg[0],arg);
281
        fprintf(stderr,"%s not_INStalled",progname);
282
        exit(127);
283
    }
284
    else {      /* parent */
285
        addpid(pid); mxpid=pid;
286
        if(outf) {
287
            int status;
288
            close(pipe_in[1]);
289
            if(waitpid(pid,&status,0)==pid) {
290
                rmpid(pid); mxpid=-1;
291
            }
292
        }
293
    }
294
    return 0;
295
}
296
 
297
        /* verify illegal strings in parms. */
298
void find_illegal(char *p)
299
{
300
    char *pp, *pe;
301
    int i, l;
302
    for(pp=p;*pp;pp++) {
303
        if((*pp<' ' && *pp!='\n' && *pp!='      ') || *pp>=127) *pp=' ';
304
    }
305
    for(i=0;i<illpart_no;i++) {
306
        pe=illpart[i]; l=strlen(pe);
307
        for(pp=strstr(p,pe); pp; pp=strstr(pp+1,pe)) {
308
            if(!isupper(pe[0]) || !islower(*(pp+l))) {
309
                if(pp[1]!='j' && pp[1]!='J') pp[1]='J';
310
                else pp[1]='Z';
311
            }
312
        }
313
    }
314
    for(i=0;i<illegal_no;i++) {
315
        pe=illegal[i]; l=strlen(pe);
316
        for(pp=strstr(p,pe); pp; pp=strstr(pp+1,pe)) {
317
            if((pp==p || !isalnum(*(pp-1))) && !isalnum(*(pp+l))) {
318
                if(pp[1]!='j' && pp[1]!='J') pp[1]='J';
319
                else pp[1]='Z';
320
            }
321
        }
322
    }
323
}
324
 
325
        /* strip trailing zeros */
326
void strip_zeros(char *p)
327
{
328
    char *pp, *p2, *numend, *ee;
329
    int i;
330
    for(pp=p;*pp!=0;pp++) {
331
        if(!isdigit(*pp)) continue;
332
        i=0;
333
        for(numend=pp;isdigit(*numend) || *numend=='.';numend++)
334
          if(*numend=='.') i=1;
335
        if(i==0) {
336
            pp=numend-1;continue;
337
        }
338
        for(p2=numend;p2>pp && *(p2-1)=='0';p2--);
339
        for(ee=numend;isspace(*ee);ee++);
340
        if(*(pp+1)=='.' && (*ee=='E' || *ee=='e')
341
           && *(ee+1)=='-') {
342
            int k=0;
343
            char *pt=ee+2;
344
            while(isdigit(*pt)) {
345
                k*=10;k+=*pt-'0';pt++;
346
            }
347
            if(precision>8 && (k>precision*2 || (k>precision && *pp=='0'))) {
348
 
349
                sprintf(pp,"0.0%s",pt);
350
 
351
                pp+=strlen("0.0")-1;
352
                continue;
353
            }
354
        }
355
 
356
        if(*(p2-1)=='.' && p2<numend) p2++;
357
 
358
        if(p2<numend) {
3718 reyssat 359
            ovlstrcpy(p2,numend);numend=p2;
10 reyssat 360
        }
361
        pp=numend-1;
362
    }
363
}
364
 
365
char *hname[]={"", "_1","_2","_3","_4","_5","_6","_7","_8"};
366
#define hnameno (sizeof(hname)/sizeof(hname[0]))
367
 
368
void putheader(void)
369
{
370
    char hbuf[64];
371
    char *p;
372
    int i;
373
 
374
    inputptr=dynsetup(inputptr,inputend);
375
    snprintf(inputptr,inputend-inputptr,"%s",header);
376
    inputptr+=strlen(inputptr);
377
    for(i=0;i<hnameno;i++) {
378
        snprintf(hbuf,sizeof(hbuf),"w_%s_header%s",progname,hname[i]);
379
        p=getenv(hbuf); if(p!=NULL && *p!=0) {
380
            snprintf(parmbuf,parmlim,"%s",p);
381
            check_parm(parmbuf);
382
            snprintf(inputptr,inputend-inputptr,"%s\n",parmbuf);
383
            inputptr+=strlen(inputptr);
384
        }
385
    }
386
}
387
 
388
void putparm(void)
389
{
390
    snprintf(parmbuf,parmlim,"%s",parm); check_parm(parmbuf);
391
    snprintf(inputptr,inputend-inputptr,stringprinter,startstring);
392
    inputptr+=strlen(inputptr);
393
    snprintf(inputptr,inputend-inputptr,"%s",parmbuf);
394
    inputptr+=strlen(inputptr);
395
    if(inputptr<inputend && inputptr>inputbuf && inputptr[-1]!='\n')
396
      *inputptr++='\n';
397
    snprintf(inputptr,inputend-inputptr,stringprinter,endstring);
398
    inputptr+=strlen(inputptr);
399
    *inputptr=0;
400
}
401
 
402
        /* general first preparation */
403
void prepare1(void)
404
{
405
    char *p, buf[256];
406
    int i;
407
    unsigned int r[4];
408
    struct timeval t;
409
 
410
    parm=getenv("wims_exec_parm");
411
        /* nothing to do if no calling parameter */
412
    if(parm==NULL || *parm==0) exit(0);
413
    inputptr=inputbuf; inputend=inputbuf+inputlim-1;
414
    multiexec_random=getenv("multiexec_random");
415
    if(multiexec_random==NULL) multiexec_random="";
416
    if(*parm && strcmp(parm,multiexec_random)==0) {
417
        multiexec=1;
418
        getstdin(); parm=stdinbuf;
419
        if(parm[0]==0) exit(0);
420
    }
421
    if(pipe(pipe_in)<0 || pipe(pipe_out)<0) {
422
        fprintf(stderr,"%s: unable to create pipe.\n",progname);
423
        exit(1);
424
    }
425
/*    i=fcntl(pipe_in[1],F_GETFL); if(i>=0) fcntl(pipe_in[1],F_SETFL,i|O_NONBLOCK);
426
    i=fcntl(pipe_out[0],F_GETFL); if(i>=0) fcntl(pipe_out[0],F_SETFL,i|O_NONBLOCK);
427
*/    tmp_dir=getenv("tmp_dir"); if(tmp_dir==NULL || *tmp_dir==0) tmp_dir=tmpdir;
428
    setenv("TMPDIR",tmp_dir,1);
429
    mypid=getpid();
430
    gettimeofday(&t,NULL); seed=t.tv_usec*t.tv_sec+mypid;
431
    srandom(seed);
432
    for(i=0;i<4;i++) r[i]=random();
433
    snprintf(startstring,sizeof(startstring),
434
             "Start line %s %u %u %u %u",progname,r[0],r[1],r[2],r[3]);
435
    snprintf(endstring,sizeof(endstring),
436
             "End line %s %u %u %u %u",progname,r[0],r[1],r[2],r[3]);
437
    snprintf(buf,sizeof(buf),"%s_command",progname); p=getenv(buf);
438
    if(p!=NULL && *find_word_start(p)!=0) nameofcmd=find_word_start(p);
439
    snprintf(cmdbuf,sizeof(cmdbuf),"%s",nameofcmd); nameofcmd=cmdbuf;
440
    cmdparm=find_word_end(nameofcmd); if(*cmdparm) *cmdparm++=0;
441
    cmdparm=find_word_start(cmdparm);
442
    snprintf(pidfname,sizeof(pidfname),"%s/exec.pid",tmp_dir); addpid(mypid);
443
    snprintf(inputfname,sizeof(inputfname),"%s/%s_input.%d",tmp_dir,progname,mypid);
444
    snprintf(outputfname,sizeof(outputfname),"%s/%s_output.%d",tmp_dir,progname,mypid);
445
    errorf=NULL;
446
    inpf=inputfname; outpf=outputfname;
447
    isabout=0; p=find_word_start(parm); i=strlen("about");
448
    if(memcmp(p,"about",i)==0 && *find_word_start(p+i)==0) isabout=1;
449
    p=getenv("multiexec_debug"); if(p && strcmp(p,"yes")==0) debug=1;
450
}
451
 
452
void prepabout(char *cmd, char *outf, char *errf)
453
{
3843 kbelabas 454
    (void)write(pipe_in[1],cmd,strlen(cmd));
10 reyssat 455
    execredirected(nameofcmd,NULL,outf,errf,cmdparm);
456
}
457
 
458
        /* read to aboutbuf. Returns content length. */
459
int readabout(void)
460
{
461
    FILE *ff;
462
    long int l;
463
    char *p;
464
 
465
    aboutbuf[0]=0; ff=fopen(outputfname,"r");
466
    if(ff!=NULL) {
467
        fseek(ff,0,SEEK_END); l=ftell(ff); fseek(ff,0,SEEK_SET);
468
        l=fread(aboutbuf,1,aboutlen-10,ff); fclose(ff);
469
        if(l>0 && l<aboutlen) aboutbuf[l]=0; else aboutbuf[0]=0;
3718 reyssat 470
        p=find_word_start(aboutbuf); if(p>aboutbuf) ovlstrcpy(aboutbuf,p);
10 reyssat 471
    }
472
    return strlen(aboutbuf);
473
}
474
 
475
        /* read result of execution */
476
void readresult(void)
477
{
478
    FILE *ff;
479
    char *p, *pp, *pe;
480
 
481
    if(debug) {
482
        ff=fopen(outputfname,"a"); if(ff) {
483
            fputs(obuf,ff); fclose(ff);
484
        }
485
    }
486
    pe=NULL;
487
    p=strstr(obuf,startstring);
488
    if(p) {
489
        p+=strlen(startstring);
490
        pe=strstr(p,endstring);
491
        if(pe) {
492
            for(pp=pe-1; pp>=p && pp>pe-64 && *pp!='\n'; pp--);
493
            if(pp>=p && *pp=='\n') pe=pp;
494
        }
495
    }
496
    if(pe) {
497
        *pe=0;
498
        while((pe=strstr(p,startstring))!=NULL) {
499
            p=pe+strlen(startstring);
500
        }
501
        output(p);
502
    }
503
    else {
504
        if(mxpid>=0) {
505
            if(kill(mxpid,0)<0 && errno==ESRCH) {       /* this doesn't work */
506
                fprintf(stderr,"%s not_INStalled",progname);
507
            }
508
            else {
509
                fprintf(stderr,"%s: execution error or time out.\n",progname);
510
                kill(mxpid,SIGKILL);
511
            }
512
            rmpid(mxpid); mxpid=-1;
513
        }
514
        else {
515
            fprintf(stderr,"%s: aborted on earlier error.\n",progname);
516
        }
517
    }
518
    if(multiexec && *multiexec_random) printf("%s\n",multiexec_random);
519
    fflush(stdout);
520
}
521
 
522
#ifdef linebyline1
523
 
524
        /* this one is for maxima but not used */
525
void dopipes(void)
526
{
527
    long int i, l;
528
    char *outptr;
529
    char *p1, *p2, *pp, *pe;
530
    struct timeval t;
531
    fd_set rset;
532
 
533
    if(mxpid<0) {
534
        *obuf=0; return;
535
    }
536
    outptr=obuf; pp=pe=NULL;
537
    for(p1=ibuf; *p1; p1=p2) {
538
        p2=strchr(p1,'\n'); if(p2) p2++; else p2=p1+strlen(p1);
539
        write(pipe_in[1],p1,p2-p1);
540
 
541
        if(strstr(p1,startstring)!=NULL) iactive=1;
542
        reread:
543
        l=read(fifofd2,lp,MAX_LINELEN-(lp-lbuf));
544
        if(!iactive) continue;
545
        if(l<0 || l>MAX_LINELEN-(lp-lbuf)) l=0;
546
        lp+=l; *lp=0;
547
        if(active==0) {
548
            char *pp;
549
            pp=strstr(lbuf,startstring);
550
            if(pp!=NULL) {
3718 reyssat 551
                active=1; ovlstrcpy(lbuf,pp); lp=lbuf+strlen(lbuf);
10 reyssat 552
            }
553
        }
554
        if(active!=0 && strstr(lbuf,linebyline)!=NULL) {
555
            fprintf(ff,"%s",lbuf); lp=lbuf;
556
            if(strstr(lbuf,endstring)!=NULL) {lbuf[0]=0; active=-1; break;}
557
            lbuf[0]=0; continue;
558
        }
559
        /* time out allowance between each silence */
560
        t.tv_sec=3; t.tv_usec=400000;
561
        i=select(fifofd2+1,&rset,NULL,NULL,&t);
562
        if(i>0) goto reread;
563
        else break; /* time out or error */
564
    }
565
}
566
 
567
#else
568
 
569
void dopipes(void)
570
{
571
    long int i, k, l;
572
    int interval=20000; /* in microseconds */
573
    int timeout =300;   /* in intervals */
574
    char *outptr;
575
    char *p1, *p2, *inp, *pw;
576
    struct timeval t;
577
    fd_set rset, wset;
578
 
579
    *obuf=0; if(mxpid<0) return;
580
    outptr=obuf; inp=inputbuf; k=0;
581
    while(inp<inputptr) {
582
        t.tv_sec=0; t.tv_usec=interval;
583
        FD_ZERO(&rset); FD_SET(pipe_out[0],&rset);
584
        FD_ZERO(&wset); FD_SET(pipe_in[1],&wset);
585
        i=pipe_out[0]; if(i<pipe_in[1]) i=pipe_in[1];
586
        i=select(i+1,&rset,&wset,NULL,&t);
587
        if(i<=0) {
588
            k++; if(k>=timeout) return; /* time out */
589
        }
590
        if(FD_ISSET(pipe_in[1],&wset)) {
591
                /* Writing must be line by line, for otherwise
592
                 * it will block when the input is large. */
593
            for(pw=inp; pw<inputptr && *pw!='\n'; pw++);
594
            if(pw<inputptr) pw++;
595
            l=write(pipe_in[1],inp,pw-inp);
596
            if(l<0 || l>inputptr-inp) return;
597
            inp+=l;
598
        }
599
        if(FD_ISSET(pipe_out[0],&rset)) {
600
            l=read(pipe_out[0],outptr,fsizelim-(outptr-obuf)-1);
601
            if(l<=0 || l>fsizelim-(outptr-obuf)-1) {
602
                *outptr=0; break;
603
            }
604
            outptr+=l; *outptr=0;
605
        }
606
    }
607
    p2=NULL;
608
    p1=strstr(obuf,startstring);
609
    if(p1) {
610
        p1+=strlen(startstring);
611
        p2=strstr(p1,endstring);
612
    }
613
    while(!p2) {
614
        t.tv_sec=0; t.tv_usec=interval;
615
        FD_ZERO(&rset); FD_SET(pipe_out[0],&rset);
616
        i=select(pipe_out[0]+1,&rset,NULL,NULL,&t);
617
        if(i>0) {
618
            l=read(pipe_out[0],outptr,fsizelim-(outptr-obuf)-1);
619
            if(l<=0 || l>fsizelim-(outptr-obuf)-1) {
620
                *outptr=0; break;
621
            }
622
            outptr+=l; *outptr=0;
623
        }
624
        else {
625
            k++; if(k>=timeout) break;
626
        }
627
        if(!p1) {
628
            p1=strstr(obuf,startstring);
629
            if(p1) p1+=strlen(startstring);
630
        }
631
        if(p1) p2=strstr(p1,endstring);
632
    }
633
}
634
 
635
#endif
636
 
637
void run(void)
638
{
639
    FILE *ff;
640
 
641
    if(isabout) {about(); goto end;}
642
    execredirected(nameofcmd,NULL,NULL,NULL,cmdparm);
643
    putheader();
644
    obuf=xmalloc(fsizelim); if(!obuf) return;
645
    rep:
646
    putparm();
647
    if(!multiexec) {
648
        snprintf(inputptr,inputend-inputptr,"%s",quitstring);
649
        inputptr+=strlen(inputptr);
650
    }
651
    if(debug) {
652
        ff=fopen(inputfname,"a"); if(ff) {
653
            fputs(inputbuf,ff); fclose(ff);
654
        }
655
    }
656
    dopipes();
657
    readresult();
658
    if(multiexec) {
659
        getstdin(); inputptr=inputbuf; inputbuf[0]=0;
660
        goto rep;
661
    }
662
    end: if(strstr(tmp_dir,"tmp/sessions/")==NULL) {
663
        unlink(inputfname); unlink(outputfname);
664
    }
665
    free(obuf); rmpid(mypid);
666
    if(mxpid>0) {kill(mxpid,SIGKILL); rmpid(mxpid);}
667
}
668