Rev 7079 | Rev 8082 | 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 | |||
7674 | bpr | 138 | /* searches a list. Returns index if found, -1 if nomatch. |
139 | * Uses binary search, list must be sorted. */ |
||
10 | reyssat | 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; |
||
7674 | bpr | 145 | |
10 | reyssat | 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; |
||
7674 | bpr | 151 | p=list+(items-1)*item_size; |
10 | reyssat | 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;) { |
||
7674 | bpr | 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;} |
||
10 | reyssat | 161 | } |
162 | return -1; |
||
163 | } |
||
164 | |||
7674 | bpr | 165 | /* Read/write to a file with variable parms to print filename */ |
10 | reyssat | 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) { |
||
7674 | bpr | 177 | if(*type=='r') content[0]=0; return; |
10 | reyssat | 178 | } |
179 | switch(*type) { |
||
7674 | bpr | 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 | } |
||
10 | reyssat | 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 { |
||
7674 | bpr | 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;} |
||
10 | reyssat | 208 | } |
209 | while(k>0); |
||
210 | } |
||
211 | |||
7674 | bpr | 212 | /* add a pid to the list of running childs */ |
10 | reyssat | 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) { |
||
7674 | bpr | 221 | snprintf(buf+l,sizeof(buf)-l," %s",pidbuf); |
222 | accessfile(buf,"w",pidfname); |
||
10 | reyssat | 223 | } |
224 | } |
||
225 | |||
7674 | bpr | 226 | /* Remove a pidname to the list of running childs */ |
10 | reyssat | 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) { |
||
7674 | bpr | 234 | ovlstrcpy(p,find_word_start(find_word_end(p))); |
235 | accessfile(buf,"w",pidfname); |
||
10 | reyssat | 236 | } |
237 | } |
||
238 | |||
7674 | bpr | 239 | int execredirected(char *cmdf, char *inf, char *outf, char *errf, char *args) |
10 | reyssat | 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 | |||
7079 | bpr | 247 | for(cm=cmdf; isspace(*cm); cm++){}; |
7076 | obado | 248 | if(*cmdf==0) return -1; |
7674 | bpr | 249 | fflush(NULL); |
250 | /* flush all output streams before forking |
||
251 | * otherwise they will be doubled */ |
||
10 | reyssat | 252 | pid=fork(); if(pid==-1) return -1; |
7674 | bpr | 253 | if(!pid) { /* child */ |
254 | if(!inf) { |
||
255 | dup2(pipe_in[0],0); close(pipe_in[1]); |
||
256 | } |
||
257 | else if (freopen(inf,"r",stdin) == NULL) |
||
3843 | kbelabas | 258 | fprintf(stderr,"freopen failed"); |
7674 | bpr | 259 | if(!outf) { |
260 | dup2(pipe_out[1],1); close(pipe_out[0]); |
||
261 | } |
||
262 | else if (freopen(outf,"w",stdout) == NULL) |
||
3843 | kbelabas | 263 | fprintf(stderr,"freopen failed"); |
7674 | bpr | 264 | if(errf && freopen(errf,"w",stderr) == NULL) |
3843 | kbelabas | 265 | fprintf(stderr,"freopen failed"); |
7674 | bpr | 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); |
||
10 | reyssat | 283 | } |
7674 | bpr | 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 | } |
||
10 | reyssat | 293 | } |
294 | return 0; |
||
295 | } |
||
296 | |||
7674 | bpr | 297 | /* verify illegal strings in parms. */ |
10 | reyssat | 298 | void find_illegal(char *p) |
299 | { |
||
300 | char *pp, *pe; |
||
301 | int i, l; |
||
302 | for(pp=p;*pp;pp++) { |
||
7674 | bpr | 303 | if((*pp<' ' && *pp!='\n' && *pp!=' ') || *pp>=127) *pp=' '; |
10 | reyssat | 304 | } |
305 | for(i=0;i<illpart_no;i++) { |
||
7674 | bpr | 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 | } |
||
10 | reyssat | 313 | } |
314 | for(i=0;i<illegal_no;i++) { |
||
7674 | bpr | 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 | } |
||
10 | reyssat | 322 | } |
323 | } |
||
324 | |||
7674 | bpr | 325 | /* strip trailing zeros */ |
10 | reyssat | 326 | void strip_zeros(char *p) |
327 | { |
||
328 | char *pp, *p2, *numend, *ee; |
||
329 | int i; |
||
330 | for(pp=p;*pp!=0;pp++) { |
||
7674 | bpr | 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) { |
||
359 | ovlstrcpy(p2,numend);numend=p2; |
||
360 | } |
||
361 | pp=numend-1; |
||
10 | reyssat | 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; |
||
7674 | bpr | 373 | |
10 | reyssat | 374 | inputptr=dynsetup(inputptr,inputend); |
375 | snprintf(inputptr,inputend-inputptr,"%s",header); |
||
376 | inputptr+=strlen(inputptr); |
||
377 | for(i=0;i<hnameno;i++) { |
||
7674 | bpr | 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 | } |
||
10 | reyssat | 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 | |||
7674 | bpr | 402 | /* general first preparation */ |
10 | reyssat | 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"); |
||
7674 | bpr | 411 | /* nothing to do if no calling parameter */ |
10 | reyssat | 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) { |
||
7674 | bpr | 417 | multiexec=1; |
418 | getstdin(); parm=stdinbuf; |
||
419 | if(parm[0]==0) exit(0); |
||
10 | reyssat | 420 | } |
421 | if(pipe(pipe_in)<0 || pipe(pipe_out)<0) { |
||
7674 | bpr | 422 | fprintf(stderr,"%s: unable to create pipe.\n",progname); |
423 | exit(1); |
||
10 | reyssat | 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), |
||
7674 | bpr | 434 | "Start line %s %u %u %u %u",progname,r[0],r[1],r[2],r[3]); |
10 | reyssat | 435 | snprintf(endstring,sizeof(endstring), |
7674 | bpr | 436 | "End line %s %u %u %u %u",progname,r[0],r[1],r[2],r[3]); |
10 | reyssat | 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 | |||
7674 | bpr | 458 | /* read to aboutbuf. Returns content length. */ |
10 | reyssat | 459 | int readabout(void) |
460 | { |
||
461 | FILE *ff; |
||
462 | long int l; |
||
463 | char *p; |
||
7674 | bpr | 464 | |
10 | reyssat | 465 | aboutbuf[0]=0; ff=fopen(outputfname,"r"); |
466 | if(ff!=NULL) { |
||
7674 | bpr | 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; |
||
470 | p=find_word_start(aboutbuf); if(p>aboutbuf) ovlstrcpy(aboutbuf,p); |
||
10 | reyssat | 471 | } |
472 | return strlen(aboutbuf); |
||
473 | } |
||
474 | |||
7674 | bpr | 475 | /* read result of execution */ |
10 | reyssat | 476 | void readresult(void) |
477 | { |
||
478 | FILE *ff; |
||
479 | char *p, *pp, *pe; |
||
480 | |||
481 | if(debug) { |
||
7674 | bpr | 482 | ff=fopen(outputfname,"a"); if(ff) { |
483 | fputs(obuf,ff); fclose(ff); |
||
484 | } |
||
10 | reyssat | 485 | } |
486 | pe=NULL; |
||
487 | p=strstr(obuf,startstring); |
||
488 | if(p) { |
||
7674 | bpr | 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 | } |
||
10 | reyssat | 495 | } |
496 | if(pe) { |
||
7674 | bpr | 497 | *pe=0; |
498 | while((pe=strstr(p,startstring))!=NULL) { |
||
499 | p=pe+strlen(startstring); |
||
500 | } |
||
501 | output(p); |
||
10 | reyssat | 502 | } |
503 | else { |
||
7674 | bpr | 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 | } |
||
10 | reyssat | 517 | } |
518 | if(multiexec && *multiexec_random) printf("%s\n",multiexec_random); |
||
519 | fflush(stdout); |
||
520 | } |
||
521 | |||
522 | #ifdef linebyline1 |
||
523 | |||
7674 | bpr | 524 | /* this one is for maxima but not used */ |
10 | reyssat | 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) { |
||
7674 | bpr | 534 | *obuf=0; return; |
10 | reyssat | 535 | } |
536 | outptr=obuf; pp=pe=NULL; |
||
537 | for(p1=ibuf; *p1; p1=p2) { |
||
7674 | bpr | 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) { |
||
551 | active=1; ovlstrcpy(lbuf,pp); lp=lbuf+strlen(lbuf); |
||
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 */ |
||
10 | reyssat | 564 | } |
565 | } |
||
566 | |||
567 | #else |
||
568 | |||
569 | void dopipes(void) |
||
570 | { |
||
571 | long int i, k, l; |
||
7674 | bpr | 572 | int interval=20000; /* in microseconds */ |
573 | int timeout =300; /* in intervals */ |
||
10 | reyssat | 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; |
||
7674 | bpr | 580 | outptr=obuf; inp=inputbuf; k=0; |
10 | reyssat | 581 | while(inp<inputptr) { |
7674 | bpr | 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 | } |
||
10 | reyssat | 606 | } |
607 | p2=NULL; |
||
608 | p1=strstr(obuf,startstring); |
||
609 | if(p1) { |
||
7674 | bpr | 610 | p1+=strlen(startstring); |
611 | p2=strstr(p1,endstring); |
||
10 | reyssat | 612 | } |
613 | while(!p2) { |
||
7674 | bpr | 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); |
||
10 | reyssat | 632 | } |
633 | } |
||
634 | |||
635 | #endif |
||
636 | |||
637 | void run(void) |
||
638 | { |
||
639 | FILE *ff; |
||
7674 | bpr | 640 | |
10 | reyssat | 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) { |
||
7674 | bpr | 648 | snprintf(inputptr,inputend-inputptr,"%s",quitstring); |
649 | inputptr+=strlen(inputptr); |
||
10 | reyssat | 650 | } |
651 | if(debug) { |
||
7674 | bpr | 652 | ff=fopen(inputfname,"a"); if(ff) { |
653 | fputs(inputbuf,ff); fclose(ff); |
||
654 | } |
||
10 | reyssat | 655 | } |
656 | dopipes(); |
||
657 | readresult(); |
||
658 | if(multiexec) { |
||
7674 | bpr | 659 | getstdin(); inputptr=inputbuf; inputbuf[0]=0; |
660 | goto rep; |
||
10 | reyssat | 661 | } |
662 | end: if(strstr(tmp_dir,"tmp/sessions/")==NULL) { |
||
7674 | bpr | 663 | unlink(inputfname); unlink(outputfname); |
10 | reyssat | 664 | } |
665 | free(obuf); rmpid(mypid); |
||
666 | if(mxpid>0) {kill(mxpid,SIGKILL); rmpid(mxpid);} |
||
667 | } |
||
668 |