Subversion Repositories wimsdev

Rev

Rev 17465 | 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
 
18
#include <utime.h>
8185 bpr 19
#include "wims.h"
10 reyssat 20
 
7673 bpr 21
/* Subroutines to process examinations */
10 reyssat 22
 
23
char eparm[MAX_LINELEN+1];
24
 
25
void exam_parm(void)
26
{
12245 bpr 27
  char *p1, *p2, *p3;
28
  int v;
29
  setvar("module_init_parm",eparm);
30
  for(v=0,p1=eparm; *p1; p1=p2) {
31
    while(*p1=='&') p1++;
32
    p2=strchr(p1,'&');
33
    if(p2==NULL) p2=p1+strlen(p1); else *p2++=0;
34
    p3=strchr(p1,'='); if(p3==NULL) continue; else *p3++=0;
35
    p1=find_word_start(p1); *find_word_end(p1)=0;
36
    p3=find_word_start(p3); strip_trailing_spaces(p3);
37
    user_variable[v].name=p1; user_variable[v].value=p3;
38
    v++;
39
  }
40
  user_var_no=v;
10 reyssat 41
}
42
 
7673 bpr 43
/* prepare examination situation */
10 reyssat 44
void check_exam(void)
45
{
12245 bpr 46
  char *p, *p2, *e1, *e2, *pc=NULL;
47
  char ps[64], pb[64], cbuf[64], dbuf[64], vbuf[MAX_FNAME+1];
48
  int t1, t2;
49
  int start, duration, remain;
50
  double prime;
51
  struct stat st;
10 reyssat 52
 
12245 bpr 53
  p=getvar(ro_name[ro_session]);
54
  if(p==NULL || (p2=strstr(p,"_exam"))==NULL) return;
55
  mystrncpy(pb,p,sizeof(pb)); p=pb;
56
  p2=strstr(p,"_exam"); if(p2==NULL) return; else *p2=0;
10 reyssat 57
 
12245 bpr 58
  if(strchr(p2+1,'t')==NULL) {
59
    e1=getvar(ro_name[ro_worksheet]);
60
    if(e1==NULL || *e1==0) {
61
      bad: user_error("bad_exam"); return;
10 reyssat 62
    }
12245 bpr 63
    e2=strchr(e1,'.'); if(e2==NULL) goto bad;
64
    e2++; t1=atoi(e1); t2=atoi(e2);
65
  }
66
  else {
67
    char *pt1,*pt2;
68
    pt1=strchr(p2+1,'t'); pt2=strchr(pt1+1,'t');
69
    *pt1++=0; *pt2++=0; t1=atoi(pt1); t2=atoi(pt2);
70
  }
71
  if(t1<1 || t1>99 || t2<1 || t2>99) goto bad;
72
  snprintf(ps,sizeof(ps),"%s_examt%dt%d",p,t1,t2);
73
  isexam=1; setsesdir(ps); force_setvar("wims_isexam","1");
74
  force_setvar(ro_name[ro_session],ps);
13168 bpr 75
  /* get exam setup data */
12245 bpr 76
  accessfile(cbuf,"r","%s/%s/examdata.%d", session_dir,pb,t1);
77
  if(cbuf[0]==0) goto bad;
78
  p=find_word_start(cbuf); p2=find_word_end(p); if(*p2) *p2++=0;
79
  duration=atoi(p)*60; if(duration==0) goto bad;
80
  if(*p2) prime=atof(p2); else prime=0;
81
  if (strstr(ps,parent_dir_string)!=NULL) user_error("wrong_session");
13168 bpr 82
  /* Whether the exercise is already done */
12245 bpr 83
  p=getvar(ro_name[ro_cmd]); if(p!=NULL) {
84
    if(strcmp(p,"getins")==0 || strcmp(p,"getframe")==0) goto skipped;
85
  }
86
  exam_currscore(t1);
87
  if(exam_scoredata[t2-1]!=-1000) {
88
    snprintf(dbuf,sizeof(dbuf),"%.1f",exam_scoredata[t2-1]);
89
    setvar("wims_exo_lastscore",dbuf);
13168 bpr 90
    /* Do we need to erase subsession? */
17616 bpr 91
    /* cannot see the page of the statement because of the user_error */
12245 bpr 92
    user_error("exam_exo_finished");
93
  }
94
  skipped:
95
  snprintf(session_prefix,sizeof(session_prefix),"%s/%s",session_dir,ps);
96
  snprintf(vbuf,sizeof(vbuf),"%s/var",session_prefix);
97
  if(stat(vbuf,&st)==0) { /* exists */
98
    unsetvar("module");
99
    p=getvar(ro_name[ro_cmd]);
100
    if(p==NULL) {
101
      recmd:
102
      force_setvar(ro_name[ro_cmd],commands[cmd_resume]);
103
      user_var_no=0;
10 reyssat 104
    }
12245 bpr 105
    else {
106
      int i;
107
      for(i=0;i<CMD_NO && strcmp(p,commands[i]);i++);
108
      if(i>=CMD_NO || i==cmd_intro || i==cmd_new || i==cmd_renew || i==cmd_hint)
109
        goto recmd;
10 reyssat 110
    }
12245 bpr 111
  }
112
  else { /* new */
113
    char *pt, cbuf[MAX_FNAME+1], ebuf[MAX_FNAME+1];
114
    char buf[2][MAX_LINELEN+1];
115
    int w1,w2;
7673 bpr 116
 
12245 bpr 117
    force_setvar(ro_name[ro_cmd],commands[cmd_new]);
118
    get_static_session_var();
7673 bpr 119
 
12245 bpr 120
    pc=getvar("wims_class"); if(pc==NULL) pc="";
121
    snprintf(cbuf,sizeof(cbuf),"%s/%s",class_base,pc);
122
    snprintf(ebuf,sizeof(ebuf),"%s/exams/.exam%d",cbuf,t1);
123
    direct_datafile=1;
124
    datafile_fnd_record(ebuf,t2,buf[0]);
125
    direct_datafile=0;
126
    if(buf[0][0]==0) goto bad;
127
    fnd_line(buf[0],4,buf[1]);
128
    if(buf[1][0]!=0) { /* dependencies */
129
      if(!exam_depcheck(buf[1],t1)) {
130
        user_error("exam_dep");
131
      }
10 reyssat 132
    }
12245 bpr 133
    fnd_line(buf[0],2,buf[1]); if(buf[1][0]==0) goto bad;
134
    calc_randitem(buf[1]);
135
    pt=strchr(buf[1],'.');
136
    if(pt==NULL) {
137
      bad2: module_error("bad_exam_2"); return;
138
    }
139
    snprintf(exam_sheetexo,sizeof(exam_sheetexo),"      %s",buf[1]);
140
    *pt++=0; w1=atoi(buf[1]); w2=atoi(pt);
141
    if(w1<1 || w1>99 || w2<1 || w2>99) goto bad2;
142
    snprintf(ebuf,sizeof(ebuf),"%s/sheets/.sheet%d",cbuf,w1);
143
    direct_datafile=1;
144
    datafile_fnd_record(ebuf,w2,buf[0]);
145
    direct_datafile=0;
146
    if(buf[0][0]==0) goto bad2;
147
    fnd_line(buf[0],1,buf[1]); if(buf[1][0]==0) goto bad2;
148
    force_setvar(ro_name[ro_module],buf[1]);
149
    fnd_line(buf[0],2,eparm); /* if(eparm[0]==0) goto bad2; */
150
    exam_parm();
151
  }
17451 guerimand 152
  get_static_session_var();
17255 guerimand 153
 /* detect open exam in other session and forbidden open a new */
154
  char *pu, pbuf1[MAX_LINELEN+1];
17435 guerimand 155
  if(pc==NULL) pc=getvar("wims_class");
156
  if(pc==NULL) pc="";
17255 guerimand 157
  pu=getvar("wims_user"); if(pu==NULL) pu="";
17435 guerimand 158
 /* line not needed at this step make directory is done later
17255 guerimand 159
  snprintf(pbuf1,sizeof(pbuf1),"%s/%s/.parmreg", class_base, pc);
17435 guerimand 160
  mkdirs(pbuf1);*/
17255 guerimand 161
  snprintf(pbuf1,sizeof(pbuf1),"%s/%s/.parmreg/%s.exam",class_base, pc, pu);
162
  if(stat(pbuf1,&st)==0) { /* search for other session ?? */
163
    /* read file pbuf1 */
164
    char pbuf2[MAX_LINELEN+1], *pf1, *pf2;
165
    accessfile(pbuf2,"r",pbuf1);
166
    pf1=find_word_start(find_word_end(find_word_start(pbuf2)));pf2=find_word_end(pf1);
167
    memmove(pbuf2,pf1,pf2-pf1);pbuf2[pf2-pf1]=0;
17415 guerimand 168
    if( strcmp(pbuf2,pb)!=0 && strcmp("supervisor",pu)!=0 ) { /* other exam session open */
17255 guerimand 169
        user_error("other_exam_session"); return;
170
    }
171
  }
172
  /* end of add for detect */
173
 
13168 bpr 174
  /* Register start time */
12245 bpr 175
  snprintf(vbuf,sizeof(vbuf),"%s/%s/examreg.%d",
176
        session_dir,pb,t1);
177
  if(stat(vbuf,&st)==0) { /* reg exists */
178
    char tbuf[MAX_LINELEN+1];
179
    struct utimbuf ut;
180
    accessfile(tbuf,"r",vbuf); start=atoi(tbuf);
181
    if(start<=nowtime-duration) {
182
      user_error("expired_exam"); return;
13168 bpr 183
    }
184
    /* refresh session times */
185
    ut.actime=ut.modtime=nowtime;
186
    utime(mkfname(NULL,"%s/%s",session_dir,pb),&ut);
12245 bpr 187
  }
188
  else { /* First time call: register starting time */
17255 guerimand 189
    char *p1, tbuf[MAX_LINELEN+1];
12245 bpr 190
    snprintf(dbuf,sizeof(dbuf),"%u",(unsigned int) nowtime);
191
    accessfile(dbuf,"w","%s",vbuf); start=nowtime;
17616 bpr 192
/*  variable initializing before
12245 bpr 193
    if(pc==NULL) pc=getvar("wims_class");
194
    if(pc==NULL) pc="";
17435 guerimand 195
    pu=getvar("wims_user"); if(pu==NULL) pu="";*/
196
    snprintf(vbuf,sizeof(vbuf),"%s/%s/.parmreg", class_base, pc);
197
    mkdirs(vbuf);
12245 bpr 198
    snprintf(vbuf,sizeof(vbuf),"%s/%s/.parmreg/%s.exam",
199
         class_base, pc, pu);
200
    p1=remote_addr;
201
    snprintf(dbuf,sizeof(dbuf),"%s %s %u %d",
202
         p1, pb, (unsigned int) start+duration, t1);
203
    accessfile(dbuf,"w","%s",vbuf);
204
    accessfile(tbuf,"r","%s/%s/.E%d",class_base,pc,t1);
205
    if(strchr(tbuf,'#')==NULL && strcmp(pu,"supervisor")!=0) {  /* not for simulation */
206
      snprintf(tbuf,sizeof(tbuf),"%d 00 %d %u %s %s %s\n",
207
             t1, duration/60, (unsigned int) start,p1,pb,
208
             nowstr);
209
      if(prime!=0) {
12287 bpr 210
        int n=strlen(tbuf);
7673 bpr 211
          snprintf(tbuf+n,sizeof(tbuf)-n,"%d %.2f -1 %u %s %s\n",
212
                t1,prime,(unsigned int) start,p1,pb);
12287 bpr 213
      }
214
      accessfile(tbuf,"a","%s/%s/score/%s.exam",
7673 bpr 215
                 class_base,pc,pu);
12245 bpr 216
    }
217
    else accessfile("yes","w","%s/%s/examsimu.%d",
7673 bpr 218
          session_dir,pb,t1);
12245 bpr 219
  }
17457 guerimand 220
  /* set up wims_scoring + wims_time_remain */
221
  if(pc==NULL) pc=getvar("wims_class");
17459 guerimand 222
  remain=duration+start-nowtime;
17457 guerimand 223
  if(pc) {
224
    int maxremain;
225
    maxremain=getscorestatus(pc,t1);
17459 guerimand 226
    /* negative return is score retriction timeleft */
17465 guerimand 227
    if (maxremain<0 && -maxremain < remain) {
228
      remain=-maxremain;
229
    }
230
    snprintf(vbuf,sizeof(vbuf),"%s/%s/examdepend.%d",session_dir,pb,t1);
231
    snprintf(dbuf,sizeof(dbuf),"%u",(unsigned int) nowtime+remain);
232
    accessfile(dbuf,"w","%s",vbuf);
233
  }
17457 guerimand 234
  if(remain<0) remain=0;
12245 bpr 235
  snprintf(dbuf,sizeof(dbuf),"%d",remain);
17457 guerimand 236
  setvar("wims_exam_remain",dbuf);
10 reyssat 237
}
238
 
