Rev 256 | 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 | /* this is part of wims server source. |
||
19 | * This file does execution commands. */ |
||
20 | |||
21 | static void _skip_contents(int isif); |
||
22 | |||
23 | /* common routine for the two if's. */ |
||
24 | static void _exec_if_while(char *p, int numerical, int isif) |
||
25 | { |
||
26 | if(compare(p,numerical,0)==0) _skip_contents(isif); /* skip if false */ |
||
27 | else if(!isif) m_file.for_idx++; |
||
28 | return; |
||
29 | } |
||
30 | |||
31 | /* 'if' non-numerical (unless comparisons are < or >, etc.) */ |
||
32 | void exec_if(char *p) |
||
33 | { |
||
34 | _exec_if_while(p,0,1); |
||
35 | } |
||
36 | |||
37 | /* 'if' numerical. */ |
||
38 | void exec_ifval(char *p) |
||
39 | { |
||
40 | _exec_if_while(p,1,1); |
||
41 | } |
||
42 | |||
43 | void _exec_while(char *p, int numerical) |
||
44 | { |
||
45 | FOR_STACK *stk; |
||
46 | if(m_file.for_idx>=MAX_FOR_LEVEL) module_error("too_many_fors"); |
||
47 | stk=&(m_file.for_stack[m_file.for_idx]); |
||
48 | stk->lineno=m_file.l; |
||
49 | memmove(stk->varname,"?",2); |
||
50 | _exec_if_while(p,numerical,0); |
||
51 | } |
||
52 | |||
53 | /* 'while' non-numerical (unless comparisons are < or >, etc.) */ |
||
54 | void exec_while(char *p) |
||
55 | { |
||
56 | _exec_while(p,0); |
||
57 | } |
||
58 | |||
59 | /* 'while' numerical. */ |
||
60 | void exec_whileval(char *p) |
||
61 | { |
||
62 | _exec_while(p,1); |
||
63 | } |
||
64 | |||
65 | void exec_endwhile(char *p) |
||
66 | { |
||
67 | FOR_STACK *stk; |
||
68 | if(m_file.for_idx<=0) module_error("next_without_for"); |
||
69 | stk=&(m_file.for_stack[m_file.for_idx-1]); |
||
70 | if(stk->varname[0]!='?') module_error("next_without_for"); |
||
71 | m_file.for_idx--; *p=0; |
||
72 | m_file.linepointer=stk->lineno; |
||
73 | executed_gotos++; |
||
74 | if(executed_gotos>=GOTO_LIMIT) module_error("too_many_gotos"); |
||
75 | } |
||
76 | |||
77 | /* Should provide a method to stop infinite loop. */ |
||
78 | void exec_goto(char *p) |
||
79 | { |
||
80 | char lbuf[MAX_NAMELEN+17]; |
||
81 | char *label_start, *line_start; |
||
82 | int old_line; |
||
83 | int i; |
||
84 | executed_gotos++; |
||
85 | if(executed_gotos>=GOTO_LIMIT) module_error("too_many_gotos"); |
||
86 | old_line=m_file.l; |
||
87 | label_start=find_word_start(p); |
||
88 | *find_word_end(label_start)=0; |
||
89 | m_file.l=m_file.linepointer=0; |
||
90 | for(i=0;i<m_file.linecnt;i++) { |
||
91 | if(((m_file.lines[i].isstart)&4)==0) continue; |
||
92 | line_start=find_word_start((m_file.lines[i]).address); |
||
93 | if(line_start>(m_file.lines[i+1]).address && i<m_file.linecnt) |
||
94 | continue; |
||
95 | m_file.linepointer=i; |
||
96 | wgetline(lbuf,MAX_NAMELEN+8,&m_file); |
||
97 | line_start=find_word_start(lbuf); |
||
98 | if(*line_start!=label_prefix_char) continue; |
||
99 | line_start++;*find_word_end(line_start)=0; |
||
100 | if(line_start[0]!='*' && strcmp(line_start,label_start)!=0) continue; |
||
101 | *p=0; i++; return; |
||
102 | } |
||
103 | m_file.l=old_line; |
||
104 | setvar(error_data_string,label_start); module_error("label_not_found"); |
||
105 | /* m_file.linepointer=m_file.linecnt; *p=0; |
||
106 | return; |
||
107 | */} |
||
108 | |||
109 | /* 'else' with or without 'if'. |
||
110 | * Philosophy: we implement a loosely checked grammar. |
||
111 | * We cannot check 'if' grammar if we want to use 'goto' |
||
112 | * together with 'if'. */ |
||
113 | void exec_else(char *p) |
||
114 | { |
||
115 | _skip_contents(1); return; |
||
116 | } |
||
117 | |||
118 | /* 'endif': nothing needs to be done here. */ |
||
119 | void exec_endif(char *p) |
||
120 | { |
||
121 | return; |
||
122 | } |
||
123 | |||
124 | /* find out the end of a for loop */ |
||
125 | void goto_for_end(void) |
||
126 | { |
||
127 | int inner; |
||
128 | char buf[16]; |
||
129 | inner=0; |
||
130 | while(m_file.linepointer<m_file.linecnt) { |
||
131 | if((m_file.lines[m_file.linepointer].isstart&2)==0) { |
||
132 | m_file.linepointer++; continue; |
||
133 | } |
||
134 | if(wgetline(buf,8,&m_file)==EOF) break; |
||
135 | *find_word_end(buf)=0; |
||
136 | if(strcmp(buf,"!for")==0) { |
||
137 | inner++; continue; |
||
138 | } |
||
139 | if(strcmp(buf,"!next")==0) { |
||
140 | if(inner>0) { |
||
141 | inner--; continue; |
||
142 | } |
||
143 | else break; |
||
144 | } |
||
145 | } |
||
146 | } |
||
147 | |||
148 | /* for */ |
||
149 | void exec_for(char *p) |
||
150 | { |
||
151 | char *p1, *p2, *p3; |
||
152 | double v1, v2, step; |
||
153 | char buf[MAX_LINELEN+1]; |
||
154 | FOR_STACK *stk; |
||
155 | |||
156 | if(m_file.for_idx>=MAX_FOR_LEVEL) module_error("too_many_fors"); |
||
157 | stk=&(m_file.for_stack[m_file.for_idx]); |
||
158 | stk->lineno=m_file.l; |
||
159 | p1=find_word_start(p); |
||
160 | for(p2=p1; !isspace(*p2) && *p2!=0 && *p2!='=' ; p2++); |
||
161 | if(*p2==0) syntax: module_error("for_syntax"); |
||
162 | if(p2-p1>MAX_NAMELEN) module_error("name_too_long"); |
||
163 | memmove(stk->varname,p1,p2-p1); |
||
164 | stk->varname[p2-p1]=0; |
||
165 | p1=find_word_start(p2); if(*p1==0) goto syntax; |
||
166 | if(*p1=='=') { |
||
167 | p1++; |
||
168 | assign: |
||
169 | stk->from=0; |
||
170 | p2=wordchr(p1,"to"); |
||
171 | if(p2==NULL) p2=strstr(p1,".."); |
||
172 | if(p2==NULL) goto syntax; |
||
173 | *p2=0; p2+=2; |
||
174 | p3=wordchr(p2,"step"); |
||
175 | if(p3!=NULL) { |
||
176 | *p3=0; p3+=strlen("step"); |
||
177 | step=evalue(p3); |
||
178 | if(step==0) module_error("zero_step"); |
||
179 | } |
||
180 | else step=1; |
||
181 | v1=evalue(p1); v2=evalue(p2); |
||
182 | float2str(v1,buf); setvar(stk->varname, buf); |
||
183 | if((step>0 && v1>v2) || (step<0 && v1<v2) ) { /* condition not met */ |
||
184 | loop_out: |
||
185 | goto_for_end(); |
||
186 | } |
||
187 | else { |
||
188 | stk->varval=v1; stk->varend=v2; stk->step=step; |
||
189 | stk->lineno=m_file.linepointer; |
||
190 | m_file.for_idx++; |
||
191 | } |
||
192 | *p=0; return; |
||
193 | } |
||
194 | if(memcmp(p1,"from",strlen("from"))==0 && isspace(*(p1+strlen("from")))) { |
||
195 | p1+=strlen("from"); goto assign; |
||
196 | } |
||
197 | if(memcmp(p1,"in",strlen("in"))==0 && isspace(*(p1+strlen("in")))) { |
||
198 | stk->from=1; p1+=strlen("in"); |
||
199 | p1=find_word_start(p1); if(*p1==0) goto loop_out; |
||
200 | p2=xmalloc(MAX_LINELEN+1); |
||
201 | mystrncpy(p2,p1,MAX_LINELEN); |
||
202 | substit(p2); |
||
203 | strip_trailing_spaces(p2); |
||
204 | if(*p2==0) goto loop_out; |
||
205 | p1=strparchr(p2,','); stk->bufpt=p2; |
||
206 | if(p1!=NULL) { |
||
207 | *p1=0; stk->list_pt=find_word_start(p1+1); |
||
208 | } |
||
209 | else stk->list_pt=NULL; |
||
210 | strip_trailing_spaces(p2); setvar(stk->varname,p2); |
||
211 | stk->lineno=m_file.linepointer; |
||
212 | m_file.for_idx++; *p=0; return; |
||
213 | } |
||
214 | goto syntax; |
||
215 | } |
||
216 | |||
217 | /* break a for loop */ |
||
218 | void exec_break(char *p) |
||
219 | { |
||
220 | FOR_STACK *stk; |
||
221 | if(m_file.for_idx>0) { |
||
222 | stk=&(m_file.for_stack[m_file.for_idx-1]); |
||
223 | if(stk->varname[0]=='?') _skip_contents(0); |
||
224 | else goto_for_end(); |
||
225 | m_file.for_idx--; |
||
226 | } |
||
227 | *p=0; return; |
||
228 | } |
||
229 | |||
230 | /* next */ |
||
231 | void exec_next(char *p) |
||
232 | { |
||
233 | double v1, v2, step; |
||
234 | char *p1, *p2; |
||
235 | char buf[MAX_LINELEN+1]; |
||
236 | FOR_STACK *stk; |
||
237 | if(m_file.for_idx<=0) module_error("next_without_for"); |
||
238 | stk=&(m_file.for_stack[m_file.for_idx-1]); |
||
239 | if(stk->varname[0]=='?') module_error("next_without_for"); |
||
240 | if(stk->from) { /* list style */ |
||
241 | if(stk->list_pt==NULL) { |
||
242 | free(stk->bufpt); |
||
243 | m_file.for_idx--; |
||
244 | *p=0; return; |
||
245 | } |
||
246 | p1=strchr(stk->list_pt,','); |
||
247 | if(p1!=NULL) { |
||
248 | *p1=0; p2=find_word_start(p1+1); |
||
249 | } |
||
250 | else p2=NULL; |
||
251 | strip_trailing_spaces(stk->list_pt); |
||
252 | setvar(stk->varname,stk->list_pt); |
||
253 | stk->list_pt=p2; goto loop_back; |
||
254 | } |
||
255 | v1=stk->varval; v2=stk->varend; step=stk->step; |
||
256 | v1+=step; stk->varval=v1; |
||
257 | float2str(v1,buf); |
||
258 | setvar(stk->varname, buf); |
||
259 | if((step>0 && v1<=v2) || (step<0 && v1>=v2)) { /* loop */ |
||
260 | loop_back: |
||
261 | m_file.linepointer=stk->lineno; |
||
262 | executed_gotos++; |
||
263 | if(executed_gotos>=GOTO_LIMIT) module_error("too_many_gotos"); |
||
264 | } |
||
265 | else m_file.for_idx--; |
||
266 | *p=0; return; |
||
267 | } |
||
268 | |||
269 | /* Execution of a file in the module directory, |
||
270 | * only for trusted modules. */ |
||
271 | void exec_mexec(char *p) |
||
272 | { |
||
273 | direct_exec=1; |
||
274 | calc_mexec(p); |
||
275 | direct_exec=0; |
||
276 | } |
||
277 | |||
278 | /* call shell. */ |
||
279 | void _exec_ex(char *p, char *arg0, char *arg1, int n) |
||
280 | { |
||
281 | char *abuf[8]; |
||
282 | char errorfname[MAX_FNAME+1]; |
||
283 | |||
284 | if(robot_access) { |
||
285 | *p=0; return; |
||
286 | } |
||
287 | if(!noout || !trusted_module() || is_class_module) { |
||
288 | _calc_exec(p,arg0,arg1,n); if(outputing) output0(p); |
||
289 | return; |
||
290 | } |
||
291 | mkfname(errorfname,"%s/exec.err",tmp_dir); |
||
292 | abuf[0]=arg0; abuf[1]=arg1; abuf[n]=p; abuf[n+1]=NULL; |
||
293 | wrapexec=1; exportall(); |
||
294 | execredirected(abuf[0],NULL,NULL,errorfname,abuf); |
||
295 | } |
||
296 | |||
297 | /* call shell. */ |
||
298 | void exec_sh(char *p) |
||
299 | { |
||
300 | _exec_ex(p,"sh","-c",2); |
||
301 | } |
||
302 | |||
303 | /* call perl. */ |
||
304 | void exec_perl(char *p) |
||
305 | { |
||
306 | _exec_ex(p,"perl","-e",2); |
||
307 | } |
||
308 | |||
309 | /* file should not be cached */ |
||
310 | void exec_nocache(char *p) |
||
311 | { m_file.nocache|=1; *p=0; } |
||
312 | |||
313 | /* Read another file. */ |
||
314 | void exec_read(char *p) |
||
315 | { |
||
316 | WORKING_FILE save; |
||
317 | char parmsave[MAX_LINELEN+1]; |
||
318 | char *pp,*ps; |
||
319 | int t,cache; |
||
320 | |||
321 | strip_trailing_spaces(p);p=find_word_start(p); |
||
322 | if(*p==0) return; |
||
323 | pp=find_word_end(p); if(*pp) *pp++=0; |
||
324 | pp=find_word_start(pp); |
||
325 | ps=getvar("wims_read_parm"); if(ps==NULL) ps=""; |
||
326 | mystrncpy(parmsave,ps,sizeof(parmsave)); |
||
327 | setvar("wims_read_parm",pp); |
||
328 | memmove(&save,&m_file,sizeof(WORKING_FILE)); |
||
329 | cache=1; if(p[0]=='.' && p[1]=='/') {p+=2; cache=0;} |
||
330 | t=untrust; |
||
331 | if(strncmp(p,"wimshome/",9)==0) { |
||
332 | if((untrust&255)!=0 && |
||
333 | (m_file.name[0]=='/' || strncmp(m_file.name,"wimshome/",9)==0)) |
||
334 | module_error("Illegal_file_access"); |
||
335 | untrust|=0x200; |
||
336 | } |
||
337 | if((untrust&0x202)!=0) { |
||
338 | pp=getvar("wims_trustfile"); |
||
339 | if(pp!=NULL && *pp!=0 && wordchr(pp,p)!=NULL) |
||
340 | untrust&=0xfdfd; |
||
341 | } |
||
342 | readnest++; if(readnest>MAX_READNEST) module_error("too_many_nested_read"); |
||
343 | if(outputing) phtml_put(p,cache); else var_proc(p,cache); |
||
344 | readnest--; untrust=t; |
||
345 | memmove(&m_file,&save,sizeof(WORKING_FILE)); |
||
346 | setvar("wims_read_parm",parmsave); |
||
347 | } |
||
348 | |||
349 | /* read a variable processing file */ |
||
350 | void exec_readproc(char *p) |
||
351 | { |
||
352 | int o=outputing; outputing=0; exec_read(p); outputing=o; |
||
353 | } |
||
354 | |||
355 | void exec_defread(char *p) |
||
356 | { |
||
357 | int t,o; |
||
358 | secure_exec(); |
||
359 | t=untrust; untrust|=0x400; |
||
360 | o=outputing; outputing=0; |
||
361 | exec_read(p); untrust=t; outputing=o; |
||
362 | } |
||
363 | |||
364 | /* Change to another file (no return) */ |
||
365 | void exec_changeto(char *p) |
||
366 | { |
||
367 | m_file.linepointer=m_file.linecnt; |
||
368 | exec_read(p); |
||
369 | } |
||
370 | |||
371 | int header_executed=0, tail_executed=0; |
||
372 | |||
373 | /* internal routine: get other language versions */ |
||
374 | void other_langs(void) |
||
375 | { |
||
376 | int i,j,k; |
||
377 | char *p, lbuf[4], pbuf[MAX_FNAME+1], *phtml; |
||
378 | char namebuf[MAX_FNAME+1], listbuf[4*MAX_LANGUAGES]; |
||
379 | static int otherlangs_got=0; |
||
380 | |||
381 | if(otherlangs_got) return; |
||
382 | mystrncpy(namebuf,module_prefix,sizeof(namebuf)); |
||
383 | listbuf[0]=0;j=strlen(namebuf)-3; p=listbuf; |
||
384 | if(j>=2 && strcmp("light",namebuf+j-2)==0) { |
||
385 | setvar("wims_light_module","yes"); |
||
386 | phtml=getvar("phtml"); |
||
387 | if(phtml==NULL || *phtml==0) return; |
||
388 | mystrncpy(pbuf,phtml,sizeof(pbuf)); |
||
389 | j=strlen(pbuf)-3; |
||
390 | if(pbuf[j]!='.') return; |
||
391 | j++; strcpy(lbuf,pbuf+j); pbuf[j]=0; |
||
392 | j=strlen(namebuf); |
||
393 | snprintf(namebuf+j,MAX_FNAME-j-10,"/pages/%s",pbuf); |
||
394 | j=strlen(namebuf); |
||
395 | for(i=k=0;i<available_lang_no;i++) { |
||
396 | if(strcmp(lbuf,available_lang[i])==0) continue; |
||
397 | mystrncpy(namebuf+j,available_lang[i],MAX_FNAME-j); |
||
398 | if(ftest(namebuf)<0) continue; |
||
399 | if(k>0) *p++=','; |
||
400 | mystrncpy(p,available_lang[i],sizeof(listbuf)-4-(p-listbuf)); |
||
401 | p+=strlen(p); |
||
402 | k++; |
||
403 | } |
||
404 | goto end; |
||
405 | } |
||
406 | if(j>0 && namebuf[j]=='.') { |
||
407 | setvar("wims_light_module",""); |
||
408 | j++; strcpy(lbuf,namebuf+j); namebuf[j]=0; |
||
409 | for(i=k=0;i<available_lang_no;i++) { |
||
410 | if(strcmp(lbuf,available_lang[i])==0) continue; |
||
411 | snprintf(namebuf+j,MAX_FNAME-j,"%s/main.phtml", |
||
412 | available_lang[i]); |
||
413 | if(ftest(namebuf)<0) continue; |
||
414 | if(k>0) *p++=','; |
||
415 | mystrncpy(p,available_lang[i],sizeof(listbuf)-4-(p-listbuf)); |
||
416 | p+=strlen(p); |
||
417 | k++; |
||
418 | } |
||
419 | } |
||
420 | end: setvar("wims_otherlangs",listbuf); otherlangs_got=1; |
||
421 | } |
||
422 | |||
423 | /* Standardised reference to wims home */ |
||
424 | void exec_homeref(char *p) |
||
425 | { |
||
426 | char *ref, *user; |
||
427 | |||
428 | if(ismhelp || tail_executed) return; |
||
429 | setvar("wims_homeref_parm",p); *p=0; |
||
430 | user=getvar("wims_user"); |
||
431 | if(user==NULL) user=""; |
||
432 | if(*user==0 || robot_access) ref=home_referer; |
||
433 | else { |
||
434 | if(strcmp(user,"supervisor")==0) ref=home_referer_supervisor; |
||
435 | else ref=home_referer_user; |
||
436 | } |
||
437 | if(user[0]==0 && !robot_access) other_langs(); |
||
438 | phtml_put_base(ref,0); tail_executed=1; |
||
439 | } |
||
440 | |||
441 | /* Standardised header menu */ |
||
442 | void exec_headmenu(char *p) |
||
443 | { |
||
444 | char *ref, *user; |
||
445 | |||
446 | if(header_executed) return; |
||
447 | setvar("wims_headmenu_parm",p); *p=0; |
||
448 | user=getvar("wims_user"); |
||
449 | if(user==NULL) user=""; |
||
450 | if(*user==0 || robot_access) ref=header_menu; |
||
451 | else { |
||
452 | if(strcmp(user,"supervisor")==0) ref=header_menu_supervisor; |
||
453 | else ref=header_menu_user; |
||
454 | } |
||
455 | if(user[0]==0 && !robot_access) other_langs(); |
||
456 | phtml_put_base(ref,0); header_executed=1; |
||
457 | } |
||
458 | |||
459 | /* uniformized title */ |
||
460 | void exec_title(char *p) |
||
461 | { |
||
462 | char *s; |
||
463 | *p=0; |
||
464 | if(!outputing) return; |
||
465 | s=getvar("wims_title_title"); |
||
466 | if(s==NULL || *s==0) { |
||
467 | s=getvar("module_title"); |
||
468 | if(s==NULL || *s==0) return; |
||
469 | force_setvar("wims_title_title",s); |
||
470 | } |
||
471 | phtml_put_base(title_page,0); |
||
472 | } |
||
473 | |||
474 | /* standardized html tail */ |
||
475 | void exec_tail(char *p) |
||
476 | { |
||
477 | if(!outputing || tail_executed) { |
||
478 | *p=0; return; |
||
479 | } |
||
480 | if(!ismhelp) exec_homeref(p); *p=0; |
||
481 | _output_("</body></html>"); |
||
482 | tail_executed=1; |
||
483 | } |
||
484 | |||
485 | void determine_font(char *l); |
||
486 | |||
487 | /* standardized header */ |
||
488 | void exec_header(char *p) |
||
489 | { |
||
490 | char *s1, *s2, hbuf[MAX_LINELEN+1], *ws="", *ws2="", *bo, *ol; |
||
491 | char wsbuf[MAX_LINELEN+1],wsbuf2[MAX_LINELEN+1]; |
||
492 | setvar("wims_header_parm",p); *p=0; |
||
493 | if(!outputing || header_executed) return; |
||
494 | s1=getvar("wims_window"); |
||
495 | if(mode==mode_popup) { |
||
496 | if(s1!=NULL && *s1!=0) { |
||
497 | char *p1, *p2; |
||
498 | int t1,t2/*,t3,t4*/; |
||
499 | p1=find_word_start(s1); |
||
500 | for(p2=p1; myisdigit(*p2); p2++); |
||
501 | *p2=0; t1=atoi(p1); p1=p2+1; |
||
502 | while(!myisdigit(*p1) && *p1) p1++; |
||
503 | for(p2=p1; myisdigit(*p2); p2++); |
||
504 | *p2=0; t2=atoi(p1); p1=p2+1; |
||
505 | /* while(!myisdigit(*p1) && *p1) p1++; |
||
506 | for(p2=p1; myisdigit(*p2); p2++); |
||
507 | *p2=0; t3=atoi(p1); p1=p2+1; |
||
508 | while(!myisdigit(*p1) && *p1) p1++; |
||
509 | for(p2=p1; myisdigit(*p2); p2++); |
||
510 | *p2=0; t4=atoi(p1); p1=p2+1; |
||
511 | while(!myisdigit(*p1) && *p1) p1++; |
||
512 | for(p2=p1; myisdigit(*p2); p2++); |
||
513 | if(t3<5) t3=5; if(t4<20) t4=20; |
||
514 | */ snprintf(wsbuf,sizeof(wsbuf), |
||
515 | "window.focus();window.resizeTo(%d,%d);", |
||
516 | t1,t2); ws=wsbuf; |
||
517 | /* snprintf(wsbuf,sizeof(wsbuf), |
||
518 | "window.focus();window.resizeTo(%d,%d);window.moveTo(%d,%d);", |
||
519 | t1,t2,t3,t4); ws=wsbuf; |
||
520 | */ } |
||
521 | } |
||
522 | else { |
||
523 | if(s1!=NULL && strcmp(s1,"new")==0) |
||
524 | ws="window.focus();window.resizeTo(800,640);window.moveTo(15,35);"; |
||
525 | } |
||
526 | if(strstr(session_prefix,"_exam")!=NULL) { |
||
527 | /* char buf[64]; */ |
||
528 | if(*ws==0) ws="window.focus();"; |
||
529 | else ws= "window.focus();window.moveTo(5,70);"; |
||
530 | /* snprintf(buf,sizeof(buf),"name.phtml.%s",lang); |
||
531 | phtml_put_base(buf); |
||
532 | phtml_put_base("jsclock.phtml"); */ |
||
533 | } |
||
534 | s1=getvar("wims_html_header"); if(s1==NULL) s1=""; |
||
535 | determine_font(getvar("module_language")); |
||
536 | s2=getvar("module_title"); if(s2!=NULL && *s2!=0) { |
||
537 | mystrncpy(hbuf,s2,sizeof(hbuf)); calc_detag(hbuf); |
||
538 | setvar("module_title2",hbuf); |
||
539 | } |
||
540 | mystrncpy(hbuf,s1,sizeof(hbuf)); substit(hbuf); |
||
541 | s2=getvar("wims_htmlbody"); if(s2==NULL) s2=""; |
||
542 | bo=getvar("wims_html_bodyoption"); if(bo==NULL) bo=""; |
||
543 | ws2=getvar("wims_html_onload"); if(ws2==NULL) ws2=""; |
||
544 | snprintf(wsbuf2,sizeof(wsbuf2),"%s%s",ws,ws2); |
||
545 | setvar("wims_html_onload",wsbuf2); |
||
546 | if(wsbuf2[0]) ol=" onload="; else ol=""; |
||
547 | /* output("<html xmlns=\"http://www.w3.org/1999/xhtml\"><head>%s\n\ |
||
548 | </head><body %s %s%s %s>\n", */ |
||
549 | output("<html>\n\ |
||
550 | <head>%s\n\ |
||
551 | </head><body %s %s%s %s>\n", |
||
552 | hbuf,s2,ol,wsbuf2,bo); |
||
553 | exec_headmenu(p); |
||
554 | exec_title(p); |
||
555 | if(cmd_type==cmd_help) { |
||
556 | char *s=getvar("special_parm"); |
||
557 | if(s==NULL) s=""; |
||
558 | m_file.linepointer=m_file.linecnt; |
||
559 | if(strcmp(s,"about")==0) strcpy(hbuf,"about.phtml"); |
||
560 | else strcpy(hbuf,"help.phtml"); |
||
561 | exec_read(hbuf); exec_tail(p); /* param of exec_...() must be readable */ |
||
562 | return; |
||
563 | } |
||
564 | header_executed=1; |
||
565 | } |
||
566 | |||
567 | char href_target[128]; |
||
568 | char jsbuf[512]; |
||
569 | #define jsstr " onClick=\"%s=window.open('','%s','status=no,toolbar=no,location=no,menubar=no,scrollbars=yes,resizable=yes')\"" |
||
570 | int ref_mhelp=0; |
||
571 | int follow_list[]={ |
||
572 | ro_session, ro_lang, ro_useropts, ro_module |
||
573 | }; |
||
574 | #define follow_no (sizeof(follow_list)/sizeof(follow_list[0])) |
||
575 | |||
576 | void _httpfollow(char b1[], char *wn, int new) |
||
577 | { |
||
578 | int i; |
||
579 | char *p1, *s, *ss, sb[MAX_LINELEN+1], qbuf[MAX_LINELEN+1]; |
||
580 | |||
581 | sb[0]=0; |
||
582 | for(i=0;i<follow_no;i++) { |
||
583 | if(robot_access && follow_list[i]==ro_session) continue; |
||
584 | if(!new && follow_list[i]!=ro_session |
||
585 | && follow_list[i]!=ro_module && follow_list[i]!=ro_lang) |
||
586 | continue; |
||
587 | if(follow_list[i]==ro_module) { |
||
588 | char *pp; |
||
589 | if(new) continue; |
||
590 | pp=strstr(b1,"cmd="); |
||
591 | if(pp==NULL) continue; |
||
592 | pp+=strlen("cmd="); |
||
593 | if(memcmp(pp,"intro",strlen("intro"))==0 || |
||
594 | memcmp(pp,"new",strlen("new"))==0) continue; |
||
595 | } |
||
596 | s=getvar(ro_name[follow_list[i]]); |
||
597 | ss=strstr(b1,ro_name[follow_list[i]]); |
||
598 | if(s!=NULL && *s!=0 && |
||
599 | (ss==NULL || (ss>b1 && *(ss-1)!='&') |
||
600 | || *(ss+strlen(ro_name[follow_list[i]]))!='=')) { |
||
601 | if(follow_list[i]==ro_session && memcmp(href_target,"wims_",5)==0) { |
||
602 | char st[MAX_LINELEN+1]; |
||
603 | char *s1; |
||
604 | s1=getvar("wims_session"); |
||
605 | if(s1==NULL) internal_error("exec_href() error.\n"); |
||
606 | if(ref_mhelp) { |
||
607 | if(strstr(s1,"_mhelp")!=0) |
||
608 | snprintf(st,sizeof(st),"%s",s1); |
||
609 | else |
||
610 | snprintf(st,sizeof(st),"%s_mhelp",s1); |
||
611 | } |
||
612 | else snprintf(st,sizeof(st),"%.10s%s",s1,href_target+4); |
||
613 | s=st; |
||
614 | } |
||
615 | snprintf(sb+strlen(sb),MAX_LINELEN-strlen(sb),"%s=%s&", |
||
616 | ro_name[follow_list[i]],s); |
||
617 | if(ismhelp && follow_list[i]==ro_session && |
||
618 | strstr(sb,"_mhelp")==NULL) |
||
619 | snprintf(sb+strlen(sb)-1,MAX_LINELEN-strlen(sb)+1,"_mhelp&"); |
||
620 | } |
||
621 | } |
||
622 | snprintf(qbuf,MAX_LINELEN,"%s%s%s",wn,sb,b1); |
||
623 | /* cleaning up query string */ |
||
624 | for(p1=qbuf;*p1;p1++) { |
||
625 | if(*p1=='"') string_modify(qbuf,p1,p1+1,"%22"); |
||
626 | if(*p1=='&' && isalpha(*(p1+1))) { |
||
627 | p1++; string_modify(qbuf,p1,p1,"+"); |
||
628 | } |
||
629 | } |
||
630 | mystrncpy(b1,qbuf,MAX_LINELEN); |
||
631 | } |
||
632 | |||
633 | /* Restart with a new module, using http code 302. */ |
||
634 | void exec_restart(char *p) |
||
635 | { |
||
636 | char buf[MAX_LINELEN+1], *rfn, buf2[MAX_LINELEN+1]; |
||
637 | /* long int t; */ |
||
638 | |||
639 | if(robot_access || outputing || !trusted_module() || is_class_module) return; |
||
640 | /* accessfile(buf,"r","%s/restart.time",s2_prefix); |
||
641 | t=atoi(buf); if(t==nowtime) return; */ /* possible looping */ |
||
642 | mystrncpy(buf,find_word_start(p),sizeof(buf)); |
||
643 | *find_word_end(buf)=0; |
||
644 | _httpfollow(buf,"",0); |
||
645 | nph_header(301); |
||
646 | rfn=strchr(ref_name,':'); if(rfn==NULL) { |
||
647 | usual: snprintf(buf2,sizeof(buf2),"%s?%s",ref_name,buf); |
||
648 | } |
||
649 | else { |
||
650 | char *p; |
||
651 | p=getvar("wims_protocol"); |
||
652 | if(p!=NULL && strcmp(p,"https")==0) { |
||
653 | snprintf(buf2,sizeof(buf2),"https%s?%s",rfn,buf); |
||
654 | } |
||
655 | else goto usual; |
||
656 | } |
||
657 | printf("Location: %s\r\n\r\n\ |
||
658 | <html><body><a href=\"%s\">%s</a></body></html>",buf2,buf2,buf2); |
||
659 | close_working_file(&m_file,0); write_logs(); |
||
660 | snprintf(buf,sizeof(buf),"%ld",nowtime); |
||
661 | /* accessfile(buf,"w","%s/restart.time",s2_prefix); |
||
662 | */ delete_pid(); exit(0); |
||
663 | } |
||
664 | |||
665 | /* extract target tag from parm string. */ |
||
666 | void href_find_target(char *p) |
||
667 | { |
||
668 | char *pp, *pe,buf1[MAX_LINELEN+1]; |
||
669 | href_target[0]=0; jsbuf[0]=0; ref_mhelp=0; |
||
670 | for(pp=find_word_start(p);*pp!=0;pp=find_word_start(pe)) { |
||
671 | pe=find_word_end(pp); |
||
672 | if(strncasecmp(pp,"target=wims_",strlen("target=wims_"))!=0) continue; |
||
673 | memmove(buf1,pp,pe-pp); buf1[pe-pp]=0; substit(buf1); |
||
674 | if(strncasecmp(buf1,"target=wims_mhelp",strlen("target=wims_mhelp"))==0) { |
||
675 | if(*pe!=0) *pe++=0; strcpy(href_target,"wims_help"); |
||
676 | ref_mhelp=1; |
||
677 | } |
||
678 | else { |
||
679 | if(*pe!=0) *pe++=0; |
||
680 | mystrncpy(href_target,buf1+strlen("target="),sizeof(href_target)); |
||
681 | } |
||
682 | snprintf(jsbuf,sizeof(jsbuf),jsstr,href_target,href_target); |
||
683 | strcpy(pp,pe);return; |
||
684 | } |
||
685 | pp=getvar("module_help"); |
||
686 | if(href_target[0]==0 && pp!=NULL && strcmp(pp,"popup")==0 && |
||
687 | (pe=strstr(p,"cmd=help"))!=NULL) { |
||
688 | if(pe==p || *(pe-1)=='&') { |
||
689 | strcpy(href_target,"wims_help"); ref_mhelp=1; |
||
690 | snprintf(jsbuf,sizeof(jsbuf),jsstr,href_target,href_target); |
||
691 | } |
||
692 | } |
||
693 | } |
||
694 | |||
695 | void _href_getdef(char src[], char vname[], char buf[], int buflen) |
||
696 | { |
||
697 | char *p1, *p2, *p3; |
||
698 | buf[0]=0; |
||
699 | for(p1=strstr(src,vname); p1; p1=strstr(p2,vname)) { |
||
700 | p2=p1+strlen(vname); if(*p2!='=') continue; |
||
701 | if(p1>src && *(p1-1)!='&') continue; |
||
702 | p2++; p3=strchr(p2,'&'); if(p3==NULL) p3=p2+strlen(p2); |
||
703 | if(p3-p2>=buflen) return; /* too long */ |
||
704 | memmove(buf,p2, p3-p2); buf[p3-p2]=0; return; |
||
705 | } |
||
706 | } |
||
707 | |||
708 | /* Create href to wims requests. subst() is not done. */ |
||
709 | void exec_href(char *p) |
||
710 | { |
||
711 | char *s, st[128], *p1, *p2, *p3, *wn=""; |
||
712 | char *U="<u><FONT COLOR=\"#A0A0C0\">%s</u></FONT>"; |
||
713 | char b1[MAX_LINELEN+1], b2[MAX_LINELEN+1]; |
||
714 | int new=0; |
||
715 | if(!outputing) return; |
||
716 | href_find_target(p); |
||
717 | p1=find_word_start(p); |
||
718 | p2=find_word_end(p1); if(*p2) *(p2++)=0; |
||
719 | mystrncpy(b1,p1,sizeof(b1)); |
||
720 | mystrncpy(b2,find_word_start(p2),sizeof(b2)); |
||
721 | substit(b1); substit(b2); |
||
722 | /* standard reference */ |
||
723 | if(*b2==0 && strchr(b1,'=')==NULL) { |
||
724 | char b[MAX_LINELEN+1], *ll; |
||
725 | p1=find_word_start(b1); *find_word_end(p1)=0; |
||
726 | if(*p1==0 || strlen(p1)>64) return; |
||
727 | ll=getvar("module_language"); |
||
728 | if(ll==NULL || *ll==0 || *(ll+1)==0 || *(ll+2)!=0) ll=lang; |
||
729 | accessfile(b,"r","html/href.%s",ll); |
||
730 | memmove(p1+1,p1,64); *p1='\n'; strcat(p1," "); |
||
731 | p2=strstr(b,p1); if(p2==NULL) return; |
||
732 | p1=find_word_start(p2+strlen(p1)); p2=find_word_end(p1); |
||
733 | if(*p2) *(p2++)=0; |
||
734 | p3=strchr(p2,'\n'); if(p3!=NULL) *p3=0; |
||
735 | mystrncpy(b1,p1,sizeof(b1)); |
||
736 | mystrncpy(b2,find_word_start(p2),sizeof(b2)); |
||
737 | substit(b1); substit(b2); |
||
738 | } |
||
739 | /* for robots: only references without defining cmd. */ |
||
740 | if(robot_access && strstr(b1,"cmd=")!=NULL && |
||
741 | strstr(b1,"module=adm/doc")==NULL) { |
||
742 | _output_(b2); return; |
||
743 | } |
||
744 | if(robot_access && strstr(aliased_cgi,"yes")!=NULL) { |
||
745 | char mbuf[256], lbuf[16]; |
||
746 | _href_getdef(b1,"module",mbuf,sizeof(mbuf)); |
||
747 | if(mbuf[0]==0) mystrncpy(mbuf,home_module,sizeof(mbuf)); |
||
748 | _href_getdef(b1,"lang",lbuf,sizeof(lbuf)); |
||
749 | if(strlen(lbuf)!=2) {mystrncpy(lbuf,lang,4);lbuf[2]=0;} |
||
750 | if(strncmp(mbuf,"adm/doc",strlen("adm/doc"))==0) { |
||
751 | char dbuf[256], bbuf[256]; |
||
752 | _href_getdef(b1,"doc",dbuf,sizeof(dbuf)); |
||
753 | _href_getdef(b1,"block",bbuf,sizeof(bbuf)); |
||
754 | if(!myisdigit(dbuf[0])) dbuf[0]=0; |
||
755 | if(dbuf[0]!=0 && bbuf[0]==0) snprintf(bbuf,sizeof(bbuf),"main"); |
||
756 | if(dbuf[0]==0) |
||
757 | output("<a href=\"%s%s_doc~.html\">%s</a>", ref_base,lbuf,b2); |
||
758 | else |
||
759 | output("<a href=\"%s%s_doc~%s~%s.html\">%s</a>", |
||
760 | ref_base,lbuf,dbuf,bbuf,b2); |
||
761 | } |
||
762 | else { |
||
763 | for(s=strchr(mbuf,'/'); s!=NULL; s=strchr(s+1,'/')) *s='~'; |
||
764 | output("<a href=\"%s%s_%s.html\">%s</a>", ref_base,lbuf,mbuf,b2); |
||
765 | } |
||
766 | return; |
||
767 | } |
||
768 | s=getvar("wims_ref_target"); |
||
769 | if(href_target[0]!=0) s=href_target; |
||
770 | if(s!=NULL && *s!=0 && !isspace(*s)) { |
||
771 | snprintf(st,sizeof(st)," target=\"%s\"",s); |
||
772 | if(strcmp(s,"_parent")!=0) { |
||
773 | new=1; wn="wims_window=new&"; |
||
774 | } |
||
775 | } |
||
776 | else st[0]=0; |
||
777 | _httpfollow(b1,wn,new); |
||
778 | tohttpquery(b1); |
||
779 | if(strstr(session_prefix,"_check")!=NULL) { |
||
780 | if(*b2) output(U,b2); |
||
781 | else _output_("<a name=\"0\">"); |
||
782 | return; |
||
783 | } |
||
784 | if(jsbuf[0]==0 && st[0]==0 && strstr(session_prefix,"_exam")!=NULL) { |
||
785 | p1=strstr(b1,"cmd="); if(p1!=NULL) { |
||
786 | p1+=strlen("cmd="); |
||
787 | if(strncmp(p1,"new",3)==0 || strncmp(p1,"renew",5)==0 || |
||
788 | strncmp(p1,"intro",5)==0) { |
||
789 | if(*b2) output(U,b2); |
||
790 | else _output_("<a name=\"#\">"); |
||
791 | return; |
||
792 | } |
||
793 | } |
||
794 | } |
||
795 | if(*b2) |
||
796 | output("<a href=\"%s?%s\"%s%s>%s</a>", |
||
797 | ref_name, b1, st, jsbuf, b2); |
||
798 | else |
||
799 | output("<a href=\"%s?%s\"%s%s>",ref_name, b1, st, jsbuf); |
||
800 | } |
||
801 | |||
802 | /* Create form refering to the page. */ |
||
803 | void exec_form(char *p) |
||
804 | { |
||
805 | char *s, *p1, *p2, *a, *m, *opt, st[128], *wn=""; |
||
806 | char abuf[128]; |
||
807 | int i, new=0; |
||
808 | if(!outputing) return; |
||
809 | href_find_target(p); |
||
810 | s=getvar("wims_ref_target"); |
||
811 | if(href_target[0]!=0) s=href_target; |
||
812 | if(s!=NULL && *s!=0 && !isspace(*s)) { |
||
813 | snprintf(st,sizeof(st)," target=%s",s); |
||
814 | if(strcmp(s,"_parent")!=0) { |
||
815 | new=1; wn="<input type=hidden name=wims_window value=yes>\n"; |
||
816 | } |
||
817 | } |
||
818 | else st[0]=0; |
||
819 | a=getvar("wims_ref_anchor"); if(a==NULL) a=""; |
||
820 | opt=find_word_start(find_word_end(find_word_start(p))); |
||
821 | m=getvar("wims_form_method"); |
||
822 | if(m!=NULL) { |
||
823 | m=find_word_start(m); |
||
824 | if(strncasecmp(m,"post",4)==0) m="post"; |
||
825 | else if(strncasecmp(m,"get",3)==0) m="get"; |
||
826 | else if(strncasecmp(m,"file",4)==0) { |
||
827 | m="post\" enctype=\"multipart/form-data"; |
||
828 | snprintf(abuf,sizeof(abuf),"?form-data%ld%s",random(),a); a=abuf; |
||
829 | force_setvar("wims_form_method",""); |
||
830 | } |
||
831 | else m=default_form_method; |
||
832 | } |
||
833 | else m=default_form_method; |
||
834 | if(strstr(session_prefix,"_check")!=NULL) { |
||
835 | output("<p><form action=\"NON_EXISTING_PAGE\" onsubmit=\"window.close();\" %s>\n", |
||
836 | opt); |
||
837 | return; |
||
838 | } |
||
839 | output("<p><form action=\"%s%s\"%s method=\"%s\" %s>\n%s",ref_name,a,st,m,opt,wn); |
||
840 | if(a!=abuf && a[0]) force_setvar("wims_ref_anchor",""); |
||
841 | for(i=0;i<follow_no;i++) { |
||
842 | if(robot_access && follow_list[i]==ro_session) continue; |
||
843 | if(!new && follow_list[i]!=ro_session |
||
844 | && follow_list[i]!=ro_module && follow_list[i]!=ro_lang) |
||
845 | continue; |
||
846 | if(follow_list[i]==ro_module) continue; |
||
847 | s=getvar(ro_name[follow_list[i]]); |
||
848 | if(s!=NULL && *s!=0) { |
||
849 | if(follow_list[i]==ro_session && memcmp(href_target,"wims_",5)==0) { |
||
850 | char st[MAX_LINELEN+1]; |
||
851 | char *s1; |
||
852 | s1=getvar("wims_session"); |
||
853 | if(s1==NULL) internal_error("exec_form() error.\n"); |
||
854 | snprintf(st,sizeof(st),"%.10s%s",s1,href_target+4); |
||
855 | s=st; |
||
856 | } |
||
857 | output("<input type=hidden name=%s value=%s>\n", |
||
858 | ro_name[follow_list[i]],s); |
||
859 | } |
||
860 | } |
||
861 | p1=find_word_start(p);p2=find_word_end(p1); |
||
862 | if(p2>p1) { |
||
863 | char buf[64]; |
||
864 | int i; |
||
865 | i=p2-p1; if(i>60) i=60; |
||
866 | memmove(buf,p1,i);buf[i]=0; |
||
867 | for(i=0;i<CMD_NO && strcmp(buf,commands[i]);i++); |
||
868 | if(i<CMD_NO) { |
||
869 | output("<input type=hidden name=cmd value=%s>\n",buf); |
||
870 | if(i!=cmd_intro && i!=cmd_new) |
||
871 | output("<input type=hidden name=module value=%s>\n", |
||
872 | getvar(ro_name[ro_module])); |
||
873 | } |
||
874 | } |
||
875 | } |
||
876 | |||
877 | /* Creat link to trap robot access, an internal command |
||
878 | * which should not be documented */ |
||
879 | void exec_robottrap(char *p) |
||
880 | { |
||
881 | char buf[MAX_LINELEN+1]; |
||
882 | if(robot_access) return; |
||
883 | strcpy(buf,"session=$wims_session.1&module=adm/trap"); |
||
884 | _output_("<!-- >"); exec_href(buf); |
||
885 | _output_("Robot trapper, do not click!</a> < -->"); |
||
886 | exec_href(buf); _output_("<font></font></a>"); |
||
887 | } |
||
888 | |||
889 | /* set definitions in a file. Trusted modules only. */ |
||
890 | void exec_setdef(char *p) |
||
891 | { |
||
892 | char *p1, *pp; |
||
893 | char nbuf[MAX_LINELEN+1], fbuf[MAX_LINELEN+1], tbuf[MAX_LINELEN+1]; |
||
894 | if(robot_access || !trusted_module() || is_class_module) return; |
||
895 | p1=wordchr(p,"in"); if(p1==NULL) module_error("syntax_error"); |
||
896 | *p1=0; p1=find_word_start(p1+strlen("in")); |
||
897 | strcpy(nbuf,p); |
||
898 | mystrncpy(tbuf,p1,sizeof(tbuf)); |
||
899 | substit(nbuf); substit(tbuf); |
||
900 | if(find_module_file(tbuf,fbuf,1)) return; |
||
901 | pp=find_word_start(nbuf); p1=find_word_start(fbuf); *find_word_end(p1)=0; |
||
902 | strip_trailing_spaces(pp); |
||
903 | setdef(p1,pp); |
||
904 | } |
||
905 | |||
906 | /* Set a variable. */ |
||
907 | void exec_set(char *name) |
||
908 | { |
||
909 | char *p, *defn, *parm; |
||
910 | char tbuf2[MAX_LINELEN+1], namebuf[MAX_LINELEN+1]; |
||
911 | int i; |
||
912 | |||
913 | p=strchr(name,'='); |
||
914 | if(p==NULL) return; /* warning or error! */ |
||
915 | *p=0; defn=find_word_start(p+1); |
||
916 | *find_word_end(name)=0; |
||
917 | mystrncpy(namebuf,find_word_start(name),sizeof(namebuf)); |
||
918 | /* we allow substit in names, to implement array */ |
||
919 | substit(namebuf); *find_word_end(namebuf)=0; |
||
920 | if(*defn!=calc_prefix_char) { |
||
921 | /* substitute by default */ |
||
922 | mystrncpy(tbuf2,defn,sizeof(tbuf2)); |
||
923 | substit(tbuf2); setvar(namebuf,tbuf2); return; |
||
924 | } |
||
925 | /* called from !readdef */ |
||
926 | if((untrust&4)!=0) module_error("not_trusted"); |
||
927 | /* definition is a command */ |
||
928 | parm=find_word_end(defn+1); |
||
929 | if( *parm != 0 ) { *parm=0; parm=find_word_start(parm+1); } |
||
930 | i=m_file.lines[m_file.l].varcode; |
||
931 | if(i<0) { |
||
932 | i=search_list(calc_routine,CALC_FN_NO,sizeof(calc_routine[0]),defn+1); |
||
933 | m_file.lines[m_file.l].varcode=i; |
||
934 | } |
||
935 | if(i<0) { |
||
936 | /* replace by warning? */ |
||
937 | setvar(error_data_string,defn+1); module_error("bad_cmd"); |
||
938 | return; |
||
939 | } |
||
940 | mystrncpy(tbuf2,parm,sizeof(tbuf2)); execnt++; |
||
941 | if(calc_routine[i].tag==0) substit(tbuf2); |
||
942 | tbuf2[sizeof(tbuf2)-1]=0; calc_routine[i].routine(tbuf2); |
||
943 | /* remove trailing new line */ |
||
944 | tbuf2[sizeof(tbuf2)-1]=0; |
||
945 | if(tbuf2[strlen(tbuf2)-1]=='\n') tbuf2[strlen(tbuf2)-1]=0; |
||
946 | setvar(namebuf,tbuf2); |
||
947 | } |
||
948 | |||
949 | /* set but do not overwrite. */ |
||
950 | void exec_default(char *p) |
||
951 | { |
||
952 | char *start, *end, c, *pp; |
||
953 | char namebuf[MAX_LINELEN+1]; |
||
954 | start=find_word_start(p); |
||
955 | for(end=start;*end!=0 && !isspace(*end) && *end!='='; end++); |
||
956 | c=*end; *end=0; |
||
957 | if(end-start<=MAX_LINELEN-1) { |
||
958 | memmove(namebuf,start,end-start+1); substit(namebuf); |
||
959 | pp=getvar(namebuf); |
||
960 | if(pp!=NULL && *pp!=0) return; |
||
961 | } |
||
962 | *end=c; exec_set(p); |
||
963 | } |
||
964 | |||
965 | /* Does nothing; just a comment. */ |
||
966 | void exec_comment(char *p) |
||
967 | { |
||
968 | return; |
||
969 | } |
||
970 | |||
971 | /* Exit the file under interpretation */ |
||
972 | void exec_exit(char *p) |
||
973 | { |
||
974 | m_file.linepointer=m_file.linecnt; |
||
975 | return; |
||
976 | } |
||
977 | |||
978 | /* output a file. Undocumented. Aliases: |
||
979 | * getfile, outfile, fileout */ |
||
980 | void exec_getfile(char *p) |
||
981 | { |
||
982 | char *s, *p1, url[MAX_LINELEN+1]; |
||
983 | char *prompt; |
||
984 | |||
985 | p=find_word_start(p); prompt=find_word_end(p); |
||
986 | if(*prompt!=0) *prompt++=0; |
||
987 | prompt=find_word_start(prompt); |
||
988 | if(*p==0 || !outputing) return; |
||
989 | if(!trusted_module() || is_class_module) return; |
||
990 | s=getvar(ro_name[ro_session]); |
||
991 | if(s==NULL || *s==0 || strstr(s,"robot")!=NULL) return; |
||
992 | mystrncpy(url,ref_name,sizeof(url)); |
||
993 | for(p1=url+strlen(url);p1>url && *(p1-1)!='/'; p1--); |
||
994 | if(good_httpd) snprintf(p1,sizeof(url)+p1-url, |
||
995 | "getfile/%s?&session=%s&modif=%ld", |
||
996 | p,s,nowtime); |
||
997 | else snprintf(url,sizeof(url), |
||
998 | "%s?cmd=getfile&session=%s&special_parm=%s&modif=%ld", |
||
999 | ref_name,s,p,nowtime); |
||
1000 | snprintf(jsbuf,sizeof(jsbuf),jsstr,"wims_file","wims_file"); |
||
1001 | if(*prompt) output("<a href=\"%s\">%s</A>\n", url,prompt); |
||
1002 | else output("<a href=%s>",url); |
||
1003 | } |
||
1004 | |||
1005 | /* internal */ |
||
1006 | void count_insert(void) |
||
1007 | { |
||
1008 | insert_no++; |
||
1009 | if(insert_no>=INS_LIMIT) module_error("too_many_ins"); |
||
1010 | } |
||
1011 | |||
1012 | int animated_ins=0; |
||
1013 | int grouped_ins=0; |
||
1014 | |||
1015 | /* generic insertion */ |
||
1016 | void _exec_ins(char *p, char *script_name,char *format) |
||
1017 | { |
||
1018 | char *s, *b, *at, *tag, *tag2, *al, *fmt, *mh; |
||
1019 | char *p1, *pt; |
||
1020 | char buf[1024],buf2[1024],url[MAX_LINELEN+1],altbuf[1024]; |
||
1021 | char outbuf[1024]; |
||
1022 | int border, middle, vspace; |
||
1023 | long int tel; |
||
1024 | |||
1025 | if(robot_access) return; |
||
1026 | count_insert(); outbuf[0]=0; |
||
1027 | setenv("ins_source",p,1); /* value kept from user tamper */ |
||
1028 | if(animated_ins) fmt=getvar("anim_format"); else fmt=format; |
||
1029 | if(fmt==NULL) fmt="gif"; |
||
1030 | if(ismhelp) mh="mh"; else mh=""; |
||
1031 | snprintf(buf,sizeof(buf),"%s/insert%s-%d.%s",s2_prefix,mh,insert_no,fmt); |
||
1032 | if(grouped_ins) {unlink(buf); goto grouped;} |
||
1033 | exportall(); |
||
1034 | call_ssh("%s/%s %d %s >%s/ins.out 2>%s/ins.err", |
||
1035 | bin_dir,script_name,insert_no,tmp_dir,tmp_dir,tmp_dir); |
||
1036 | unlink(buf); wrapexec=1; |
||
1037 | if(trusted_module()) setenv("trusted_module","yes",1); |
||
1038 | else if(untrust) setenv("trusted_module","no",1); |
||
1039 | call_ssh("mv %s/insert%s-%d.%s %s >/dev/null 2>/dev/null", |
||
1040 | tmp_dir,mh,insert_no,fmt,s2_prefix); |
||
1041 | tel=filelength("%s", buf); |
||
1042 | if(tel<=5) { |
||
1043 | char bbuf[MAX_LINELEN+1]; |
||
1044 | accessfile(bbuf,"r","%s/ins.err",tmp_dir); |
||
1045 | snprintf(url,sizeof(url),"gifs/badins.gif"); |
||
1046 | for(p1=bbuf;p1<bbuf+512 && *p1;p1++) |
||
1047 | if(*p1=='<' || *p1=='>') *p1='?'; |
||
1048 | *p1=0; |
||
1049 | if(bbuf[0]==0) snprintf(bbuf,sizeof(bbuf),"Fail"); |
||
1050 | snprintf(outbuf+strlen(outbuf),sizeof(outbuf)-strlen(outbuf), |
||
1051 | " <img src=%s alt=Error> <p><small><pre>%s</pre></small> <p> ", |
||
1052 | url,bbuf); |
||
1053 | setvar("ins_warn","fail"); |
||
1054 | setvar("ins_cnt","0"); |
||
1055 | goto reset; |
||
1056 | } |
||
1057 | grouped: |
||
1058 | s=getvar(ro_name[ro_session]); |
||
1059 | b=getvar("ins_border"); at=getvar("ins_attr"); |
||
1060 | tag=getvar("ins_tag"); al=getvar("ins_align"); |
||
1061 | if(at==NULL) at=""; |
||
1062 | if(tag==NULL) tag=""; |
||
1063 | if(al==NULL) al="";al=find_word_start(al); |
||
1064 | if(*al!=0) snprintf(buf2,sizeof(buf2),"align=%s",al); else buf2[0]=0; |
||
1065 | if(strcasecmp(al,"middle")==0) middle=1; else middle=0; |
||
1066 | tag2=""; vspace=0; |
||
1067 | if(*tag!=0) { |
||
1068 | mystrncpy(buf,tag,sizeof(buf)); tag=find_word_start(buf); |
||
1069 | tag2=find_word_end(tag); |
||
1070 | if(*tag2!=0) *tag2++=0; |
||
1071 | tag2=find_word_start(tag2); |
||
1072 | } |
||
1073 | if(b==NULL || *b==0) border=0; |
||
1074 | else border=atoi(b); |
||
1075 | if(border<0) border=0; if(border>100) border=100; |
||
1076 | if(middle) { |
||
1077 | snprintf(outbuf+strlen(outbuf), |
||
1078 | sizeof(outbuf)-strlen(outbuf),mathalign_sup1); |
||
1079 | vspace=2; |
||
1080 | } |
||
1081 | mystrncpy(url,ref_name,sizeof(url)); |
||
1082 | for(p1=url+strlen(url);p1>url && *(p1-1)!='/'; p1--); |
||
1083 | snprintf(p1,sizeof(url)+p1-url, |
||
1084 | "wims.%s?cmd=getins&session=%s&special_parm=insert%s-%d.%s&modif=%ld", |
||
1085 | fmt,s,mh,insert_no,fmt,nowtime); |
||
1086 | if(strchr(ins_alt,'"')!=NULL || strlen(ins_alt)>256) ins_alt[0]=0; |
||
1087 | pt=getvar("wims_ins_alt"); if(pt==NULL) pt=""; |
||
1088 | if(ins_alt[0] && strcmp(pt,"none")!=0) |
||
1089 | snprintf(altbuf,sizeof(altbuf)," alt=\"%s\"",ins_alt); |
||
1090 | else altbuf[0]=0; |
||
1091 | if(strcasecmp(tag,"form")!=0) { |
||
1092 | snprintf(outbuf+strlen(outbuf),sizeof(outbuf)-strlen(outbuf), |
||
1093 | "<img src=%s border=%d vspace=%d %s %s%s>", |
||
1094 | url, border, vspace, at, buf2, altbuf); |
||
1095 | } |
||
1096 | else { |
||
1097 | char *n; |
||
1098 | if(*tag2!=0) n="name="; else n=""; |
||
1099 | snprintf(outbuf+strlen(outbuf),sizeof(outbuf)-strlen(outbuf), |
||
1100 | "<input type=image %s%s src=%s border=%d vspace=%d %s %s%s>", |
||
1101 | n,tag2,url,border,vspace, at,buf2, altbuf); |
||
1102 | } |
||
1103 | if(middle) snprintf(outbuf+strlen(outbuf), |
||
1104 | sizeof(outbuf)-strlen(outbuf),mathalign_sup2); |
||
1105 | setvar("ins_warn",""); ins_alt[0]=0; |
||
1106 | setvar("ins_cnt",int2str(insert_no)); |
||
1107 | reset: |
||
1108 | if(outputing) _output_(outbuf); |
||
1109 | setvar("ins_out",outbuf); |
||
1110 | setvar("ins_attr",""); setvar("ins_tag",""); |
||
1111 | setvar("ins_url",url); |
||
1112 | snprintf(buf2,sizeof(buf2),"insert%s-%d.%s",mh,insert_no,fmt); |
||
1113 | setvar("ins_filename",buf2); |
||
1114 | animated_ins=0; |
||
1115 | } |
||
1116 | |||
1117 | /* instex: dynamically insert tex outputs */ |
||
1118 | void exec_instex(char *p) |
||
1119 | { |
||
1120 | char *ts, *tc, *f, *mh, buf[MAX_FNAME+1]; |
||
1121 | |||
1122 | if(robot_access) { |
||
1123 | *p=0; return; |
||
1124 | } |
||
1125 | f=instex_check_static(p); substit(p); |
||
1126 | if(f==NULL) { |
||
1127 | /* Use static instex if there is no real substitution |
||
1128 | * and the source file is not in sessions directory. */ |
||
1129 | calc_instexst(p); if(outputing) _output_(p); |
||
1130 | return; |
||
1131 | } |
||
1132 | if(ismhelp) mh="mh"; else mh=""; |
||
1133 | fix_tex_size(); f="gif"; |
||
1134 | setenv("texgif_style",instex_style,1); |
||
1135 | setenv("texgif_tmpdir",tmp_dir,1); |
||
1136 | setenv("texgif_src",p,1); |
||
1137 | if(ins_alt[0]==0) mystrncpy(ins_alt,p,sizeof(ins_alt)); |
||
1138 | mkfname(buf,"%s/insert%s-%d.gif",tmp_dir,mh,insert_no+1); |
||
1139 | setenv("texgif_outfile",buf,1); |
||
1140 | ts=getvar("wims_texsize"); tc=getvar("instex_color"); |
||
1141 | if(lastout_file!=-1 && (tc==NULL || *tc==0) && |
||
1142 | (ts==NULL || *ts==0 || strcmp(ts,"0")==0) && |
||
1143 | strstr(p,"\\begin{")==NULL) { |
||
1144 | int ls, ln; |
||
1145 | char *pagebreak; |
||
1146 | ls=strlen(instex_src); ln=strlen(instex_fname); |
||
1147 | if(ls+strlen(p)>=MAX_LINELEN-256 || |
||
1148 | ln+strlen(buf)>=MAX_LINELEN-16) { |
||
1149 | instex_flush(); ls=ln=0; |
||
1150 | } |
||
1151 | if(instex_cnt>0) pagebreak="\\pagebreak\n"; else pagebreak=""; |
||
1152 | snprintf(instex_src+ls,MAX_LINELEN-ls,"%s %s %s %s\n", |
||
1153 | pagebreak,instex_style,p,instex_style); |
||
1154 | snprintf(instex_fname+ln,MAX_LINELEN-ln,"%s\n",buf); |
||
1155 | grouped_ins=1; |
||
1156 | } |
||
1157 | mkfname(buf,"%s/texgif.dvi",tmp_dir); unlink(buf); |
||
1158 | wrapexec=0; _exec_ins(p,instex_processor,f); |
||
1159 | if(grouped_ins) instex_cnt++; |
||
1160 | grouped_ins=0; |
||
1161 | } |
||
1162 | |||
1163 | /* patches the gnuplot integer division (mis)feature. */ |
||
1164 | void gnuplot_patch(char *p,int oneline) |
||
1165 | { |
||
1166 | char *pp; |
||
1167 | for(pp=strchr(p,'/');pp!=NULL;pp=strchr(pp+1,'/')) { |
||
1168 | char *p1; |
||
1169 | if(pp<=p || !myisdigit(*(pp-1)) || !myisdigit(*(pp+1))) continue; |
||
1170 | for(p1=pp-2;p1>=p && myisdigit(*p1);p1--); |
||
1171 | if(p1>=p && *p1=='.') continue; |
||
1172 | for(p1=pp+2;*p1 && myisdigit(*p1);p1++); |
||
1173 | if(*p1=='.') continue; |
||
1174 | string_modify(p,p1,p1,".0"); |
||
1175 | } |
||
1176 | for(pp=strchr(p,'^');pp!=NULL;pp=strchr(pp+1,'^')) |
||
1177 | string_modify(p,pp,pp+1,"**"); |
||
1178 | /* disallow new lines and ';' */ |
||
1179 | if(oneline) |
||
1180 | for(pp=p;*pp!=0;pp++) if(*pp==';' || *pp=='\n') *pp=' '; |
||
1181 | } |
||
1182 | |||
1183 | /* This is to disable pipe in the gnuplot plotting function. |
||
1184 | * We do not allow ' followed by < . */ |
||
1185 | void prepare_insplot_parm(char *p) |
||
1186 | { |
||
1187 | int i,j,multanim; char *pp, *s; |
||
1188 | double d; |
||
1189 | char setbuf[MAX_LINELEN+10],buf[MAX_LINELEN+1]; |
||
1190 | |||
1191 | j=strlen(p); |
||
1192 | /* pipe in plot command */ |
||
1193 | for(i=0;i<j;i++) { |
||
1194 | if(*(p+i)!='\'' && *(p+i)!='"') continue; |
||
1195 | pp=find_word_start(p+i+1); if(*pp=='<') module_error("illegal_plot_cmd"); |
||
1196 | } |
||
1197 | gnuplot_patch(p,1); |
||
1198 | /* multiplot */ |
||
1199 | multanim=0; |
||
1200 | pp=getvar("insplot_split"); |
||
1201 | if(pp!=NULL) i=linenum(pp); else i=0; |
||
1202 | /* arbitrary limit: 16 multiplots */ |
||
1203 | if(i>16) i=16; |
||
1204 | if(i>1) { |
||
1205 | char tbuf[MAX_LINELEN*(i+1)+100], bbuf[MAX_LINELEN+1]; |
||
1206 | tbuf[0]=0; |
||
1207 | if(*p!=0) snprintf(tbuf,sizeof(tbuf),"%s\n",p); |
||
1208 | snprintf(buf,sizeof(buf),"%d",i); setenv("multiplot",buf,1); |
||
1209 | for(j=1;j<=i;j++) { |
||
1210 | snprintf(buf,sizeof(buf),"insplot_parm_%d",j); |
||
1211 | pp=getvar(buf); |
||
1212 | if(pp==NULL || *pp==0) { |
||
1213 | if(j==1 && *p!=0) continue; |
||
1214 | pp=""; |
||
1215 | } |
||
1216 | else { |
||
1217 | mystrncpy(bbuf,pp,sizeof(bbuf)); |
||
1218 | gnuplot_patch(bbuf,1); |
||
1219 | } |
||
1220 | strcat(tbuf,bbuf);strcat(tbuf,"\n"); |
||
1221 | } |
||
1222 | setenv("insplot_source",tbuf,1); |
||
1223 | if(varchr(tbuf,"s")!=NULL) multanim=1; |
||
1224 | } |
||
1225 | /* no illegal chaining */ |
||
1226 | pp=getvar("insplot_font"); if(pp!=NULL) { |
||
1227 | for(s=pp;s<pp+MAX_LINELEN && *s;s++) |
||
1228 | if(*s==';' || *s=='\n' || *s==' ') *s=0; |
||
1229 | if(s>=pp+MAX_LINELEN) *s=0; |
||
1230 | setvar("insplot_font",pp); |
||
1231 | } |
||
1232 | pp=getvar("insplot_set"); if(pp!=NULL) { |
||
1233 | char tbuf[MAX_LINELEN+1]; |
||
1234 | mystrncpy(tbuf,pp,sizeof(tbuf)); |
||
1235 | i=strlen(tbuf)-1; |
||
1236 | while(i>0 && isspace(tbuf[i])) i--; |
||
1237 | if(tbuf[i]==';') tbuf[i]=0; |
||
1238 | gnuplot_patch(tbuf,0);pp=tbuf; |
||
1239 | strcpy(setbuf,"set "); j=strlen("set "); |
||
1240 | for(i=0; *(pp+i)!=0 && j<MAX_LINELEN; i++) { |
||
1241 | if(*(pp+i)=='\n') {setbuf[j++]=' '; continue;} |
||
1242 | if(*(pp+i)!=';') {setbuf[j++]=*(pp+i); continue;} |
||
1243 | strcpy(setbuf+j,"\nset "); j+=strlen("\nset "); |
||
1244 | } |
||
1245 | setbuf[j]=0; |
||
1246 | setenv("insplot_set",setbuf,1); |
||
1247 | } |
||
1248 | else setenv("insplot_set","",1); |
||
1249 | /* frames of animation */ |
||
1250 | pp=getvar("ins_anim_frames"); |
||
1251 | if(pp!=NULL) i=evalue(pp); else i=1; |
||
1252 | if(i>=ANIM_LIMIT) i=ANIM_LIMIT-1; if(i<1) i=1; |
||
1253 | if(strstr(setbuf,"step")==NULL && strstr(p,"step")==NULL |
||
1254 | && varchr(setbuf,"s")==NULL && varchr(p,"s")==NULL && !multanim) i=1; |
||
1255 | setenv("ins_anim_frames",int2str(i),1); |
||
1256 | setvar("ins_anim_frames",""); |
||
1257 | if(i>1) {setvar("ins_animation","yes");animated_ins=1;} |
||
1258 | else setvar("ins_animation","no"); |
||
1259 | /* delay of animation */ |
||
1260 | pp=getvar("ins_anim_delay"); |
||
1261 | if(pp!=NULL) d=evalue(pp); else d=0; |
||
1262 | if(d>=10) d=10; if(d<0) d=0; |
||
1263 | setenv("ins_anim_delay",int2str(d*100),1); |
||
1264 | } |
||
1265 | |||
1266 | /* Insert dynamic 2d plot */ |
||
1267 | void exec_insplot(char *p) |
||
1268 | { |
||
1269 | char *fmt; |
||
1270 | if(robot_access) { |
||
1271 | *p=0; return; |
||
1272 | } |
||
1273 | fmt=getvar("ins_format"); if(fmt==NULL || *fmt==0) fmt=DEFAULT_INS_FORMAT; |
||
1274 | prepare_insplot_parm(p); setenv("insplot_method","2D",1); |
||
1275 | _exec_ins(p,insplot_processor,fmt); |
||
1276 | wrapexec=1; |
||
1277 | /* call_ssh("mv %s/insplot_cmd %s 2>/dev/null",tmp_dir,s2_prefix); */ |
||
1278 | unsetenv("multiplot"); setvar("insplot_split",""); |
||
1279 | } |
||
1280 | |||
1281 | /* Insert dynamic 3d plot */ |
||
1282 | void exec_insplot3d(char *p) |
||
1283 | { |
||
1284 | char *fmt; |
||
1285 | if(robot_access) { |
||
1286 | *p=0; return; |
||
1287 | } |
||
1288 | fmt=getvar("ins_format"); if(fmt==NULL || *fmt==0) fmt=DEFAULT_INS_FORMAT; |
||
1289 | prepare_insplot_parm(p); setenv("insplot_method","3D",1); |
||
1290 | _exec_ins(p,insplot_processor,fmt); |
||
1291 | wrapexec=1; |
||
1292 | /* call_ssh("mv %s/insplot_cmd %s 2>/dev/null",tmp_dir,s2_prefix); */ |
||
1293 | unsetenv("multiplot");setvar("insplot_split",""); |
||
1294 | } |
||
1295 | |||
1296 | /* Insert dynamic gif draw. The parm preparation is specific to fly. */ |
||
1297 | void exec_insdraw(char *p) |
||
1298 | { |
||
1299 | char *pp, *fmt; |
||
1300 | int i; |
||
1301 | double d; |
||
1302 | |||
1303 | if(robot_access) { |
||
1304 | *p=0; return; |
||
1305 | } |
||
1306 | /* calc_tolower(p); */ |
||
1307 | fmt=getvar("ins_format"); if(fmt==NULL || *fmt==0) fmt=DEFAULT_INS_FORMAT; |
||
1308 | while((pp=wordchr(p,"output"))!=NULL) memmove(pp,"zqkwfx",6); |
||
1309 | /* frames of animation */ |
||
1310 | pp=getvar("ins_anim_frames"); |
||
1311 | if(pp!=NULL) i=evalue(pp); else i=1; |
||
1312 | if(i>=ANIM_LIMIT) i=ANIM_LIMIT-1; if(i<1) i=1; |
||
1313 | if(i>1 && varchr(p,"s")==NULL && varchr(p,"animstep")==NULL |
||
1314 | && varchr(p,"step")==NULL) i=1; |
||
1315 | setenv("ins_anim_frames",int2str(i),1); |
||
1316 | setvar("ins_anim_frames",""); |
||
1317 | if(i>1) {setvar("ins_animation","yes");animated_ins=1;} |
||
1318 | else setvar("ins_animation","no"); |
||
1319 | /* delay of animation */ |
||
1320 | pp=getvar("ins_anim_delay"); |
||
1321 | if(pp!=NULL) d=evalue(pp); else d=0; |
||
1322 | if(d>=10) d=10; if(d<0) d=0; |
||
1323 | setenv("ins_anim_delay",int2str(d*100),1); |
||
1324 | pp=getvar("insdraw_filebase"); |
||
1325 | if(pp!=NULL && strstr(pp,parent_dir_string)!=NULL) |
||
1326 | setvar("insdraw_filebase",""); |
||
1327 | _exec_ins(p,insdraw_processor,fmt); |
||
1328 | } |
||
1329 | |||
1330 | void exec_increase(char *p) |
||
1331 | { |
||
1332 | char *p1, *p2; |
||
1333 | p1=find_word_start(p); p2=find_word_end(p1); |
||
1334 | if(p2<=p1) { |
||
1335 | *p=0; return; |
||
1336 | } |
||
1337 | *p2=0;p2=getvar(p1); |
||
1338 | if(p2==NULL) p2=""; |
||
1339 | setvar(p1,int2str(atoi(p2)+1)); *p=0; |
||
1340 | } |
||
1341 | |||
1342 | /* bound a variable */ |
||
1343 | void exec_bound(char *p) |
||
1344 | { |
||
1345 | char *p1, *p2, *p3; |
||
1346 | int doub,i,bcnt,defaulted; |
||
1347 | double d1,d2,dd,val; |
||
1348 | char nbuf[MAX_LINELEN+1],lbuf[MAX_LINELEN+1],dbuf[MAX_LINELEN+1]; |
||
1349 | char vbuf[MAX_LINELEN+1]; |
||
1350 | char *blist[2048]; |
||
1351 | |||
1352 | p1=find_word_start(p); p2=find_word_end(p1); |
||
1353 | if(*p2==0) { |
||
1354 | syntax: module_error("syntax_error"); |
||
1355 | } |
||
1356 | *p2=0; strcpy(nbuf,p1);substit(nbuf); p1=find_word_start(p2+1); |
||
1357 | p2=getvar(nbuf);if(p2==NULL) p2=""; |
||
1358 | mystrncpy(vbuf,find_word_start(p2),sizeof(vbuf)); |
||
1359 | strip_trailing_spaces(vbuf); |
||
1360 | p2=find_word_end(p1); if(*p2==0) goto syntax; |
||
1361 | *p2=0;p2++; |
||
1362 | p3=wordchr(p2,"default"); |
||
1363 | if(p3!=NULL) { |
||
1364 | *p3=0; defaulted=1; |
||
1365 | p3=find_word_start(p3+strlen("default")); |
||
1366 | strcpy(dbuf,p3); substit(dbuf); |
||
1367 | } |
||
1368 | else defaulted=0; |
||
1369 | if(strcmp(p1,"between")==0) { |
||
1370 | p1=find_word_start(p2); |
||
1371 | i=strlen("integer"); |
||
1372 | if(strncmp(p1,"integer",i)==0 && |
||
1373 | (isspace(*(p1+i)) || (*(p1+i)=='s' && isspace(*(p1+i+1))))) { |
||
1374 | doub=0; p1=find_word_start(find_word_end(p1)); |
||
1375 | val=rint(evalue(vbuf)); |
||
1376 | if(vbuf[0]) float2str(val,vbuf); |
||
1377 | } |
||
1378 | else { |
||
1379 | doub=1;val=evalue(vbuf); |
||
1380 | } |
||
1381 | p2=wordchr(p1,"and"); p3=p2+strlen("and"); |
||
1382 | if(p2==NULL) { |
||
1383 | p2=strchr(p1,','); p3=p2+1; |
||
1384 | } |
||
1385 | if(p2==NULL) goto syntax; |
||
1386 | *p2=0;p2=find_word_start(p3); |
||
1387 | if(*p1==0 || *p2==0) goto syntax; |
||
1388 | d1=evalue(p1);d2=evalue(p2); |
||
1389 | if(!finite(d1) || !finite(d2) || |
||
1390 | abs(d1)>(double)(1E10) || abs(d2)>(double)(1E10)) goto syntax; |
||
1391 | if(d1>d2) { |
||
1392 | dd=d1;d1=d2;d2=dd; |
||
1393 | } |
||
1394 | if(vbuf[0] && val<=d2 && val>=d1) { |
||
1395 | if(!doub) setvar(nbuf,vbuf); |
||
1396 | *p=0; return; |
||
1397 | } |
||
1398 | if(defaulted) strcpy(p,dbuf); |
||
1399 | else { |
||
1400 | if(!doub) { |
||
1401 | d1=ceil(d1);d2=floor(d2); |
||
1402 | } |
||
1403 | if(vbuf[0]==0 || val<d1) val=d1; |
||
1404 | else val=d2; |
||
1405 | float2str(val,p); |
||
1406 | } |
||
1407 | setvar(nbuf,p); *p=0; return; |
||
1408 | } |
||
1409 | else { |
||
1410 | if(strcmp(p1,"within")==0 || strcmp(p1,"among")==0) { |
||
1411 | strcpy(lbuf,p2);substit(lbuf); |
||
1412 | bcnt=cutitems(lbuf,blist,2048); |
||
1413 | if(bcnt<=0) { |
||
1414 | *p=0; return; |
||
1415 | } |
||
1416 | for(i=0;i<bcnt;i++) { |
||
1417 | if(strcmp(blist[i],vbuf)==0) { |
||
1418 | *p=0; return; |
||
1419 | } |
||
1420 | } |
||
1421 | if(defaulted) strcpy(p,dbuf); else strcpy(p,blist[0]); |
||
1422 | setvar(nbuf,p); *p=0; |
||
1423 | return; |
||
1424 | } |
||
1425 | else goto syntax; |
||
1426 | } |
||
1427 | } |
||
1428 | |||
1429 | /* detrust the module. */ |
||
1430 | void exec_detrust(char *p) |
||
1431 | { untrust|=1; *p=0; } |
||
1432 | |||
1433 | void exec_warn(char *p) |
||
1434 | { |
||
1435 | char *p1,*p2; |
||
1436 | char buf[MAX_FNAME+1]; |
||
1437 | WORKING_FILE save; |
||
1438 | |||
1439 | if(!outputing) goto end; |
||
1440 | p1=find_word_start(p);p2=find_word_end(p1); |
||
1441 | if(p2<=p1) goto end; |
||
1442 | *p2=0; |
||
1443 | snprintf(buf,sizeof(buf),"wims_warn_%s",p1); |
||
1444 | p2=getvar(buf); |
||
1445 | if(p2==NULL || *p2==0) goto end; |
||
1446 | p2=getvar("module_language");if(p2==NULL) p2="en"; |
||
1447 | mkfname(buf,"msg/warn_%s.phtml.%s",p1,p2); |
||
1448 | memmove(&save,&m_file,sizeof(WORKING_FILE)); |
||
1449 | if(open_working_file(&m_file,buf)==0) phtml_put(NULL,0); |
||
1450 | memmove(&m_file,&save,sizeof(WORKING_FILE)); |
||
1451 | end: |
||
1452 | *p=0; return; |
||
1453 | } |
||
1454 | |||
1455 | /* write an error message. */ |
||
1456 | void exec_msg(char *p) |
||
1457 | { |
||
1458 | char *p1,*p2, buf[64], *l; |
||
1459 | secure_exec(); |
||
1460 | p1=find_word_start(p); p2=find_word_end(p1); |
||
1461 | if(*p2) { |
||
1462 | *p2=0; p2=find_word_start(p2+1); |
||
1463 | } |
||
1464 | force_setvar("wims_error",p1); force_setvar("wims_error_parm",p2); |
||
1465 | l=getvar("module_language"); |
||
1466 | if(l!=NULL && strlen(l)==2) { |
||
1467 | snprintf(buf,sizeof(buf),"msg.phtml.%s",l); |
||
1468 | phtml_put_base(buf,0); |
||
1469 | } |
||
1470 | *p=0; |
||
1471 | } |
||
1472 | |||
1473 | struct { |
||
1474 | char *name; |
||
1475 | int (*routine) (char *p, char *list[], int max); |
||
1476 | } distr_cmd[]={ |
||
1477 | {"char", NULL}, |
||
1478 | {"charof", NULL}, |
||
1479 | {"chars", NULL}, |
||
1480 | {"charsof", NULL}, |
||
1481 | {"item", cutitems}, |
||
1482 | {"itemof", cutitems}, |
||
1483 | {"items", cutitems}, |
||
1484 | {"itemsof", cutitems}, |
||
1485 | {"line", cutlines}, |
||
1486 | {"lineof", cutlines}, |
||
1487 | {"lines", cutlines}, |
||
1488 | {"linesof", cutlines}, |
||
1489 | {"list", cutitems}, |
||
1490 | {"word", cutwords}, |
||
1491 | {"wordof", cutwords}, |
||
1492 | {"words", cutwords}, |
||
1493 | {"wordsof", cutwords} |
||
1494 | }; |
||
1495 | |||
1496 | #define distr_cmd_no (sizeof(distr_cmd)/sizeof(distr_cmd[0])) |
||
1497 | |||
1498 | /* distribute a number of lines, items, etc. into a list of vars. */ |
||
1499 | void exec_distribute(char *p) |
||
1500 | { |
||
1501 | int i,k,n; |
||
1502 | char *p1, *p2; |
||
1503 | char bf1[MAX_LINELEN+1],bf2[MAX_LINELEN+1]; |
||
1504 | char *names[4096],*vals[4096]; |
||
1505 | p1=find_word_start(p); p2=find_word_end(p1); |
||
1506 | if(p2<=p1 || *p2==0) module_error("syntax_error"); |
||
1507 | *p2++=0; |
||
1508 | i=search_list(distr_cmd,distr_cmd_no,sizeof(distr_cmd[0]),p1); |
||
1509 | if(i<0) module_error("syntax_error"); |
||
1510 | p2=find_word_start(p2); p1=wordchr(p2,"into"); |
||
1511 | if(p1==NULL) module_error("syntax_error"); |
||
1512 | *p1=0;mystrncpy(bf1,p2,sizeof(bf1)); |
||
1513 | p1=find_word_start(p1+strlen("into")); |
||
1514 | mystrncpy(bf2,p1,sizeof(bf2)); |
||
1515 | substit(bf1);substit(bf2); |
||
1516 | strip_trailing_spaces(bf1); |
||
1517 | items2words(bf2); n=cutwords(bf2,names,4096); |
||
1518 | if(distr_cmd[i].routine!=NULL) { |
||
1519 | k=distr_cmd[i].routine(bf1,vals,n); |
||
1520 | for(i=0;i<k;i++) setvar(names[i],vals[i]); |
||
1521 | for(;i<n;i++) setvar(names[i],""); |
||
1522 | } |
||
1523 | else { |
||
1524 | char buf[2]; |
||
1525 | buf[1]=0; |
||
1526 | for(p1=bf1,i=0;i<n;i++) { |
||
1527 | buf[0]=*p1; if(*p1) p1++; |
||
1528 | setvar(names[i],buf); |
||
1529 | } |
||
1530 | } |
||
1531 | } |
||
1532 | |||
1533 | /* reset variables */ |
||
1534 | void exec_reset(char *p) |
||
1535 | { |
||
1536 | char *p1, *p2; |
||
1537 | |||
1538 | items2words(p); |
||
1539 | for(p1=find_word_start(p); *p1; p1=find_word_start(p2)) { |
||
1540 | p2=find_word_end(p1); if(*p2) *p2++=0; |
||
1541 | setvar(p1,""); |
||
1542 | } |
||
1543 | } |
||
1544 | |||
1545 | /* exchange the values of two variables */ |
||
1546 | void exec_exchange(char *p) |
||
1547 | { |
||
1548 | char buf[MAX_LINELEN+1],b1[MAX_LINELEN+1],b2[MAX_LINELEN+1]; |
||
1549 | char *p1,*p2,*pb; |
||
1550 | p1=wordchr(p,"and"); |
||
1551 | if(p1!=NULL) { |
||
1552 | *p1=0; p2=find_word_start(p1+strlen("and")); |
||
1553 | } |
||
1554 | else { |
||
1555 | p1=strchr(p,','); |
||
1556 | if(p1==NULL) module_error("syntax_error"); |
||
1557 | *p1=0; p2=find_word_start(p1+1); |
||
1558 | } |
||
1559 | p1=find_word_start(p); |
||
1560 | mystrncpy(b1,p1,sizeof(b1)); substit(b1); *find_word_end(b1)=0; |
||
1561 | mystrncpy(b2,p2,sizeof(b2)); substit(b2); *find_word_end(b2)=0; |
||
1562 | if(*b1==0 || *b2==0) module_error("syntax_error"); |
||
1563 | pb=getvar(b1);if(pb==NULL) pb=""; |
||
1564 | mystrncpy(buf,pb,sizeof(buf)); |
||
1565 | pb=getvar(b2);if(pb==NULL) pb=""; |
||
1566 | setvar(b1,pb); setvar(b2,buf); |
||
1567 | } |
||
1568 | |||
1569 | /* Send a mail */ |
||
1570 | void exec_mailto(char *p) |
||
1571 | { |
||
1572 | char *p1,*p2,*pp; |
||
1573 | |||
1574 | if(!trusted_module() || is_class_module) return; |
||
1575 | p1=strchr(p,'\n'); if(p1==NULL) return; |
||
1576 | *p1++=0; p=find_word_start(p); |
||
1577 | if(*p==0) return; |
||
1578 | p2=strchr(p1,'\n'); if(p2==NULL) return; |
||
1579 | *p2++=0; |
||
1580 | for(pp=p1;*pp;pp++) if(*pp=='"' || *pp=='\n') *pp=' '; |
||
1581 | accessfile(p2,"w","%s/mail.body",tmp_dir); |
||
1582 | wrapexec=1; |
||
1583 | call_sh("mail %s -s \" %s \" %s <%s/mail.body; chmod og-rwx %s/mail.body", |
||
1584 | mail_opt, p1,p,tmp_dir,tmp_dir); |
||
1585 | mail_log(p); |
||
1586 | *p=0; |
||
1587 | } |
||
1588 | |||
1589 | /* Generates a user error. Internal and undocumented. */ |
||
1590 | void exec_usererror(char *p) |
||
1591 | { |
||
1592 | if(trusted_module()) user_error(p); |
||
1593 | } |
||
1594 | |||
1595 | /* stop output. */ |
||
1596 | void exec_directout(char *p) |
||
1597 | { |
||
1598 | if(outputing || !trusted_module()) return; |
||
1599 | printf("%s",p); |
||
1600 | noout=1; |
||
1601 | } |
||
1602 | |||
1603 | enum { |
||
1604 | EXEC_IF, EXEC_JUMP, EXEC_ELSE, EXEC_ENDIF, EXEC_EXEC, |
||
1605 | EXEC_WHILE, EXEC_ENDWHILE, |
||
1606 | EXEC_FOR, EXEC_VAR, EXEC_DEBUG, EXEC_DAEMON, |
||
1607 | EXEC_SET, EXEC_DEFAULT, EXEC_COMMENT, EXEC_READ, EXEC_HREF, |
||
1608 | EXEC_INS, EXEC_STRING, EXEC_PEDIA, EXEC_DIR, |
||
1609 | EXEC_TRUST, EXEC_WARN, EXEC_ERROR, EXEC_SQL, EXEC_SCORE, |
||
1610 | EXEC_MAIL, EXEC_OTHER |
||
1611 | } EXEC_TYPES; |
||
1612 | #define EXEC_SUBST 0x1000 |
||
1613 | #define EXEC_USECALC 0x2000 |
||
1614 | #define EXEC_PROCTOO 0x4000 |
||
1615 | MYFUNCTION exec_routine[]={ |
||
1616 | {"!", EXEC_COMMENT, exec_comment}, |
||
1617 | {"TeXmath", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,texmath}, |
||
1618 | {"add", EXEC_STRING|EXEC_USECALC,calc_sum}, |
||
1619 | {"advance", EXEC_VAR|EXEC_SUBST, exec_increase}, |
||
1620 | {"append", EXEC_STRING|EXEC_USECALC,calc_append}, |
||
1621 | {"appendfile", EXEC_DIR|EXEC_SUBST, fileappend}, |
||
1622 | {"bound", EXEC_STRING, exec_bound}, |
||
1623 | {"break", EXEC_FOR, exec_break}, |
||
1624 | {"call", EXEC_EXEC|EXEC_SUBST|EXEC_PROCTOO|EXEC_USECALC, calc_exec}, |
||
1625 | {"changeto", EXEC_READ|EXEC_SUBST, exec_changeto}, |
||
1626 | {"char", EXEC_STRING|EXEC_USECALC,calc_charof}, |
||
1627 | {"chars", EXEC_STRING|EXEC_USECALC,calc_charof}, |
||
1628 | {"checkhost", EXEC_STRING|EXEC_USECALC|EXEC_SUBST,calc_checkhost}, |
||
1629 | {"column", EXEC_STRING|EXEC_USECALC,calc_columnof}, |
||
1630 | {"columns", EXEC_STRING|EXEC_USECALC,calc_columnof}, |
||
1631 | {"comment", EXEC_COMMENT, exec_comment}, |
||
1632 | {"daemon", EXEC_DAEMON|EXEC_USECALC|EXEC_SUBST,calc_daemon}, |
||
1633 | {"date", EXEC_STRING|EXEC_USECALC|EXEC_SUBST,calc_date}, |
||
1634 | {"deaccent", EXEC_STRING|EXEC_USECALC|EXEC_SUBST,deaccent}, |
||
1635 | {"debug", EXEC_DEBUG, calc_debug}, |
||
1636 | {"declosing", EXEC_STRING|EXEC_USECALC|EXEC_SUBST,calc_declosing}, |
||
1637 | {"def", EXEC_SET, exec_set}, |
||
1638 | {"default", EXEC_SET, exec_default}, |
||
1639 | {"define", EXEC_SET, exec_set}, |
||
1640 | {"definitionof", EXEC_SCORE|EXEC_USECALC,calc_defof}, |
||
1641 | {"defof", EXEC_SCORE|EXEC_USECALC,calc_defof}, |
||
1642 | {"defread", EXEC_READ|EXEC_SUBST, exec_defread}, |
||
1643 | {"detag", EXEC_STRING|EXEC_USECALC|EXEC_SUBST,calc_detag}, |
||
1644 | {"detrust", EXEC_TRUST, exec_detrust}, |
||
1645 | /* {"dictionary", EXEC_STRING|EXEC_USECALC,calc_dictionary}, */ |
||
1646 | {"dir", EXEC_DIR|EXEC_SUBST|EXEC_USECALC,calc_listfile}, |
||
1647 | {"distribute", EXEC_STRING, exec_distribute}, |
||
1648 | {"distrust", EXEC_TRUST, exec_detrust}, |
||
1649 | {"else", EXEC_ELSE, exec_else}, |
||
1650 | {"embraced", EXEC_STRING|EXEC_USECALC,calc_embraced}, |
||
1651 | {"encyclo", EXEC_PEDIA|EXEC_SUBST|EXEC_USECALC,pedia}, |
||
1652 | {"encyclopedia", EXEC_PEDIA|EXEC_SUBST|EXEC_USECALC,pedia}, |
||
1653 | {"endif", EXEC_ENDIF, exec_endif}, |
||
1654 | {"endwhile", EXEC_ENDWHILE, exec_endwhile}, |
||
1655 | {"evalsubst", EXEC_STRING|EXEC_USECALC,calc_evalsubst}, |
||
1656 | {"evalsubstit", EXEC_STRING|EXEC_USECALC,calc_evalsubst}, |
||
1657 | {"evalsubstitute",EXEC_STRING|EXEC_USECALC,calc_evalsubst}, |
||
1658 | {"evaluesubst", EXEC_STRING|EXEC_USECALC,calc_evalsubst}, |
||
1659 | {"evaluesubstit", EXEC_STRING|EXEC_USECALC,calc_evalsubst}, |
||
1660 | {"evaluesubstitute",EXEC_STRING|EXEC_USECALC,calc_evalsubst}, |
||
1661 | {"examscore", EXEC_SCORE|EXEC_SUBST|EXEC_USECALC,calc_examscore}, |
||
1662 | {"exchange", EXEC_STRING, exec_exchange}, |
||
1663 | {"exec", EXEC_EXEC|EXEC_SUBST|EXEC_PROCTOO|EXEC_USECALC, calc_exec}, |
||
1664 | {"execute", EXEC_EXEC|EXEC_SUBST|EXEC_PROCTOO|EXEC_USECALC, calc_exec}, |
||
1665 | {"exit", EXEC_JUMP, exec_exit}, |
||
1666 | {"fileappend", EXEC_DIR|EXEC_SUBST, fileappend}, |
||
1667 | {"filelist", EXEC_DIR|EXEC_SUBST|EXEC_USECALC,calc_listfile}, |
||
1668 | {"fileout", EXEC_HREF|EXEC_SUBST, exec_getfile}, |
||
1669 | {"filewrite", EXEC_DIR|EXEC_SUBST, filewrite}, |
||
1670 | {"for", EXEC_FOR, exec_for}, |
||
1671 | {"form", EXEC_HREF|EXEC_SUBST, exec_form}, |
||
1672 | {"formbar", EXEC_HREF, exec_formbar}, |
||
1673 | {"formcheckbox", EXEC_HREF, exec_formcheckbox}, |
||
1674 | {"formradio", EXEC_HREF, exec_formradio}, |
||
1675 | {"formradiobar", EXEC_HREF, exec_formbar}, |
||
1676 | {"formselect", EXEC_HREF, exec_formselect}, |
||
1677 | {"getdef", EXEC_SCORE|EXEC_USECALC,calc_defof}, |
||
1678 | {"getfile", EXEC_HREF|EXEC_SUBST, exec_getfile}, |
||
1679 | {"getscore", EXEC_SCORE|EXEC_SUBST|EXEC_USECALC,calc_getscore}, |
||
1680 | {"getscoremean", EXEC_SCORE|EXEC_SUBST|EXEC_USECALC,calc_getscoremean}, |
||
1681 | {"getscorepercent",EXEC_SCORE|EXEC_SUBST|EXEC_USECALC,calc_getscorepercent}, |
||
1682 | {"getscoreremain",EXEC_SCORE|EXEC_SUBST|EXEC_USECALC,calc_getscoreremain}, |
||
1683 | {"getscorerequire",EXEC_SCORE|EXEC_SUBST|EXEC_USECALC,calc_getscorerequire}, |
||
1684 | {"getscoreweight",EXEC_SCORE|EXEC_SUBST|EXEC_USECALC,calc_getscoreweight}, |
||
1685 | {"goto", EXEC_JUMP|EXEC_SUBST, exec_goto}, |
||
1686 | {"header", EXEC_HREF, exec_header}, |
||
1687 | {"headmenu", EXEC_HREF, exec_headmenu}, |
||
1688 | {"hex", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_hex}, |
||
1689 | {"homeref", EXEC_HREF, exec_homeref}, |
||
1690 | {"href", EXEC_HREF, exec_href}, |
||
1691 | {"htmlbar", EXEC_HREF, exec_formbar}, |
||
1692 | {"htmlcheckbox", EXEC_HREF, exec_formcheckbox}, |
||
1693 | {"htmlheader", EXEC_HREF, exec_header}, |
||
1694 | {"htmlmath", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,htmlmath}, |
||
1695 | {"htmlradio", EXEC_HREF, exec_formradio}, |
||
1696 | {"htmlradiobar", EXEC_HREF, exec_formbar}, |
||
1697 | {"htmlselect", EXEC_HREF, exec_formselect}, |
||
1698 | {"htmltail", EXEC_HREF, exec_tail}, |
||
1699 | {"htmltitle", EXEC_HREF, exec_title}, |
||
1700 | {"if", EXEC_IF, exec_if}, |
||
1701 | {"ifval", EXEC_IF, exec_ifval}, |
||
1702 | {"ifvalue", EXEC_IF, exec_ifval}, |
||
1703 | {"imgrename", EXEC_STRING|EXEC_USECALC|EXEC_SUBST,calc_imgrename}, |
||
1704 | {"include", EXEC_READ|EXEC_SUBST, exec_read}, |
||
1705 | {"increase", EXEC_VAR|EXEC_SUBST, exec_increase}, |
||
1706 | {"input", EXEC_READ|EXEC_SUBST, exec_read}, |
||
1707 | {"insdraw", EXEC_INS|EXEC_SUBST, exec_insdraw}, |
||
1708 | {"insmath", EXEC_INS, insmath}, |
||
1709 | {"inspaint", EXEC_INS|EXEC_SUBST, exec_insdraw}, |
||
1710 | {"insplot", EXEC_INS|EXEC_SUBST, exec_insplot}, |
||
1711 | {"insplot3d", EXEC_INS|EXEC_SUBST, exec_insplot3d}, |
||
1712 | {"instex", EXEC_INS, exec_instex}, |
||
1713 | {"instexst", EXEC_INS|EXEC_USECALC, calc_instexst}, |
||
1714 | {"instexstatic", EXEC_INS|EXEC_USECALC, calc_instexst}, |
||
1715 | {"item", EXEC_STRING|EXEC_USECALC,calc_itemof}, |
||
1716 | {"items", EXEC_STRING|EXEC_USECALC,calc_itemof}, |
||
1717 | {"items2lines", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,items2lines}, |
||
1718 | {"items2words", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,items2words}, |
||
1719 | {"itemstolines", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,items2lines}, |
||
1720 | {"itemstowords", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,items2words}, |
||
1721 | {"let", EXEC_SET, exec_set}, |
||
1722 | {"leveldata", EXEC_STRING|EXEC_USECALC,calc_leveldata}, |
||
1723 | {"levelpoints", EXEC_STRING|EXEC_USECALC,calc_leveldata}, |
||
1724 | {"line", EXEC_STRING|EXEC_USECALC,calc_lineof}, |
||
1725 | {"lines", EXEC_STRING|EXEC_USECALC,calc_lineof}, |
||
1726 | {"lines2items", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,lines2items}, |
||
1727 | {"lines2list", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,lines2items}, |
||
1728 | {"lines2words", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,lines2words}, |
||
1729 | {"linestoitems", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,lines2items}, |
||
1730 | {"linestolist", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,lines2items}, |
||
1731 | {"linestowords", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,lines2words}, |
||
1732 | {"list2lines", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,items2lines}, |
||
1733 | {"list2words", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,items2words}, |
||
1734 | {"listfile", EXEC_DIR|EXEC_SUBST|EXEC_USECALC,calc_listfile}, |
||
1735 | {"listfiles", EXEC_DIR|EXEC_SUBST|EXEC_USECALC,calc_listfile}, |
||
1736 | {"listintersect", EXEC_STRING|EXEC_USECALC,calc_listintersect}, |
||
1737 | {"listintersection", EXEC_STRING|EXEC_USECALC,calc_listintersect}, |
||
1738 | {"listtolines", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,items2lines}, |
||
1739 | {"listtowords", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,items2words}, |
||
1740 | {"listunion", EXEC_STRING|EXEC_USECALC,calc_listunion}, |
||
1741 | {"listuniq", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_listuniq}, |
||
1742 | {"listunique", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_listuniq}, |
||
1743 | {"listvar", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,mathvarlist}, |
||
1744 | {"lookup", EXEC_STRING|EXEC_USECALC, calc_lookup}, |
||
1745 | {"lower", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_tolower}, |
||
1746 | {"lowercase", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_tolower}, |
||
1747 | {"ls", EXEC_DIR|EXEC_SUBST|EXEC_USECALC,calc_listfile}, |
||
1748 | {"mailto", EXEC_MAIL|EXEC_SUBST, exec_mailto}, |
||
1749 | {"mailurl", EXEC_MAIL|EXEC_SUBST|EXEC_USECALC,calc_mailurl}, |
||
1750 | {"makelist", EXEC_STRING|EXEC_USECALC,calc_makelist}, |
||
1751 | {"mathsubst", EXEC_STRING|EXEC_USECALC,calc_mathsubst}, |
||
1752 | {"mathsubstit", EXEC_STRING|EXEC_USECALC,calc_mathsubst}, |
||
1753 | {"mathsubstitute",EXEC_STRING|EXEC_USECALC,calc_mathsubst}, |
||
1754 | {"mexec", EXEC_EXEC|EXEC_SUBST, exec_mexec}, |
||
1755 | {"module", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_module}, |
||
1756 | {"msg", EXEC_EXEC|EXEC_SUBST ,exec_msg}, |
||
1757 | {"multiply", EXEC_STRING|EXEC_USECALC,calc_product}, |
||
1758 | {"next", EXEC_FOR, exec_next}, |
||
1759 | {"nocache", EXEC_READ, exec_nocache}, |
||
1760 | {"non_empty", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_nonempty}, |
||
1761 | {"nonempty", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_nonempty}, |
||
1762 | {"nospace", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,nospace}, |
||
1763 | {"outfile", EXEC_HREF|EXEC_SUBST, exec_getfile}, |
||
1764 | {"pedia", EXEC_PEDIA|EXEC_SUBST|EXEC_USECALC,pedia}, |
||
1765 | {"perl", EXEC_EXEC|EXEC_PROCTOO|EXEC_SUBST,exec_perl}, |
||
1766 | {"position", EXEC_STRING|EXEC_USECALC,calc_pos}, |
||
1767 | {"positionof", EXEC_STRING|EXEC_USECALC,calc_pos}, |
||
1768 | {"positions", EXEC_STRING|EXEC_USECALC,calc_pos}, |
||
1769 | {"prod", EXEC_STRING|EXEC_USECALC,calc_product}, |
||
1770 | {"product", EXEC_STRING|EXEC_USECALC,calc_product}, |
||
1771 | {"rawmath", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,rawmath}, |
||
1772 | {"rawmatrix", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,rawmatrix}, |
||
1773 | {"reaccent", EXEC_STRING|EXEC_USECALC|EXEC_SUBST,reaccent}, |
||
1774 | {"read", EXEC_READ|EXEC_SUBST, exec_read}, |
||
1775 | {"readdef", EXEC_READ|EXEC_SUBST, exec_defread}, |
||
1776 | {"readproc", EXEC_READ|EXEC_SUBST, exec_readproc}, |
||
1777 | {"record", EXEC_STRING|EXEC_USECALC,calc_recordof}, |
||
1778 | {"records", EXEC_STRING|EXEC_USECALC,calc_recordof}, |
||
1779 | {"recursion", EXEC_STRING|EXEC_USECALC,calc_recursion}, |
||
1780 | {"reinput", EXEC_STRING|EXEC_USECALC|EXEC_SUBST,calc_reinput}, |
||
1781 | {"rem", EXEC_COMMENT, exec_comment}, |
||
1782 | {"remark", EXEC_COMMENT, exec_comment}, |
||
1783 | {"replace", EXEC_STRING|EXEC_USECALC,calc_replace}, |
||
1784 | {"reset", EXEC_SET|EXEC_SUBST, exec_reset}, |
||
1785 | {"restart", EXEC_JUMP|EXEC_SUBST, exec_restart}, |
||
1786 | {"return", EXEC_JUMP, exec_exit}, |
||
1787 | {"robotrap", EXEC_HREF|EXEC_SUBST, exec_robottrap}, |
||
1788 | {"robottrap", EXEC_HREF|EXEC_SUBST, exec_robottrap}, |
||
1789 | {"rootof", EXEC_STRING|EXEC_USECALC,calc_solve}, |
||
1790 | {"row", EXEC_STRING|EXEC_USECALC,calc_rowof}, |
||
1791 | {"rows", EXEC_STRING|EXEC_USECALC,calc_rowof}, |
||
1792 | {"rows2lines", EXEC_STRING|EXEC_USECALC|EXEC_SUBST,calc_rows2lines}, |
||
1793 | {"run", EXEC_EXEC|EXEC_SUBST|EXEC_PROCTOO|EXEC_USECALC, calc_exec}, |
||
1794 | {"select", EXEC_STRING|EXEC_USECALC,calc_select}, |
||
1795 | {"set", EXEC_SET, exec_set}, |
||
1796 | {"setdef", EXEC_OTHER, exec_setdef}, |
||
1797 | {"sh", EXEC_EXEC|EXEC_PROCTOO|EXEC_SUBST,exec_sh}, |
||
1798 | {"shortout", EXEC_JUMP|EXEC_SUBST, exec_directout}, |
||
1799 | {"singlespace", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,singlespace}, |
||
1800 | {"solve", EXEC_STRING|EXEC_USECALC,calc_solve}, |
||
1801 | {"sort", EXEC_STRING|EXEC_USECALC, calc_sort}, |
||
1802 | /* {"sql", EXEC_SQL|EXEC_SUBST|EXEC_USECALC, calc_sql}, */ |
||
1803 | {"staticinstex", EXEC_INS|EXEC_USECALC, calc_instexst}, |
||
1804 | {"stinstex", EXEC_INS|EXEC_USECALC, calc_instexst}, |
||
1805 | {"sum", EXEC_STRING|EXEC_USECALC,calc_sum}, |
||
1806 | {"system", EXEC_EXEC|EXEC_PROCTOO|EXEC_SUBST,exec_sh}, |
||
1807 | {"tail", EXEC_HREF, exec_tail}, |
||
1808 | {"test", EXEC_DEBUG, exec_test}, |
||
1809 | {"texmath", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,texmath}, |
||
1810 | {"text", EXEC_STRING|EXEC_USECALC,text}, |
||
1811 | {"title", EXEC_HREF, exec_title}, |
||
1812 | {"tohex", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_hex}, |
||
1813 | {"tolower", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_tolower}, |
||
1814 | {"toupper", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_toupper}, |
||
1815 | {"translate", EXEC_STRING|EXEC_USECALC,calc_translate}, |
||
1816 | {"trim", EXEC_STRING|EXEC_USECALC,calc_trim}, |
||
1817 | {"upper", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_toupper}, |
||
1818 | {"uppercase", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,calc_toupper}, |
||
1819 | {"usererror", EXEC_WARN|EXEC_SUBST, exec_usererror}, |
||
1820 | {"values", EXEC_STRING|EXEC_USECALC,calc_values}, |
||
1821 | {"varlist", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,mathvarlist}, |
||
1822 | {"warn", EXEC_WARN|EXEC_SUBST, exec_warn}, |
||
1823 | {"warning", EXEC_WARN|EXEC_SUBST, exec_warn}, |
||
1824 | {"while", EXEC_WHILE, exec_while}, |
||
1825 | {"whileval", EXEC_WHILE, exec_whileval}, |
||
1826 | {"whilevalue", EXEC_WHILE, exec_whileval}, |
||
1827 | {"wimsheader", EXEC_HREF, exec_header}, |
||
1828 | {"wimsref", EXEC_HREF, exec_homeref}, |
||
1829 | {"wimstail", EXEC_HREF, exec_tail}, |
||
1830 | {"wimstitle", EXEC_HREF, exec_title}, |
||
1831 | {"word", EXEC_STRING|EXEC_USECALC,calc_wordof}, |
||
1832 | {"words", EXEC_STRING|EXEC_USECALC,calc_wordof}, |
||
1833 | {"words2items", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,words2items}, |
||
1834 | {"words2lines", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,words2lines}, |
||
1835 | {"words2list", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,words2items}, |
||
1836 | {"wordstoitems", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,words2items}, |
||
1837 | {"wordstolines", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,words2lines}, |
||
1838 | {"wordstolist", EXEC_STRING|EXEC_SUBST|EXEC_USECALC,words2items}, |
||
1839 | {"writefile", EXEC_DIR|EXEC_SUBST, filewrite}, |
||
1840 | }; |
||
1841 | #define EXEC_FN_NO (sizeof(exec_routine)/sizeof(exec_routine[0])) |
||
1842 | |||
1843 | /* internal: to skip the content of a false if/while. */ |
||
1844 | static void _skip_contents(int isif) |
||
1845 | { |
||
1846 | char buf[MAX_NAMELEN+8], *p1; |
||
1847 | int i,j,loop; |
||
1848 | loop=0; |
||
1849 | while(m_file.linepointer<m_file.linecnt) { |
||
1850 | j=m_file.linepointer; |
||
1851 | if((m_file.lines[j].isstart&2)==0) { |
||
1852 | m_file.linepointer++; continue; |
||
1853 | } |
||
1854 | i=m_file.lines[j].execcode; if(i<0) { |
||
1855 | if(wgetline(buf,MAX_NAMELEN+4,&m_file)==EOF) return; |
||
1856 | p1=buf+1; if(*p1!='i' && *p1!='e' && *p1!='w') continue; |
||
1857 | *find_word_end(p1)=0; |
||
1858 | i=search_list(exec_routine,EXEC_FN_NO,sizeof(exec_routine[0]),p1); |
||
1859 | if(i>=0) m_file.lines[j].execcode=i; |
||
1860 | } |
||
1861 | else m_file.linepointer++; |
||
1862 | if(i<0) continue; |
||
1863 | switch(exec_routine[i].tag & 0xffff) { |
||
1864 | case EXEC_WHILE: |
||
1865 | if(!isif) loop++; break; |
||
1866 | case EXEC_IF: |
||
1867 | if(isif) loop++; break; |
||
1868 | case EXEC_ELSE: { |
||
1869 | if(!isif) break; |
||
1870 | if(loop<=0) return; else break; |
||
1871 | } |
||
1872 | case EXEC_ENDIF: { |
||
1873 | if(!isif) break; |
||
1874 | if(loop>0) { |
||
1875 | loop--; break; |
||
1876 | } |
||
1877 | else return; |
||
1878 | } |
||
1879 | case EXEC_ENDWHILE: { |
||
1880 | if(isif) break; |
||
1881 | if(loop>0) { |
||
1882 | loop--; break; |
||
1883 | } |
||
1884 | else return; |
||
1885 | } |
||
1886 | default: break; |
||
1887 | } |
||
1888 | } |
||
1889 | } |
||
1890 | |||
1891 | /* Execute a command defined by !. Returns 0 if OK. */ |
||
1892 | void exec_main(char *p) |
||
1893 | { |
||
1894 | int i,j; |
||
1895 | char *pp; |
||
1896 | char tbuf2[MAX_LINELEN+1]; |
||
1897 | |||
1898 | pp=find_word_end(p); |
||
1899 | if(*pp!=0) { |
||
1900 | *(pp++)=0; pp=find_word_start(pp); |
||
1901 | } |
||
1902 | i=m_file.lines[m_file.l].execcode; |
||
1903 | if(i<0) { |
||
1904 | i=search_list(exec_routine,EXEC_FN_NO,sizeof(exec_routine[0]),p); |
||
1905 | m_file.lines[m_file.l].execcode=i; |
||
1906 | } |
||
1907 | if(i<0) { |
||
1908 | setvar(error_data_string,p); module_error("bad_cmd"); |
||
1909 | } |
||
1910 | /* called from !readdef, no right other than set; bail out */ |
||
1911 | execnt++; |
||
1912 | if((untrust&4)!=0 && (j=(exec_routine[i].tag&0xffff))!=EXEC_SET) { |
||
1913 | tbuf2[0]=0; exec_exit(tbuf2); |
||
1914 | } |
||
1915 | strcpy(tbuf2,pp); j=exec_routine[i].tag; |
||
1916 | if(j&EXEC_SUBST) substit(tbuf2); |
||
1917 | if(j&EXEC_USECALC) { |
||
1918 | if(!outputing && (j&EXEC_PROCTOO)==0) return; |
||
1919 | exec_routine[i].routine(tbuf2); if(outputing) output0(tbuf2); |
||
1920 | } |
||
1921 | else exec_routine[i].routine(tbuf2); |
||
1922 | return; |
||
1923 | } |
||
1924 |