Subversion Repositories wimsdev

Rev

Rev 17822 | 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
 */
7673 bpr 17
/* routines to process variables */
10 reyssat 18
 
8185 bpr 19
#include "wims.h"
10 reyssat 20
char *computed_var_start; /* pointer to read-in var def file */
21
int session_var_ready=0;
22
char last_host[32]="";
23
char *robotcheck="";
24
 
25
char *header_var_name[]={
26
    "REMOTE_ADDR", "HTTP_REFERER", "QUERY_STRING", "HTTP_USER_AGENT",
27
     "HTTP_COOKIE"
28
};
29
#define HEADER_VAR_NO (sizeof(header_var_name)/sizeof(header_var_name[0]))
30
 
8368 bpr 31
struct special_name {char *name; int value;} special_name[]={
8479 bpr 32
  {"MAX_EXAMS",MAX_EXAMS},
8368 bpr 33
  {"MAX_EXOS",MAX_EXOS},
14769 guerimand 34
  {"MAX_FREEWORKS",MAX_FREEWORKS},
15743 guerimand 35
  {"MAX_LTECHVAR",MAX_LTECHVAR},
8368 bpr 36
  {"MAX_OEFCHOICES",MAX_OEFCHOICES},
37
  {"MAX_OEFREPLIES",MAX_OEFREPLIES},
38
  {"MAX_SHEETS",MAX_SHEETS},
12021 guerimand 39
  {"MAX_TECHVARVAL",MAX_TECHVARVAL},
14329 guerimand 40
  {"MAX_USERFORGRADES",MAX_USERFORGRADES},
8368 bpr 41
  {"MAX_VOTES",MAX_VOTES},
42
};
43
int special_name_no=(sizeof(special_name)/sizeof(special_name[0]));
10 reyssat 44
char *var_allow[]={
45
    "deny" , "init" , "config" ,
46
      "reply", "any", "help"
47
};
48
enum {
7673 bpr 49
    var_allow_deny, var_allow_init, var_allow_config,
10 reyssat 50
      var_allow_reply, var_allow_any, var_allow_help
51
} VAR_ALLOWS;
52
#define VAR_ALLOW_NO (sizeof(var_allow)/sizeof(var_allow[0]))
53
 
12381 bpr 54
struct internal_name internaldef_name[]={
55
  {"exotrymax",var_allow_init}
56
};
57
int INTERNALDEF_NAME_NO=(sizeof(internaldef_name)/sizeof(internaldef_name[0]));
58
 
7673 bpr 59
/* install a temporary directory for the session */
10 reyssat 60
void mktmpdir(char *p)
61
{
12216 bpr 62
  char *base;
63
  if(p==NULL || *p==0 || strstr(p,"robot")!=NULL) return;
64
  if(strstr(tmp_dir,"sessions")!=NULL) return;
65
  if(ftest("../chroot/tmp/sessions/.chroot")==is_file) base="chroot/tmp";
66
  else base="tmp";
67
  mkfname(tmp_dir,"../%s/sessions/%s",base,p);
68
  remove_tree(tmp_dir); mkdirs(tmp_dir);
69
  chmod(tmp_dir,S_IRUSR|S_IWUSR|S_IXUSR
7673 bpr 70
       |S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH);
12216 bpr 71
  setenv("tmp_dir",tmp_dir,1); setenv("TMPDIR",tmp_dir,1);
10 reyssat 72
}
73
 
7673 bpr 74
/* Open session variable file */
10 reyssat 75
FILE *fopen_session_var_file(char read_or_write[])
76
{
12216 bpr 77
  char *nbuf; FILE *f;
10 reyssat 78
 
12216 bpr 79
  nbuf=mkfname(NULL,"%s/var",session_prefix);
80
  if(read_or_write[0]=='r') {
81
    if(open_working_file(&m_file,nbuf)!=0) return NULL;
82
    mkfname(m_file.name,"session_var");
83
    return stdin;
84
  }
85
  f=fopen(nbuf,read_or_write);
86
  if(f==NULL) {
7673 bpr 87
/* expired_session */
12216 bpr 88
    internal_error("fopen_session_var_file(): unable to create session variable file.");
89
  }
90
  mkfname(m_file.name,"session_var");
91
  m_file.l=0;
92
  return f;
10 reyssat 93
}
94
 
7673 bpr 95
/* Open a module file, read only, with name checking.
8155 bpr 96
 * returns NULL if error.
97
 */
10 reyssat 98
int read_module_file(char *fname)
99
{
12216 bpr 100
  char nbuf[MAX_FNAME+1];
10 reyssat 101
 
12216 bpr 102
  if(get_cached_file(fname)>=0) return 0;
103
  if(find_module_file(fname,nbuf,0)) return -1;
104
  if(open_working_file(&m_file,nbuf)!=0) return -1;
105
  untrust|=(untrust>>8);
106
  mystrncpy(m_file.name,fname,sizeof(m_file.name));
107
  if(strncmp(module_prefix,module_dir,strlen(module_dir))!=0) m_file.nocache|=8;
108
  return 0;
10 reyssat 109
}
12011 bpr 110
/* list of variables get from the query parms */
10 reyssat 111
int varget[]={ro_module,ro_lang,ro_useropts,ro_worksheet};
112
#define varget_no (sizeof(varget)/sizeof(varget[0]))
113
 
7673 bpr 114
/* set up ref strings according to protocol */
10 reyssat 115
void set_protocol(void)
116
{
12216 bpr 117
  if(strcmp(protocol,"https")!=0) return;
118
  if(strncmp(ref_name,"http:",5)==0) {
119
    string_modify(ref_name,ref_name+4,ref_name+4,"s");
120
    string_modify(ref_base,ref_base+4,ref_base+4,"s");
121
    force_setvar("wims_ref_name",ref_name);
122
  }
10 reyssat 123
}
124
 
7673 bpr 125
/* verify class participant connection data */
10 reyssat 126
void classlock(void)
127
{
12216 bpr 128
  int lvl;
129
  char *p;
7673 bpr 130
 
12216 bpr 131
  p=getvar("wims_classlock"); if(p==NULL) lvl=0; else {
132
    p=find_word_start(p);
133
    lvl=*p-'0'; if(lvl<0 || lvl>7) lvl=0;
134
  }
135
  if(lvl==7) { /* closed */
136
    p=getvar("wims_user");
137
    if(p==NULL || strcmp(p,"supervisor")!=0) user_error("class_closed");
138
  }
139
  if(lvl==2 || lvl==4 || lvl==6) { /* https */
140
    p=getenv("HTTPS");
141
    if(p==NULL || strcasecmp(p,"on")!=0) user_error("need_https");
142
  }
143
  if(lvl==3 || lvl>=5) {
144
    if(strcmp(last_host,remote_addr)!=0) user_error("bad_host");
145
  }
146
  if((lvl==1 || lvl>=4) && cookiegot[0]==0) { /* cookie */
147
    setcookie=1;
148
    setvar("cookie_module",getvar(ro_name[ro_module]));
149
    setvar("cookie_cmd",getvar(ro_name[ro_cmd]));
150
    force_setvar(ro_name[ro_module],home_module);
151
    force_setvar(ro_name[ro_cmd],commands[cmd_new]);
152
    setvar("wims_askcookie","yes");
153
    return;
154
  }
155
  else setcookie=0;
10 reyssat 156
}
157
 
7673 bpr 158
/* get static session variables */
10 reyssat 159
void get_static_session_var(void)
160
{
12216 bpr 161
  char *p, *pe, *p2, *p3;
162
  char sbuf[MAX_FNAME+1], tbuf[MAX_LINELEN+1];
163
  mystrncpy(sbuf,session_prefix,sizeof(sbuf));
164
  for(p=sbuf+strlen(sbuf);p>sbuf && *p!='_' && *p!='/'; p--);
165
  if(p>sbuf && *p=='_') *p=0;
166
  accessfile(tbuf,"r","%s/var.stat",sbuf);
167
  p=strrchr(sbuf,'/'); if(p!=NULL) p++; else p=sbuf;
168
  mktmpdir(p);
169
  for(p=find_word_start(tbuf);*p;p=find_word_start(pe)) {
170
    pe=strchr(p,'\n'); if(pe!=NULL) *pe++=0; else pe=p+strlen(p);
171
    p2=strchr(p,'='); if(p2==NULL) continue;
172
    *p2++=0; force_setvar(p,p2);
173
  }
174
  p=getvar("wims_class"); if(p==NULL || *p==0) return;
175
  mkfname(class_dir,"%s/%s",class_base,p);
176
  classlock();
177
  p3=getvar("wims_class_refcolor");
178
  if(p3!=NULL && *p3!=0) force_setvar("wims_ref_bgcolor",p3);
179
  p3=getvar("wims_class_ref_menucolor");
180
  if(p3!=NULL && *p3!=0) force_setvar("wims_ref_menucolor",p3);
181
  p3=getvar("wims_class_ref_button_color");
182
  if(p3!=NULL && *p3!=0) force_setvar("wims_ref_button_color",p3);
183
  p3=getvar("wims_class_ref_button_bgcolor");
184
  if(p3!=NULL && *p3!=0) force_setvar("wims_ref_button_bgcolor",p3);
185
  p3=getvar("wims_class_ref_button_help_bgcolor");
186
  if(p3!=NULL && *p3!=0) force_setvar("wims_ref_button_help_bgcolor",p3);
187
  p3=getvar("wims_class_ref_button_help_color");
188
  if(p3!=NULL && *p3!=0) force_setvar("wims_ref_button_help_color",p3);
189
  p2=getvar(ro_name[ro_module]);
190
  if(p2==NULL || strncmp(p2,"classes/",strlen("classes/"))!=0) return;
191
  mkfname(sbuf,"classes/%s",lang);
192
  if(strcmp(sbuf,p2)!=0) force_setvar(ro_name[ro_module],sbuf);
10 reyssat 193
}
194
 
7673 bpr 195
/* set one static session variable */
10 reyssat 196
void set_static_session_var(char *name, char *val)
197
{
12216 bpr 198
  char *p;
199
  char sbuf[MAX_FNAME+1], tbuf[MAX_LINELEN+1];
200
  mystrncpy(sbuf,session_prefix,sizeof(sbuf));
201
  for(p=sbuf+strlen(sbuf);p>sbuf && *p!='_' && *p!='/'; p--)
202
  ;
203
  if(p>sbuf && *p=='_') *p=0;
204
  snprintf(sbuf+strlen(sbuf),sizeof(sbuf)-strlen(sbuf),"/var.stat");
205
  snprintf(tbuf,sizeof(tbuf),"%s=%s",name,val);
206
  setdef(sbuf,tbuf); setvar(name,val);
10 reyssat 207
}
208
 
7673 bpr 209
/* The session is probably robot. */
10 reyssat 210
void robot_doubt(void)
211
{
12216 bpr 212
  char *h, *p;
7673 bpr 213
 
12216 bpr 214
  p=getvar("special_parm"); h=getvar("module");
215
  if(p==NULL || h==NULL) {
216
    bad: user_error("robot_doubt"); return;
217
  }
218
  p=find_word_start(p); strip_trailing_spaces(p);
219
  if(strcmp(p,"wims")!=0 || strcmp(h,home_module)!=0) goto bad;
220
  set_static_session_var("wims_robotcheck","manual");
10 reyssat 221
}
222
 