239
double currexamscore(int sh)
240
{
12245 bpr 241
  char buf[MAX_FNAME+1], sbuf[MAX_LINELEN+1];
242
  char *p, *p1, *cl;
243
  int i, excnt;
244
  double sc, w, ww, prime;
7673 bpr 245
 
12245 bpr 246
  cl=getvar("wims_class"); if(cl==NULL || *cl==0) return 0;
247
  mystrncpy(sbuf,session_prefix,sizeof(sbuf));
248
  p=strstr(sbuf,"_exam"); if(p) *p=0;
249
  accessfile(buf,"r","%s/examdata.%d",sbuf,sh);
250
  p=find_word_start(find_word_end(find_word_start(buf)));
251
  if(*p) prime=atof(p); else prime=0;
252
  exam_currscore(sh);
253
  snprintf(buf,sizeof(buf),"%s/%s/exams/.exam%d",class_base,cl,sh);
254
  direct_datafile=1;
255
  excnt=datafile_recordnum(buf);
13168 bpr 256
  w=sc=0;
257
  for(i=0;i<excnt;i++) {
12245 bpr 258
    sbuf[0]=0; datafile_fnd_record(buf,i+1,sbuf);
259
    p1=find_word_start(sbuf); *find_word_end(p1)=0;
260
    ww=atof(p1); if(ww<=0) continue;
261
    w+=ww; if(exam_scoredata[i]>-1000) sc+=exam_scoredata[i]*ww;
262
  }
263
  direct_datafile=0; if(sc<0) sc=0;
264
  if(w==0) return 0; else return (1-prime/10)*sc/w+prime;
10 reyssat 265
}
266
 
267
void calc_examdep(char *p)
268
{
12245 bpr 269
  char *p1, *p2;
270
  int t;
271
  if(!trusted_module()) {abt: *p=0; return;}
272
  p1=find_word_start(p); p2=find_word_end(p1);
273
  if(*p2==0) goto abt;
274
  *p2++=0; p2=find_word_start(p2);
275
  t=atoi(p1);
276
  snprintf(p,MAX_LINELEN, exam_depcheck(p2,t)? "yes" : "no");
10 reyssat 277
}