Logo Search packages:      
Sourcecode: wims version File versions  Download package

variables.c

/*    Copyright (C) 1998 XIAO, Gang of Universite de Nice - Sophia Antipolis
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
            /* routines to process variables */

char *computed_var_start; /* pointer to read-in var def file */
char last_host[32]="";

00022 typedef struct {
    char *name;
    char *type_str;
    char *allow_str;
    char *ulim_str;
    char *llim_str;
    int allow;
    int log_num;
    int beg,end;
    int defined_in_parm;
} VAR_DEFINE_LINE;

VAR_DEFINE_LINE var_def[MAX_VAR_NUM];
int defined_var_total;

char *header_var_name[]={
    "REMOTE_ADDR", "HTTP_REFERER", "QUERY_STRING", "HTTP_USER_AGENT",
     "HTTP_COOKIE"
};
#define HEADER_VAR_NO (sizeof(header_var_name)/sizeof(header_var_name[0]))

char *var_allow[]={
    "deny" , "init" , "config" ,
      "reply", "any", "help"
};
enum {
    var_allow_deny, var_allow_init, var_allow_config, 
      var_allow_reply, var_allow_any, var_allow_help
} VAR_ALLOWS;
#define VAR_ALLOW_NO (sizeof(var_allow)/sizeof(var_allow[0]))

      /* install a temporary directory for the session */
void mktmpdir(char *p)
{
    if(p==NULL || *p==0 || strstr(p,"robot")!=NULL) return;
    if(strstr(tmp_dir,"sessions")!=NULL) return;
    snprintf(tmp_dir+strlen(tmp_dir),sizeof(tmp_dir)-strlen(tmp_dir),
           "/sessions/%s",p);
    remove_tree(tmp_dir); mkdirs(tmp_dir);
    chmod(tmp_dir,S_IRUSR|S_IWUSR|S_IXUSR
        |S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH);
    setenv("tmp_dir",tmp_dir,1); setenv("TMPDIR",tmp_dir,1);
}

      /* Open session variable file */
FILE *fopen_session_var_file(char read_or_write[])
{
    char tbuf[MAX_LINELEN+1]; FILE *f;

    snprintf(tbuf,MAX_LINELEN,"%s/var",session_prefix);
    if(read_or_write[0]=='r') {
      if(open_working_file(&m_file,tbuf)!=0) return NULL;
      snprintf(m_file.name,sizeof(m_file.name),"session_var");
      return stdin;
    }
    f=fopen(tbuf,read_or_write);
    if(f==NULL) {
        /* expired_session */
      internal_error("fopen_session_var_file(): unable to create session variable file.");
    }
    snprintf(m_file.name,sizeof(m_file.name),"session_var");
    m_file.l=0;
    return f;
}

      /* Open module var.def, read only */
FILE *fopen_var_def(void)
{
    char tbuf[MAX_LINELEN+1];
    FILE *f;

    snprintf(tbuf,MAX_LINELEN,"%s/%s",module_prefix,var_def_file);
    f=fopen(tbuf,"r");
    if(f!=NULL) {
      snprintf(m_file.name,sizeof(m_file.name),"%s",var_def_file);
      m_file.ff=f; m_file.l=-1;
    }
    return f;
}

      /* Open a module file, read only, with name checking. 
       * returns NULL if error. */
int fopen_module_file(char *fname)
{
    char tbuf[MAX_LINELEN+1];
    
    if(*fname==0) return -1;
      /* Name checking: no directory backtracing. */
    if(strstr(fname,parent_dir_string)!=NULL) {
      setenv(error_data_string,fname,1); module_error("illegal_fname");
      return -1;
    }
    snprintf(tbuf,sizeof(tbuf),"%s/%s",module_prefix,fname);
    if(open_working_file(&m_file,tbuf)!=0) {
      if(strncmp(fname,"adm/",4)==0 && !trusted_module()) return -1;
      snprintf(tbuf,sizeof(tbuf),"scripts/%s",fname);
      if(open_working_file(&m_file,tbuf)!=0) return -1;
    }
    snprintf(m_file.name,sizeof(m_file.name),"%s",fname);
    return 0;
}

      /* User has changed module within an operation.
       * Probably due to robot access. */
void bad_module(void)
{
    struct stat st;
    char buf[256];
    snprintf(buf,sizeof(buf),"%s/.manual",session_prefix);
    if(stat(buf,&st)!=0) accessfile("yes","w","%s/.robot",session_prefix);
    else setvar("wims_human_access","yes");
    user_error("module_change");
}

      /* The session is probably robot. */
void robot_doubt(void)
{
    char *h, *p, buf[256];
  
    p=getvar("special_parm"); h=getvar("module");
    if(p==NULL || h==NULL) {
      bad: user_error("robot_doubt"); return;
    }
    p=find_word_start(p); strip_trailing_spaces(p);
    if(strcmp(p,"wims")!=0 || strcmp(h,home_module)!=0) goto bad;
    snprintf(buf,sizeof(buf),"%s/.robot",session_prefix); unlink(buf);
}

int varget[]={ro_module,ro_lang,ro_useropts,ro_worksheet};
#define varget_no (sizeof(varget)/sizeof(varget[0]))

      /* set up ref strings according to protocol */
void set_protocol(void)
{
    if(strcmp(protocol,"https")!=0) return;
    if(strncmp(ref_name,"http:",5)==0) {
      string_modify(ref_name,ref_name+4,ref_name+4,"s");
      string_modify(ref_base,ref_base+4,ref_base+4,"s");
      force_setvar("wims_ref_name",ref_name);
    }
}

      /* verify class participant connection data */
void classlock(void)
{
    int lvl;
    char *p;
    
    p=getvar("wims_classlock"); if(p==NULL) lvl=0; else {
      p=find_word_start(p);
      lvl=*p-'0'; if(lvl<0 || lvl>6) lvl=0;
    }
    if(lvl==2 || lvl==4 || lvl==6) {      /* https */
      p=getenv("HTTPS");
      if(p==NULL || strcasecmp(p,"on")!=0) user_error("need_https");
    }
    if(lvl==3 || lvl>=5) {
      if(strcmp(last_host,remote_addr)!=0) user_error("bad_host");
    }
    if((lvl==1 || lvl>=4) && cookiegot[0]==0) { /* cookie */
      setcookie=1;
      setvar("cookie_module",getvar(ro_name[ro_module]));
      setvar("cookie_cmd",getvar(ro_name[ro_cmd]));
      force_setvar(ro_name[ro_module],"home");
      force_setvar(ro_name[ro_cmd],commands[cmd_new]);
      setvar("wims_askcookie","yes");
      return;
    }
    else setcookie=0;
}

      /* static session variables */
