Subversion Repositories wimsdev

Rev

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