Subversion Repositories wimsdev

Rev

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