void set_static_session_var(void)
{
    char *p, *pe, *p2, *p3;
    char sbuf[256], tbuf[MAX_LINELEN+1];
    snprintf(sbuf,sizeof(sbuf),"%s",session_prefix);
    for(p=sbuf+strlen(sbuf);p>sbuf && *p!='_' && *p!='/'; p--);
    if(p>sbuf && *p=='_') *p=0;
    accessfile(tbuf,"r","%s/var.stat",sbuf);
    p=strrchr(sbuf,'/'); if(p!=NULL) p++; else p=sbuf;
    mktmpdir(p);
    for(p=find_word_start(tbuf);*p;p=find_word_start(pe)) {
      pe=strchr(p,'\n'); if(pe!=NULL) *pe++=0;
      p2=strchr(p,'='); if(p2==NULL) continue;
      *p2++=0; force_setvar(p,p2);
    }
    p=getvar("wims_class"); if(p==NULL || *p==0) return;
    classlock();
    p3=getvar("wims_class_refcolor"); if(p3!=NULL && *p3!=0)
      force_setvar("wims_ref_bgcolor",p3);
    p2=getvar(ro_name[ro_module]);
    if(p2==NULL || strncmp(p2,"classes/",strlen("classes/"))!=0) return;
    snprintf(sbuf,sizeof(sbuf),"classes/%s",p);
    if(strcmp(sbuf,p2)!=0) force_setvar(ro_name[ro_module],sbuf);
}

      /* returns 1 if session directory exists */
int session_exists(char *s)
{
    struct stat st;
    char sbuf[256];
    snprintf(sbuf,sizeof(sbuf),"%s/%s/var",session_dir,s);
    if(stat(sbuf,&st)==0) return 1; else return 0;
}

      /* Check the validity of session number .
       * returns 0 if OK, else -1. */
int check_session(void)
{
    char tbuf[MAX_LINELEN+1], vbuf[MAX_LINELEN+1];
    char *p, *pp, *pr;
    int i,m,n,pl,rapid;
    FILE *rf;
    struct stat st;

    rapid=0; pr="";
    if(fopen_session_var_file("r")==NULL) return -1;
    snprintf(vbuf,sizeof(vbuf),"%s/.robot",session_prefix);
    if(stat(vbuf,&st)==0) robot_doubt();
    snprintf(vbuf,sizeof(vbuf),"%s/.referer",session_prefix);
    rf=fopen(vbuf,"r"); if(rf!=NULL) {
      fgets(vbuf,MAX_LINELEN,rf); setenv("HTTP_REFERER",vbuf,1);
      setvar("httpd_HTTP_REFERER",vbuf);
      fclose(rf);
    }
      /* form access means manual access. Mark this. */
    if(form_access) {
      snprintf(vbuf,sizeof(vbuf),"%s/.manual",session_prefix);
      if(stat(vbuf,&st)!=0) accessfile("yes\n","w",vbuf);
    }
      /* REMOTE_ADDR */
    wgetline(vbuf,MAX_LINELEN,&m_file);
    snprintf(last_host,sizeof(last_host),"%s",vbuf+strlen("REMOTE_ADDR="));
    m_file.linepointer++; /* now it points to query_string */
    pp=getenv("QUERY_STRING");
    if(pp!=NULL && *pp!=0 && strlen(pp)<=MAX_LINELEN) {
            /* we compare the query string with the last one. */
      char *p1, *p2;
      n=strlen(pp); last_query_string=xmalloc(n+64);
      p1=last_query_string+strlen("QUERY_STRING=");
      wgetline(last_query_string,n+16,&m_file);
      if(strncmp(last_query_string,"QUERY_STRING=",strlen("QUERY_STRING="))==0) {
          if(strcmp(pp,p1)==0) {
                  /* query string does not change */
            uselast: putlastout(); delete_pid(); exit(0);
          }
      }
            /* stop rapidfire requests */
      if((cmd_type==cmd_new || cmd_type==cmd_renew) &&
         strncmp(p1,"session=",strlen("session="))==0 &&
         strncmp(pp,"session=",strlen("session="))==0) {
          p1=strchr(p1,'&'); if(p1==NULL) p1="";
          p2=strchr(pp,'&'); if(p2==NULL) p2=""; pr=p2;
          if(strcmp(p1,p2)==0) rapid=1;
      }
    }
    m_file.linepointer=3;
    wgetline(vbuf,MAX_LINELEN,&m_file); /* stored user_agent */
    p=getenv("HTTP_USER_AGENT"); if(p==NULL) p="";
    if(strcmp(vbuf+strlen("HTTP_USER_AGENT="),p)!=0) bad_ident();
    if(cookiegot[0]!=0) {
      snprintf(tbuf,sizeof(tbuf),"%s",session_prefix);
      p=strchr(tbuf,'_'); if(p!=NULL) *p=0;
      accessfile(vbuf,"r","%s/.cookie",tbuf);
      if(strcmp(cookiegot,vbuf)!=0) bad_ident();
    }
    m_file.linepointer=HEADER_VAR_NO;
    pl=strlen(var_prefix);i=-1;
    while(wgetline(tbuf,MAX_LINELEN,&m_file)!=EOF) {
      if(tbuf[0]==0) break;   /* blank line */
      if(strncmp(tbuf,var_prefix,pl)!=0) break;
      i++;if(i>=RO_NAME_NO) break;
      for(n=0;n<varget_no && varget[n]!=i;n++);
      if(n>=varget_no) continue;
      m=pl+strlen(ro_name[i]);
      if(tbuf[m]!='=' || tbuf[m+1]==0) continue;
      if(i==ro_module && cmd_type!=cmd_new && cmd_type!=cmd_intro) {
          char *pp;
          pp=getvar(ro_name[i]);
          if(pp!=NULL && *pp!=0 && strcmp(pp,tbuf+m+1)!=0) bad_module();
      }
      if(i==ro_lang && !user_lang)
        force_setvar(ro_name[i],tbuf+m+1);
      else setvar(ro_name[i],tbuf+m+1);
    }
      /* recover internal variables */
    do {
      char *v;
      if(tbuf[0]==0) break;
      v=strchr(tbuf,'=');
      if(v==NULL) break; else *(v++)=0;
      if(strncmp(tbuf,var_prefix,strlen(var_prefix))!=0) setenv(tbuf,v,1);
      else if(tbuf[strlen(var_prefix)]) force_setvar(tbuf+strlen(var_prefix),v);
    }
    while(wgetline(tbuf,MAX_LINELEN,&m_file)!=EOF);
    close_working_file(&m_file);
    set_static_session_var();
    if(rapid) {
      int rapidfiredelay;
      char *pw, fnbuf[1024];
            /* Delay: 10 seconds within worksheets, 1 second otherwise. */
      pw=getvar("wims_developer");
      if(pw!=NULL && *pw!=0) goto delcheckend;
      pw=getvar("wims_user"); 
      if(pw==NULL || *pw==0 || strcmp(pw,"supervisor")==0) rapidfiredelay=1;
      else {
          pw=strstr(pr,"&+worksheet=");
          if(pw!=NULL && isdigit(*(pw+strlen("&+worksheet=")))) rapidfiredelay=10;
          else rapidfiredelay=2;
      }
      snprintf(fnbuf,sizeof(fnbuf),"%s/%s",session_prefix,lastout);
      if(stat(fnbuf,&st)==0 && nowtime-st.st_mtime<rapidfiredelay)
        goto uselast;
    }
      /* set protocol string */
    delcheckend: pp=getvar("wims_protocol");
    if(pp!=NULL && strcmp(pp,"https")==0) {
      protocol="https"; set_protocol();
    }
    useropts(); return 0;
}
      /* check whether a session is trapped. */