7673 bpr 223
/* User has changed module within an operation.
8155 bpr 224
 * Probably due to robot access.
225
 */
10 reyssat 226
void bad_module(void)
227
{
12216 bpr 228
  char *p;
229
  p=getvar("wims_user"); if(p==NULL) p="";
230
  if(*p==0 && strcmp(robotcheck,"manual")!=0) set_static_session_var("wims_robotcheck","robot");
231
  else setvar("wims_human_access","yes");
232
  user_error("module_change");
10 reyssat 233
}
234
 
7673 bpr 235
/* returns 1 if session directory exists */
10 reyssat 236
int session_exists(char *s)
237
{
12216 bpr 238
  if(ftest(mkfname(NULL,"../%s/%s/var",SESSION_BASE,s))==is_file) return 1;
239
  else return 0;
10 reyssat 240
}
241
 
7673 bpr 242
/* Check the validity of session number .
8155 bpr 243
 * returns 0 if OK, else -1.
244
 */
10 reyssat 245
int check_session(void)
246
{
12216 bpr 247
  char tbuf[MAX_LINELEN+1], vbuf[MAX_LINELEN+1];
248
  char *p, *pp, *pr;
249
  int i,m,n,pl,rapid,badmod;
250
  struct stat st;
10 reyssat 251
 
12216 bpr 252
  rapid=badmod=0; pr="";
253
  if(fopen_session_var_file("r")==NULL) return -1;
254
  if(ftest(s2_prefix)!=is_dir) mkdirs(s2_prefix);
255
  session_var_ready=1; memmove(&svar_file,&m_file,sizeof(WORKING_FILE));
7673 bpr 256
/* REMOTE_ADDR */
12216 bpr 257
  wgetline(vbuf,MAX_LINELEN,&m_file);
258
  mystrncpy(last_host,vbuf+strlen("REMOTE_ADDR="),sizeof(last_host));
259
  m_file.linepointer++; /* now it points to query_string */
260
  pp=getenv("QUERY_STRING");
261
  if(pp!=NULL && *pp!=0 && strlen(pp)<=MAX_LINELEN) {
7673 bpr 262
/* we compare the query string with the last one. */
12216 bpr 263
    char *p1, *p2;
264
    wgetline(tbuf,MAX_LINELEN,&m_file);
265
    p1=tbuf+strlen("QUERY_STRING=");
266
    if(strncmp(tbuf,"QUERY_STRING=",strlen("QUERY_STRING="))==0 &&
7673 bpr 267
        strcmp(pp,p1)==0 && strstr(session_prefix,"_test")==NULL) {
268
/* query string does not change */
12216 bpr 269
      if(ftest(mkfname(NULL,"%s/%s",s2_prefix,lastout))==is_file &&
7673 bpr 270
            ftest_size > 0) {
12216 bpr 271
        uselast:
272
        putlastout(); delete_pid(); exit(0);
273
      }
274
      else {
275
        if(cmd_type==cmd_new || cmd_type==cmd_renew ||
7673 bpr 276
             cmd_type==cmd_reply || cmd_type==cmd_next) {
12216 bpr 277
          cmd_type=cmd_resume;
278
          force_setvar(ro_name[ro_cmd],"resume");
279
          forceresume=1;
280
        }
281
      }
282
    }
7673 bpr 283
/* stop rapidfire requests */
12216 bpr 284
    if((cmd_type==cmd_new || cmd_type==cmd_renew) &&
7673 bpr 285
        strncmp(p1,"session=",strlen("session="))==0 &&
286
        strncmp(pp,"session=",strlen("session="))==0) {
12216 bpr 287
      p1=strchr(p1,'&'); if(p1==NULL) p1="";
288
      p2=strchr(pp,'&'); if(p2==NULL) p2=""; pr=p2;
289
      if(strcmp(p1,p2)==0) rapid=1;
10 reyssat 290
    }
12216 bpr 291
  }
292
  m_file.linepointer=3;
293
  wgetline(vbuf,MAX_LINELEN,&m_file); /* stored user_agent */
10 reyssat 294
/*    p=getenv("HTTP_USER_AGENT"); if(p==NULL) p="";
295
    if(strcmp(vbuf+strlen("HTTP_USER_AGENT="),p)!=0) bad_ident(); */
12216 bpr 296
  m_file.linepointer=HEADER_VAR_NO;
297
  pl=strlen(var_prefix);i=-1;
298
  while(wgetline(tbuf,MAX_LINELEN,&m_file)!=EOF) {
299
    if(tbuf[0]==0) break; /* blank line */
300
    if(strncmp(tbuf,var_prefix,pl)!=0) break;
301
    i++;if(i>=RO_NAME_NO) break;
302
    for(n=0;n<varget_no && varget[n]!=i;n++)
303
    ;
304
      if(n>=varget_no) continue;
305
    m=pl+strlen(ro_name[i]);
306
    if(tbuf[m]!='=' || tbuf[m+1]==0) continue;
307
    if(i==ro_module && cmd_type!=cmd_new && cmd_type!=cmd_intro && cmd_type!=cmd_help) {
308
      char *pp;
309
      pp=getvar(ro_name[i]);
310
      if(pp!=NULL && *pp!=0 && strcmp(pp,tbuf+m+1)!=0) badmod=1;
10 reyssat 311
    }
12216 bpr 312
    if(i==ro_lang && !user_lang)
313
      force_setvar(ro_name[i],tbuf+m+1);
314
    else setvar(ro_name[i],tbuf+m+1);
315
  }
7673 bpr 316
/* recover internal variables */
12216 bpr 317
  do
318
  {
319
    char *v;
320
    if(tbuf[0]==0) break;
321
    v=strchr(tbuf,'=');
322
    if(v==NULL) break; else *(v++)=0;
323
    if(strncmp(tbuf,var_prefix,strlen(var_prefix))!=0) setenv(tbuf,v,1);
324
    else if(tbuf[strlen(var_prefix)]) force_setvar(tbuf+strlen(var_prefix),v);
325
  }
326
  while(wgetline(tbuf,MAX_LINELEN,&m_file)!=EOF);
327
  get_static_session_var();
328
  robotcheck=getvar("wims_robotcheck"); if(robotcheck==NULL) robotcheck="";
7673 bpr 329
/* form access means manual access. Mark this. */
12216 bpr 330
  if(form_access && strcmp(robotcheck,"manual")!=0) {
331
    robotcheck="manual";
332
    set_static_session_var("wims_robotcheck","manual");
333
  }
334
  else if(strcmp(robotcheck,"robot")==0) robot_doubt();
335
  if(badmod) bad_module();
336
  if(cookiegot[0]!=0) {
337
    p=getvar("wims_sescookie");
338
    if(p!=NULL && *p!=0 && strcmp(cookiegot,p)!=0) bad_ident();
339
  }
340
  p=getvar("wims_sreferer");
341
  if(p!=NULL && *p!=0) {
342
    setenv("HTTP_REFERER",p,1); setvar("httpd_HTTP_REFERER",p);
343
  }
344
  if(rapid) {
345
    int rapidfiredelay;
346
    char *pw, fnbuf[MAX_FNAME+1];
347
/* Delay: 10 seconds within worksheets, 1 second otherwise. */
348
    pw=getvar("wims_developer");
349
    if(pw!=NULL && *pw!=0) goto delcheckend;
350
    pw=getvar("wims_user");
351
    if(pw==NULL || *pw==0 || strcmp(pw,"supervisor")==0) rapidfiredelay=1;
352
    else {
353
      pw=strstr(pr,"&+worksheet=");
354
      if(pw!=NULL && myisdigit(*(pw+strlen("&+worksheet=")))) rapidfiredelay=10;
355
        else rapidfiredelay=2;
10 reyssat 356
    }
12216 bpr 357
    if(ftest(mkfname(fnbuf,"%s/%s",s2_prefix,lastout))==is_file
7673 bpr 358
        && ftest_size > 0
359
        && stat(fnbuf,&st) == 0
360
        && st.st_mtime > nowtime-rapidfiredelay && st.st_mtime <= nowtime)
12216 bpr 361
      goto uselast;
362
  }
7673 bpr 363
/* set protocol string */
12216 bpr 364
  delcheckend: pp=getvar("wims_protocol");
365
  if(pp!=NULL && strcmp(pp,"https")==0) {
366
    protocol="https"; set_protocol();
367
  }
368
  useropts(); return 0;
10 reyssat 369
}
7673 bpr 370
/* check whether a session is trapped. */
10 reyssat 371
void trap_check(char *s)
372
{
12216 bpr 373
  char buf[64];
374
  char *p;
375
  time_t t1;
10 reyssat 376
 
12216 bpr 377
  setvar("wims_session_expired",s);
378
  accessfile(tmplbuf,"r","../tmp/log/trap.check");
379
  if(tmplbuf[0]==0) return;
380
  p=getenv("REMOTE_ADDR");if(p==NULL) return;
381
  snprintf(buf,sizeof(buf),":%s,%s,",s,p);
382
  p=strstr(tmplbuf,buf); if(p==NULL) return;
383
  p+=strlen(buf);*find_word_end(p)=0;
384
  t1=atoi(p);
385
  if(t1>nowtime) user_error("trapped");
10 reyssat 386
}
387
 
