Subversion Repositories wimsdev

Rev

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