void trap_check(char *s)
{
    char buf[MAX_LINELEN+1],cbuf[MAX_LINELEN+1];
    char *p;
    time_t t1;

    setvar("wims_session_expired",s);
    accessfile(cbuf,"r","%s/trap.check",log_dir);
    if(cbuf[0]==0) return;
    p=getenv("REMOTE_ADDR");if(p==NULL) return;
    snprintf(buf,sizeof(buf),":%s,%s,",s,p);
    p=strstr(cbuf,buf); if(p==NULL) return;
    p+=strlen(buf);*find_word_end(p)=0;
    t1=atoi(p);
    if(t1>nowtime) user_error("trapped");
}

char cars[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

void set_cookie(void)
{
    #define keylen 20
    char sesbuf[16], keybuf[keylen+8], buf[MAX_LINELEN+1];
    char *p;

    p=getvar(ro_name[ro_session]); if(p==NULL) return;
    snprintf(sesbuf,sizeof(sesbuf),"%s",p);
    if(strchr(sesbuf,'_')==NULL) {  /* main session */
      int i;
      for(i=0;i<keylen;i++) keybuf[i]=cars[random()%36];
      keybuf[keylen]=0; cookiegot[0]=0;
      snprintf(cookieset,sizeof(cookieset),"%s-%s",sesbuf,keybuf);
      accessfile(cookieset,"w","%s/.cookie",session_prefix);
      setcookie=1;
    }
    else {  /* subsession */
      *strchr(sesbuf,'_')=0;
      accessfile(buf,"r","%s/%s/.cookie",session_dir,sesbuf);
      snprintf(cookieset,sizeof(cookieset),"%s",buf);
    }
}

      /* create a session number */
void create_session(void)
{
    long t; char session_str[64],*s;
    char *p, ses_dir_buf[1024];
    
      /* no session is created for robots */
    if(robot_access) return;
      /* If session is given in request_string: use it. */
    s=getvar(ro_name[ro_session]); if(s==NULL) goto creat;
    strncpy(session_str,s,32); session_str[32]=0;
    s=strchr(session_str,'.'); if(s!=NULL) *s=0;
    s=session_str;
    if(*s!=0) {
      struct stat st;
      int i;
      snprintf(ses_dir_buf,sizeof(ses_dir_buf),"%s/%s",session_dir,s);
      i=stat(ses_dir_buf,&st);
      if(i!=0) {
          trap_check(s);
            /* subsession */
          if(strlen(s)>10 && strchr(s,'_')!=NULL) {
            char *tt;
            tt=strrchr(ses_dir_buf,'_'); if(tt!=NULL) *tt=0;
            /* parent session gone. */
            if(stat(ses_dir_buf,&st)!=0) goto creat;
            goto creat2;
          }
          else goto creat;
      }
      if(!S_ISDIR(st.st_mode)) {
          trap_check(s);
          remove_tree(ses_dir_buf); goto creat;
      }
      return;
    }
    creat:
    t=create_job_ident();
    snprintf(session_str,sizeof(session_str),"%c%c%08lX",
           cars[random()%36],cars[random()%36],t);
    creat2:
    force_setvar(ro_name[ro_session],session_str);
    force_setvar("wims_session",session_str);
      /* check whether the environment is created. */
    s=getvar(ro_name[ro_session]);
    if(s==NULL || strcmp(s,session_str))
      internal_error("cannot_create_session_number");
    snprintf(ses_dir_buf,sizeof(ses_dir_buf)-100,"%s/%s",
           session_dir,session_str);
    if(mkdir(ses_dir_buf,S_IRWXU)==-1)
      internal_error("cannot_create_session_directory");
    strcpy(session_prefix,ses_dir_buf); create_pid();
    accessfile("deny from all\n","w","%s/.htaccess",ses_dir_buf);
    if(strchr(session_str,'_')==NULL && 
       (s=getenv("HTTP_REFERER"))!=NULL && *s!=0
       && strstr(s,"wims")==NULL) {
      char *tt;
      tt=getenv("SERVER_NAME");
      if(tt==NULL || *tt==0 || strstr(s,tt)==NULL) {
          accessfile(s,"w","%s/.referer",ses_dir_buf);
          setvar("httpd_HTTP_REFERER",s);
      }
    }
      /* determine http protocol name. How to detect? */
    p=getenv("HTTPS"); if(p!=NULL && strcmp(p,"on")==0) {
      protocol="https"; set_protocol();
    }
    force_setvar("wims_protocol",protocol);
    new_session=1; session_serial=0;
    setvar("wims_new_session","yes");
    set_cookie();
    if(strchr(session_str,'_')!=NULL) set_static_session_var();
}

      /* Register time of the request. */
void set_req_time(void)
{
    char tstr[256];
    
    snprintf(tstr,sizeof(tstr),"%04d-%02d-%02d.%02d:%02d:%02d=%lu",
          (now->tm_year)+1900, (now->tm_mon)+1, now->tm_mday,
          now->tm_hour, now->tm_min, now->tm_sec, nowtime);
    setvar("wims_req_time",tstr);
    if(cmd_type == cmd_new || cmd_type == cmd_renew)
      setvar("wims_module_start_time",tstr);
    if(new_session) setvar("wims_session_start_time",tstr);
}

      /* set up module_prefix. */
void set_module_prefix(void)
{
    char tbuf[MAX_LINELEN+5], mmbuf[MAX_LINELEN+1], *p;
    FILE *f;

    isclassmodule=0;
    p=getvar(ro_name[ro_module]);
    if(p==NULL || *p==0) user_error("no_module_name");
      /* security measure: we should not allow users to go back to
       * parent directories. */
    if (strstr(p,parent_dir_string)!=NULL) user_error("wrong_module");
    if(strncmp(p,"classes/",strlen("classes/"))==0) isclassmodule=1;
    snprintf(module_prefix,sizeof(module_prefix),"%s/%s",module_dir,p);
      /* Check validity of the module. */
    snprintf(tbuf,sizeof(tbuf),"%s/%s",module_prefix,html_file);
    f=fopen(tbuf,"r");
    if(f==NULL && p[strlen(p)-3]!='.') {
      int i,j;
      char *l;
      l=getvar(ro_name[ro_lang]);
      j=available_lang_no;
      for(i=-1;i<j && f==NULL;i++) {
          if(i<0) snprintf(mmbuf,sizeof(mmbuf),"%s.%s",p,l);
          else snprintf(mmbuf,sizeof(mmbuf),"%s.%s",p,available_lang[i]);
          snprintf(module_prefix,sizeof(module_prefix),"%s/%s",module_dir,mmbuf);
          snprintf(tbuf,sizeof(tbuf),"%s/%s",module_prefix,html_file);
          f=fopen(tbuf,"r");
      }
      if(f!=NULL) force_setvar(ro_name[ro_module],mmbuf);
    }
    if(f==NULL) user_error("wrong_module");
    fclose(f);
    setenv("module_dir",module_prefix,1); setvar("module_dir",module_prefix);
    module_index();
}

      /* set up session_prefix. */
int set_session_prefix(void)
{
    char *p, s[256];
    DIR *sesdir;
    struct stat st;

    if(robot_access) {
      strcpy(session_prefix,robot_session);
      return 0;
    }
    p=getvar(ro_name[ro_session]);
    if(p==NULL || *p==0) user_error("no_session");
      /* same reason as for modules */
    if (strstr(p,parent_dir_string)!=NULL) 
      user_error("wrong_session");
    strncpy(s,p,255);s[255]=0;
    p=strchr(s,'.'); if(p!=NULL) *p=0;
    snprintf(session_prefix,sizeof(session_prefix),"%s/%s",session_dir,s);
    p=strstr(session_prefix,"_mhelp"); if(p!=NULL) *p=0;
      /* Just to set access time to the session directory file. */
    sesdir=opendir(session_prefix); 
    if(sesdir==NULL) return -1;
    setenv("session_dir",session_prefix,1);
    readdir(sesdir); closedir(sesdir); 
    snprintf(s,sizeof(s),"%s/.trap",session_prefix);
    if(stat(s,&st)==0) user_error("trapped");
    return 0;
}

      /* check reserved name values in query_string */      
void parse_ro_names(void)
{
    int i;
    char *cmd, *p;
    char sesbuf[MAX_LINELEN+1];
    create:
    cmd=getvar(ro_name[ro_cmd]);
    if(cmd==NULL || *cmd==0) user_error("no_command");
    for(i=0;i<CMD_NO;i++) if(strcmp(cmd,commands[i])==0) break;
    if(i>=CMD_NO) user_error("bad_command");
    cmd_type=i;
    if(cmd_type == cmd_new) {
      create_session();
      if(set_session_prefix()==0) {
          check_session();
          set_module_prefix();
      }
      else goto redo;
    }
    if (set_session_prefix()==-1 || (cmd_type != cmd_new && check_session())) {
      redo:
      force_setvar(ro_name[ro_cmd],commands[cmd_new]);
/*    force_setvar(ro_name[ro_module],home_module); */
      if(strcmp(ro_name[ro_module],home_module)!=0) user_var_no=0;
      goto create;
    }
    if(!new_session) create_pid();
    session_serial++;
    if(robot_access) session_serial=1;
    snprintf(sesbuf,sizeof(sesbuf),"%d",session_serial);
    force_setvar("wims_session_serial",sesbuf);
    p=getvar(ro_name[ro_session]);
    if(p==NULL || *p==0) internal_error("parse_ro_names(): bad session.\n");
    strncpy(sesbuf,p,MAX_LINELEN);sesbuf[MAX_LINELEN-1]=0;
    p=strchr(sesbuf+5,'.'); if(p!=NULL) *p=0;
    mktmpdir(sesbuf);
    if(!robot_access) {
      force_setvar("wims_session",sesbuf);
      p=strchr(sesbuf,'_');
      if(p!=NULL) force_setvar("wims_subsession",p);
    }
    snprintf(sesbuf+strlen(sesbuf),sizeof(sesbuf)-strlen(sesbuf),
           ".%d",session_serial);
    force_setvar(ro_name[ro_session],sesbuf);
    if(cmd_type != cmd_new) set_module_prefix();
    set_req_time();
    if(robot_access) check_load(0);
    else {
      if(new_session) auth();
      else {
          p=getvar("wims_user"); if(p==NULL || *p==0) check_load(2);
      }
    }
    if(cmd_type==cmd_help && open_working_file(&m_file,module_about_file)==0)
      var_proc(NULL);
}

      /* parse module's variable definitions */
void get_var_defs(void)
{
    FILE *varf;
    int i, v, add, llen;
    long varf_len, varf_read_len;
    char *e, *p, *q, *pp, *lstart, *lend;
    
    varf=fopen_var_def();
    if(varf==NULL) {
      defined_var_total=0; return;
    }
    fseek(varf,0,SEEK_END);
    varf_len=ftell(varf);
    if(varf_len<=0) {
      fclose(varf); defined_var_total=0; return;
/*    module_error("bad_var_def"); */
    }
    if(varf_len>=VAR_DEF_LENGTH_LIMIT) {
      setenv(error_data_string,"var.def",1); module_error("file_too_long");
    }
    var_def_buf=xmalloc(varf_len+2);
    fseek(varf,0,SEEK_SET);
    varf_read_len=fread(var_def_buf,1,varf_len,varf);
    fclose(varf);
    if(varf_read_len>varf_len) internal_error("get_var_defs(): mysterious file read error.");
    if(varf_read_len<=0) 
      internal_error("get_var_defs(): error reading file.");
    *(var_def_buf+varf_read_len)=0;
    e=var_def_buf-1;
    for(v=add=0;add<MAX_VAR_NUM && e<var_def_buf+varf_read_len && e!=NULL ;) {
      p=e+1;
rep:  e=strchr(p,'\n'); m_file.l++;
      if(e!=NULL && e>p && *(e-1)=='\\') {  /* escaped new-line */
          *(e-1)=*e=' '; goto rep;
      }
      if(e!=NULL) *e=0;   /* make string out of a line */
      p=find_word_start(p);
      if(*p==0 || *p==comment_prefix_char) continue;  /* empty or comment lines */
      lstart=p; llen=strlen(lstart);
      lend=lstart+llen;
      var_def[v].name=p; q=find_word_end(p);
      if((q-p)>=MAX_NAMELEN) module_error("name_too_long");
            /* internal names cannot appear in def. */
      *q=0;
      if(search_list(internal_name,INTERNAL_NAME_NO,
                   sizeof(internal_name[0]),p)>=0 ||
         search_list(ro_name,RO_NAME_NO,
                   sizeof(ro_name[0]),p)>=0) {
          setenv("wims_reserved_name",p,1);
          module_error("name_is_reserved");
      }
      if(*(q-1)==']') {
          int j;
          *(q-1)=0; pp=strchr(p,'['); 
          if(pp==NULL || pp==p) module_error("illegal_name");
          *pp++=0; j=atoi(pp);
          if(j<1) j=1; if(j>MAX_VAR_NUM-add) j=MAX_VAR_NUM-add;
          var_def[v].beg=1; var_def[v].end=j;
          add+=j;
      }
      else {
          add++;
          for(pp=q; pp>p && isdigit(*(pp-1)); pp--);
          if(*pp && *pp!='0' && pp>p) {
            var_def[v].beg=var_def[v].end=atoi(pp); *pp=0;
          }
          else var_def[v].beg=var_def[v].end=-1;
      }
      p=find_word_start(q+1);
            /* check permission */
      if(*p==0 || p>=lend) module_error("too_few_columns");
      var_def[v].allow_str=p; q=find_word_end(p);
      p=find_word_start(q); *q=0;
      for(i=0;i<VAR_ALLOW_NO;i++) 
        if(strcasecmp(var_def[v].allow_str,var_allow[i])==0) break;
      if(i>=VAR_ALLOW_NO) module_error("bad_allow");
      else var_def[v].allow=i;
      
      if(*p==0 || p>=lend) {
          var_def[v].log_num=0;
          var_def[v].llim_str=var_def[v].ulim_str="";
          goto done;
      }
      q=find_word_end(p); *q=0; var_def[v].log_num=atoi(p);
      if(q<lend) p=find_word_start(q+1); else p=q;
            /* If limits are defined. */
      var_def[v].llim_str=p;
      q=find_word_end(p); *q=0;
      if(q<lend) p=find_word_start(q+1); else p=q=lend;
      var_def[v].ulim_str=p;
      q=find_word_end(p); *q=0;
      done:
      var_def[v].defined_in_parm=0;
      v++;
    }
    if(v>=MAX_VAR_NUM) module_error("too_many_variables");
    defined_var_total=v;
}
    
      /* set environ variables from last session save
       * The session var file starts with variables which should not
       * be restored. Variables which are restored follow a blank line. */
void set_vars_from_session(void)
{
    char lbuf[MAX_LINELEN+1];
    int c;
    char *p;

    fopen_session_var_file("r");
      /* look for the first blank line. */
    do c=wgetline(lbuf,MAX_LINELEN,&m_file);
    while(c!=0 && c!=EOF);
    if(c==EOF) return;
    while(wgetline(lbuf,MAX_LINELEN, &m_file)!=EOF) {
      p=strchr(lbuf,'='); 
      if(p==NULL || p<=lbuf || isspace(lbuf[0]) ) {
                  /* this time it is corrupted var file */
        call_ssh("cat %s/var >../log/corrupt.var.bak",session_prefix);
        internal_error("get_vars_from_session(): corrupt session variable file.");
      }
      *p=0;p++;
            /* Here we suppose that nobody can tamper session variable
             * file, and do not check variable names against module's
             * definition file. Policy under reserve. */
          /* We do not allow override though.
           * Especially because reply variables should
           * be preserved. */
      if(strncmp(lbuf,var_prefix,strlen(var_prefix))!=0) 
        setenv(lbuf,p,0);
      else if(lbuf[strlen(var_prefix)]!=0 && getvar(lbuf+strlen(var_prefix))==NULL)
        setvar(lbuf+strlen(var_prefix),p);
    }
    close_working_file(&m_file);
}

      /* Initialize environment variables according to module's
       * variable init or calculation file. 
       * init is only used when cmd=new or renew.
       * Requires get_var_defs be run first. */
void var_proc(char *fname)
{
    int  linend;
    char *name;
    char tbuf[MAX_LINELEN+1];

    if(fname!=NULL) if(fopen_module_file(fname)) return;
    do {
      linend=wgetline(tbuf,MAX_LINELEN,&m_file); substnest=0;
      name=find_word_start(tbuf);
      if(*name==0 || *name==comment_prefix_char) continue;
      if(*name==exec_prefix_char) {
          exec_main(name+1); continue;
      }
      if (*name==label_prefix_char) continue;
      exec_set(name);
    }
    while(linend!=EOF);
    close_working_file(&m_file);
}

      /* Deposit the content of wims_deposit into a file */
void var_deposit(char *p)
{
    char fn[256];
    FILE *f;
    int l;
    if(deplen>0) l=deplen; else {
      while(isspace(*p)) p++; l=strlen(p);
    }
    if(l<=0) return;
    if(!trusted_module()) return;
    snprintf(fn,sizeof(fn),"%s/user-deposit",session_prefix);
    f=fopen(fn,"w"); if(f==NULL) return;
    if(l>MAX_DEPOSITLEN) l=MAX_DEPOSITLEN; /* silent truncation, should not occur */
    fwrite(p,1,l,f); fclose(f);
    snprintf(fn,sizeof(fn),"%u",l); setvar("wims_deposit_len",fn);
}

      /* Check and set variables passed in query_string */
void set_vars_from_parm(void)
{
    int i,j,nn,tt,al;
    char *s,*p, vbuf[MAX_LINELEN+1];
    for(i=0; i<user_var_no; i++) {
      s=user_variable[i].name; nn=strlen(s);
      for(p=s+nn;p>s && isdigit(*(p-1));p--);
      if(*p && p>s && *p!='0') {
          nn=p-s; tt=atoi(p);
      }
      else tt=-1;
      for(j=0;j<defined_var_total && 
          (*s!=var_def[j].name[0] || strlen(var_def[j].name)!=nn ||
           strncmp(s,var_def[j].name,nn) || 
           (tt>0 && (var_def[j].beg>tt || var_def[j].end<tt)) ||
           (tt<0 && var_def[j].beg>=0)
           );j++);
            /* Unknown variable: simply ignored. */
      if(j>=defined_var_total) continue;
           /* check permissions */
      al=var_def[j].allow;
      if(al != var_allow_any) switch(cmd_type) {
          case cmd_new:
          case cmd_renew:
              if (al != var_allow_init && al != var_allow_config) {
violat:               /* setenv(error_data_string,user_variable[i].name,1);
                user_error("allow_violation"); */
                goto loopend;
            }
              break;
          
          case cmd_config:
              if(al != var_allow_config) goto violat;
              break;

          case cmd_reply:
            if(al != var_allow_reply) goto violat;
              break;
          
          case cmd_help:
            if(al != var_allow_help) goto violat;
            break;
          
          default: goto violat;
      }
      var_def[j].defined_in_parm=1;
      if(strcmp(user_variable[i].name,"wims_deposit")==0) {
          var_deposit(user_variable[i].value); continue;
      }
      snprintf(vbuf,sizeof(vbuf),"%s",user_variable[i].value);
      if(strchr(vbuf,'$')!=NULL) {
          char *p;
          while((p=strchr(vbuf,'$'))!=NULL) 
            string_modify(vbuf,p,p+1,"&#36;");
      }
      s=getvar(user_variable[i].name);
      if(s==NULL || *s==0)
        force_setvar(user_variable[i].name, vbuf);
      else {  /* concatenate */
          char buf[MAX_LINELEN+1];
          int k;
          k=strlen(s)+strlen(vbuf);
          if(k>=MAX_LINELEN-2) user_error("string_too_long");
          snprintf(buf,sizeof(buf),"%s, %s",s,vbuf);
          force_setvar(user_variable[i].name, buf);       
      }
      loopend: ;
    }
}

      /* Check variable bounds. Obsolete. */
void check_var_bounds(void)
{
    int i;
    double llim,ulim,parmvar;
    char buf[MAX_LINELEN+1], *p;
    
    for(i=0;i<defined_var_total;i++) {
      if(*(var_def[i].llim_str)==0) continue;
      llim=evalue(var_def[i].llim_str);
      if(*(var_def[i].ulim_str)!=0) ulim=evalue(var_def[i].ulim_str);
      else ulim=llim;
            /* Here it is a bit tricky to put error messages; 
             * so I simply ignore error. */
      if(ulim<llim) ulim=llim;
      p=getvar(var_def[i].name); if(p==NULL || *p==0) continue;
      parmvar=evalue(p);
      if(parmvar<llim) {
          parmvar=llim;
  reset:    float2str(parmvar,buf);
          setvar(var_def[i].name,buf);
          continue;
      }
      if(parmvar>ulim) {
          parmvar=ulim; goto reset;
      }
    }
}

      /* parms to be eliminated from module_init_parm */
/* char *init_elim[]={
    "module","cmd","session","lang","worksheet","wims_access","useropts"
};
#define init_elim_no (sizeof(init_elim)/sizeof(init_elim[0]))
*/

void elim_parm(char *str, char *parm)
{
    char *p1, *p2;
    for(p1=strstr(str,parm);p1!=NULL;p1=strstr(p1+1,parm)) {
      if( (p1>str && *(p1-1)!='&') || *(p1+strlen(parm))!='=')
        continue;
      p2=strchr(p1,'&');
      if(p2==NULL) {
          if(p1>str) *(p1-1)=0; else *p1=0;
          return;
      }
      strcpy(p1,p2+1); p1--;
    }
}

      /* eliminate technical definitions form parameter string. */
void prep_init_parm(char rqv[])
{
    int i;
    char *p;

    for(p=strstr(rqv,"&+"); p!=NULL; p=strstr(++p,"&+"))
      strcpy(p+1,p+2);
    for(i=0;i<RO_NAME_NO;i++) elim_parm(rqv,ro_name[i]);
    if(strlen(rqv)>=MAX_LINELEN) rqv[0]=0;
    while(rqv[0]=='&') strcpy(rqv,rqv+1);
    while(rqv[0]!=0 && rqv[strlen(rqv)-1]=='&') rqv[strlen(rqv)-1]=0;
}

      /* retain initializing parameters, for use in user references */
void set_init_parm(void)
{
    char *rq, rqv[MAX_LINELEN*2+2], *u, *sh;
    char *shname;
    int public_sheet;

    if(isexam) return;
    force_setvar("wims_sheet",""); force_setvar("wims_exo","");
    rq=getenv("QUERY_STRING");
    if(rq==NULL || *rq==0) {
      empty:
      setvar("module_init_parm",""); return;
    }
    if(strlen(rq)>=MAX_LINELEN*2) goto empty;
    _http2env(rqv,rq); prep_init_parm(rqv);
    setvar("module_init_parm",rqv); public_sheet=0;
      /* now determine the sheet number for user */
    sh=getvar(ro_name[ro_worksheet]); if(sh==NULL) return;
    if(*sh=='P') {public_sheet=1; sh++;}
    shname="sheet";
    u=getvar("wims_user"); if(u==NULL) u="";
    if(sh!=NULL && *sh!=0) {
      char *buf,ubuf[1024], nbuf[1024], *c, *m;
      char *p1,*p2,*p3,*p4,*p5;
      int i,j,sheet,act; long int flen;
      FILE *ef;
      sheet=atoi(sh); if(sheet<=0 || sheet>256) return;
      m=getvar(ro_name[ro_module]);
      if(m==NULL) internal_error("set_init_parm(): module name disapears.");
      if(*u==0) public_sheet=1;
      if(!public_sheet) {
          c=getvar("wims_class"); if(c==NULL) c="";
          if(strcmp(u,"supervisor")==0) act=0; else act=1;
          snprintf(nbuf,sizeof(nbuf),"%s/classes/%s/sheets/.%s%d",
                 log_dir,c,shname,sheet);
      }
      else {
          char bf[MAX_LINELEN+1];
          int i;
          accessfile(bf,"r","%s/.sheets",session_prefix);
          if(bf[0]==0) return;
          for(i=1, p1=bf;i<sheet;i++,p1=p2) {
            p2=strchr(p1,'\n');
            if(p2!=NULL) *p2++=0; else p2=p1+strlen(p1);
          }
          p2=strchr(p1,'\n'); if(p2) *p2=0;
          snprintf(nbuf,sizeof(nbuf),"bases/sheet/%s.def",p1);
      }
      ef=fopen(nbuf,"r"); if(ef==NULL) return;
      fseek(ef,0,SEEK_END); flen=ftell(ef); if(flen<=0) return;
      buf=xmalloc(flen+16); fseek(ef,0,SEEK_SET);
      fread(buf,1,flen,ef);buf[flen]=0; fclose(ef);
      for(p1=strstr(buf,"&+");p1!=NULL;p1=strstr(++p1,"&+"))
          strcpy(p1+1,p1+2);
      if(strncmp(m,"classes/",strlen("classes/"))==0) {
          m="classes/";
          for(p1=strstr(buf,":classes/");p1;p1=strstr(p1+1,":classes/")) {
            if(p1==buf || *(p1-1)=='\n') {
                p1+=strlen(":classes/");
                p2=find_word_end(p1); if(p2>p1 && *p2=='\n') strcpy(p1,p2);
            }
          }
      }
      snprintf(nbuf,sizeof(nbuf),":%s\n%s\n",m,rqv);
      p1=strstr(buf,nbuf);
      while(p1>buf && *(p1-1)!='\n') p1=strstr(p1+1,nbuf);
      if(p1!=NULL) {
          p2=strchr(buf,':');
          while(p2>buf && *(p2-1)!='\n') p2=strchr(p2+1,':');
          for(i=1;p2!=NULL && p2<p1;i++) {
            p2=strchr(p2+1,':');
            while(p2>buf && *(p2-1)!='\n') p2=strchr(p2+1,':');
          }
          if(p2==NULL) return;      /* error which should not occur */
          snprintf(ubuf,sizeof(ubuf),"%d",i);
            /* look for dependency information */
          for(j=0, p3=strchr(p1+strlen(nbuf),'\n');
            j<3 && p3 && *(p3+1)!=':';
            j++, p3=strchr(p3+1,'\n'));
          if(j>=3 && p3!=NULL && *(p3+1)!=':') {
            p3++; p4=strchr(p3,'\n');
            if(p4) {
                *p4++=0; if(*p4!=':') {   /* options */
                  p5=strchr(p4,'\n'); if(p5) *p5=0;
                  force_setvar("wims_exoption",p4);
                }
            }
            p3=find_word_start(p3); strip_trailing_spaces(p3);
                  /* non-empty dependency information */
            if(*p3 && !public_sheet) {
                exodepOK=depcheck(sh,i,p3);
                if(!exodepOK) setvar("wims_exodep","pending");
            }
          }
          if(public_sheet) {
            char bf[32];
            snprintf(bf,16,"P%s",sh);
            force_setvar("wims_sheet",bf);
          }
          else force_setvar("wims_sheet",sh);
          force_setvar("wims_exo",ubuf);
          wims_sheet=sheet; wims_exo=i;
      }
      free(buf);
    }
}

      /* user with class: whether exercise is registered
       * Returns 1 if got, 0 otherwise. */
int get_parmreg(void)
{
    char *p, *cl, *u, nbuf[1024], lbuf[MAX_LINELEN+1];
    struct stat st;

    u=getvar("wims_user"); cl=getvar("wims_class");
    if(u==NULL || cl==NULL || *u==0 || *cl==0 || strcmp(u,"supervisor")==0
       || wims_sheet<=0 || wims_exo<=0) return 0;
    snprintf(nbuf,sizeof(nbuf),"%s/classes/%s/.parmreg/%s.%d.%d",
           log_dir,cl,u,wims_sheet,wims_exo);
    p=getvar("wims_scorereg"); if(p!=NULL && strcmp(p,"suspend")==0) {
      unlink(nbuf); return 0;
    }
    if(stat(nbuf,&st)) return 0;
      /* latency is 10 min. */
    if(st.st_mtime<nowtime-600) {
      unlink(nbuf); return 0;
    }
    if(open_working_file(&m_file,nbuf)!=0) return 0;
    snprintf(m_file.name,sizeof(m_file.name),"parmreg/%s.%d.%d",u,wims_sheet,wims_exo);
    while(wgetline(lbuf,MAX_LINELEN, &m_file)!=EOF) {
      p=strchr(lbuf,'='); 
      if(p==NULL || p<=lbuf || isspace(lbuf[0]) )
                  /* this time it is corrupted var file */
        internal_error("get_parmreg(): corrupt parmreg file.");
      *p=0;p++; 
      if(strncmp(lbuf,var_prefix,strlen(var_prefix))!=0) setenv(lbuf,p,1);
      else if(lbuf[strlen(var_prefix)]!=0) force_setvar(lbuf+strlen(var_prefix),p);
    }
    parm_restore=1;
    close_working_file(&m_file); return 1;
}

      /* set environment variables */
void set_variables(void)
{
    outputing=0;
    get_var_defs();
    set_vars_from_parm();
    if(cmd_type != cmd_new && cmd_type != cmd_renew) set_vars_from_session();
    else {
      set_init_parm();
      if(wims_sheet>0 && get_parmreg()) {
          cmd_type=cmd_resume; force_setvar("cmd","resume");
          var_proc(main_var_proc_file); return;
      }
      checkrafale();
      var_proc(var_init_file);
    }
    check_var_bounds();
    var_proc(main_var_proc_file);
}

      /* Output a phtml file. */
void phtml_put(char *fname)
{
    char buf[MAX_LINELEN+1];

    outputing=1;
     /* File not found; we give empty output, but no error message. */
    if(fname!=NULL && fopen_module_file(fname)!=0) return;
    while(wgetline(buf,MAX_LINELEN,&m_file)!=EOF) {
      char *lstart;
      lstart=find_word_start(buf); substnest=0;
      if(*lstart==exec_prefix_char) {
           exec_main(lstart+1); continue;
      }
      if (*lstart==label_prefix_char) {   /* labels are not printed */
          continue;
      }
      substit(buf); output("%s\n", buf);
    }
    if(fname!=NULL) close_working_file(&m_file);
}

      /* output a file in base html directory. Internal use only. */
void phtml_put_base(char *fname)
{
    WORKING_FILE save;
    char modsave[MAX_LINELEN+1];
    memmove(&save,&m_file,sizeof(WORKING_FILE));
    strcpy(modsave,module_prefix); strcpy(module_prefix,"html");
    phtml_put(fname);
    strcpy(module_prefix,modsave);
    memmove(&m_file,&save,sizeof(WORKING_FILE));
}

      /* Read main.phtml, process it, and write to stdout. */
void main_phtml_put(char *mname)
{
    char *p, buf[1024], txbuf[256], bgbuf[256];
    char *bcolor, *refcolor, *bg, *tx;
    define_html_header();
    p=getvar("wims_backslash_insmath");
    if(p!=NULL && strcasecmp(p,"yes")==0) backslash_insmath=1;
    p=getvar("wims_expire");
    if(p!=NULL) p=strstr(p,"no-cache");
    if(p!=NULL) output("Cache-Control: no-cache\nPragma: no-cache\n");
    output("Server: %s %s (%s)\n", SHORTSWNAME,wims_version,LONGSWNAME);
    if(!robot_access && strcasecmp(usecookie,"yes")==0 && setcookie
       && mode!=mode_popup) {
      if(cookieset[0]==0) {
          char bf[MAX_LINELEN+1], sbuf[1024];
          snprintf(sbuf,sizeof(sbuf),"%s",session_prefix);
          p=strchr(sbuf,'_'); if(p) *p=0;
          accessfile(bf,"r","%s/.cookie",sbuf);
          snprintf(cookieset,sizeof(cookieset),"%s",bf);
      }
      output("Set-Cookie: %s%s; path=/\n",cookieheader,cookieset);
    }
    p=getvar("wims_main_font");
    if(p!=NULL && *p!=0) output("Content-type: text/html; charset=%s\n\n",p);
    else output("Content-type: text/html\n\n");
    bcolor=getvar("wims_bgcolor");
    if(bcolor==NULL || *bcolor==0) bcolor=bgcolor;
    refcolor=getvar("wims_ref_bgcolor");
    if(refcolor==NULL || *refcolor==0) {
      setvar("wims_ref_bgcolor","white");
      refcolor="white";
    }
    bg=getvar("wims_bgimg"); bgbuf[0]=0;
    if(bg!=NULL && *bg!=0 && strchr(bg,'\"')==NULL) {
      if(strchr(bg,'/')==NULL)
        snprintf(bgbuf,sizeof(bgbuf),"BACKGROUND=\"gifs/bg/%s\"",bg);
      else
        snprintf(bgbuf,sizeof(bgbuf),"BACKGROUND=\"%s\"",bg);
    }
    tx=getvar("wims_textcolor");
    if(tx!=NULL && *tx!=0 && strchr(tx,'\"')==NULL) {
      snprintf(txbuf,sizeof(txbuf),"TEXT=\"%s\"",tx);
    }
    else txbuf[0]=0;
    snprintf(buf,sizeof(buf),
           "BGCOLOR=\"%s\" %s %s LINK=blue VLINK=blue",
           bcolor,txbuf, bgbuf);
    setvar("wims_htmlbody",buf);
    phtml_put(mname);
}

void _write_var(char *name, FILE *varf,int user,int skip)
{
    char *s, buf[MAX_NAMELEN+10];

    if(user!=0) {
      snprintf(buf,sizeof(buf),"%s%s",var_prefix,name); s=_getvar(name);
    }
    else {
      snprintf(buf,sizeof(buf),"%s",name); s=getenv(name);
    }
    if(s==NULL) s="";
    if(skip && *s==0) return;
    fprintf(varf,"%s=",buf);
    if(strchr(s,'\n')==NULL) fputs(s,varf);
    else while(*s) {
        if(*s=='\n') fputc('\\',varf);
        fputc(*s,varf); s++;
    }
    fputc('\n',varf);
}

      /* save exercise parm for registered users */
void save_parmreg(void)
{
    char *p, *cl, *u, *sh, *ex, nbuf[1024], dbuf[1024];
    int i,c,s;
    FILE *varf;

    if(cmd_type!=cmd_reply && cmd_type!=cmd_new && cmd_type!=cmd_renew)
      return;
    u=getvar("wims_user"); cl=getvar("wims_class");
    if(u==NULL || cl==NULL || *u==0 || *cl==0) return;
    sh=getvar("wims_sheet"); ex=getvar("wims_exo");
    if(sh==NULL || ex==NULL || *sh==0 || *ex==0) return;
    snprintf(nbuf,sizeof(nbuf),"%s/classes/%s/.parmreg/%s.%s.%s",
           log_dir,cl,u,sh,ex);
    if(cmd_type==cmd_reply) {
      unlink(nbuf); return;
    }
    p=getvar("wims_scorereg");
    if(p!=NULL && strcmp(p,"suspend")==0) return;
      /* these two lines must be before random factor 
       * in order to set variable wims_scoring */
    c=atoi(cl); s=atoi(sh); if(getscorestatus(c,s)==0) return;
    if(strcmp(u,"supervisor")==0) return;
      /* 0.2 is random factor to trigger exercise parm register */
/*    return;
*/    if((double) random()>(double) RAND_MAX*0.2) return;
    snprintf(dbuf,sizeof(dbuf),"%s/classes/%s/.parmreg",log_dir,cl);
    mkdirs(dbuf); varf=fopen(nbuf,"w"); if(varf==NULL) return;
    _write_var("module_init_parm",varf,1,0);
    _write_var("wims_sheet",varf,1,1);
    _write_var("wims_exo",varf,1,1);
    _write_var("wims_scoring",varf,1,1);
    for(i=0;i<defined_var_total;i++) {
      if(var_def[i].beg>=0) {
          int j;
          for(j=var_def[i].beg;j<=var_def[i].end; j++) {
            snprintf(nbuf,sizeof(nbuf),"%s%d",var_def[i].name,j);
            _write_var(nbuf,varf,1,1);
          }
      }
      else _write_var(var_def[i].name,varf,1,1);
    }
    fclose(varf);
}

      /* save variables to session var file */
void save_session_vars(void)
{
    int i;
    char nbuf[128], *mp;
    FILE *varf;
      /* light pages don't need saved variables. ? */
/*    if(varchr(module_prefix,"light")!=NULL) return;
*/
    if(robot_access) return;
      /* no variable saving if cmd=help? */        
    if(cmd_type==cmd_help) return;
    lessrafale();
    mp=getvar("wims_nextmodule"); if(mp!=NULL && *mp!=0) {
      mp=getvar("module"); if(strcmp(mp,"home")==0) 
        force_setvar("module",getvar("wims_nextmodule"));
    }
    varf=fopen_session_var_file("w");
    for(i=0;i<HEADER_VAR_NO;i++)
      _write_var(header_var_name[i],varf,0,0);
    for(i=0;i<RO_NAME_NO;i++)
      _write_var(ro_name[i],varf,1,0);
    for(i=0;i<INTERNAL_NAME_NO;i++) {
      if(internal_name[i].stat==0)
        _write_var(internal_name[i].name,varf,1,0);
    }
    _write_var("password",varf,0,1);
    save_parmreg();
    fprintf(varf,"\n");
    _write_var("module_init_parm",varf,1,0);
    _write_var("wims_sheet",varf,1,1);
    _write_var("wims_exo",varf,1,1);
    _write_var("wims_scoring",varf,1,1);
    for(i=0;i<defined_var_total;i++) {
      if(var_def[i].beg>=0) {
          int j;
          for(j=var_def[i].beg;j<=var_def[i].end; j++) {
            snprintf(nbuf,sizeof(nbuf),"%s%d",var_def[i].name,j);
            _write_var(nbuf,varf,1,1);
          }
      }
      else _write_var(var_def[i].name,varf,1,1);
    }
    fclose(varf);
    free(var_def_buf);
}


Generated by  Doxygen 1.6.0   Back to index