Rev 14048 | Rev 15573 | 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 | |||
8155 | bpr | 18 | /* Web exerciser */ |
10 | reyssat | 19 | |
8178 | bpr | 20 | #include "wims.h" |
14873 | georgesk | 21 | enum Name_Modes NAME_MODES; |
22 | enum Ro_Names RO_NAMES; |
||
23 | enum _commands COMMANDS; |
||
24 | WORKING_FILE m_file, svar_file, mcache[MAX_MCACHE]; |
||
25 | struct VAR_DEF var_def[MAX_VAR_NUM]; |
||
26 | char examlogf[MAX_FNAME+1]; |
||
27 | char mpboundary[1024]; |
||
28 | char *stdinbuf; |
||
29 | struct user_variable user_variable[MAX_VAR_NUM]; |
||
30 | char available_lang[MAX_LANGUAGES][4]; |
||
8178 | bpr | 31 | |
8121 | bpr | 32 | struct { |
12263 | bpr | 33 | char *name; |
34 | char *font; |
||
8121 | bpr | 35 | } charname[]={ |
12263 | bpr | 36 | {"en","windows-1252"}, |
37 | {"fr","windows-1252"}, |
||
38 | {"es","windows-1252"}, |
||
39 | {"cn","gb2312"}, |
||
40 | {"de","windows-1252"}, |
||
41 | {"it","windows-1252"}, |
||
42 | {"nl","windows-1252"}, |
||
43 | {"si","iso-8859-2"}, |
||
44 | {"ar","iso-8859-6"}, |
||
45 | {"tw","big5"}, |
||
46 | {"pt","windows-1252"}, |
||
47 | {"ca","windows-1252"}, |
||
48 | {"pt","windows-1252"}, |
||
49 | {"ru","iso-8859-5"}, |
||
50 | {"ty","iso-8859-13"} |
||
8121 | bpr | 51 | }; |
52 | |||
53 | #define charname_no (sizeof(charname)/sizeof(charname[0])) |
||
54 | |||
8155 | bpr | 55 | /* left to right or right to left writing */ |
8121 | bpr | 56 | struct { |
12263 | bpr | 57 | char *name; |
58 | char *dirn; |
||
8121 | bpr | 59 | } dirnname[]={ |
12263 | bpr | 60 | {"en","ltr"}, |
61 | {"fr","ltr"}, |
||
62 | {"es","ltr"}, |
||
63 | {"cn","ltr"}, |
||
64 | {"de","ltr"}, |
||
65 | {"it","ltr"}, |
||
66 | {"nl","ltr"}, |
||
67 | {"si","ltr"}, |
||
68 | {"ar","rtl"}, |
||
69 | {"tw","ltr"}, |
||
70 | {"pt","ltr"}, |
||
71 | {"ca","ltr"}, |
||
72 | {"pt","ltr"}, |
||
73 | {"ru","ltr"}, |
||
74 | {"ty","ltr"} |
||
8121 | bpr | 75 | |
76 | }; |
||
77 | |||
78 | #define dirnname_no (sizeof(dirnname)/sizeof(dirnname[0])) |
||
79 | |||
80 | |||
10 | reyssat | 81 | #define evalue strevalue |
82 | char *robot_session="../tmp/robot"; |
||
83 | int robot_access=0,human_access=0; |
||
84 | int user_error_nolog=0; |
||
85 | char *good_agent[]={ |
||
12263 | bpr | 86 | "Mozilla","Netscape","Opera","WIMS", |
87 | "MSIE","Konqueror","Java" |
||
10 | reyssat | 88 | }; |
89 | #define good_agent_no (sizeof(good_agent)/sizeof(good_agent[0])) |
||
90 | |||
91 | char *bad_agent[]={ /* These are really bad agents: prohibited. */ |
||
12263 | bpr | 92 | "HTTrack","MemoWeb","Teleport","Offline","Wget","eCatch", |
93 | "Powermarks","EmailSiphon", "WebCopier" |
||
10 | reyssat | 94 | }; |
95 | #define bad_agent_no (sizeof(bad_agent)/sizeof(bad_agent[0])) |
||
96 | |||
97 | /* used for debugging */ |
||
98 | int debug=0; |
||
99 | |||
100 | char class_dir[MAX_FNAME+1]; /* directory name of this class */ |
||
101 | |||
8185 | bpr | 102 | struct user_variable user_variable[MAX_VAR_NUM]; |
10 | reyssat | 103 | int user_var_no; |
104 | |||
8185 | bpr | 105 | struct VAR_DEF var_def[MAX_VAR_NUM]; |
10 | reyssat | 106 | int defined_var_total; |
107 | |||
7673 | bpr | 108 | /* Destinated to module error messages */ |
10 | reyssat | 109 | WORKING_FILE m_file,svar_file,mcache[MAX_MCACHE]; |
110 | int mcachecnt; |
||
111 | |||
7673 | bpr | 112 | /* Limit for any data working files. */ |
10 | reyssat | 113 | int WORKFILE_LIMIT=2048*1024; |
114 | |||
7673 | bpr | 115 | /* whether the user has defined language */ |
10 | reyssat | 116 | int user_lang=0; |
117 | |||
7673 | bpr | 118 | /* for instex grouping */ |
10 | reyssat | 119 | int instex_cnt=0, getwimstexsize=1; |
120 | char instex_src[MAX_LINELEN+1], instex_fname[MAX_LINELEN+1]; |
||
121 | char *instex_processor="tex..gif"; |
||
122 | |||
7673 | bpr | 123 | /* Cookie management */ |
10 | reyssat | 124 | char cookiegot[256], cookieset[256], cookieheader[64]="WIMSUSER="; |
125 | |||
7673 | bpr | 126 | /* multipart boundary */ |
10 | reyssat | 127 | char mpboundary[1024]; |
128 | int deplen=0; /* length of deposit */ |
||
129 | |||
130 | int confset=0; /* set to 1 if setvar for config */ |
||
131 | |||
7673 | bpr | 132 | /* Operating mode: default, popup, raw, etc. */ |
8185 | bpr | 133 | |
10 | reyssat | 134 | int mode=mode_default; |
135 | |||
7673 | bpr | 136 | /* Switch; notice subroutines wherether we are outputing. */ |
10 | reyssat | 137 | int outputing; |
138 | |||
139 | char *home_module="home"; /* name of home module */ |
||
7673 | bpr | 140 | extern char **environ; /* table of environment variables */ |
10 | reyssat | 141 | int module_defined=0; |
142 | |||
143 | /* directory prefix buffers */ |
||
144 | char session_prefix[MAX_FNAME+1], s2_prefix[MAX_FNAME+1], module_prefix[MAX_FNAME+1]; |
||
145 | |||
146 | char *stdinbuf; |
||
7673 | bpr | 147 | int sesrandomtab[MAX_SESRANDOM]; /* session random values */ |
10 | reyssat | 148 | char multiexec_random[64]; |
149 | int executed_gotos; /* number of goto's executed. to check with GOTO_LIMIT. */ |
||
150 | int insert_no; /* number of instex, insplot, insPLOT. */ |
||
151 | int output_length; /* length of the output. */ |
||
7673 | bpr | 152 | int isexam=0; /* non-zero if request is exam */ |
153 | int simuxam=0; /* exam is simulation */ |
||
154 | int is_multiexec=0; /* for execredirected */ |
||
10 | reyssat | 155 | int multiexec_index; |
156 | int direct_datafile=0; |
||
157 | int exec_is_module=0; |
||
158 | /* root directory of modules */ |
||
159 | char *module_dir="modules"; |
||
160 | int new_session=0; /* =1 if new session created */ |
||
7673 | bpr | 161 | int good_httpd=0; /* Whether the http server is intelligent */ |
10 | reyssat | 162 | /* int internal_sql=0; */ /* for internal sql use */ |
163 | int direct_exec=0; /* calc routine is exected by exec if 1 */ |
||
164 | int print_precision=8; /* precision when printing real numbers */ |
||
165 | int session_serial; /* request serial for session control */ |
||
7673 | bpr | 166 | int form_access=0; /* identifies form access, for robot identification */ |
167 | int lastout_file=-1; /* file to hold last output */ |
||
168 | char *instex_style=""; /* "": text "$": math "$$": displaymath */ |
||
169 | int instex_usedynamic=0; /* always dynamic if 1 */ |
||
170 | int wrapexec=0; /* if set to 1, change uid (nobody) to euid (wims). |
||
171 | * if set to -1, change euid to uid when exec(). */ |
||
172 | int parm_restore=0; /* Restoring saved parameters? */ |
||
173 | int exec_wait=1; /* whether to wait for fork return */ |
||
174 | int execnt=0; /* count executions */ |
||
175 | int readnest; /* nested read count */ |
||
176 | int mfilecnt=0; /* count working files */ |
||
177 | int forceresume=0; /* force user to resume old request */ |
||
178 | int manageable=0; /* whether the connection may be site manager |
||
179 | * 0: no; 1: maybe; 2: sure */ |
||
180 | int ismhelp=0; /* 1 if session is in mhelp. */ |
||
181 | int getvar_len; /* length of the last-got variable. */ |
||
182 | int noout=0; /* if set to 1 then output is skipped */ |
||
183 | char tmp_dir[MAX_FNAME+1]; /* temporary directory */ |
||
184 | char *bin_dir="bin"; /* directory containing executable scripts and programs. */ |
||
185 | char cwdbuf[MAX_FNAME+1]; /* store current working directory */ |
||
186 | char var_hacking=0; /* Trying to hack a variable? */ |
||
10 | reyssat | 187 | char *tmp_debug="no"; |
11104 | bpr | 188 | char *tmp_debug_var=""; |
7673 | bpr | 189 | char ins_alt[MAX_LINELEN+1]; /* dynamic insertion alternative text */ |
190 | char *devel_modules="close"; /* whether to open devel modules */ |
||
191 | int isclassmodule=0; /* 1 if the module is class module */ |
||
192 | int isdevelmodule=0; /* development module? */ |
||
193 | int setcookie=0; /* 1 if need to set cookie */ |
||
194 | int killpid=0; /* pid of process to kill by alarm */ |
||
195 | char *mathalign_sup1, *mathalign_sup2; /* see mathalign_base */ |
||
196 | int substnest=0; /* nesting level of substit() */ |
||
10 | reyssat | 197 | int exodepOK=1; |
7673 | bpr | 198 | long int startmtime; /* start time in milliseconds */ |
199 | long int startmtime2; /* start time in microseconds */ |
||
200 | int backslash_insmath=0; /* \(...) substitution? */ |
||
201 | char examlogf[MAX_FNAME+1]; /* examlog file name */ |
||
202 | char examlogd[MAX_FNAME+1]; /* examlog file name */ |
||
203 | char exam_sheetexo[32]; /* sheet data of an exam */ |
||
10 | reyssat | 204 | char loadavg[64]; |
7673 | bpr | 205 | /* user file variable access control. */ |
10 | reyssat | 206 | char *var_readable, *var_writable, *var_nr, *var_nw, *var_pfx; |
207 | int hostcquota; |
||
7673 | bpr | 208 | int var_noexport; /* do not export variable */ |
10 | reyssat | 209 | |
7673 | bpr | 210 | char tmplbuf[MAX_LINELEN+1]; /* for temporary uses not thru subroutines. */ |
10 | reyssat | 211 | |
7673 | bpr | 212 | struct tm *now, Now; /* time of request */ |
10 | reyssat | 213 | time_t nowtime, limtime, limtimex; |
214 | char nowstr[32]; |
||
215 | |||
7673 | bpr | 216 | /* Resource limits. Capital names are reserved by system. */ |
217 | int rlimit_cpu=20; /* cpu time in seconds */ |
||
10 | reyssat | 218 | int rlimit_fsize=8388608;/* file size */ |
5222 | guerimand | 219 | int rlimit_as=614457600;/* virtual memory size */ |
14048 | guerimand | 220 | int rlimit_data=2004857600;/* data segment size; maxima requires a lot (must be lower than rlimit_as)*/ |
10 | reyssat | 221 | int rlimit_stack=2097152;/* stack size */ |
7673 | bpr | 222 | int rlimit_core=0; /* core dump size */ |
223 | int rlimit_rss=16777216; /* resident size */ |
||
224 | int rlimit_nproc=1024; /* number of processes */ |
||
225 | int rlimit_nofile=512; /* number of open files */ |
||
10 | reyssat | 226 | int rlimit_memlock=2097152;/* locked-in-memory address space */ |
227 | |||
228 | char *var_str; /* malloc'ed buffer to hold translated query_string */ |
||
229 | |||
7673 | bpr | 230 | /* buffer to hold module's variable definition file, malloc'ed. */ |
10 | reyssat | 231 | char *var_def_buf; |
232 | |||
8185 | bpr | 233 | /* job_identifier is even a reserved variable name */ |
10 | reyssat | 234 | char job_identifier[32]; |
235 | |||
8185 | bpr | 236 | /* site manager definition IPv4 IPv6*/ |
4648 | bpr | 237 | char *manager_site="127.0.0.1 ::1"; |
10 | reyssat | 238 | int manager_https=0; |
239 | |||
8185 | bpr | 240 | /* sheet and exercise information */ |
10 | reyssat | 241 | int wims_sheet=0,wims_exo=0; |
242 | |||
8185 | bpr | 243 | /* Form method: get or post */ |
10 | reyssat | 244 | char *default_form_method="post"; |
245 | |||
8185 | bpr | 246 | /* Je suis maintenant oblige de passer a l'anglais |
247 | * pour la langue de defaut. |
||
248 | */ |
||
10 | reyssat | 249 | char lang[16]="en"; |
250 | char available_lang[MAX_LANGUAGES][4]={"en","fr"}; |
||
251 | int available_lang_no=2; |
||
252 | char pre_language[4]=""; |
||
10051 | bpr | 253 | FILE *trace_file; |
11104 | bpr | 254 | int trace_indent=0; |
10 | reyssat | 255 | char *protocol="http"; /* http or https */ |
256 | |||
8185 | bpr | 257 | /* check for coordinate input. This will mean that |
258 | * the request is manual, but not robot. |
||
259 | */ |
||
10 | reyssat | 260 | int coord_input=0; |
261 | |||
8155 | bpr | 262 | /* These are readonly environment variable names |
263 | * special parm used for special cmds (getins, etc). |
||
264 | */ |
||
10 | reyssat | 265 | char *ro_name[]={ |
12271 | bpr | 266 | "cmd", |
12263 | bpr | 267 | "empty", |
12271 | bpr | 268 | "lang", |
269 | "module", |
||
270 | "session", |
||
12263 | bpr | 271 | "special_parm", |
272 | "special_parm2", |
||
273 | "special_parm3", |
||
274 | "special_parm4", |
||
275 | "useropts" , |
||
276 | "wims_session", |
||
277 | "wims_subsession", |
||
278 | "wims_window", |
||
279 | "worksheet" |
||
10 | reyssat | 280 | }; |
281 | |||
8185 | bpr | 282 | int RO_NAME_NO=(sizeof(ro_name)/sizeof(ro_name[0])); |
283 | |||
10 | reyssat | 284 | int cmd_type; |
285 | char *commands[]={ |
||
286 | "intro" , "new" , "renew" , "reply" , "config" , "hint" , "help" , |
||
287 | "resume", "next", "getins", "getframe", "getfile", "close", "ref" |
||
288 | }; |
||
289 | |||
8185 | bpr | 290 | int CMD_NO=(sizeof(commands)/sizeof(commands[0])); |
291 | |||
8155 | bpr | 292 | /* stat=0: saved variables |
293 | * all names starting with wims_priv_ are also internal. |
||
294 | */ |
||
8185 | bpr | 295 | struct internal_name internal_name[]={ |
12263 | bpr | 296 | {"accessright", 1}, /* right to access commercial resources */ |
297 | {"caller", 1}, /* caller session */ |
||
298 | {"check", 1}, /* for exam check use */ |
||
299 | {"class", 1}, |
||
300 | {"class_examlog", 1}, |
||
301 | {"class_exolog", 1}, |
||
302 | {"class_limit", 1}, |
||
303 | {"class_quota", 1}, |
||
304 | {"class_regpass", 1}, |
||
305 | {"class_user_limit", 1}, |
||
306 | {"classdir", 1}, |
||
307 | {"classname", 1}, |
||
308 | {"devel_modules", 1}, |
||
309 | {"developer", 1}, |
||
310 | {"doc_quota", 1}, |
||
311 | {"doc_regpass", 1}, |
||
312 | {"email", 1}, |
||
313 | {"exo", 0}, /* exercise number */ |
||
314 | {"exoption", 1}, /* exercise option */ |
||
12381 | bpr | 315 | {"exotrymax", 0}, |
12263 | bpr | 316 | {"firstname", 1}, |
317 | {"forum_limit", 1}, |
||
318 | {"home", 1}, |
||
319 | {"institutionname", 1}, |
||
320 | {"isexam", 0}, /* whether the sheet is an exam sheet */ |
||
321 | {"ismanager", 0}, |
||
322 | {"lastname", 1}, |
||
323 | {"mode", 0}, /* operating mode */ |
||
324 | {"module_start_time", 0}, |
||
325 | {"now", 1}, /* date and time, yyyymmdd.hh:mm:ss */ |
||
326 | {"nowseconds", 1}, /* date and time, seconds since EPOCH */ |
||
327 | {"nr", 1}, /* non-readable variables in user file, words */ |
||
328 | {"nw", 1}, /* non-writable variables in user file, words */ |
||
329 | {"otherclass", 1}, /* Remember other logins */ |
||
330 | {"participate", 1}, /* superclass definition */ |
||
331 | {"prefix", 1}, /* user file prefix */ |
||
332 | {"protocol", 0}, /* http protocol */ |
||
333 | {"rafale", 0}, /* rapidfire request information */ |
||
334 | {"readable", 1}, /* readable variables in user file, words */ |
||
335 | {"realuser", 1}, /* real user for supervisor in gateway */ |
||
336 | {"req_time", 0}, /* time of the request */ |
||
337 | {"sclassdir", 1}, |
||
338 | {"scorereg", 0}, /* score registration flag */ |
||
339 | {"seed", 0}, |
||
340 | {"seed_repeat",0}, |
||
341 | {"seed_score", 0}, |
||
12363 | bpr | 342 | {"seedcnt",0}, |
343 | {"seedlastcnt",0}, |
||
12263 | bpr | 344 | {"sequence", 0}, /* sequence number */ |
345 | {"sescookie", 1}, /* session cookie */ |
||
346 | {"sesdir", 1}, |
||
347 | {"session_serial", 0}, /* request serial in the session */ |
||
348 | {"session_start_time", 0}, |
||
349 | {"sheet", 0}, /* sheet number */ |
||
350 | {"sup_secure", 1}, /* secure level of supervisor */ |
||
351 | {"superclass", 1}, /* superclass code */ |
||
352 | {"superclass_quota", 1}, |
||
353 | {"supertype", 1}, /* superclass type */ |
||
354 | {"supervise", 1}, /* superclass definition */ |
||
355 | {"supervisor", 1}, /* real name of the supervisor */ |
||
356 | {"supervisormail",1}, /* email of supervisor */ |
||
357 | {"trustfile", 1}, /* trusted files in special adm modules */ |
||
358 | {"useropts", 1}, /* user options */ |
||
359 | {"writable", 1}, /* writable variables in user file, words */ |
||
10 | reyssat | 360 | }; |
8185 | bpr | 361 | int INTERNAL_NAME_NO=(sizeof(internal_name)/sizeof(internal_name[0])); |
10 | reyssat | 362 | |
363 | char *httpd_vars[]={ |
||
12263 | bpr | 364 | "HTTP_ACCEPT", |
365 | "HTTP_ACCEPT_CHARSET", |
||
366 | "HTTP_ACCEPT_LANGUAGE", |
||
367 | "HTTP_COOKIE", |
||
368 | "HTTP_HOST", |
||
369 | "HTTP_USER_AGENT", |
||
370 | "HTTP_X_REQUESTED_WITH", |
||
371 | "HTTPS", |
||
372 | "QUERY_STRING", |
||
373 | "REMOTE_HOST", |
||
374 | "REMOTE_ADDR", |
||
375 | "REMOTE_PORT", |
||
376 | "REQUEST_METHOD", |
||
377 | "SCRIPT_NAME", |
||
378 | "SERVER_NAME", |
||
379 | "SERVER_SOFTWARE", |
||
380 | "SERVER_PROTOCOL" |
||
10 | reyssat | 381 | }; |
382 | #define HTTPD_VAR_NO (sizeof(httpd_vars)/sizeof(httpd_vars[0])) |
||
383 | |||
8155 | bpr | 384 | /* security: these variables will not be visible to child processes */ |
10 | reyssat | 385 | char *unsetvars[]={ |
12263 | bpr | 386 | "DOCUMENT_ROOT","SERVER_SIGNATURE","SERVER_SOFTWARE", |
10 | reyssat | 387 | "UNIQUE_ID","HTTP_KEEP_ALIVE","SSL_SESSION_ID" |
388 | }; |
||
389 | #define unsetvarcnt (sizeof(unsetvars)/sizeof(unsetvars[0])) |
||
390 | |||
391 | int httpd_type=httpd_apache; |
||
392 | |||
7673 | bpr | 393 | char *remote_addr=""; /* storing for performance */ |
10 | reyssat | 394 | char *remote_host=""; |
395 | |||
396 | char ref_name[2048], ref_base[2048]; |
||
397 | |||
398 | void put_special_page(char *pname); |
||
399 | void useropts(void); |
||
400 | |||
7673 | bpr | 401 | /* Make certain httpd variables readable by modules */ |
10 | reyssat | 402 | void take_httpd_vars(void) |
403 | { |
||
12263 | bpr | 404 | int i; |
405 | char *p, buf[MAX_NAMELEN+1]; |
||
406 | var_noexport=1; |
||
407 | for(i=0;i<HTTPD_VAR_NO;i++) { |
||
408 | snprintf(buf,sizeof(buf),"httpd_%s",httpd_vars[i]); |
||
409 | if((p=getenv(httpd_vars[i]))!=NULL) setvar(buf,p); |
||
410 | } |
||
411 | var_noexport=0; |
||
7673 | bpr | 412 | |
12263 | bpr | 413 | for(i=0;i<unsetvarcnt;i++) unsetenv(unsetvars[i]); |
414 | /* IPv4 IPv6*/ |
||
415 | p=getenv("REMOTE_ADDR");if(p!=NULL && (strcmp(p,"127.0.0.1")==0 || strcmp(p,"::1")==0)) human_access=1; |
||
416 | p=getenv("HTTP_REFERER"); if(p!=NULL && *p!=0) setvar("wims_referer",p); |
||
10 | reyssat | 417 | } |
418 | |||
11735 | obado | 419 | /* cookie2session */ |
10 | reyssat | 420 | void cookie2session(void) |
421 | { |
||
12263 | bpr | 422 | char cksession[64], psession[32], *ckey, *p; |
423 | char nbuf[MAX_FNAME+1]; |
||
10 | reyssat | 424 | |
12263 | bpr | 425 | if(mode==mode_popup) return; |
426 | if(cookiegot[0]==0) { |
||
427 | ckset: cookiegot[0]=0; setcookie=1; return; |
||
428 | } |
||
429 | p=getvar("special_parm"); |
||
430 | if(p!=NULL && strcmp(p,"ignorecookie")==0) return; |
||
431 | mystrncpy(cksession,cookiegot,sizeof(cksession)); |
||
432 | ckey=strchr(cksession,'-'); |
||
433 | if(ckey==NULL) goto ckset; else *ckey++=0; |
||
434 | p=getvar("wims_session"); if(p==NULL) p=""; |
||
435 | if(strstr(p,"new")!=NULL) goto ckset; |
||
436 | mystrncpy(psession,p,sizeof(psession)); |
||
437 | p=strchr(psession,'_'); if(p!=NULL) *p=0; |
||
438 | if(psession[0]!=0) { |
||
439 | if(strcmp(psession,cksession)==0) return; |
||
440 | if(session_exists(psession)) goto ckset; |
||
441 | if(session_exists(cksession)) goto change; |
||
442 | } |
||
443 | else { |
||
444 | if(!session_exists(cksession)) return; |
||
445 | change: |
||
446 | p=getenv("HTTPS"); |
||
447 | if(p!=NULL && strcasecmp(p,"on")==0) goto ckset; |
||
448 | mkfname(nbuf,"%s/%s/var",session_dir,cksession); |
||
449 | getdef(nbuf,"w_wims_ismanager",tmplbuf); |
||
450 | if(tmplbuf[0]!=0 && tmplbuf[0]!='0') goto ckset; |
||
451 | getdef(nbuf,"w_wims_protocol",tmplbuf); |
||
452 | if(strcasecmp(tmplbuf,"https")==0) goto ckset; |
||
453 | mkfname(nbuf,"%s/%s/var.stat",session_dir,cksession); |
||
454 | getdef(nbuf,"wims_user",tmplbuf); |
||
455 | if(tmplbuf[0]!=0) goto ckset; |
||
456 | force_setvar(ro_name[ro_session],cksession); |
||
457 | setsesdir(cksession); |
||
458 | force_setvar("wims_subsession",""); |
||
459 | session_serial=0; |
||
460 | } |
||
10 | reyssat | 461 | } |
462 | |||
463 | void determine_font(char *l) |
||
464 | { |
||
12263 | bpr | 465 | int i; |
7673 | bpr | 466 | |
12263 | bpr | 467 | if(l==NULL || *l==0) return; |
468 | for(i=0;i<charname_no && memcmp(charname[i].name,l,2);i++); |
||
469 | if(i<charname_no) setvar("wims_main_font",charname[i].font); |
||
10 | reyssat | 470 | } |
471 | |||
3278 | reyssat | 472 | void determine_dirn(char *l) |
473 | { |
||
12263 | bpr | 474 | int i; |
7673 | bpr | 475 | |
12263 | bpr | 476 | if(l==NULL || *l==0) return; |
477 | for(i=0;i<dirnname_no && memcmp(dirnname[i].name,l,2);i++); |
||
478 | if(i<dirnname_no) setvar("wims_main_dirn",dirnname[i].dirn); |
||
3278 | reyssat | 479 | } |
480 | |||
10 | reyssat | 481 | void predetermine_language(void) |
482 | { |
||
12263 | bpr | 483 | char *p; |
484 | int i,n; |
||
10 | reyssat | 485 | |
12263 | bpr | 486 | if(pre_language[0]!=0) p=pre_language; |
487 | else p=getenv("HTTP_ACCEPT_LANGUAGE"); |
||
488 | if(p!=NULL && strlen(p)>=2) { |
||
10 | reyssat | 489 | for(i=0;i<available_lang_no && memcmp(p,available_lang[i],2)!=0;i++); |
12263 | bpr | 490 | if(i<available_lang_no) goto lend; |
491 | } |
||
492 | p=getenv("HTTP_USER_AGENT"); |
||
493 | if(p!=NULL && strlen(p)>=5) { |
||
494 | char *q; |
||
495 | if((q=strchr(p,'['))!=NULL && islower(*(q+1)) && islower(*(q+2)) && *(q+3)==']') { |
||
496 | char bb[4]; |
||
497 | bb[0]=*(q+1);bb[1]=*(q+2);bb[2]=0; |
||
498 | for(i=0;i<available_lang_no && memcmp(bb,available_lang[i],2)!=0;i++); |
||
499 | if(i<available_lang_no) { |
||
500 | memmove(lang,bb,2); lang[2]=0; |
||
501 | goto lend2; |
||
502 | } |
||
10 | reyssat | 503 | } |
12263 | bpr | 504 | } |
505 | p=getenv("HTTP_HOST"); if(p==NULL) goto lend2; |
||
506 | n=strlen(p); if(n<=3 || *(p+n-3)!='.') goto lend2; |
||
507 | p=p+n-2; |
||
508 | for(i=0;i<available_lang_no && memcmp(p,available_lang[i],2)!=0;i++); |
||
509 | if(i<available_lang_no) { |
||
510 | lend: memmove(lang,p,2); lang[2]=0; |
||
511 | lend2: determine_font(lang);determine_dirn(lang); |
||
512 | } |
||
10 | reyssat | 513 | } |
514 | |||
7673 | bpr | 515 | /* print a special page */ |
10 | reyssat | 516 | void put_special_page(char *pname) |
517 | { |
||
12263 | bpr | 518 | determine_font(lang); |
519 | determine_dirn(lang); |
||
520 | phtml_put_base(mkfname(NULL,"%s.phtml.%s",pname,lang),0); |
||
521 | write_logs();free(var_str); |
||
10 | reyssat | 522 | } |
523 | |||
7673 | bpr | 524 | /* check whether the connection is a site manager. */ |
10 | reyssat | 525 | void manager_check(void) |
526 | { |
||
12263 | bpr | 527 | char *p, *pp, buf[16]; |
528 | struct stat confstat; |
||
529 | int i; |
||
7673 | bpr | 530 | |
12263 | bpr | 531 | manageable=0; |
532 | if(robot_access || *manager_site==0 || checkhost(manager_site)<1) |
||
533 | goto mend; |
||
534 | if(manager_https) { |
||
535 | p=getenv("HTTPS"); |
||
536 | if(p==NULL || strcmp(p,"on")!=0) goto mend; |
||
537 | } |
||
8185 | bpr | 538 | /* IPv4 IPv6*/ |
12263 | bpr | 539 | if(strcmp(remote_addr,"127.0.0.1")==0 || strcmp(remote_addr,"::1")==0) { |
540 | int port, port2; |
||
541 | char tester[128]; |
||
542 | p=getenv("REMOTE_PORT"); if(p==NULL) goto mend; |
||
543 | port=atoi(p); if(port<1024 || port>65535) goto mend; |
||
544 | p=getenv("SERVER_PORT"); if(p==NULL) goto mend; |
||
545 | port2=atoi(p); if(port2>=10000 || port2<=0) goto mend; |
||
7673 | bpr | 546 | /* this is very non-portable */ |
12263 | bpr | 547 | manageable=1; |
548 | accessfile(tmplbuf,"r","/proc/net/tcp"); |
||
549 | snprintf(tester,sizeof(tester)," 0100007F:%04X 0100007F:%04X ", |
||
550 | port,port2); |
||
551 | p=strstr(tmplbuf,tester); |
||
552 | if(p!=NULL) { |
||
553 | pp=strchr(p,'\n'); if(pp!=NULL) *pp=0; |
||
554 | if(strlen(p)>=75) { |
||
555 | p=find_word_start(p+70); *find_word_end(p)=0; |
||
556 | if(atoi(p)==geteuid()) manageable=2; |
||
7673 | bpr | 557 | } |
10 | reyssat | 558 | } |
12263 | bpr | 559 | } |
560 | else manageable=1; |
||
561 | i=stat(config_file,&confstat); |
||
562 | if(i==0 && manageable>0 && (confstat.st_mode&(S_IRWXO|S_IRWXG))!=0) manageable=-1; |
||
563 | if(manageable>0 && !trusted_module()) manageable=0; |
||
564 | if(manageable==1) { |
||
565 | accessfile(tmplbuf,"r","%s/.manager",session_prefix); |
||
566 | if(strstr(tmplbuf,"yes")!=NULL) manageable=2; |
||
567 | } |
||
568 | if(manageable==1) { |
||
569 | p=getvar(ro_name[ro_module]); |
||
570 | if(p!=NULL && strncmp(p,"adm/manage",strlen("adm/manage"))==0) { |
||
571 | struct stat pstat; |
||
572 | if(stat("../log/.wimspass",&pstat)==0) { |
||
573 | if((S_IFMT&pstat.st_mode)!=S_IFREG || |
||
574 | ((S_IRWXO|S_IRWXG)&pstat.st_mode)!=0) |
||
575 | manageable=-2; |
||
7673 | bpr | 576 | } |
10 | reyssat | 577 | } |
12263 | bpr | 578 | } |
579 | mend: |
||
580 | mystrncpy(buf,int2str(manageable),sizeof(buf)); |
||
581 | force_setvar("wims_ismanager",buf); |
||
582 | if(manageable>=2) { |
||
583 | struct rlimit rlim; |
||
584 | rlimit_cpu*=10; |
||
585 | rlim.rlim_cur=rlim.rlim_max=rlimit_cpu; |
||
586 | setrlimit(RLIMIT_CPU,&rlim); |
||
587 | mystrncpy(buf,int2str(rlimit_cpu),sizeof(buf)); |
||
588 | setvar("wims_cpu_limit",buf); |
||
589 | initalarm(); |
||
590 | } |
||
10 | reyssat | 591 | } |
592 | |||
7673 | bpr | 593 | /* check for robot access */ |
10 | reyssat | 594 | void robot_check(void) |
595 | { |
||
12263 | bpr | 596 | char *ua, *p, *ses, *c, *mod; |
597 | int i; |
||
10 | reyssat | 598 | |
12263 | bpr | 599 | if(human_access) return; |
600 | mod=getvar(ro_name[ro_module]); |
||
601 | if(mod!=NULL && strcmp(mod,"adm/raw")==0) return; |
||
602 | ses=getvar(ro_name[ro_session]); |
||
7673 | bpr | 603 | /* user has valid session; OK */ |
12263 | bpr | 604 | if(ses!=NULL && strncmp(ses,robot_session,strlen(robot_session))!=0 |
605 | && strchr(ses,'/')==NULL |
||
606 | && ftest(mkfname(NULL,"%s/%s",s2_dir,ses))==is_dir) |
||
607 | return; |
||
608 | ua=getenv("HTTP_USER_AGENT"); if(ua==NULL) ua=""; |
||
609 | ua=find_word_start(ua); |
||
610 | if(strncasecmp(ua,"Mozilla",strlen("Mozilla"))==0 && |
||
611 | (p=strstr(ua,"compatible"))!=NULL) |
||
612 | ua=find_word_start(find_word_end(p)); |
||
613 | if(*ua) { |
||
614 | for(i=0;i<good_agent_no |
||
615 | && strncasecmp(ua,good_agent[i],strlen(good_agent[i]));i++); |
||
616 | if(i<good_agent_no) return; |
||
617 | for(i=0;i<bad_agent_no |
||
618 | && strstr(ua,bad_agent[i])==NULL;i++); |
||
619 | if(i<bad_agent_no) user_error("trapped"); |
||
620 | } |
||
621 | force_setvar(ro_name[ro_session],robot_session); |
||
622 | setsesdir(robot_session); |
||
623 | c=getvar(ro_name[ro_cmd]); |
||
624 | robot_access=1; |
||
625 | if(c!=NULL && strcmp(c,"new") && strcmp(c,"intro")) { |
||
626 | force_setvar(ro_name[ro_cmd],"robot_error"); |
||
627 | nph_header(450); put_special_page("robot"); |
||
628 | flushoutput(); flushlog(); exit(0); |
||
629 | } |
||
10 | reyssat | 630 | } |
631 | |||
7673 | bpr | 632 | /* type=0: ordinary; type=1: multipart/form-data */ |
10 | reyssat | 633 | void parse_query_string(int len, int type) |
634 | { |
||
12263 | bpr | 635 | int i,j,l,v,cmd_defined; |
636 | int parenth=-1, ll, lb, dlen; |
||
637 | char *start, *p, *p1, *pt, *b1=""; |
||
7673 | bpr | 638 | |
12263 | bpr | 639 | cmd_defined=0; |
640 | setvar("wims_subsession",""); |
||
641 | ll=lb=0; |
||
642 | if(type) { |
||
643 | ll=strlen(mpboundary); |
||
644 | start=strstr(var_str,mpboundary); |
||
645 | if(start==NULL) start=var_str+strlen(var_str); |
||
646 | if(strstr(var_str,"\r\n\r\n")!=NULL) b1="\r\n\r\n"; |
||
647 | else b1="\n\n"; |
||
648 | lb=strlen(b1); |
||
649 | } |
||
650 | else start=var_str; |
||
651 | for(v=0, p1=start;p1<var_str+len;p1+=l) { |
||
10 | reyssat | 652 | if(type) { |
12263 | bpr | 653 | char *p2, *p3, *p4, *p5; |
654 | p2=p1+ll; p3=memstr(p2,mpboundary,var_str+len-p2); l=p3-p1; |
||
655 | p=memstr(p2,b1,var_str+len-p2); if(p>=p3) continue; |
||
656 | p+=lb; |
||
657 | if(p3<var_str+len) { |
||
658 | while(*p3!='\n' && p3>p2) p3--; |
||
659 | *p3=0; |
||
660 | p3--; if(*p3=='\r') *p3=0; |
||
661 | } |
||
662 | dlen=p3-p; |
||
663 | p2=memstr(p2,"name=",p3-p2); if(p2>=p3) continue; |
||
664 | p2+=strlen("name="); if(*p2=='"') p2++; |
||
665 | for(p3=p2; myisalnum(*p3) || strchr("._",*p3)!=NULL; p3++); |
||
666 | if(p3==p2) continue; |
||
667 | if(p3-p2==strlen("wims_deposit") && |
||
668 | strncmp(p2,"wims_deposit",p3-p2)==0) { |
||
669 | p4=memstr(p1,"filename=",p-p1); if(p4<p) { |
||
670 | p4+=strlen("filename="); if(*p4=='"') { |
||
671 | p4++; p5=strchr(p4,'"'); |
||
672 | if(p5==NULL || p5-p4>=MAX_FNAME) goto emptyquote; |
||
7673 | bpr | 673 | } |
12263 | bpr | 674 | else { |
675 | emptyquote: |
||
676 | for(p5=p4; p5<p && !isspace(*p5) && |
||
677 | strchr(";\"~#*?=,'",*p5)==NULL; p5++); |
||
678 | } |
||
679 | if(p5>p4) { |
||
680 | *p5=0; |
||
681 | for(p5--; |
||
682 | p5>=p4 && !isspace(*p5) && strchr("/\\:",*p5)==NULL; |
||
683 | p5--); |
||
684 | if(p5>=p4) p4=p5+1; |
||
685 | if(*p4==0) goto noname; |
||
686 | if(strstr(p4,"..")!=NULL || *p4=='.') |
||
687 | p4="noname.file"; |
||
688 | setvar("wims_deposit",p4); |
||
689 | } |
||
690 | else { |
||
691 | noname: setvar("wims_deposit","noname.file"); |
||
692 | } |
||
7673 | bpr | 693 | } |
12263 | bpr | 694 | deplen=dlen; |
695 | } |
||
696 | *p3=0; l-=p2-p1; p1=p2; |
||
697 | } |
||
698 | else { |
||
699 | p1=find_word_start(p1); |
||
700 | l=strlen(p1)+1; p=strchr(p1,'='); |
||
701 | if(p==NULL) p=p1+strlen(p1); |
||
702 | if(*p==0 && l>1) { |
||
703 | user_variable[v].name="no_name"; |
||
704 | user_variable[v].value=p1; |
||
705 | coord_input=1; |
||
706 | goto nnext; |
||
7673 | bpr | 707 | } |
12263 | bpr | 708 | *p++=0; |
709 | } |
||
7673 | bpr | 710 | /* empty name or empty value: ignore */ |
12263 | bpr | 711 | if(*p1==0 || *p==0) continue; |
7673 | bpr | 712 | /* We do not treat names containing '.' */ |
12263 | bpr | 713 | for(pt=strchr(p1,'.'); pt; pt=strchr(++pt,'.')) *pt='_'; |
7673 | bpr | 714 | /* Restrictions on variable names */ |
12263 | bpr | 715 | for(pt=p1; myisalnum(*pt) || *pt=='_'; pt++); |
716 | if(*pt) continue; |
||
717 | if(strcmp(p1,"wims_deposit")!=0) _tolinux(p); |
||
7673 | bpr | 718 | /* This is a restriction: |
8155 | bpr | 719 | * Every parameter must have matching parentheses. |
720 | */ |
||
12263 | bpr | 721 | if(parenth==-1 && strncmp(p1,"freepar_",strlen("freepar_"))!=0 |
7673 | bpr | 722 | && strcmp(p1,"wims_deposit")!=0 |
723 | && check_parentheses(p,1)) parenth=v; |
||
12263 | bpr | 724 | if(strcmp(p1,"special_parm")==0 && strcmp(p,"wims")==0) |
7673 | bpr | 725 | human_access=1; |
12263 | bpr | 726 | j=search_list(ro_name,RO_NAME_NO,sizeof(ro_name[0]),p1); |
727 | if(j>=0) { |
||
728 | if(j==ro_session) { |
||
729 | p=find_word_start(p); *find_word_end(p)=0; |
||
730 | if(strlen(p)>MAX_SESSIONLEN) continue; |
||
731 | if(strcmp(p,robot_session)==0) p=""; |
||
732 | if(strcasecmp(p,"popup")==0) { |
||
733 | mode=mode_popup; |
||
734 | force_setvar("wims_mode","popup"); |
||
735 | force_setvar("session",""); |
||
7673 | bpr | 736 | continue; |
12263 | bpr | 737 | } |
7673 | bpr | 738 | } |
12263 | bpr | 739 | if(j==ro_module) module_defined=1; |
740 | if(j==ro_cmd) { |
||
741 | p=find_word_start(p); *find_word_end(p)=0; |
||
742 | if(strlen(p)>16) continue; |
||
743 | cmd_defined=1; |
||
7673 | bpr | 744 | } |
12263 | bpr | 745 | if(j==ro_lang) { |
746 | if(strlen(p)!=2) continue; |
||
747 | for(i=0;i<available_lang_no && strcmp(available_lang[i],p)!=0;i++); |
||
748 | if(i<available_lang_no) {user_lang=1; ovlstrcpy(lang,p);} |
||
749 | else continue; |
||
750 | } |
||
751 | /* strip leading and trailing '/'s in module name */ |
||
752 | if(j==ro_module) { |
||
753 | p=find_word_start(p); *find_word_end(p)=0; |
||
754 | while(*p=='/') p++; |
||
755 | while(*p!=0 && *(p+strlen(p)-1)=='/') *(p+strlen(p)-1)=0; |
||
756 | if(strlen(p)>MAX_MODULELEN) continue; |
||
757 | } |
||
758 | setvar(p1,p); |
||
759 | if(j==ro_session && mode!=mode_popup) { |
||
760 | char *pp, *pr; |
||
761 | char buf[1024]; |
||
762 | mystrncpy(buf,p,sizeof(buf)); |
||
763 | if((pp=strchr(buf,'.'))!=NULL) { |
||
764 | *pp++=0; session_serial=atoi(pp); |
||
765 | if(pp<0) pp=0; |
||
766 | } |
||
767 | else session_serial=0; |
||
768 | pp=strchr(buf,'_'); |
||
769 | if(pp!=NULL && (pr=strstr(pp,"_mhelp"))!=NULL) { |
||
770 | *pr=0; ismhelp=1; lastout_file=-1; |
||
771 | setvar("wims_inssub","mh"); |
||
772 | } |
||
773 | force_setvar("wims_session",buf); |
||
774 | if(pp!=NULL) force_setvar("wims_subsession",pp); |
||
775 | } |
||
776 | continue; |
||
10 | reyssat | 777 | } |
12263 | bpr | 778 | user_variable[v].name=p1; |
779 | user_variable[v].value=p; |
||
780 | nnext:v++; if(v>=MAX_VAR_NUM) user_error("too_many_variables"); |
||
781 | } |
||
782 | user_var_no=v; |
||
783 | if(parenth>=0) { |
||
784 | char buf[16]; |
||
785 | mystrncpy(buf,int2str(user_var_no),sizeof(buf)); |
||
786 | setvar("user_var_no",buf); |
||
787 | for(i=0;i<user_var_no;i++) { |
||
788 | snprintf(buf,sizeof(buf),"name%d",i); |
||
789 | setvar(buf,user_variable[i].name); |
||
790 | snprintf(buf,sizeof(buf),"value%d",i); |
||
791 | setvar(buf,user_variable[i].value); |
||
10 | reyssat | 792 | } |
12263 | bpr | 793 | mystrncpy(buf,int2str(parenth),sizeof(buf)); |
794 | setvar("bad_parentheses",buf); |
||
795 | user_error("unmatched_parentheses"); |
||
796 | } |
||
797 | p=getenv("SCRIPT_NAME"); |
||
798 | if(p!=NULL && (p=strstr(p,"/getfile/"))!=NULL) { |
||
799 | p+=strlen("/getfile/"); |
||
800 | force_setvar(ro_name[ro_cmd],commands[cmd_getfile]); |
||
801 | force_setvar("special_parm",p); |
||
802 | cmd_defined=1; |
||
803 | } |
||
804 | if(module_defined && !cmd_defined) setvar(ro_name[ro_cmd],commands[cmd_intro]); |
||
805 | robot_check(); cookie2session(); |
||
10 | reyssat | 806 | } |
807 | |||
7673 | bpr | 808 | /* parse special commands */ |
10 | reyssat | 809 | void special_cmds(void) |
810 | { |
||
12263 | bpr | 811 | char *c, *p; |
812 | int i; |
||
813 | long int l=-1; |
||
7673 | bpr | 814 | |
12263 | bpr | 815 | c=getvar(ro_name[ro_cmd]); |
816 | if(c==NULL || *c==0) { /* no module name nor command */ |
||
817 | setvar(ro_name[ro_module],home_module); |
||
818 | setvar(ro_name[ro_cmd],commands[cmd_new]); |
||
819 | return; |
||
820 | } |
||
821 | for(i=0;i<CMD_NO && strcmp(commands[i],c)!=0; i++); |
||
822 | switch(i) { |
||
823 | case cmd_intro: { |
||
824 | set_module_prefix(); |
||
825 | default_form_method="get"; |
||
826 | if(ftest(mkfname(NULL,"%s/%s",module_prefix,intro_file))<0) { |
||
827 | force_setvar(ro_name[ro_cmd],commands[cmd_new]); |
||
828 | return; |
||
829 | } |
||
830 | p=getvar("wims_session"); |
||
831 | if(p!=NULL && *p!=0) { |
||
832 | if(set_session_prefix()==0) check_session(); |
||
833 | else { |
||
834 | trap_check(p); |
||
835 | if(strchr(p,'_')!=NULL && strchr(p,'/')==NULL) { |
||
836 | get_static_session_var(); |
||
7673 | bpr | 837 | } |
12263 | bpr | 838 | } |
839 | } |
||
7673 | bpr | 840 | /* determine http protocol name. How to detect? */ |
12263 | bpr | 841 | p=getenv("HTTPS"); |
842 | if(p!=NULL && strcmp(p,"on")==0) { |
||
843 | protocol="https"; set_protocol(); |
||
7673 | bpr | 844 | } |
12263 | bpr | 845 | force_setvar("wims_protocol",protocol); |
846 | determine_font(lang); |
||
847 | determine_dirn(lang); |
||
848 | main_phtml_put(intro_file); debug_output(); |
||
849 | introend: write_logs();free(var_str); |
||
850 | delete_pid(); exit(0); |
||
851 | } |
||
852 | case cmd_ref: { |
||
853 | set_module_prefix(); |
||
854 | default_form_method="get"; |
||
855 | p=getvar("wims_session"); |
||
856 | if(p!=NULL && *p!=0) { |
||
857 | if(set_session_prefix()==0) check_session(); |
||
858 | else trap_check(p); |
||
7673 | bpr | 859 | } |
12263 | bpr | 860 | determine_font(lang); |
861 | determine_dirn(lang); |
||
862 | main_phtml_put(ref_file); goto introend; |
||
863 | } |
||
864 | case cmd_getins: { |
||
865 | c=getvar(ro_name[ro_special_parm]); |
||
866 | if(c==NULL || *c==0) { |
||
867 | user_error_nolog=1; user_error("no_insnum"); |
||
868 | } |
||
869 | if(*c=='/' || strstr(c,"..")!=NULL) goto badins; |
||
870 | set_session_prefix(); |
||
871 | if(strstr(session_prefix,"robot")!=NULL) exit(0); |
||
872 | l=filelength("%s/%s",s2_prefix,c); |
||
873 | if(l<0) { |
||
874 | badins: user_error_nolog=1; user_error("bad_insnum"); |
||
875 | } |
||
876 | { |
||
877 | char *fmt; |
||
878 | fmt=strchr(c,'.'); |
||
879 | if(fmt==NULL) { |
||
880 | user_error_nolog=1; user_error("bad_insnum"); |
||
881 | } |
||
882 | else fmt++; |
||
7673 | bpr | 883 | |
12263 | bpr | 884 | nph_header(200); |
10 | reyssat | 885 | /* insert format problem; bricolage */ |
12263 | bpr | 886 | printf("Content-type: image/%s\r\n\ |
10 | reyssat | 887 | Content-length: %ld\r\n\r\n",fmt,l); |
12263 | bpr | 888 | catfile(stdout,"%s/%s",s2_prefix,c); exit(0); |
7673 | bpr | 889 | } |
12263 | bpr | 890 | } |
891 | case cmd_getfile: { |
||
892 | char fname[MAX_FNAME+1]; |
||
893 | c=getvar(ro_name[ro_special_parm]); |
||
894 | if(c==NULL || *c==0) { |
||
895 | user_error_nolog=1; user_error("no_insnum"); |
||
896 | } |
||
897 | if(*c=='/' || strstr(c,"..")!=NULL) goto badfile; |
||
7673 | bpr | 898 | |
12263 | bpr | 899 | set_session_prefix(); |
900 | if(strstr(session_prefix,"robot")!=NULL) exit(0); |
||
901 | mkfname(fname,"%s/getfile/%s",session_prefix,c); |
||
902 | l=filelength("%s",fname); |
||
903 | if(l<0 && strchr(session_prefix,'_')!=NULL) { |
||
904 | char *pt; |
||
905 | mystrncpy(fname,session_prefix,sizeof(fname)); |
||
906 | pt=strrchr(fname,'_'); if(pt) *pt=0; |
||
907 | snprintf(fname+(pt-fname),sizeof(fname)-(pt-fname), |
||
908 | "/getfile/%s",c); |
||
909 | l=filelength("%s",fname); |
||
910 | } |
||
911 | if(l<0) { |
||
912 | badfile: user_error_nolog=1; user_error("bad_insnum"); |
||
913 | } |
||
914 | if(l>512*1024) { |
||
915 | struct rlimit rlim; |
||
916 | rlimit_cpu*=l/(10*1024); |
||
917 | rlim.rlim_cur=rlim.rlim_max=rlimit_cpu; |
||
918 | initalarm(); |
||
919 | } |
||
920 | { |
||
921 | char *p1; |
||
922 | char mime[MAX_LINELEN+1]; |
||
923 | for(p1=c+strlen(c);p1>c && isalpha(*(p1-1)); p1--); |
||
924 | ovlstrcpy(mime,"application/octet-stream"); |
||
925 | if(p1>c && *(p1-1)=='.') { |
||
926 | setvar("translator_unknown",mime); |
||
927 | setvar("dictionary","bases/sys/mime"); |
||
928 | snprintf(mime,sizeof(mime),"translator %s",p1); |
||
929 | calc_exec(mime); |
||
930 | } |
||
931 | nph_header(200); |
||
932 | printf("Content-type: %s\r\n\ |
||
10 | reyssat | 933 | Content-length: %ld\r\n\r\n",mime,l); |
12263 | bpr | 934 | catfile(stdout,"%s",fname); exit(0); |
7673 | bpr | 935 | } |
12263 | bpr | 936 | } |
12373 | bpr | 937 | case cmd_close: { |
938 | char *p, b2[32]; int w; |
||
939 | char nbuf[MAX_FNAME+1], vbuf[MAX_LINELEN+1]; |
||
940 | p=getvar(ro_name[ro_session]); |
||
941 | if(p==NULL || strlen(p)<10 || |
||
942 | strchr(p,'/')!=NULL) return; |
||
943 | mystrncpy(b2,p,sizeof(b2)); |
||
944 | p=strchr(b2,'.'); if(p!=NULL) *p=0; |
||
945 | mkfname(nbuf,"%s/%s/var.stat",session_dir,b2); |
||
946 | getdef(nbuf,"wims_caller",vbuf); |
||
947 | if(vbuf[0]!=0) force_setvar(ro_name[ro_session],vbuf); |
||
948 | w=wrapexec; wrapexec=1; |
||
949 | call_sh("rm -Rf %s/%s* %s/%s* >/dev/null 2>&1",session_dir,b2,s2_dir,b2); |
||
950 | wrapexec=w; cookiegot[0]=0; |
||
951 | force_setvar(ro_name[ro_cmd],"new"); |
||
952 | } |
||
953 | default: return; |
||
12263 | bpr | 954 | } |
10 | reyssat | 955 | } |
956 | |||
7673 | bpr | 957 | /* This is run only when manually invoking the program. |
8155 | bpr | 958 | * Verifies the orderedness of various list tables. |
959 | */ |
||
10 | reyssat | 960 | int verify_tables(void) |
961 | { |
||
962 | if(verify_order(calc_routine,CALC_FN_NO,sizeof(calc_routine[0]))) return -1; |
||
963 | if(verify_order(exec_routine,EXEC_FN_NO,sizeof(exec_routine[0]))) return -1; |
||
964 | if(verify_order(main_config,MAIN_CONFIG_NO,sizeof(main_config[0]))) return -1; |
||
965 | if(verify_order(mathname,mathname_no,sizeof(mathname[0]))) return -1; |
||
966 | if(verify_order(hmname,hmname_no,sizeof(hmname[0]))) return -1; |
||
967 | if(verify_order(ro_name,RO_NAME_NO,sizeof(ro_name[0]))) return -1; |
||
968 | if(verify_order(distr_cmd,distr_cmd_no,sizeof(distr_cmd[0]))) return -1; |
||
969 | if(verify_order(internal_name,INTERNAL_NAME_NO, |
||
7673 | bpr | 970 | sizeof(internal_name[0]))) return -1; |
10 | reyssat | 971 | if(verify_order(tmathfn,tmathfn_no,sizeof(tmathfn[0]))) return -1; |
972 | if(verify_order(tmathvar,tmathvar_no,sizeof(tmathvar[0]))) return -1; |
||
973 | if(verify_order(modindex,MODINDEX_NO,sizeof(modindex[0]))) return -1; |
||
974 | if(verify_order(exportvars,exportvarcnt,sizeof(exportvars[0]))) return -1; |
||
975 | if(evaltab_verify()) return -1; |
||
976 | if(textab_verify()) return -1; |
||
977 | return 0; |
||
978 | } |
||
979 | |||
980 | void config_defaults(void) |
||
981 | { |
||
3857 | kbelabas | 982 | int i; |
10 | reyssat | 983 | for(i=0;i<MAIN_CONFIG_NO;i++) { |
7673 | bpr | 984 | if((1&main_config[i].is_integer)==1) { |
985 | int *pi = (int*)main_config[i].address; |
||
986 | printf("DF_%s=%d\n",main_config[i].name, *pi); |
||
3857 | kbelabas | 987 | } |
7673 | bpr | 988 | else { |
3857 | kbelabas | 989 | char **ps = (char**)main_config[i].address; |
7673 | bpr | 990 | printf("DF_%s=%s\n",main_config[i].name,*ps); |
3857 | kbelabas | 991 | } |
10 | reyssat | 992 | } |
993 | } |
||
994 | |||
7673 | bpr | 995 | /* get and set useroptions */ |
10 | reyssat | 996 | void useropts(void) |
997 | { |
||
998 | char *p; |
||
999 | setvar("lang",lang); |
||
1000 | p=getvar("useropts"); |
||
1001 | if(p==NULL || *p==0) p=getvar("wims_useropts"); |
||
1002 | if(p!=NULL && *p!=0) { |
||
6178 | bpr | 1003 | if(myisdigit(p[0])) { |
1004 | usertexsize=p[0]-'0'; |
||
6184 | bpr | 1005 | /* fourth digit is for special fonts*/ |
6178 | bpr | 1006 | if(p[1]!=0) { mathalign_base=p[1]-'0'; } |
1007 | } |
||
6184 | bpr | 1008 | if(myisdigit(p[3]) && p[3]!=0){ spec_font=p[3]-'0';} |
1009 | } |
||
1010 | if(mathalign_base==1) { |
||
6178 | bpr | 1011 | mathalign_sup1="<sup>"; mathalign_sup2="</sup>"; |
6184 | bpr | 1012 | } else mathalign_sup1=mathalign_sup2=""; |
10 | reyssat | 1013 | } |
1014 | |||
7673 | bpr | 1015 | /* popup module help */ |
10 | reyssat | 1016 | void mhelp(void) |
1017 | { |
||
1018 | char *p, buf[MAX_LINELEN+1]; |
||
1019 | main_phtml_put(""); buf[0]=0; |
||
1020 | if(cmd_type!=cmd_help) { |
||
7673 | bpr | 1021 | phtml_put_base("closemhelp.phtml",0); |
10 | reyssat | 1022 | } |
1023 | else { |
||
7673 | bpr | 1024 | phtml_put_base("mhelpheader.phtml",0); |
1025 | p=getvar("special_parm"); |
||
1026 | if(p!=NULL && strcmp(p,"about")==0) |
||
1027 | phtml_put("about.phtml",0); |
||
11125 | georgesk | 1028 | else phtml_put("help.phtml",0); |
1029 | phtml_put_base("mhelptail.phtml",0); |
||
7673 | bpr | 1030 | exec_tail(buf); |
10 | reyssat | 1031 | } |
1032 | } |
||
1033 | |||
1034 | #define READSTDIN_WINDOW 4096 |
||
1035 | |||
1036 | void readstdin(int len) |
||
1037 | { |
||
1038 | int ll, l1, lt, lr; |
||
1039 | int cpulim; |
||
7673 | bpr | 1040 | |
10 | reyssat | 1041 | cpulim=rlimit_cpu; rlimit_cpu=3; |
1042 | lr=len; l1=0; |
||
1043 | while(lr>0) { |
||
7673 | bpr | 1044 | nowtime=time(0); initalarm(); |
1045 | ll=lr; if(ll>READSTDIN_WINDOW) ll=READSTDIN_WINDOW; |
||
1046 | lt=fread(stdinbuf+l1,1,ll,stdin); |
||
1047 | if(lt!=ll) user_error("parm_too_long"); |
||
1048 | lr-=ll; l1+=ll; |
||
10 | reyssat | 1049 | } |
1050 | if(l1!=len) user_error("parm_too_long"); |
||
1051 | stdinbuf[len]=0; rlimit_cpu=cpulim; |
||
1052 | } |
||
1053 | |||
7673 | bpr | 1054 | /* input: p=QUERY_STRING. output: parameter length. */ |
1055 | /* Netscape puts form content into /tmp. */ |
||
10 | reyssat | 1056 | int formdata(char *p) |
1057 | { |
||
1058 | char *pp; |
||
1059 | int inlen; |
||
1060 | char *ctype; |
||
1061 | inlen=0; ctype=getenv("CONTENT_TYPE"); |
||
1062 | if(ctype==NULL || strstr(ctype,"multipart/form-data")==NULL |
||
1063 | || (p=strstr(ctype,"boundary="))==NULL) { |
||
7673 | bpr | 1064 | bad: stdinbuf=""; return 0; |
10 | reyssat | 1065 | } |
1066 | pp=getenv("CONTENT_LENGTH"); |
||
1067 | if(pp==NULL) goto bad; |
||
1068 | inlen=atoi(pp); if(inlen<=10) goto bad; |
||
1069 | if(inlen>=MAX_DEPOSITLEN) user_error("parm_too_long"); |
||
1070 | stdinbuf=xmalloc(inlen+1); readstdin(inlen); |
||
1071 | p+=strlen("boundary="); |
||
1072 | for(pp=p;myisalnum(*pp) || *pp=='-'; pp++); |
||
1073 | if(pp-p<sizeof(mpboundary)-2) { |
||
7673 | bpr | 1074 | memmove(mpboundary,p,pp-p); mpboundary[pp-p]=0; |
10 | reyssat | 1075 | } |
7673 | bpr | 1076 | /* empty data */ |
10 | reyssat | 1077 | if(strstr(stdinbuf,mpboundary)==NULL || strstr(stdinbuf,"name=")==NULL) { |
7673 | bpr | 1078 | free(stdinbuf); goto bad; |
10 | reyssat | 1079 | } |
1080 | form_access=1; post_log(); |
||
1081 | return inlen; |
||
1082 | } |
||
1083 | |||
7673 | bpr | 1084 | /* get the content of POST */ |
10 | reyssat | 1085 | void getpost(void) |
1086 | { |
||
1087 | int ll; |
||
1088 | char *pp; |
||
1089 | pp=getenv("CONTENT_LENGTH"); |
||
1090 | if(pp==NULL || (ll=atoi(pp))<=0) { |
||
7673 | bpr | 1091 | stdinbuf=xmalloc(16); stdinbuf[0]=0; |
10 | reyssat | 1092 | } |
1093 | else { |
||
7673 | bpr | 1094 | if(ll>QUERY_STRING_LIMIT) user_error("parm_too_long"); |
1095 | stdinbuf=xmalloc(ll+16); readstdin(ll); |
||
1096 | if(ll>0) { |
||
1097 | setenv("QUERY_STRING",stdinbuf,1); |
||
1098 | form_access=1; post_log(); |
||
1099 | } |
||
10 | reyssat | 1100 | } |
1101 | } |
||
1102 | |||
1103 | void buffer_init(void) |
||
1104 | { |
||
1105 | struct timeval tv; |
||
7673 | bpr | 1106 | |
10 | reyssat | 1107 | mcachecnt=readnest=0; |
1108 | mpboundary[0]=cookiegot[0]=cookieset[0]=cwdbuf[0]=0; |
||
1109 | rscore_class[0]=rscore_user[0]=multiexec_random[0]=0; |
||
1110 | lastftest[0]=0; |
||
1111 | lastdatafile[0]=0; lastdata=xmalloc(WORKFILE_LIMIT); |
||
1112 | outptr=outbuf; |
||
1113 | instex_src[0]=instex_fname[0]=module_prefix[0]=0; |
||
1114 | examlogf[0]=examlogd[0]=exam_sheetexo[0]=0; |
||
1115 | stdinbuf=NULL; |
||
1116 | mkfname(tmp_dir,"../tmp/forall"); |
||
1117 | mkfname(session_dir,"../%s",SESSION_BASE); |
||
1118 | mkfname(s2_dir,"../%s",S2_BASE); |
||
1119 | if(gettimeofday(&tv,NULL)) startmtime=startmtime2=0; |
||
1120 | else { |
||
7673 | bpr | 1121 | startmtime=((tv.tv_sec%10000)*1000+tv.tv_usec/1000); |
1122 | startmtime2=(tv.tv_sec%1000)*1000000+tv.tv_usec; |
||
10 | reyssat | 1123 | } |
1124 | } |
||
1125 | |||
8216 | bpr | 1126 | /** |
1127 | * runs the test suite, to check whether the documented commands of modtool |
||
1128 | * behave properly. |
||
1129 | * @param prefix path to the proc file to process |
||
1130 | * @param p name of the proc file to proceed |
||
1131 | * @param vars a list of var names to print. |
||
1132 | **/ |
||
1133 | void test_suite(char *prefix, char *p, char *vars){ |
||
1134 | char *v, *nextv; |
||
1135 | mystrncpy(module_prefix, prefix, sizeof(module_prefix)); |
||
1136 | exec_read(p); |
||
1137 | nextv=vars; |
||
1138 | while (*nextv!='\0'){ |
||
1139 | v=find_word_start(nextv); |
||
1140 | nextv=find_word_end(v); |
||
1141 | if (*nextv != '\0'){ |
||
1142 | *nextv++='\0'; |
||
1143 | } |
||
8925 | bpr | 1144 | v=getvar(v); |
1145 | if(v) puts(v); else putchar('\n'); |
||
8216 | bpr | 1146 | } |
1147 | } |
||
1148 | |||
10 | reyssat | 1149 | int main(int argc, char *argv[], char *envp[]) |
1150 | { |
||
12011 | bpr | 1151 | char *p, homebuf[MAX_FNAME+1], lbuf[32], buf[64]; |
10 | reyssat | 1152 | int inlen=0; |
8155 | bpr | 1153 | /* int mfd; */ |
8195 | bpr | 1154 | |
10 | reyssat | 1155 | class_dir[0]=0; |
1156 | substitute=substit; buffer_init(); var_init(); |
||
7673 | bpr | 1157 | /* WIMS internal locale is always C. */ |
10 | reyssat | 1158 | setenv("LANG","C",1); umask(022); |
1159 | setenv("LANGUAGE","us",1); |
||
1160 | setenv("LC_ALL","C",1); |
||
1161 | if(argc>1) { |
||
7673 | bpr | 1162 | if(strcasecmp(argv[1],"table")==0) { |
1163 | if(verify_tables()) internal_error("Table disorder."); |
||
1164 | else printf("Table orders OK.\n"); |
||
1165 | return 0; |
||
1166 | } |
||
1167 | if(strcasecmp(argv[1],"version")==0) { |
||
1168 | printf("%s",wims_version); return 0; |
||
1169 | } |
||
1170 | if(strcasecmp(argv[1],"defaults")==0) { |
||
1171 | config_defaults(); return 0; |
||
1172 | } |
||
8216 | bpr | 1173 | if(strcasecmp(argv[1],"test")==0) { |
8851 | bpr | 1174 | /* launches a test suite */ |
12288 | bpr | 1175 | if (argc < 5) { |
1176 | printf("Not enough arguments to launch a test; usage:\n"); |
||
1177 | printf("wims test path_to_file name_of_proc_file 'var1 var2 ...'\n\n"); |
||
1178 | printf("the file at path_to_file/name_of_proc_file will be evaluated by wims for\nexec commands, then the values of var1, var2, ... will be printed\nin the standard output, one per line.\n"); |
||
1179 | return 1; |
||
1180 | } |
||
1181 | test_suite(argv[2], argv[3], argv[4]); |
||
1182 | return 0; |
||
1183 | } |
||
10 | reyssat | 1184 | } |
1185 | p=getenv("SERVER_SOFTWARE"); if(p!=NULL && strcasecmp(p,"WIMS")==0) |
||
1186 | httpd_type=httpd_wims; |
||
1187 | p=getenv("REMOTE_ADDR"); if(p!=NULL) remote_addr=p; |
||
1188 | p=getenv("REMOTE_HOST"); if(p!=NULL) remote_host=p; |
||
1189 | nowtime=time(0); now=localtime(&nowtime); |
||
9286 | bpr | 1190 | /* nowtime contains the seconds elapsed from EPOCH (1970) |
1191 | but tm_year is set to current year-1900. |
||
1192 | */ |
||
10 | reyssat | 1193 | memmove(&Now, now, sizeof(Now)); now=&Now; |
1194 | snprintf(nowstr,sizeof(nowstr),"%04d%02d%02d.%02d:%02d:%02d", |
||
7673 | bpr | 1195 | (now->tm_year)+1900,(now->tm_mon)+1,now->tm_mday, |
1196 | now->tm_hour,now->tm_min,now->tm_sec); |
||
10 | reyssat | 1197 | p=getenv("QUERY_STRING"); |
1198 | if(p==NULL || *p==0) getpost(); |
||
1199 | else if(strncmp(p,"form-data",9)==0) inlen=formdata(p); |
||
7673 | bpr | 1200 | |
10 | reyssat | 1201 | force_setvar("wims_now",nowstr); |
1202 | snprintf(lbuf,sizeof(lbuf),"%lu",nowtime); |
||
1203 | force_setvar("wims_nowseconds",lbuf); |
||
1204 | nowtime=time(0); |
||
1205 | initalarm(); |
||
7673 | bpr | 1206 | |
10 | reyssat | 1207 | executed_gotos=insert_no=output_length=0; ins_alt[0]=0; |
7673 | bpr | 1208 | setvar("empty",""); /* lock this variable */ |
10 | reyssat | 1209 | setvar("wims_version",wims_version); |
1210 | setvar("wims_version_date",wims_version_date); |
||
1211 | setvar("wims_main_font","utf-8"); |
||
1212 | take_httpd_vars(); |
||
1213 | |||
1214 | main_configure(); |
||
1215 | checklogd(); |
||
8155 | bpr | 1216 | /* mfd=shm_open(SHM_NAME,O_RDONLY,-1); |
1217 | * if(mfd==-1) internal_error("Unable to find shared memory."); |
||
1218 | * shmptr=mmap(0,SHM_SIZE,PROT_READ,MAP_SHARED,mfd,0); |
||
1219 | * if(shmptr==MAP_FAILED) internal_error("Shared memory failure."); |
||
1220 | */ |
||
7673 | bpr | 1221 | getppid(); /* this is the first sysmask trigger, must be after checklogd() */ |
10 | reyssat | 1222 | predetermine_language(); |
6784 | kbelabas | 1223 | /* modify a few rlimits for 64-bit processors */ |
1224 | if (sizeof(long) == 8) { |
||
1225 | rlimit_as*=2; /* virtual memory size */ |
||
1226 | rlimit_data*=2; /* data segment size; maxima requires a lot */ |
||
1227 | rlimit_stack*=2; /* stack size */ |
||
1228 | } |
||
10 | reyssat | 1229 | set_rlimits(); |
12011 | bpr | 1230 | /*init_random();*/ |
12363 | bpr | 1231 | seed_time(); |
1232 | p=getvar("wims_seed"); |
||
1233 | mystrncpy(buf,p,sizeof(buf)); |
||
1234 | exec_setseed(buf); |
||
10 | reyssat | 1235 | module_configure(); |
1236 | set_job_ident(); |
||
1237 | m_file.name[0]=0;m_file.linecnt=m_file.linepointer=0; |
||
1238 | p=getenv("QUERY_STRING"); |
||
1239 | if(p==NULL || strlen(p)==0) { |
||
7673 | bpr | 1240 | setvar("lang",lang); |
1241 | snprintf(homebuf,sizeof(homebuf),"module=%s",home_module); |
||
1242 | p=homebuf; |
||
10 | reyssat | 1243 | } |
1244 | if(strlen(p)>=QUERY_STRING_LIMIT) user_error("parm_too_long"); |
||
1245 | if(mpboundary[0]==0) { |
||
7673 | bpr | 1246 | var_str=xmalloc(strlen(p)+2); |
1247 | parse_query_string(http2env(var_str,p),0); |
||
10 | reyssat | 1248 | } |
1249 | else { |
||
7673 | bpr | 1250 | var_str=stdinbuf; |
1251 | parse_query_string(inlen,1); |
||
10 | reyssat | 1252 | } |
1253 | if(ismhelp) { |
||
7673 | bpr | 1254 | p=getvar(ro_name[ro_cmd]); |
1255 | if(p==NULL || (strcmp(p,"help")!=0 && strcmp(p,"getins")!=0)) { |
||
1256 | mhelp(); goto outgo; |
||
1257 | } |
||
10 | reyssat | 1258 | } |
1259 | check_exam(); |
||
1260 | useropts(); |
||
1261 | special_cmds(); |
||
1262 | parse_ro_names(); |
||
1263 | manager_check(); |
||
1264 | access_check(0); |
||
11132 | bpr | 1265 | /* it is really for developing in wims, so no use in general */ |
12263 | bpr | 1266 | if (1==1) { |
10051 | bpr | 1267 | if(strstr(tmp_debug,"yes")!=NULL && checkhost(manager_site)>=1) |
12363 | bpr | 1268 | trace_file = fopen(mkfname(NULL,"%s/%s",tmp_dir,"trace.txt"),"a"); |
12263 | bpr | 1269 | } |
1270 | set_variables(); |
||
1271 | determine_font(getvar("module_language")); |
||
1272 | determine_dirn(getvar("module_language")); |
||
1273 | if(!robot_access && session_prefix[0]!=0 && cmd_type!=cmd_help && !ismhelp) |
||
1274 | lastout_file=creat(mkfname(NULL,"%s/%s",s2_prefix,lastout), |
||
1275 | S_IRUSR|S_IWUSR); |
||
1276 | p=getvar("module_score"); |
||
1277 | if(p!=NULL) force_setvar("wims_seed_score",p); |
||
1278 | p=getvar("module_category"); |
||
1279 | if(p==NULL || strstr(p,"tool")==NULL) default_form_method="get"; |
||
1280 | if(noout) { |
||
1281 | write_logs(); save_session_vars(); |
||
1282 | goto outgo; |
||
1283 | } |
||
1284 | if(ismhelp) { |
||
1285 | mhelp(); |
||
1286 | } |
||
1287 | else { |
||
1288 | main_phtml_put(html_file); |
||
1289 | if(lastout_file!=-1) { |
||
12507 | bpr | 1290 | flushoutput(); close(lastout_file); putlastout(); |
10 | reyssat | 1291 | } |
12263 | bpr | 1292 | write_logs(); save_session_vars(); |
1293 | } |
||
1294 | outgo: |
||
1295 | debug_output(); |
||
1296 | if (trace_file) { fclose(trace_file); trace_file=NULL; } |
||
1297 | if(var_str!=stdinbuf) free(var_str); |
||
1298 | delete_pid(); |
||
1299 | if(mode!=mode_popup && trusted_module()) { |
||
1300 | p=getvar("wims_mode"); |
||
1301 | if(p!=NULL && strcmp(p,"popup")==0) mode=mode_popup; |
||
1302 | } |
||
1303 | if(mode==mode_popup && insert_no==0) { |
||
1304 | p=getvar("wims_mode"); |
||
1305 | if(p!=NULL && strcmp(p,"popup")==0) { |
||
1306 | remove_tree(session_prefix); |
||
7673 | bpr | 1307 | |
12263 | bpr | 1308 | remove_tree(s2_prefix); |
10 | reyssat | 1309 | } |
12263 | bpr | 1310 | } |
1311 | return 0; |
||
10 | reyssat | 1312 | } |