388
char cars[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
389
 
390
void set_cookie(void)
391
{
12216 bpr 392
  #define keylen 20
393
  char sesbuf[16], keybuf[keylen+8];
394
  char *p;
10 reyssat 395
 
12216 bpr 396
  p=getvar(ro_name[ro_session]); if(p==NULL) return;
397
  mystrncpy(sesbuf,p,sizeof(sesbuf));
398
  if(strchr(sesbuf,'_')==NULL) { /* main session */
399
    int i;
400
    for(i=0;i<keylen;i++) keybuf[i]=cars[random()%36];
401
    keybuf[keylen]=0; cookiegot[0]=0;
402
    snprintf(cookieset,sizeof(cookieset),"%s-%s",sesbuf,keybuf);
403
    set_static_session_var("wims_sescookie",cookieset);
404
    setcookie=1;
405
  }
406
  else { /* subsession */
407
    p=getvar("wims_sescookie"); if(p && *p)
408
    mystrncpy(cookieset,p,sizeof(cookieset));
409
  }
10 reyssat 410
}
411
 
7673 bpr 412
/* create a session number */
10 reyssat 413
void create_session(void)
414
{
12216 bpr 415
  long t; char session_str[64],*s;
416
  char *p, ses_dir_buf[MAX_FNAME+1], sesrandbuf[MAX_LINELEN+1];
417
  int i;
7673 bpr 418
 
419
/* no session is created for robots */
12216 bpr 420
  if(robot_access) return;
421
  sesrandbuf[0]=0;
7673 bpr 422
/* If session is given in request_string: use it. */
12216 bpr 423
  s=getvar(ro_name[ro_session]); if(s==NULL) goto creat;
424
  mystrncpy(session_str,s,sizeof(session_str));
425
  s=strchr(session_str,'.'); if(s!=NULL) *s=0;
426
  s=session_str;
427
  if(*s!=0) {
428
    int i;
429
    mkfname(ses_dir_buf,"%s/%s",session_dir,s);
430
    i=ftest(ses_dir_buf);
431
    if(i<0) {
432
      trap_check(s);
7673 bpr 433
/* subsession */
12216 bpr 434
      if(strlen(s)>10 && strchr(s,'_')!=NULL) {
435
        char *tt;
436
        tt=strrchr(ses_dir_buf,'_'); if(tt!=NULL) *tt=0;
7673 bpr 437
/* parent session gone. */
12216 bpr 438
        if(ftest(ses_dir_buf)<0) goto creat;
439
        goto creat2;
440
      }
441
      else goto creat;
10 reyssat 442
    }
12216 bpr 443
    if(i!=is_dir) {
444
      trap_check(s);
445
      remove_tree(ses_dir_buf); goto creat;
446
    }
447
    return;
448
  }
449
  creat:
450
  t=create_job_ident();
451
  for(i=0;i<MAX_SESRANDOM;i++)
452
    snprintf(sesrandbuf+strlen(sesrandbuf),
7673 bpr 453
            sizeof(sesrandbuf)-strlen(sesrandbuf),
454
            "%d,",sesrandomtab[i]);
12216 bpr 455
  sesrandbuf[strlen(sesrandbuf)-1]='\n';
456
  snprintf(session_str,sizeof(session_str),"%c%c%08lX",
7673 bpr 457
          cars[random()%36],cars[random()%36],t);
12216 bpr 458
  creat2:
459
  force_setvar(ro_name[ro_session],session_str);
460
  setsesdir(session_str);
7673 bpr 461
/* check whether the environment is created. */
12216 bpr 462
  s=getvar(ro_name[ro_session]);
463
  if(s==NULL || strcmp(s,session_str))
464
    internal_error("cannot_create_session_number");
465
  snprintf(ses_dir_buf,sizeof(ses_dir_buf)-100,"%s/%s",
7673 bpr 466
          session_dir,session_str);
12216 bpr 467
  if(mkdir(ses_dir_buf,S_IRWXU)==-1)
468
    internal_error("cannot_create_session_directory");
469
  mkfname(s2_prefix,"%s/%s",s2_dir,session_str);
470
  if(mkdir(s2_prefix,S_IRWXU)==-1) mkdirs(s2_prefix);
471
  mystrncpy(session_prefix,ses_dir_buf,sizeof(session_prefix)); create_pid();
472
  if(strchr(session_str,'_')==NULL) {
473
    if((s=getenv("HTTP_REFERER"))!=NULL && *s!=0 && strlen(s)<MAX_FNAME-20
7673 bpr 474
        && strstr(s,"wims")==NULL) {
12216 bpr 475
      char *tt;
476
      tt=getenv("SERVER_NAME");
477
      if(tt==NULL || *tt==0 || strstr(s,tt)==NULL)
478
        set_static_session_var("wims_sreferer",s);
10 reyssat 479
    }
12216 bpr 480
    if(sesrandbuf[0]) set_static_session_var("wims_sesrandom",sesrandbuf);
481
  }
7673 bpr 482
/* determine http protocol name. How to detect? */
12216 bpr 483
  p=getenv("HTTPS"); if(p!=NULL && strcmp(p,"on")==0) {
10 reyssat 484
      protocol="https"; set_protocol();
12216 bpr 485
  }
486
  force_setvar("wims_protocol",protocol);
487
  new_session=1; session_serial=0;
488
  setvar("wims_new_session","yes");
489
  if(strchr(session_str,'_')!=NULL) get_static_session_var();
490
  set_cookie();
10 reyssat 491
}
492
 
7673 bpr 493
/* Register time of the request. */
10 reyssat 494
void set_req_time(void)
495
{
12216 bpr 496
  char tstr[64];
7673 bpr 497
 
12216 bpr 498
  snprintf(tstr,sizeof(tstr),"%04d-%02d-%02d.%02d:%02d:%02d=%lu",
7673 bpr 499
         (now->tm_year)+1900, (now->tm_mon)+1, now->tm_mday,
500
         now->tm_hour, now->tm_min, now->tm_sec, nowtime);
12216 bpr 501
  force_setvar("wims_req_time",tstr);
502
  if(cmd_type == cmd_new || cmd_type == cmd_renew)
503
    force_setvar("wims_module_start_time",tstr);
504
  if(new_session) force_setvar("wims_session_start_time",tstr);
10 reyssat 505
}
12011 bpr 506
/* choose a seed and put in in wims_seed*/
507
void seed_time(void)
508
{
12216 bpr 509
  int r; char buf[64];
510
  struct timeval t;
511
  gettimeofday(&t,NULL);
512
  r=t.tv_usec+t.tv_sec*1000;
513
  if(r<=0) r=1-r;
514
  snprintf(buf,sizeof(buf),"%d",r);
515
  force_setvar("wims_seed",buf);
12011 bpr 516
}
10 reyssat 517
 
7673 bpr 518
/* set up module_prefix. */
10 reyssat 519
void set_module_prefix(void)
520
{
12216 bpr 521
  char tbuf[MAX_FNAME+1], mmbuf[MAX_FNAME+1], *p, *pp, *ps;
522
  int t,ft;
523
  struct stat st;
10 reyssat 524
 
12216 bpr 525
  isclassmodule=0;
526
  p=getvar(ro_name[ro_module]);
527
  if(p==NULL || *p==0) user_error("no_module_name");
7673 bpr 528
/* security measure: we should not allow users to go back to
8155 bpr 529
 * parent directories.
530
 */
12216 bpr 531
  if(strstr(p,parent_dir_string)!=NULL) user_error("wrong_module");
532
  if(strncmp(p,"classes/",strlen("classes/"))==0) isclassmodule=1;
533
  if(strncmp(p,"devel/",strlen("devel/"))==0) isdevelmodule=1;
534
  mkfname(module_prefix,"%s/%s",module_dir,p);
7673 bpr 535
/* Now no symbolic link should appear in the module path. */
12216 bpr 536
  mkfname(tbuf,"modules/%s",p);
537
  for(t=0,ps=pp=strchr(tbuf+strlen("modules/"),'/'); pp;
538
  *pp='/', ps=pp, pp=strchr(pp+1,'/'), t++) {
539
  *pp=0; if(lstat(tbuf,&st)) user_error("wrong_module");
540
  if(t>0 && S_ISLNK(st.st_mode)) {
541
    if(strcmp(ps,"/local")!=0 ||
542
          strncmp(tbuf,"modules/home",strlen("modules/home"))==0)
543
      user_error("wrong_module");
10 reyssat 544
    }
12216 bpr 545
  }
7673 bpr 546
/* Check validity of the module. */
12216 bpr 547
  mkfname(tbuf,"%s/%s",module_prefix,html_file);
548
  ft=stat(tbuf,&st);
549
  if(ft!=0 && p[strlen(p)-3]!='.') {
550
    int i,j;
551
    char *l;
552
    l=getvar(ro_name[ro_lang]);
553
    j=available_lang_no;
554
    for(i=-1;i<j && ft!=0;i++) {
555
      if(i<0) mkfname(mmbuf,"%s.%s",p,l);
556
      else mkfname(mmbuf,"%s.%s",p,available_lang[i]);
557
      mkfname(module_prefix,"%s/%s",module_dir,mmbuf);
558
      mkfname(tbuf,"%s/%s",module_prefix,html_file);
559
      ft=stat(tbuf,&st);
10 reyssat 560
    }
12216 bpr 561
    if(ft==0) force_setvar(ro_name[ro_module],mmbuf);
562
  }
563
  if(ft!=0 && !isclassmodule) user_error("wrong_module");
564
  setenv("module_dir",module_prefix,1); setvar("module_dir",module_prefix);
565
  module_index();
10 reyssat 566
}
567
 
7673 bpr 568
/* set up session_prefix. */
10 reyssat 569
int set_session_prefix(void)
570
{
12216 bpr 571
  char *p, s[32];
10 reyssat 572
 
12216 bpr 573
  if(robot_access) {
574
    mystrncpy(session_prefix,robot_session,sizeof(session_prefix));
575
    mystrncpy(s2_prefix,robot_session,sizeof(session_prefix));
576
    return 0;
577
  }
578
  p=getvar(ro_name[ro_session]);
579
  if(p==NULL || *p==0) user_error("no_session");
7673 bpr 580
/* same reason as for modules */
12216 bpr 581
  if (strchr(p,'/')!=NULL || strstr(p,parent_dir_string)!=NULL
7673 bpr 582
     || *find_word_end(p)!=0) user_error("wrong_session");
12216 bpr 583
  mystrncpy(s,p,sizeof(s));
584
  p=strchr(s,'.'); if(p!=NULL) *p=0;
585
  mkfname(session_prefix,"%s/%s",session_dir,s);
586
  p=strstr(session_prefix,"_mhelp"); if(p!=NULL) *p=0;
587
  if(ftest(session_prefix)!=is_dir) return -1;
588
  mkfname(s2_prefix,"%s/%s",s2_dir,s);
589
  setenv("session_dir",session_prefix,1);
590
  setenv("s2_dir",s2_prefix,1);
591
  if(ftest(mkfname(NULL,"%s/.trap",s2_prefix))==is_file)
10 reyssat 592
      user_error("trapped");
12216 bpr 593
  return 0;
10 reyssat 594
}
595
 
7673 bpr 596
/* check reserved name values in query_string */
10 reyssat 597
void parse_ro_names(void)
598
{
12216 bpr 599
  int i;
600
  char *cmd, *p;
601
  char sesbuf[64];
602
  create:
603
  cmd=getvar(ro_name[ro_cmd]);
604
  if(cmd==NULL || *cmd==0) user_error("no_command");
605
  for(i=0;i<CMD_NO;i++) if(strcmp(cmd,commands[i])==0) break;
606
  if(i>=CMD_NO) user_error("bad_command");
607
  cmd_type=i;
608
  if(cmd_type == cmd_new) {
609
    create_session();
610
    if(set_session_prefix()==0) {
611
      check_session();
612
      set_module_prefix();
10 reyssat 613
    }
12216 bpr 614
    else goto redo;
615
  }
616
  if (set_session_prefix()==-1 || (cmd_type != cmd_new && check_session())) {
617
    redo:
618
    force_setvar(ro_name[ro_cmd],commands[cmd_new]);
619
    if(strcmp(ro_name[ro_module],home_module)!=0) user_var_no=0;
7673 bpr 620
     goto create;
12216 bpr 621
  }
622
  if(!new_session) create_pid();
623
  session_serial++;
624
  if(robot_access) session_serial=1;
625
  snprintf(sesbuf,sizeof(sesbuf),"%d",session_serial);
626
  force_setvar("wims_session_serial",sesbuf);
627
  p=getvar(ro_name[ro_session]);
628
  if(p==NULL || *p==0) internal_error("parse_ro_names(): bad session.\n");
629
  mystrncpy(sesbuf,p,sizeof(sesbuf));
630
  p=strchr(sesbuf+5,'.');
631
  if(p!=NULL) *p=0;
632
  mktmpdir(sesbuf);
633
  if(!robot_access) {
634
    setsesdir(sesbuf);
635
    p=strchr(sesbuf,'_');
636
    if(p!=NULL) force_setvar("wims_subsession",p);
637
  }
638
  snprintf(sesbuf+strlen(sesbuf),sizeof(sesbuf)-strlen(sesbuf),
7673 bpr 639
          ".%d",session_serial);
12216 bpr 640
  force_setvar(ro_name[ro_session],sesbuf);
641
  if(cmd_type != cmd_new) set_module_prefix();
642
  set_req_time();
643
  if(robot_access) check_load(0);
644
  else {
645
    if(new_session) auth();
10 reyssat 646
    else {
12216 bpr 647
      p=getvar("wims_user"); if(p==NULL || *p==0) check_load(2);
10 reyssat 648
    }
12216 bpr 649
  }
650
  if(cmd_type==cmd_help && open_working_file(&m_file,module_about_file)==0)
651
    var_proc(NULL,0);
10 reyssat 652
}
653
 
654
 
7673 bpr 655
/* returns positive or 0 if var_def found, otherwise returns -1. */
10 reyssat 656
int var_def_check(char *name)
657
{
12216 bpr 658
  char *p, nbuf[MAX_NAMELEN+1];
659
  int i,tt;
7673 bpr 660
 
12216 bpr 661
  tt=-1;
662
  for(p=name+strlen(name);p>name && myisdigit(*(p-1));p--)
663
  ;
664
  if(*p && *p!='0' && p>name) tt=atoi(p);
665
  else p=name+strlen(name);
666
  if(p>name+MAX_NAMELEN) p=name+MAX_NAMELEN;
667
  memmove(nbuf,name,p-name); nbuf[p-name]=0;
668
  i=search_list(var_def,defined_var_total,sizeof(var_def[0]),nbuf);
669
  if(i<0) return -1;
670
  while(i>0 && tt<var_def[i].beg && strcmp(nbuf,var_def[i-1].name)==0) i--;
671
  while(i<defined_var_total-1 && tt>var_def[i].end &&
7673 bpr 672
           strcmp(nbuf,var_def[i+1].name)==0) i++;
12216 bpr 673
  if(tt<var_def[i].beg || tt>var_def[i].end) return -1;
674
  return i;
10 reyssat 675
}
676
 
677
int var_def_name(char *n, int v)
678
{
12216 bpr 679
  char *q, *r;
680
  int j;
681
  if(strlen(n)>=MAX_NAMELEN) module_error("defn_too_long");
682
  var_def[v].name=n;
683
  if((strncmp(n,wims_prefix,wpflen)==0 &&
684
        (strncmp(n,"wims_priv_",strlen("wims_priv_"))==0 ||
685
        search_list(internal_name,INTERNAL_NAME_NO,
7673 bpr 686
               sizeof(internal_name[0]),n+wpflen)>=0)) ||
12216 bpr 687
          search_list(ro_name,RO_NAME_NO,sizeof(ro_name[0]),n)>=0) {
688
    setvar("wims_reserved_name",n);
689
    module_error("name_is_reserved");
690
  }
691
  for(q=n;myisalnum(*q) || *q=='_'; q++);
692
  if(q==n) {
693
    illegal: setvar("wims_bad_name",n);
694
    module_error("illegal_name");
695
  }
8368 bpr 696
 
12216 bpr 697
  if(*q=='[') {
698
    *q++=0; r=find_matching(q,']');
699
    if(r==NULL) goto illegal;
700
    *r=0; int i;
701
    for(i=0;i<special_name_no && strcmp(q, special_name[i].name)!=0; i++);
702
    if(i<special_name_no) j=special_name[i].value; else j=atoi(q);
703
    if(j<1) j=1;
704
    if(j>MAX_VAR_NUM) j=MAX_VAR_NUM;
705
    var_def[v].beg=1; var_def[v].end=j;
706
    return j;
707
  }
708
  if(*q) goto illegal;
709
  for(r=q; r>n && myisdigit(*(r-1)); r--);
710
  if(*r && *r!='0' && r>n) {
711
    var_def[v].beg=var_def[v].end=atoi(r); *r=0;
712
  }
713
  else var_def[v].beg=var_def[v].end=-1;
714
  return 1;
10 reyssat 715
}
716
 
717
int var_def_allow(char *p, int v)
718
{
12216 bpr 719
  int i;
720
  for(i=0;i<VAR_ALLOW_NO && strcasecmp(p,var_allow[i])!=0; i++);
721
  if(i>=VAR_ALLOW_NO) module_error("bad_allow");
722
  else var_def[v].allow=i;
723
  return i;
10 reyssat 724
}
725
 
726
int varsort(const void *p1, const void *p2)
727
{
12216 bpr 728
  int i; const struct VAR_DEF *pp1, *pp2;
729
  pp1=p1; pp2=p2; i=strcmp(pp1->name,pp2->name);
730
  if(i) return i; else return pp1->end - pp2->end;
10 reyssat 731
}
732
 
12381 bpr 733
/* parse module's variable definitions */
10 reyssat 734
void get_var_defs(void)
735
{
12216 bpr 736
  int i, j, k, v, add;
737
  char *p, *p1, *wlist[MAX_VAR_NUM];
7673 bpr 738
 
12216 bpr 739
  defined_var_total=0;
740
  if(read_module_file(var_def_file)!=0) return;
741
  var_def_buf=m_file.textbuf;
742
  for(m_file.l=v=add=0;v<MAX_VAR_NUM && m_file.l<m_file.linecnt;m_file.l++) {
743
    if(m_file.lines[m_file.l].isstart!=1) continue;
744
    p=find_word_start(m_file.lines[m_file.l].address);
745
    if(*p==0 || *p==comment_prefix_char) continue;  /* empty or comment lines */
746
    items2words(p);
747
    if((p1=strchr(p,':'))!=NULL) {  /* new format */
748
      *p1=' '; i=cutwords(p,wlist,MAX_VAR_NUM); if(i<=1) continue;
749
      k=var_def_allow(wlist[0],v);
750
      for(j=1;j<i && v<MAX_VAR_NUM;j++) {
751
        add+=var_def_name(wlist[j],v); var_def[v].allow=k;
752
        v++;
753
      }
10 reyssat 754
    }
12216 bpr 755
    else {
756
      i=cutwords(p,wlist,3); if(i<2) module_error("too_few_columns");
12381 bpr 757
      add+=var_def_name(wlist[0],v);
758
      var_def_allow(wlist[1],v);
12216 bpr 759
      var_def[v].defined_in_parm=0;
760
      v++;
761
    }
762
  }
12381 bpr 763
  for(j=0;j<INTERNALDEF_NAME_NO;j++) {
764
    add+=var_def_name(internaldef_name[j].name,v);
765
    var_def[v].allow=internaldef_name[j].stat;
766
    v++;
767
  }
768
 
12216 bpr 769
  if(v>=MAX_VAR_NUM) module_error("too_many_variables");
770
  defined_var_total=v;
771
  qsort(var_def,v,sizeof(var_def[0]),varsort);
772
  p=getvar(ro_name[ro_module]);
773
  if(p==NULL || strncmp(p,"devel/",6)!=0) return;
774
  for(v=1;v<defined_var_total;v++) {
775
    if(strcmp(var_def[v].name,var_def[v-1].name)==0 &&
7673 bpr 776
        var_def[v].beg<=var_def[v-1].end) {
12381 bpr 777
      for(j=0;j<INTERNALDEF_NAME_NO;j++) {
778
        if(strcmp(internaldef_name[j].name,var_def[v-1].name)==0){
779
          setvar("wims_reserved_name",internaldef_name[j].name);
780
          module_error("name_is_reserved");
781
        }
782
      }
12216 bpr 783
      setvar("wims_bad_name",var_def[v].name);
784
      module_error("multiple_declaration");
12381 bpr 785
    }
12216 bpr 786
  }
10 reyssat 787
}
788
 
7673 bpr 789
/* returns 1 if hacked, else 0. */
10 reyssat 790
int try_hack(char *var)
791
{
12216 bpr 792
  int i, al;
793
  char vbuf[16];
794
  i=var_def_check(var);
795
  if(i<0) return 0;
796
  al=var_def[i].allow;
797
  if(al != var_allow_any) switch(cmd_type) {
798
    case cmd_new:
799
    case cmd_renew: {
800
      if (al != var_allow_init && al != var_allow_config) return 0;
801
      else break;
10 reyssat 802
    }
12216 bpr 803
    case cmd_config: {
804
      if(al != var_allow_config) return 0;
805
      else break;
806
    }
807
    case cmd_reply: {
808
      if(al != var_allow_reply) return 0;
809
      else break;
810
    }
811
    case cmd_help: {
812
      if(al != var_allow_help) return 0;
813
      else break;
814
    }
815
    default: return 0;
816
  }
817
  snprintf(vbuf,sizeof(vbuf),"%d",(int) irand(21));
818
  var_hacking=1; setvar(var,vbuf); var_hacking=0;
819
  return 1;
10 reyssat 820
}
7673 bpr 821
 
822
/* set environ variables from last session save
823
 * The session var file starts with variables which should not
824
 * be restored. Variables which are restored follow a blank line. */
10 reyssat 825
void set_vars_from_session(void)
826
{
12216 bpr 827
  char lbuf[MAX_LINELEN+1];
828
  int i;
829
  char *p;
10 reyssat 830
 
12216 bpr 831
  if(session_var_ready) memmove(&m_file,&svar_file,sizeof(WORKING_FILE));
832
  else fopen_session_var_file("r");
12522 bpr 833
  /* look for the first blank line. */
12216 bpr 834
  for(i=0;i<m_file.linecnt && (m_file.lines[i].isstart==0 || m_file.lines[i].llen>0);i++);
835
  for(i++;i<m_file.linecnt && m_file.lines[i].llen==0;i++);
836
  if(i>=m_file.linecnt) return;
837
  m_file.linepointer=i;
838
  if(isdevelmodule && strstr(session_prefix,"_test")==NULL) isdevelmodule=0;
839
  while(wgetline(lbuf,MAX_LINELEN, &m_file)!=EOF) {
840
    p=strchr(lbuf,'=');
841
    if(p==NULL || p<=lbuf || isspace(lbuf[0]) ) {
12522 bpr 842
  /* this time it is corrupted var file */
12216 bpr 843
      call_ssh("cat %s/var >%s/corrupt.var.bak",session_prefix,log_dir);
844
      internal_error("get_vars_from_session(): corrupt session variable file.");
845
    }
846
    *p=0;p++;
12522 bpr 847
    /* Here we suppose that nobody can tamper session variable
848
     * file, and do not check variable names against module's
849
     * definition file. Policy under reserve. */
850
    /* We do not allow override though.
851
     * Especially because reply variables should
852
     * be preserved. */
12216 bpr 853
    if(strncmp(lbuf,var_prefix,strlen(var_prefix))!=0)
854
      setenv(lbuf,p,0);
855
    else
856
      if(lbuf[strlen(var_prefix)]!=0 && getvar(lbuf+strlen(var_prefix))==NULL) {
857
        if(!isdevelmodule || !try_hack(lbuf+strlen(var_prefix))) {
7673 bpr 858
          setvar(lbuf+strlen(var_prefix),p);
12216 bpr 859
        }
860
      }
861
  }
862
  close_working_file(&m_file,0);
10 reyssat 863
}
864
 
11104 bpr 865
void start_tracefile(void)
866
{
867
  int i;
868
  putc('\n',trace_file);
869
  for(i=1; i<=2*trace_indent; i++) putc(' ',trace_file);
870
  fprintf(trace_file,"%s:",m_file.filepath);
871
  fflush(trace_file);
872
  trace_indent++;
873
}
874
 
875
void stop_tracefile(void)
876
{
877
  trace_indent--;
878
}
879
 
7673 bpr 880
/* Initialize environment variables according to module's
881
 * variable init or calculation file.
882
 * init is only used when cmd=new or renew.
883
 * Requires get_var_defs be run first. */
10 reyssat 884
void var_proc(char *fname,int cache)
885
{
12216 bpr 886
  int  t;
887
  char *p, tbuf[MAX_LINELEN+1];
10 reyssat 888
 
12216 bpr 889
  if(fname!=NULL && read_module_file(fname)) return;
890
  if(untrust&6) get_var_privileges();
891
  if (trace_file) start_tracefile();
892
  while(m_file.linepointer<m_file.linecnt) {
893
    if (trace_file) {fprintf(trace_file," %d",m_file.linepointer+1);
894
      fflush(trace_file);
10 reyssat 895
    }
12216 bpr 896
    t=m_file.lines[m_file.linepointer].isstart;
897
    if((t&~2)!=1 || m_file.lines[m_file.linepointer].llen==0) {
898
      m_file.linepointer++; continue;
899
    }
900
    wgetline(tbuf,MAX_LINELEN,&m_file); substnest=0;
901
    p=find_word_start(tbuf); if(*p==0) continue;
902
    if((t&2)!=0) exec_main(p+1);
903
    else exec_set(p);
904
  }
905
  if (trace_file) stop_tracefile();
906
  close_working_file(&m_file,cache);
10 reyssat 907
}
908
 
7673 bpr 909
/* Deposit the content of wims_deposit into a file */
10 reyssat 910
void var_deposit(char *p)
911
{
12216 bpr 912
  char fn[MAX_FNAME+1];
913
  int l,fd;
914
  if(!trusted_module()) return;
915
  if(deplen>0) l=deplen; else {
916
    while(isspace(*p)) p++;
917
    l=strlen(p);
918
  }
919
  if(l<=0) return;
920
  if(l>MAX_DEPOSITLEN) l=MAX_DEPOSITLEN; /* silent truncation, should not occur */
921
  mkfname(fn,"%s/user-deposit",session_prefix);
922
  fd=creat(fn,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if(fd==-1) return;
923
  write(fd,p,l); close(fd);
12455 bpr 924
  snprintf(fn,sizeof(fn),"%u",l); setvar("wims_deposit_len",fn);
10 reyssat 925
}
926
 
7673 bpr 927
/* Check and set variables passed in query_string */
10 reyssat 928
void set_vars_from_parm(void)
929
{
12216 bpr 930
  int i,j,al;
931
  char *s, vbuf[MAX_LINELEN+1];
932
  if(forceresume) return;
933
  for(i=0; i<user_var_no; i++) {
934
    j=var_def_check(user_variable[i].name);
935
    if(j<0) continue;
12381 bpr 936
    /* check permissions */
12216 bpr 937
    al=var_def[j].allow;
938
    if(al != var_allow_any) switch(cmd_type) {
939
      case cmd_new:
940
      case cmd_renew:
941
        if (al != var_allow_init && al != var_allow_config) {
7673 bpr 942
violat:        /* setvar(error_data_string,user_variable[i].name);
943
              user_error("allow_violation"); */
12216 bpr 944
          goto loopend;
945
        }
946
      break;
10 reyssat 947
 
12216 bpr 948
      case cmd_config:
949
      if(al != var_allow_config) goto violat;
950
      break;
7673 bpr 951
 
12216 bpr 952
      case cmd_reply:
953
        if(al != var_allow_reply) goto violat;
954
        break;
7673 bpr 955
 
12216 bpr 956
      case cmd_help:
957
        if(al != var_allow_help) goto violat;
958
        break;
7673 bpr 959
 
12216 bpr 960
      default: goto violat;
10 reyssat 961
    }
12216 bpr 962
    var_def[j].defined_in_parm=1;
963
    if(strcmp(user_variable[i].name,"wims_deposit")==0) {
964
      var_deposit(user_variable[i].value); continue;
965
    }
966
    mystrncpy(vbuf,user_variable[i].value,sizeof(vbuf));
967
    if(strchr(vbuf,'$')!=NULL) {
968
      char *p;
969
      while((p=strchr(vbuf,'$'))!=NULL)
970
        string_modify(vbuf,p,p+1,"&#36;");
971
    }
972
    s=getvar(user_variable[i].name);
973
    if(s==NULL || *s==0) setvar(user_variable[i].name, vbuf);
974
    else {  /* concatenate */
975
      int k;
976
      k=strlen(s)+strlen(vbuf);
977
      if(k>=MAX_LINELEN-2) user_error("string_too_long");
978
      snprintf(tmplbuf,sizeof(tmplbuf),"%s, %s",s,vbuf);
979
      setvar(user_variable[i].name, tmplbuf);
980
    }
981
    loopend: ;
982
  }
10 reyssat 983
}
984
 
7673 bpr 985
/* parms to be eliminated from module_init_parm */
10 reyssat 986
/* char *init_elim[]={
987
    "module","cmd","session","lang","worksheet","wims_access","useropts"
988
};
989
#define init_elim_no (sizeof(init_elim)/sizeof(init_elim[0]))
990
*/
991
 
992
void elim_parm(char *str, char *parm)
993
{
12216 bpr 994
  char *p1, *p2;
995
  for(p1=strstr(str,parm);p1!=NULL;p1=strstr(p1+1,parm)) {
996
    if( (p1>str && *(p1-1)!='&') || *(p1+strlen(parm))!='=')
997
      continue;
998
    p2=strchr(p1,'&');
999
    if(p2==NULL) {
1000
      if(p1>str) *(p1-1)=0; else *p1=0;
1001
      return;
10 reyssat 1002
    }
12216 bpr 1003
    ovlstrcpy(p1,p2+1); p1--;
1004
  }
10 reyssat 1005
}
1006
 
12011 bpr 1007
/* eliminate technical definitions form parameter string
1008
 * that is parameters from the list RO_NAMES
1009
 */
10 reyssat 1010
void prep_init_parm(char rqv[])
1011
{
12216 bpr 1012
  int i;
1013
  char *p;
10 reyssat 1014
 
12216 bpr 1015
  for(p=strstr(rqv,"&+"); p!=NULL; p=strstr(++p,"&+"))
1016
    ovlstrcpy(p+1,p+2);
1017
  for(i=0;i<RO_NAME_NO;i++) elim_parm(rqv,ro_name[i]);
1018
  if(strlen(rqv)>=MAX_LINELEN) rqv[0]=0;
1019
  while(rqv[0]=='&') ovlstrcpy(rqv,rqv+1);
1020
  while(rqv[0]!=0 && rqv[strlen(rqv)-1]=='&') rqv[strlen(rqv)-1]=0;
10 reyssat 1021
}
1022
 
7673 bpr 1023
/* retain initializing parameters, for use in user references */
10 reyssat 1024
void set_init_parm(void)
1025
{
16626 guerimand 1026
  char *rq, rqv[MAX_LINELEN*2+2], *u, *sh, *seedr, *exotrymax;
16647 guerimand 1027
  char *shname, *dirname;
1028
  int public_sheet, freework_sheet;
17822 bpr 1029
  int len;
10 reyssat 1030
 
12216 bpr 1031
  if(isexam) return;
16647 guerimand 1032
  /* reset sheet number and exo nomber for a sheet */
12216 bpr 1033
  force_setvar("wims_sheet",""); force_setvar("wims_exo","");
16647 guerimand 1034
  /* reset freework number and exo number for a freework */
1035
  force_setvar("wims_fwnumber",""); force_setvar("wims_fwexo","");
12216 bpr 1036
  rq=getenv("QUERY_STRING");
1037
  if(rq==NULL || *rq==0) {
1038
    empty:
1039
    setvar("module_init_parm",""); return;
1040
  }
1041
  if(strlen(rq)>=MAX_LINELEN*2) goto empty;
1042
  _http2env(rqv,rq); prep_init_parm(rqv);
17822 bpr 1043
  /*XSS PROTECTION see also config.c*/
1044
  len=strcspn(rqv, "<>'\"\\"); rqv[len]=0;
16647 guerimand 1045
  setvar("module_init_parm",rqv); public_sheet=0; freework_sheet=0;
12295 bpr 1046
/* seedrepeat=1 or an integer
1047
  must be in the url and seedrepeat
12273 bpr 1048
  in the var.def of the module to be used */
12216 bpr 1049
  seedr=getvar("seedrepeat");
1050
  force_setvar("wims_seed_repeat",seedr);
1051
  exotrymax=getvar("exotrymax");
1052
  force_setvar("wims_exotrymax",exotrymax);
7673 bpr 1053
/* now determine the sheet number for user */
12216 bpr 1054
  sh=getvar(ro_name[ro_worksheet]); if(sh==NULL) return;
16647 guerimand 1055
  if(*sh=='P') {public_sheet=1; sh++;}  /* for public sheet file is in session */
1056
  if(*sh=='F') {     /* for freework */
1057
    freework_sheet=1; sh++;
1058
    shname="Wfreework";
1059
    dirname="freeworks";
16724 bpr 1060
  }
16647 guerimand 1061
  else {   /* for sheet */
1062
    shname="sheet";
1063
    dirname="sheets";
16724 bpr 1064
  }
12216 bpr 1065
  u=getvar("wims_user"); if(u==NULL) u="";
1066
  if(sh!=NULL && *sh!=0) {
1067
    char buf[MAX_LINELEN+1],ubuf[32], nbuf[1024], *c, *m;
1068
    char *p1,*p2,*p3,*p4,*p5;
1069
    int i,j,sheet;
16130 bpr 1070
    sheet=atoi(sh); if(sheet<=0 || sheet>MAX_SHEETS) return;
12216 bpr 1071
    m=getvar(ro_name[ro_module]);
1072
    if(m==NULL) internal_error("set_init_parm(): module name disapears.");
1073
    if(*u==0) public_sheet=1;
1074
    if(!public_sheet) {
16647 guerimand 1075
    /* make filename for data on a freework or a sheet in a class */
12216 bpr 1076
      c=getvar("wims_class"); if(c==NULL) c="";
16647 guerimand 1077
      snprintf(nbuf,sizeof(nbuf),"%s/%s/.%s%d",
1078
               class_dir,dirname,shname,sheet);
12216 bpr 1079
    }
1080
    else {
16647 guerimand 1081
      /* make filename for data in case of a public sheet */
12216 bpr 1082
      char bf[MAX_LINELEN+1];
1083
      int i;
1084
      accessfile(bf,"r","%s/.sheets",session_prefix);
1085
      if(bf[0]==0) return;
1086
      for(i=1, p1=bf;i<sheet;i++,p1=p2) {
1087
        p2=strchr(p1,'\n');
1088
        if(p2!=NULL) *p2++=0; else p2=p1+strlen(p1);
1089
      }
1090
      p2=strchr(p1,'\n'); if(p2) *p2=0;
1091
      snprintf(nbuf,sizeof(nbuf),"bases/sheet/%s.def",p1);
1092
    }
16749 bpr 1093
    /* now nbuf is the filename for data in any case of ressource
1094
      (sheet / public_sheet / freework) */
12216 bpr 1095
    if(readfile(nbuf,buf,sizeof(buf))==NULL) return;
16647 guerimand 1096
    /* buf is the data of ressources. nbuf no more needed */
16749 bpr 1097
    for(p1=strstr(buf,"&+");p1!=NULL;p1=strstr(++p1,"&+"))    /* delete the &+ in buf */
12216 bpr 1098
      ovlstrcpy(p1+1,p1+2);
16647 guerimand 1099
    /* in case of use an exercice of the class instead of a public exercise */
12216 bpr 1100
    if(strncmp(m,"classes/",strlen("classes/"))==0) {
1101
      m="classes/";
1102
      for(p1=strstr(buf,":classes/");p1;p1=strstr(p1+1,":classes/")) {
1103
        if(p1==buf || *(p1-1)=='\n') {
1104
          p1+=strlen(":classes/");
1105
          p2=find_word_end(p1); if(p2>p1 && *p2=='\n') ovlstrcpy(p1,p2);
1106
        }
1107
      }
1108
    }
16647 guerimand 1109
    snprintf(nbuf,sizeof(nbuf),":%s\n%s\n",m,rqv);  /* rqv : execution parameters for the module ; m is the name of exercise module */
12216 bpr 1110
    p1=strstr(buf,nbuf);
16749 bpr 1111
    /* this loop searches exercise parameters in buf
18000 bpr 1112
      calculate num of the exercise in the ressources (sheet /public_sheet / freework)
16647 guerimand 1113
    */
12216 bpr 1114
    while(p1>buf && *(p1-1)!='\n') p1=strstr(p1+1,nbuf);
1115
    if(p1!=NULL) {
1116
      p2=strchr(buf,':');
1117
      while(p2>buf && *(p2-1)!='\n') p2=strchr(p2+1,':');
1118
      for(i=1;p2!=NULL && p2<p1;i++) {
1119
        p2=strchr(p2+1,':');
1120
        while(p2>buf && *(p2-1)!='\n') p2=strchr(p2+1,':');
1121
      }
1122
      if(p2==NULL) return; /* error which should not occur */
1123
      snprintf(ubuf,sizeof(ubuf),"%d",i);
16749 bpr 1124
      /* look for dependency information */
16757 guerimand 1125
      /* pas utile pour freework mais ne pose pas de probleme tant que les fichiers .wfreework$i ne contiennent
1126
       que des record avec moins de 7 lignes (pour ne pas activer la fonction de dependance
1127
       de score  */
12216 bpr 1128
      for(j=0, p3=strchr(p1+strlen(nbuf),'\n');
1129
      j<3 && p3 && *(p3+1)!=':';
1130
      j++, p3=strchr(p3+1,'\n'));
1131
      if(j>=3 && p3!=NULL && *(p3+1)!=':') {
1132
        p3++; p4=strchr(p3,'\n');
1133
        if(p4) {
1134
          *p4++=0;
1135
          if(*p4!=':') { /* options */
1136
            p5=strchr(p4,'\n'); if(p5) *p5=0;
1137
            force_setvar("wims_exoption",p4);
7673 bpr 1138
          }
12216 bpr 1139
        }
1140
        p3=find_word_start(p3); strip_trailing_spaces(p3);
7673 bpr 1141
/* non-empty dependency information */
12216 bpr 1142
        if(*p3 && !public_sheet) {
1143
          exodepOK=depcheck(sh,i,p3);
1144
          if(!exodepOK) setvar("wims_exodep","pending");
1145
        }
1146
      }
1147
      if(public_sheet) {
1148
        char bf[32];
1149
        snprintf(bf,16,"P%s",sh);
1150
        force_setvar("wims_sheet",bf);
1151
      }
16647 guerimand 1152
      else {
1153
        if(freework_sheet) {
16749 bpr 1154
          /* if an exo is already registered, user cannot launch the same exercise an other time */
16711 guerimand 1155
          snprintf(nbuf,sizeof(nbuf),"%s/log/classes/%s/freeworksdata/%s/work/%s-wimsexo/%s",
1156
               getvar("wims_home"),getvar("wims_class"),sh,u,ubuf);
1157
          if(ftest(mkfname(NULL,"%s",nbuf))!=is_file) {
1158
            force_setvar("wims_fwnumber",sh);
1159
            force_setvar("wims_fwexo",ubuf);
1160
          }
16724 bpr 1161
        }
16711 guerimand 1162
        else {
16647 guerimand 1163
          force_setvar("wims_sheet",sh);
1164
          force_setvar("wims_exo",ubuf);
1165
          wims_sheet=sheet; wims_exo=i;
1166
        }
1167
      }
10 reyssat 1168
    }
12216 bpr 1169
  }
10 reyssat 1170
}
1171
 
7673 bpr 1172
/* user with class: whether exercise is registered
1173
 * Returns 1 if got, 0 otherwise. */
10 reyssat 1174
int get_parmreg(void)
1175
{
12216 bpr 1176
  char *p, *cl, *u, nbuf[MAX_FNAME+1];
1177
  struct stat st;
10 reyssat 1178
 
12216 bpr 1179
  u=getvar("wims_user"); cl=getvar("wims_class");
1180
  if(u==NULL || cl==NULL || *u==0 || *cl==0 || strcmp(u,"supervisor")==0
10 reyssat 1181
       || wims_sheet<=0 || wims_exo<=0) return 0;
12216 bpr 1182
  mkfname(nbuf,"%s/.parmreg/%s.%d.%d", class_dir,u,wims_sheet,wims_exo);
12381 bpr 1183
  p=getvar("wims_scorereg");
1184
  if(p!=NULL && strcmp(p,"suspend")==0) {
12216 bpr 1185
    unlink(nbuf); return 0;
1186
  }
1187
  if(stat(nbuf,&st)) return 0;
12455 bpr 1188
  /* latency is 10 min. */
12216 bpr 1189
  if(st.st_mtime<nowtime-600 || st.st_mtime > nowtime) {
7673 bpr 1190
     unlink(nbuf); return 0;
12216 bpr 1191
  }
1192
  if(open_working_file(&m_file,nbuf)!=0) return 0;
1193
  mkfname(m_file.name,"parmreg/%s.%d.%d",u,wims_sheet,wims_exo);
1194
  while(wgetline(tmplbuf,MAX_LINELEN, &m_file)!=EOF) {
1195
    p=strchr(tmplbuf,'=');
1196
    if(p==NULL || p<=tmplbuf || isspace(tmplbuf[0]) )
12455 bpr 1197
      /* this time it is corrupted var file */
12216 bpr 1198
      internal_error("get_parmreg(): corrupt parmreg file.");
13381 bpr 1199
    *p=0;p++;
1200
    if(strncmp(tmplbuf,var_prefix,strlen(var_prefix))!=0) setenv(tmplbuf,p,1);
1201
    else if(tmplbuf[strlen(var_prefix)]!=0) force_setvar(tmplbuf+strlen(var_prefix),p);
12216 bpr 1202
  }
1203
  parm_restore=1;
1204
  close_working_file(&m_file,0); return 1;
10 reyssat 1205
}
1206
 
12828 bpr 1207
/* reset seed according to the values of
1208
  wims_seed_repeat and wims_seed_score
12363 bpr 1209
*/
12828 bpr 1210
/* for non registered users or suspended score,
1211
  save some variables wims_seedcnt and seedlastcnt in sessions/xxx/var
1212
*/
12011 bpr 1213
void reset_seed (void) {
12363 bpr 1214
  char *p, *seedr, buf[64], *sh, *ex, *tseed, *seedcnt, *seedlastcnt;
12373 bpr 1215
  char *mp=getvar("module");
12363 bpr 1216
  sh=getvar("wims_sheet"); ex=getvar("wims_exo");
12216 bpr 1217
  seedr=getvar("wims_seed_repeat");
12522 bpr 1218
  /* number of seeds during the sessions only used for unregistered */
12363 bpr 1219
  seedcnt=getvar("wims_seedcnt");
1220
  if(seedcnt==NULL || *seedcnt==0) {
1221
    force_setvar("wims_seedcnt","0");
1222
    seedcnt=getvar("wims_seedcnt");
1223
  }
12828 bpr 1224
  /* number of tries with the actual seed only used for unregistered
1225
    or score suspended */
12363 bpr 1226
  seedlastcnt=getvar("wims_seedlastcnt");
1227
  if(seedlastcnt==NULL || *seedlastcnt==0) {
12374 bpr 1228
    force_setvar("wims_seedlastcnt","0");
12363 bpr 1229
    seedlastcnt=getvar("wims_seedlastcnt");
1230
  }
12990 bpr 1231
  if(seedr!=NULL && atoi(seedr)>0) { /* seedrepeat>1 */
12216 bpr 1232
    p=getvar("wims_seed_score");
12273 bpr 1233
    if(evalue(p)>=10){
12216 bpr 1234
      seed_time(); force_setvar("wims_seed_score",NULL);
12816 bpr 1235
      snprintf(buf,sizeof(buf), "%d", atoi(seedcnt)+1);
1236
      force_setvar("wims_seedcnt",buf);
12818 bpr 1237
      seedcnt=getvar("wims_seedcnt");
12363 bpr 1238
      force_setvar("wims_seedlastcnt","0");
1239
      seedlastcnt=getvar("wims_seedlastcnt");
12011 bpr 1240
    }
12374 bpr 1241
    else { /* score < 10 */
12828 bpr 1242
      /* is score suspended by the student ? */
1243
      char *screg=getvar("wims_scorereg");
1244
      /* is score suspended by the supervisor ? */
1245
      int scregs=0;
1246
      if(sh!=NULL && *sh!=0)
1247
        scregs=getscorestatus(getvar("wims_class"),atoi(sh));
1248
      if(sh!=NULL && *sh!=0 && ex!=NULL && *ex!=0
1249
          && (screg==NULL || strcmp(screg,"suspend")!=0)
17457 guerimand 1250
          && (scregs!=0)){
12828 bpr 1251
        /* the case of a supervisor looking at the sheet is not treated */
12280 bpr 1252
        tseed=getseedscore(getvar("wims_class"), getvar("wims_user"), atoi(sh), atoi(ex));
12302 bpr 1253
        if( tseed!=0 ) {
12273 bpr 1254
          mystrncpy(buf, tseed,sizeof(buf));
1255
          force_setvar("wims_seed",buf);
1256
        }
12834 bpr 1257
        else seed_time();
12374 bpr 1258
      }
12828 bpr 1259
      else { /* non registered or score suspended
1260
          and seedrepeat>1 and score <10 */
12834 bpr 1261
        if (cmd_type==cmd_new ||cmd_type==cmd_renew) {
12835 bpr 1262
          snprintf(buf,sizeof(buf),"%d",atoi(seedlastcnt)+1);
1263
          force_setvar("wims_seedlastcnt",buf);
1264
          seedlastcnt=getvar("wims_seedlastcnt");
1265
          if(atoi(seedlastcnt) >= atoi(seedr)){
12834 bpr 1266
            seed_time();
1267
            if(strcmp(mp,home_module)!=0 && cmd_type!=cmd_intro){
1268
              snprintf(buf,sizeof(buf),"%d",0);
1269
              force_setvar("wims_seedlastcnt",buf);
1270
              seedlastcnt=getvar("wims_seedlastcnt");
1271
              snprintf(buf,sizeof(buf),"%d",atoi(seedcnt)+1);
1272
              force_setvar("wims_seedcnt",buf);
1273
              seedcnt=getvar("wims_seedcnt");
1274
            }
1275
            else {
1276
              force_setvar("wims_seedcnt","0");
1277
              force_setvar("wims_seedlastcnt","0");
1278
            }
12373 bpr 1279
          }
12363 bpr 1280
        }
12273 bpr 1281
      }
1282
    }
12216 bpr 1283
  }
12363 bpr 1284
  else {// no seedrepeat
1285
    seed_time();
12373 bpr 1286
    if (cmd_type==cmd_reply && strcmp(mp,home_module)!=0){
12816 bpr 1287
      snprintf(buf,sizeof(buf),"%d",atoi(seedcnt)+1);
1288
      force_setvar("wims_seedcnt",buf);
12828 bpr 1289
      seedcnt=getvar("wims_seedcnt");
12374 bpr 1290
      force_setvar("wims_seedlastcnt","0");
12372 bpr 1291
    }
12373 bpr 1292
    else {
1293
      if (strcmp(mp,home_module)==0 || cmd_type==cmd_intro) {
1294
        force_setvar("wims_seedcnt","0");
12374 bpr 1295
        force_setvar("wims_seedlastcnt","0");
12373 bpr 1296
      }
1297
    }
12363 bpr 1298
  }
12216 bpr 1299
  p=getvar("wims_seed");
1300
  if(p!=NULL && (cmd_type==cmd_new || cmd_type==cmd_renew || cmd_type==cmd_next)){
1301
    mystrncpy(buf,p,sizeof(buf)); setenv("tmp_seed",buf,1);
1302
    exec_setseed(buf);
1303
  }
12011 bpr 1304
}
1305
 
7673 bpr 1306
/* set environment variables */
10 reyssat 1307
void set_variables(void)
1308
{
12216 bpr 1309
  outputing=0; readnest=0;
1310
  get_var_defs();
1311
  set_vars_from_parm();
1312
  if(cmd_type != cmd_new && cmd_type != cmd_renew) {
1313
    set_vars_from_session();
12522 bpr 1314
    if(cmd_type==cmd_next) reset_seed();
12216 bpr 1315
  }
1316
  else {
1317
    set_init_parm();
1318
    reset_seed();
1319
    if(wims_sheet>0 && get_parmreg()) {
1320
      cmd_type=cmd_resume; force_setvar("cmd","resume");
1321
      var_proc(main_var_proc_file,0); return;
12011 bpr 1322
    }
12216 bpr 1323
    checkrafale();
1324
    var_proc(var_init_file,0);
1325
  }
12011 bpr 1326
/* check_var_bounds(); */
12216 bpr 1327
  var_proc(main_var_proc_file,0);
10 reyssat 1328
}
1329
 
7673 bpr 1330
/* Output a phtml file. */
10 reyssat 1331
void phtml_put(char *fname,int cache)
1332
{
12216 bpr 1333
  int t;
1334
  char tbuf[MAX_LINELEN+1];
16080 bpr 1335
  char *s;
12216 bpr 1336
  outputing=1;
10 reyssat 1337
     /* File not found; we give empty output, but no error message. */
12216 bpr 1338
  if(fname!=NULL && read_module_file(fname)!=0) return;
1339
  if(untrust&6) get_var_privileges();
1340
  if (trace_file) start_tracefile();
1341
  while(m_file.linepointer<m_file.linecnt) {
12223 bpr 1342
    if (trace_file) {
1343
      fprintf(trace_file," %d",m_file.linepointer+1);
1344
      fflush(trace_file);
12225 bpr 1345
    }
12216 bpr 1346
    t=m_file.lines[m_file.linepointer].isstart;
1347
    if((t&~18)!=1) {m_file.linepointer++; continue;}
1348
    wgetline(tbuf,MAX_LINELEN,&m_file); substnest=0;
1349
    if((t&2)!=0) {exec_main(tbuf+1); continue;}
16080 bpr 1350
    substit(tbuf);
1351
    s=getvar("wims_parm_detag");
1352
    if(s!=NULL && *s != 0) calc_detag(tbuf);
1353
    output0(tbuf); _output_("\n");
12216 bpr 1354
  }
1355
  if (trace_file) stop_tracefile();
1356
  close_working_file(&m_file,cache);
10 reyssat 1357
}
1358
 
7673 bpr 1359
/* output a file in base html directory. Internal use only. */
10 reyssat 1360
void phtml_put_base(char *fname,int cache)
1361
{
12216 bpr 1362
  WORKING_FILE save;
1363
  char modsave[MAX_FNAME+1];
1364
  memmove(&save,&m_file,sizeof(WORKING_FILE));
1365
  mystrncpy(modsave,module_prefix,sizeof(modsave));
1366
  ovlstrcpy(module_prefix,"html");
1367
  phtml_put(fname,cache);
1368
  mystrncpy(module_prefix,modsave,sizeof(module_prefix));
1369
  memmove(&m_file,&save,sizeof(WORKING_FILE));
10 reyssat 1370
}
1371
 
7673 bpr 1372
/* Read main.phtml, process it, and write to stdout. */
10 reyssat 1373
void main_phtml_put(char *mname)
1374
{
12216 bpr 1375
  char *p, buf[1024], txbuf[256], dirnbuf[256], bgbuf[256], spfbuf[256], ebuf[256];
12357 obado 1376
  char *bcolor, *refcolor, *bg, *tx, *dirn, *vlink, *link, *hlink, *spf ;
12216 bpr 1377
  define_html_header(); readnest=0;
1378
  nph_header(200);
1379
  p=getvar("wims_backslash_insmath");
1380
  if(p!=NULL && strcasecmp(p,"yes")==0) backslash_insmath=1;
1381
  p=getvar("wims_expire");
1382
  if(p!=NULL) p=strstr(p,"no-cache");
13359 obado 1383
  if(p!=NULL) _output_("Cache-Control: no-cache, no-store, must-revalidate\r\n");
11726 bpr 1384
/* expiration date */
12216 bpr 1385
  if(mode==mode_default) {
1386
    if(!robot_access && (cmd_type!=cmd_intro || p!=NULL)) {
1387
      char *expir="Sat, 26 Jul 1990 05:00:00 GMT";
1388
      snprintf(ebuf,sizeof(ebuf),"%s",expir);
1389
    }
1390
    else {
11726 bpr 1391
/* expiration in 10 days for robot access or intro page. */
12216 bpr 1392
      time_t t=nowtime+(long) 10*24*3600;
1393
      { struct tm *tt = localtime(&t);
1394
        strftime(ebuf,sizeof(ebuf),"%a, %d %b %Y %T GMT", tt);
11726 bpr 1395
      }
1396
    }
12216 bpr 1397
    strip_trailing_spaces(ebuf);
1398
    output("Expires:%s\r\n",ebuf);
1399
  }
11726 bpr 1400
 
12216 bpr 1401
  output("Server: %s %s (%s)\n", SHORTSWNAME,wims_version,LONGSWNAME);
1402
  if(!robot_access && strcasecmp(usecookie,"yes")==0 && setcookie
10 reyssat 1403
       && mode!=mode_popup) {
12216 bpr 1404
    if(cookieset[0]==0) {
1405
      p=getvar("wims_sescookie");
1406
      if(p!=NULL && *p!=0) mystrncpy(cookieset,p,sizeof(cookieset));
1407
    }
15276 obado 1408
     output("Set-Cookie: %s%s;SameSite=Strict; path=/\r\n",cookieheader,cookieset);
12216 bpr 1409
  }
1410
  p=getvar("wims_main_font");
1411
  if(p!=NULL && *p!=0) output("Content-type: text/html; charset=%s\r\n\r\n",p);
1412
  else _output_("Content-type: text/html\r\n\r\n");
12357 obado 1413
 
12216 bpr 1414
  bcolor=getvar("wims_bgcolor");
1415
  if(bcolor==NULL || *bcolor==0) bcolor=bgcolor;
12357 obado 1416
 
12216 bpr 1417
  link=getvar("wims_link_color");
1418
  if(link==NULL || *link==0) link="blue";
12357 obado 1419
 
12216 bpr 1420
  vlink=getvar("wims_vlink_color");
1421
  if(vlink==NULL || *vlink==0) vlink="blue";
12357 obado 1422
 
1423
  hlink=getvar("wims_hlink_color");
1424
  if(hlink==NULL || *hlink==0) vlink="red";
1425
 
12216 bpr 1426
  refcolor=getvar("wims_ref_bgcolor");
1427
  if(refcolor==NULL || *refcolor==0) {
1428
    setvar("wims_ref_bgcolor","white");
1429
    refcolor="white";
1430
  }
12357 obado 1431
 
12216 bpr 1432
  bg=getvar("wims_bgimg"); bgbuf[0]=0;
1433
  if(bg!=NULL && *bg!=0 && strchr(bg,'\"')==NULL) {
1434
    if(strchr(bg,'/')==NULL)
1435
      snprintf(bgbuf,sizeof(bgbuf),"background-image: url(\"gifs/bg/%s\");",bg);
7673 bpr 1436
     else
12216 bpr 1437
      snprintf(bgbuf,sizeof(bgbuf),"background-image: url(\"%s\");",bg);
1438
  }
1439
  setvar("wims_bodyimg",bgbuf);
1440
  tx=getvar("wims_textcolor");
1441
  if(tx!=NULL && *tx!=0 && strchr(tx,'\"')==NULL) {
1442
    snprintf(txbuf,sizeof(txbuf),"color:%s;",tx);
1443
  }
1444
  else txbuf[0]=0;
6178 bpr 1445
   /* special fonts defined in special_font -should also take the value specialfont in wims.conf */
12216 bpr 1446
  if(spec_font==1){
1447
    spf=getvar("wims_specialfont");
1448
    if(spf!=NULL && *spf!=0) { snprintf(spfbuf,sizeof(spfbuf),"%s",spf);}
1449
    else { snprintf(spfbuf,sizeof(spfbuf),"%s",special_font); }
1450
    setvar("wims_special_font",spfbuf);
1451
  }
12816 bpr 1452
  dirn=getvar("wims_main_dirn"); /* "rtl" for arabic writing ; on pourrait laisser vide pour les autres ? */
12216 bpr 1453
  if(dirn!=NULL && *dirn!=0 && strchr(dirn,'\"')==NULL) {
1454
    snprintf(dirnbuf,sizeof(dirnbuf),"dir=\"%s\"",dirn);
1455
  }
1456
  else dirnbuf[0]=0;
15005 obado 1457
  if(mode==mode_popup) {
1458
    snprintf(buf,sizeof(buf), "class=\"main_body mode_popup\" %s", dirnbuf);
1459
  }else{
1460
    snprintf(buf,sizeof(buf), "class=\"main_body\" %s",dirnbuf);
1461
  }
12216 bpr 1462
  setvar("wims_htmlbody",buf);
1463
  phtml_put(mname,0);
10 reyssat 1464
}
1465
 
1466
void _write_var(char *name, FILE *varf,int user,int skip)
1467
{
12216 bpr 1468
  char *s, buf[MAX_NAMELEN+9], nbf[MAX_NAMELEN+9];
10 reyssat 1469
 
12216 bpr 1470
  if((user&2)!=0) {
1471
    snprintf(nbf,sizeof(nbf),"%s%s",wims_prefix,name); name=nbf;
1472
  }
1473
  if((user&1)!=0) {
1474
    snprintf(buf,sizeof(buf),"%s%s",var_prefix,name); s=_getvar(name);
1475
  }
1476
  else {
1477
    mystrncpy(buf,name,sizeof(buf)); s=getenv(name);
1478
  }
1479
  if(s==NULL) s="";
1480
  if(skip && *s==0) return;
1481
  fprintf(varf,"%s=",buf);
1482
  if(strchr(s,'\n')==NULL) fputs(s,varf);
1483
  else
1484
    while(*s) {
1485
      if(*s=='\n') fputc('\\',varf);
7673 bpr 1486
       fputc(*s,varf); s++;
10 reyssat 1487
    }
12216 bpr 1488
  fputc('\n',varf);
10 reyssat 1489
}
1490
 
1491
void _write_vars(FILE *varf)
1492
{
12216 bpr 1493
  int i,j,k;
1494
  char nbuf[MAX_NAMELEN+1];
1495
  for(i=0;i<defined_var_total;i++) {
1496
    if(var_def[i].beg>=0) {
1497
      if(var_def[i].end<=var_def[i].beg) {
1498
        snprintf(nbuf,sizeof(nbuf),"%s%d",var_def[i].name,var_def[i].beg);
1499
        _write_var(nbuf,varf,1,1);
1500
      }
1501
      else {
1502
        char *pbuf[MAX_VAR_NUM];
1503
        j=varsuite(var_def[i].name,var_def[i].beg,var_def[i].end,pbuf,MAX_VAR_NUM);
1504
        for(k=0;k<j;k++) _write_var(pbuf[k],varf,1,1);
1505
      }
10 reyssat 1506
    }
12216 bpr 1507
    else _write_var(var_def[i].name,varf,1,1);
1508
  }
10 reyssat 1509
}
1510
 
7673 bpr 1511
/* save exercise parm for registered users */
10 reyssat 1512
void save_parmreg(void)
1513
{
12216 bpr 1514
  char *p, *u, *sh, *ex, nbuf[MAX_FNAME+1], dbuf[MAX_FNAME+1];
1515
  int s;
1516
  FILE *varf;
10 reyssat 1517
 
12216 bpr 1518
  if(cmd_type!=cmd_reply && cmd_type!=cmd_new && cmd_type!=cmd_renew)
1519
    return;
1520
  u=getvar("wims_user");
1521
  if(class_dir[0]==0 || *u==0) return;
1522
  sh=getvar("wims_sheet"); ex=getvar("wims_exo");
1523
  if(sh==NULL || ex==NULL || *sh==0 || *ex==0) return;
12494 bpr 1524
  mkfname(nbuf,"%s/.parmreg/%s.%s.%s", class_dir,u,sh,ex);
12216 bpr 1525
  if(cmd_type==cmd_reply) {
1526
    unlink(nbuf); return;
1527
  }
1528
  p=getvar("wims_scorereg");
1529
  if(p!=NULL && strcmp(p,"suspend")==0) return;
7673 bpr 1530
/* these two lines must be before random factor
1531
 * in order to set variable wims_scoring */
12216 bpr 1532
  s=atoi(sh); if(getscorestatus(getvar("wims_class"),s)==0) return;
1533
  if(strcmp(u,"supervisor")==0) return;
7673 bpr 1534
/* 0.2 is random factor to trigger exercise parm register */
8949 bpr 1535
/*    return;*/
12508 bpr 1536
 // if((double) random()<(double) RAND_MAX*0.2){ }
12494 bpr 1537
  return;
12216 bpr 1538
  mkfname(dbuf,"%s/.parmreg",class_dir);
1539
  mkdirs(dbuf); varf=fopen(nbuf,"w"); if(varf==NULL) return;
1540
  _write_var("module_init_parm",varf,1,0);
1541
  _write_var("wims_sheet",varf,1,1);
1542
  _write_var("wims_exo",varf,1,1);
1543
  _write_var("wims_scoring",varf,1,1);
1544
  _write_var("wims_seed",varf,1,1);
1545
  _write_vars(varf);
1546
  fclose(varf);
10 reyssat 1547
}
1548
 
1549
void exolog(char *fname)
1550
{
12216 bpr 1551
  FILE *varf, *varg;
1552
  int c;
1553
  char logftmp[MAX_FNAME+1], *sess;
4639 guerimand 1554
 
1555
/* add by FG to put w_module_score at the top of the file */
12216 bpr 1556
  if ((getenv("w_module_score"))!=NULL )
1557
  {
1558
    sess=getvar("wims_session");
1559
    mkfname(logftmp,"%s/%s/.tmp%lu",s2_dir,sess,nowtime);
1560
    rename(fname,logftmp);
1561
    varf=fopen(fname,"a");
1562
    if(varf!=NULL) {
1563
      _write_var("module_score",varf,1,1);
16727 guerimand 1564
      varg=fopen(logftmp,"r");
12216 bpr 1565
      if(varg!=NULL) {
16727 guerimand 1566
        while ( (c=getc (varg)) != EOF) putc(c,varf);
1567
        fclose(varg);
12216 bpr 1568
        }
1569
        fclose(varf);
1570
        remove(logftmp);
7673 bpr 1571
     }
12216 bpr 1572
  }
4639 guerimand 1573
/* end of add */
12216 bpr 1574
  varf=fopen(fname,"a");
1575
  if(varf!=NULL) {
7673 bpr 1576
/* The first 4 lines should not be modified */
12216 bpr 1577
    fprintf(varf,"\n:\n");
1578
    _write_var("QUERY_STRING",varf,0,0);
1579
    _write_var("module",varf,1,0);
1580
    _write_var("cmd",varf,1,0);
1581
    _write_var("module_init_parm",varf,1,0);
1582
    _write_var("wims_scoring",varf,1,1);
1583
    _write_var("module_score",varf,1,1);
1584
    fprintf(varf,"w_wims_checktime1=%lu\n\
10 reyssat 1585
w_wims_checktime2=%s\n",nowtime,nowstr);
12216 bpr 1586
    _write_var("wims_seed",varf,1,1);
1587
    _write_vars(varf);
1588
    fclose(varf);
1589
  }
10 reyssat 1590
}
4639 guerimand 1591
 
7673 bpr 1592
/* save variables to session var file */
10 reyssat 1593
void save_session_vars(void)
1594
{
12216 bpr 1595
  int i;
1596
  char *mp, *sh, *ex, *ll;
1597
  FILE *varf;
7673 bpr 1598
/* light pages don't need saved variables. ? */
1599
/*    if(varchr(module_prefix,"light")!=NULL) return;*/
12216 bpr 1600
  if(robot_access) return;
7673 bpr 1601
/* no variable saving if cmd=help? */
12216 bpr 1602
  if(cmd_type==cmd_help) return;
1603
  lastdatafile[0]=lastftest[0]=0;
1604
  lessrafale();
1605
  mp=getvar("wims_nextmodule");
1606
  if(mp!=NULL && *mp!=0) {
1607
    mp=getvar("module");
1608
    if(strcmp(mp,home_module)==0)
1609
      force_setvar("module",getvar("wims_nextmodule"));
1610
  }
1611
  varf=fopen_session_var_file("w");
1612
  for(i=0;i<HEADER_VAR_NO;i++) _write_var(header_var_name[i],varf,0,0);
1613
  for(i=0;i<RO_NAME_NO;i++) _write_var(ro_name[i],varf,1,0);
1614
  for(i=0;i<INTERNAL_NAME_NO;i++) {
1615
    if(internal_name[i].stat==0)
1616
      _write_var(internal_name[i].name,varf,3,0);
1617
  }
1618
  _write_var("password",varf,0,1);
1619
  save_parmreg();
1620
  if(new_session) fprintf(varf,"wims_new_session=yes\n");
1621
  fprintf(varf,"\n");
1622
  _write_var("module_init_parm",varf,1,0);
1623
  _write_var("wims_sheet",varf,1,1);
1624
  _write_var("wims_exo",varf,1,1);
1625
  _write_var("wims_scoring",varf,1,1);
1626
  _write_vars(varf);
1627
  fclose(varf);
1628
  if(cmd_type==cmd_new || cmd_type==cmd_renew || cmd_type==cmd_reply || cmd_type==cmd_next) {
1629
    ll=getvar("wims_class_examlog");
1630
    if(ll!=NULL && *ll!=0) i=atoi(ll); else i=examlog_limit;
1631
    if(strstr(session_prefix,"_exam")!=NULL && examlogf[0]!=0 &&
1632
        simuxam==0 && i>0) {
1633
      mkdirs(examlogd); exolog(examlogf);
10 reyssat 1634
    }
12216 bpr 1635
    else {
1636
      ll=getvar("wims_class_exolog");
1637
      sh=getvar("wims_sheet"); ex=getvar("wims_exo");
1638
      if(ll!=NULL && atoi(ll)>0) {
1639
        char buf[MAX_FNAME+1];
1640
        if(sh!=NULL && *sh!=0 && ex!=NULL && *ex!=0){
1641
          mkfname(buf,"%s/exolog.%s.%s",session_prefix,sh,ex);
1642
        }
1643
        else { mkfname(buf,"%s/exolog",session_prefix);}
1644
        if(cmd_type==cmd_new || cmd_type==cmd_renew) unlink(buf);
1645
        exolog(buf);
8479 bpr 1646
      }
16711 guerimand 1647
      /* for auto log of exercise in freework */
1648
      if(freeworklogf[0]!=0) {
16727 guerimand 1649
        char buf[MAX_FNAME+1],*sess,c;
1650
        FILE *varg;
16717 guerimand 1651
        mkdirs(freeworklogd);
1652
        sess=getvar("wims_session");
1653
        mkfname(buf,"%s/%s/exolog",session_dir,sess);
16727 guerimand 1654
        varg=fopen(buf,"r");
16717 guerimand 1655
        if(varg!=NULL) {
1656
          varf=fopen(freeworklogf,"w");
1657
          while ( (c=getc (varg)) != EOF)
1658
            putc (c,varf);
1659
          fclose(varg);
1660
          fclose(varf);
1661
        }
16711 guerimand 1662
      }
10 reyssat 1663
    }
12216 bpr 1664
  }
1665
  if(var_def_buf) free(var_def_buf);
10 reyssat 1666
}