Back to index

wims  3.65+svn20090927
wims.c
Go to the documentation of this file.
00001 /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
00002  *
00003  *  This program is free software; you can redistribute it and/or modify
00004  *  it under the terms of the GNU General Public License as published by
00005  *  the Free Software Foundation; either version 2 of the License, or
00006  *  (at your option) any later version.
00007  *
00008  *  This program is distributed in the hope that it will be useful,
00009  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  *  GNU General Public License for more details.
00012  *
00013  *  You should have received a copy of the GNU General Public License
00014  *  along with this program; if not, write to the Free Software
00015  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00016  */
00017 
00018 /* Web mathematical exerciser */
00019 
00020 #define WEBMATH 1
00021 #include "Lib/libwims.h"
00022 #include "wims.h"
00023 #include <sys/socket.h>
00024 #include <sys/un.h>
00025 
00026 #define evalue strevalue
00027 char *robot_session="../tmp/robot";
00028 int robot_access=0,human_access=0;
00029 int user_error_nolog=0;
00030 char *good_agent[]={
00031       "Mozilla","Netscape","Opera","WIMS",
00032       "MSIE","Konqueror","Java"
00033 };
00034 #define good_agent_no (sizeof(good_agent)/sizeof(good_agent[0]))
00035 
00036 char *bad_agent[]={ /* These are really bad agents: prohibited. */
00037        "HTTrack","MemoWeb","Teleport","Offline","Wget","eCatch",
00038       "Powermarks","EmailSiphon", "WebCopier"
00039 };
00040 #define bad_agent_no (sizeof(bad_agent)/sizeof(bad_agent[0]))
00041 
00042 /* used for debugging */
00043 int debug=0;
00044 
00045 char class_dir[MAX_FNAME+1]; /* directory name of this class */
00046 
00047 struct {
00048     char *name;
00049     char *value;
00050 } user_variable[MAX_VAR_NUM];
00051 int user_var_no;
00052 
00053 struct VAR_DEF {
00054     char *name;
00055     short int beg,end;
00056     char allow, log_num, defined_in_parm, unused_padding;
00057 } var_def[MAX_VAR_NUM];
00058 int defined_var_total;
00059 
00060        /* Destinated to module error messages */
00061 WORKING_FILE m_file,svar_file,mcache[MAX_MCACHE];
00062 int mcachecnt;
00063 
00064        /* Limit for any data working files. */
00065 int WORKFILE_LIMIT=2048*1024;
00066 
00067        /* whether the user has defined language */
00068 int user_lang=0;
00069 
00070        /* for instex grouping */
00071 int instex_cnt=0, getwimstexsize=1;
00072 char instex_src[MAX_LINELEN+1], instex_fname[MAX_LINELEN+1];
00073 char *instex_processor="tex..gif";
00074 
00075        /* Cookie management */
00076 char cookiegot[256], cookieset[256], cookieheader[64]="WIMSUSER=";
00077 
00078        /* multipart boundary */
00079 char mpboundary[1024];
00080 int  deplen=0; /* length of deposit */
00081 
00082 int confset=0; /* set to 1 if setvar for config */
00083 
00084        /* Operating mode: default, popup, raw, etc. */
00085 enum {mode_default, mode_popup, mode_raw} NAME_MODES;
00086 int mode=mode_default;
00087 
00088        /* Switch; notice subroutines wherether we are outputing. */
00089 int outputing;
00090 
00091 char *home_module="home"; /* name of home module */
00092 extern char **environ;             /* table of environment variables */
00093 int module_defined=0;
00094 
00095         /* directory prefix buffers */
00096 char session_prefix[MAX_FNAME+1], s2_prefix[MAX_FNAME+1], module_prefix[MAX_FNAME+1];
00097 
00098 char *stdinbuf;
00099 int sesrandomtab[MAX_SESRANDOM];   /* session random values */
00100 char multiexec_random[64];
00101 int executed_gotos; /* number of goto's executed. to check with GOTO_LIMIT. */
00102 int insert_no; /* number of instex, insplot, insPLOT. */
00103 int output_length; /* length of the output. */
00104 int isexam=0; /* non-zero if request is exam */
00105 int simuxam=0;       /* exam is simulation */
00106 int is_multiexec=0;  /* for execredirected */
00107 int multiexec_index;
00108 int direct_datafile=0;
00109 int exec_is_module=0;
00110   /* root directory of modules */
00111 char *module_dir="modules";
00112 int new_session=0; /* =1 if new session created */
00113 int good_httpd=0;    /* Whether the http server is intelligent */
00114 /* int internal_sql=0; */ /* for internal sql use */
00115 int direct_exec=0; /* calc routine is exected by exec if 1 */
00116 int print_precision=8; /* precision when printing real numbers */
00117 int session_serial; /* request serial for session control */
00118 int form_access=0;   /* identifies form access, for robot identification */
00119 int lastout_file=-1; /* file to hold last output */
00120 char *instex_style="";             /* "": text "$": math "$$": displaymath */
00121 int instex_usedynamic=0;    /* always dynamic if 1 */
00122 int wrapexec=0;             /* if set to 1, change uid (nobody) to euid (wims).
00123                       * if set to -1, change euid to uid when exec(). */
00124 int parm_restore=0;  /* Restoring saved parameters? */
00125 int exec_wait=1;     /* whether to wait for fork return */
00126 int execnt=0;        /* count executions */
00127 int readnest;        /* nested read count */
00128 int mfilecnt=0;             /* count working files */
00129 int forceresume=0;   /* force user to resume old request */
00130 int manageable=0;    /* whether the connection may be site manager
00131                       * 0: no; 1: maybe; 2: sure */
00132 int ismhelp=0;              /* 1 if session is in mhelp. */
00133 int getvar_len;             /* length of the last-got variable. */
00134 int noout=0;         /* if set to 1 then output is skipped */
00135 char tmp_dir[MAX_FNAME+1];  /* temporary directory */
00136 char *bin_dir="bin"; /* directory containing executable scripts and programs. */
00137 char cwdbuf[MAX_FNAME+1];   /* store current working directory */
00138 char var_hacking=0;  /* Trying to hack a variable? */
00139 char *tmp_debug="no";
00140 char ins_alt[MAX_LINELEN+1];       /* dynamic insertion alternative text */
00141 char *devel_modules="close";       /* whether to open devel modules */
00142 int isclassmodule=0; /* 1 if the module is class module */
00143 int isdevelmodule=0; /* development module? */
00144 int setcookie=0;     /* 1 if need to set cookie */
00145 int killpid=0;              /* pid of process to kill by alarm */
00146 char *mathalign_sup1, *mathalign_sup2;    /* see mathalign_base */
00147 int substnest=0;     /* nesting level of substit() */
00148 int exodepOK=1;
00149 long int startmtime; /* start time in milliseconds */
00150 long int startmtime2;       /* start time in microseconds */
00151 int backslash_insmath=0;    /* \(...) substitution? */
00152 char examlogf[MAX_FNAME+1]; /* examlog file name */
00153 char examlogd[MAX_FNAME+1]; /* examlog file name */
00154 char exam_sheetexo[32];     /* sheet data of an exam */
00155 char loadavg[64];
00156                      /* user file variable access control. */
00157 char *var_readable, *var_writable, *var_nr, *var_nw, *var_pfx;
00158 int hostcquota;
00159 int var_noexport;    /* do not export variable */
00160 
00161 char tmplbuf[MAX_LINELEN+1];       /* for temporary uses not thru subroutines. */
00162 
00163 struct tm *now, Now; /* time of request */
00164 time_t nowtime, limtime, limtimex;
00165 char nowstr[32];
00166 
00167        /* Resource limits. Capital names are reserved by system. */
00168 int rlimit_cpu=20;   /* cpu time in seconds */
00169 int rlimit_fsize=8388608;/* file size */
00170 int rlimit_as=209715200;/* virtual memory size */
00171 int rlimit_data=204857600;/* data segment size; maxima requires a lot */
00172 int rlimit_stack=2097152;/* stack size */
00173 int rlimit_core=0;   /* core dump size */
00174 int rlimit_rss=16777216;    /* resident size */
00175 int rlimit_nproc=1024;      /* number of processes */
00176 int rlimit_nofile=512;      /* number of open files */
00177 int rlimit_memlock=2097152;/* locked-in-memory address space */
00178 
00179 char *var_str; /* malloc'ed buffer to hold translated query_string */
00180 
00181        /* buffer to hold module's variable definition file, malloc'ed. */
00182 char *var_def_buf;
00183 
00184        /* job_identifier is even a reserved variable name */
00185 char job_identifier[32];
00186 
00187   /* site manager definition */
00188 char *manager_site="127.0.0.1";
00189 int   manager_https=0;
00190 
00191        /* sheet and exercise information */
00192 int wims_sheet=0,wims_exo=0;
00193 
00194        /* Form method: get or post */
00195 char *default_form_method="post";
00196 
00197        /* Je suis maintenant oblige de passer a l'anglais 
00198         * pour la langue de defaut. */
00199 char lang[16]="en";
00200 char available_lang[MAX_LANGUAGES][4]={"en","fr"};
00201 int available_lang_no=2;
00202 char pre_language[4]="";
00203 char *protocol="http"; /* http or https */
00204 
00205        /* check for coordinate input. This will mean that
00206         * the request is manual, but not robot. */
00207 int coord_input=0;
00208 
00209        /* These are readonly environment variable names */
00210        /* special parm used for special cmds (getins, etc). */
00211 char *ro_name[]={
00212       "cmd" ,
00213       "empty",
00214       "lang" ,
00215       "module" ,
00216       "session" ,
00217       "special_parm",
00218       "special_parm2",
00219       "useropts" ,
00220       "wims_session",
00221       "wims_subsession",
00222       "wims_window",
00223       "worksheet"
00224 };
00225 enum {
00226     ro_cmd, ro_empty, ro_lang, ro_module, ro_session, ro_special_parm,
00227       ro_special_parm2, ro_useropts, ro_wsession, ro_subsession, ro_win, ro_worksheet
00228 } RO_NAMES;
00229 #define RO_NAME_NO (sizeof(ro_name)/sizeof(ro_name[0]))
00230 
00231 int cmd_type;
00232 char *commands[]={
00233     "intro" , "new" , "renew" , "reply" , "config" , "hint" , "help" ,
00234       "resume", "next", "getins", "getframe", "getfile", "close", "ref"
00235 };
00236 enum {
00237     cmd_intro, cmd_new, cmd_renew, cmd_reply, cmd_config, cmd_hint, cmd_help,
00238       cmd_resume, cmd_next, cmd_getins, cmd_getframe, cmd_getfile, cmd_close,
00239       cmd_ref
00240 }COMMANDS;
00241 #define CMD_NO (sizeof(commands)/sizeof(commands[0]))
00242 
00243        /* stat=0: saved variables */
00244        /* all names starting with wims_priv_ are also internal. */
00245 struct {
00246     char *name; int stat;
00247 } internal_name[]={
00248       {"accessright",       1},    /* right to access commercial resources */
00249       {"caller",     1},    /* caller session */
00250       {"check",             1},    /* for exam check use */
00251       {"class",             1},
00252       {"class_examlog",     1},
00253       {"class_exolog",      1},
00254       {"class_limit",       1},
00255       {"class_quota",       1},
00256       {"class_regpass",     1},
00257       {"class_user_limit",1},
00258       {"classdir",   1},
00259       {"classname",  1},
00260       {"devel_modules", 1},
00261       {"developer",  1},
00262       {"doc_quota",  1},
00263       {"doc_regpass",       1},
00264       {"email",             1},
00265       {"exo",        0},    /* exercise number */
00266       {"exoption",   1},    /* exercise option */
00267       {"firstname",  1},
00268       {"forum_limit",       1},
00269       {"home",              1},
00270       {"institutionname",   1},
00271       {"isexam",     0},    /* whether the sheet is an exam sheet */
00272       {"ismanager",  0},
00273       {"lastname",   1},
00274       {"mode",              0},    /* operating mode */
00275       {"module_start_time",0},
00276       {"now",        1},    /* date and time, yyyymmdd.hh:mm:ss */
00277       {"nowseconds", 1},    /* date and time, seconds since EPOCH */
00278       {"nr",         1},    /* non-readable variables in user file, words */
00279       {"nw",         1},    /* non-writable variables in user file, words */
00280       {"otherclass", 1},    /* Remember other logins */
00281       {"participate",       1},    /* superclass definition */
00282       {"prefix",     1},    /* user file prefix */
00283       {"protocol",   0},    /* http protocol */
00284       {"rafale",     0},    /* rapidfire request information */
00285       {"readable",   1},    /* readable variables in user file, words */
00286       {"realuser",   1},    /* real user for supervisor in gateway */
00287       {"req_time",   0},    /* time of the request */
00288       {"sclassdir",  1},
00289       {"scorereg",   0},    /* score registration flag */
00290       {"sequence", 0},  /*sequence number */
00291       {"sescookie",  1},    /* session cookie */
00292       {"sesdir",     1},
00293       {"session_serial",0}, /* request serial in the session */
00294       {"session_start_time",0},
00295       {"sheet",             0},    /* sheet number */
00296       {"sup_secure", 1},    /* secure level of supervisor */
00297       {"superclass", 1},    /* superclass code */
00298       {"superclass_quota",  1},
00299       {"supertype",  1},    /* superclass type */
00300       {"supervise",  1},    /* superclass definition */
00301       {"supervisor", 1},    /* real name of the supervisor */
00302       {"supervisormail",1}, /* email of supervisor */
00303       {"trustfile",  1},    /* trusted files in special adm modules */
00304       {"useropts",   1},    /* user options */
00305       {"writable",   1},    /* writable variables in user file, words */
00306 };
00307 #define INTERNAL_NAME_NO (sizeof(internal_name)/sizeof(internal_name[0]))
00308 
00309 char *httpd_vars[]={
00310       "HTTP_ACCEPT",
00311       "HTTP_ACCEPT_CHARSET",
00312       "HTTP_ACCEPT_LANGUAGE",
00313       "HTTP_COOKIE",
00314       "HTTP_HOST",
00315       "HTTP_USER_AGENT",
00316       "HTTPS",
00317       "QUERY_STRING",
00318       "REMOTE_HOST",
00319       "REMOTE_ADDR",
00320       "REMOTE_PORT",
00321       "REQUEST_METHOD",
00322       "SCRIPT_NAME",
00323       "SERVER_NAME",
00324       "SERVER_SOFTWARE",
00325       "SERVER_PROTOCOL"
00326 };
00327 #define HTTPD_VAR_NO (sizeof(httpd_vars)/sizeof(httpd_vars[0]))
00328 
00329        /* security: these variables will not be visible to 
00330         * child processes */
00331 char *unsetvars[]={
00332        "DOCUMENT_ROOT","SERVER_SIGNATURE","SERVER_SOFTWARE",
00333       "UNIQUE_ID","HTTP_KEEP_ALIVE","SSL_SESSION_ID"
00334 };
00335 #define unsetvarcnt (sizeof(unsetvars)/sizeof(unsetvars[0]))
00336 
00337 enum {httpd_apache, httpd_wims};
00338 int httpd_type=httpd_apache;
00339 
00340 char *remote_addr="";       /* storing for performance */
00341 char *remote_host="";
00342 
00343 char ref_name[2048], ref_base[2048];
00344 
00345 void put_special_page(char *pname);
00346 void useropts(void);
00347 
00348 #include "lines.c"
00349 #include "var.c"
00350 #include "config.c"
00351 #include "cleaning.c"
00352 #include "files.c"
00353 #include "pedia.c"
00354 #include "evalue.c"
00355 #include "test.c"
00356 #include "compare.c"
00357 #include "html.c"
00358 #include "rawmath.c"
00359 #include "texmath.c"
00360 #include "insmath.c"
00361 #include "matrix.c"
00362 #include "score.c"
00363 #include "calc.c"
00364 #include "exec.c"
00365 #include "auth.c"
00366 #include "variables.c"
00367 #include "exam.c"
00368 #include "log.c"
00369 
00370        /* Make certain httpd variables readable by modules */
00371 void take_httpd_vars(void)
00372 {
00373     int i;
00374     char *p, buf[MAX_NAMELEN+1];
00375     var_noexport=1;
00376     for(i=0;i<HTTPD_VAR_NO;i++) {
00377        snprintf(buf,sizeof(buf),"httpd_%s",httpd_vars[i]);
00378        if((p=getenv(httpd_vars[i]))!=NULL) setvar(buf,p);
00379     }
00380     var_noexport=0;
00381     
00382     for(i=0;i<unsetvarcnt;i++) unsetenv(unsetvars[i]);
00383     p=getenv("REMOTE_ADDR");if(p!=NULL && strcmp(p,"127.0.0.1")==0) human_access=1;
00384     p=getenv("HTTP_REFERER"); if(p!=NULL && *p!=0) setvar("wims_referer",p);
00385 }
00386 
00387 void cookie2session(void)
00388 {
00389     char cksession[64], psession[32], *ckey, *p;
00390     char nbuf[MAX_FNAME+1];
00391 
00392     if(mode==mode_popup) return;
00393     if(cookiegot[0]==0 || ro_cmd==cmd_close) {
00394        ckset: cookiegot[0]=0; setcookie=1; return;
00395     }
00396     p=getvar("special_parm");
00397     if(p!=NULL && strcmp(p,"ignorecookie")==0) return;
00398     mystrncpy(cksession,cookiegot,sizeof(cksession));
00399     ckey=strchr(cksession,'-');
00400     if(ckey==NULL) goto ckset; else *ckey++=0;
00401     p=getvar("wims_session"); if(p==NULL) p="";
00402     if(strstr(p,"new")!=NULL) goto ckset;
00403     mystrncpy(psession,p,sizeof(psession));
00404     p=strchr(psession,'_'); if(p!=NULL) *p=0;
00405     if(psession[0]!=0) {
00406        if(strcmp(psession,cksession)==0) return;
00407        if(session_exists(psession)) goto ckset;
00408        if(session_exists(cksession)) goto change;
00409     }
00410     else {
00411        if(!session_exists(cksession)) return;
00412        change:
00413        p=getenv("HTTPS");
00414        if(p!=NULL && strcasecmp(p,"on")==0) goto ckset;
00415        mkfname(nbuf,"%s/%s/var",session_dir,cksession);
00416        getdef(nbuf,"w_wims_ismanager",tmplbuf);
00417        if(tmplbuf[0]!=0 && tmplbuf[0]!='0') goto ckset;
00418        getdef(nbuf,"w_wims_protocol",tmplbuf);
00419        if(strcasecmp(tmplbuf,"https")==0) goto ckset;
00420        mkfname(nbuf,"%s/%s/var.stat",session_dir,cksession);
00421        getdef(nbuf,"wims_user",tmplbuf);
00422        if(tmplbuf[0]!=0) goto ckset;
00423        force_setvar(ro_name[ro_session],cksession);
00424        setsesdir(cksession);
00425        force_setvar("wims_subsession","");
00426        session_serial=0;
00427     }
00428 }
00429 
00430 void determine_font(char *l)
00431 {
00432     int i;
00433     
00434     if(l==NULL || *l==0) return;
00435     for(i=0;i<charname_no && memcmp(charname[i].name,l,2);i++);
00436     if(i<charname_no) setvar("wims_main_font",charname[i].font);
00437 }
00438 
00439 void predetermine_language(void)
00440 {
00441     char *p;
00442     int i,n;
00443 
00444     if(pre_language[0]!=0) p=pre_language;
00445     else p=getenv("HTTP_ACCEPT_LANGUAGE");
00446     if(p!=NULL && strlen(p)>=2) {
00447       for(i=0;i<available_lang_no && memcmp(p,available_lang[i],2)!=0;i++);
00448       if(i<available_lang_no) goto lend;
00449     }
00450     p=getenv("HTTP_USER_AGENT");
00451     if(p!=NULL && strlen(p)>=5) {
00452        char *q;
00453        if((q=strchr(p,'['))!=NULL && islower(*(q+1)) && islower(*(q+2)) && *(q+3)==']') {
00454            char bb[4];
00455            bb[0]=*(q+1);bb[1]=*(q+2);bb[2]=0;
00456            for(i=0;i<available_lang_no && memcmp(bb,available_lang[i],2)!=0;i++);
00457            if(i<available_lang_no) {
00458               memmove(lang,bb,2); lang[2]=0;
00459               goto lend2;
00460            }
00461        }
00462     }
00463     p=getenv("HTTP_HOST"); if(p==NULL) goto lend2;
00464     n=strlen(p); if(n<=3 || *(p+n-3)!='.') goto lend2;
00465     p=p+n-2;
00466     for(i=0;i<available_lang_no && memcmp(p,available_lang[i],2)!=0;i++);
00467     if(i<available_lang_no) {
00468        lend:  memmove(lang,p,2); lang[2]=0;
00469        lend2: determine_font(lang);
00470     }
00471 }
00472 
00473        /* print a special page */
00474 void put_special_page(char *pname)
00475 {
00476     determine_font(lang);
00477     phtml_put_base(mkfname(NULL,"%s.phtml.%s",pname,lang),0);
00478     write_logs();free(var_str);
00479 }
00480 
00481        /* check whether the connection is a site manager. */
00482 void manager_check(void)
00483 {
00484     char *p, *pp, buf[16];
00485     struct stat confstat;
00486     int i;
00487     
00488     manageable=0;
00489     if(robot_access || *manager_site==0 || checkhost(manager_site)<1)
00490       goto mend;
00491     if(manager_https) {
00492        p=getenv("HTTPS");
00493        if(p==NULL || strcmp(p,"on")!=0) goto mend;
00494     }
00495     if(strcmp(remote_addr,"127.0.0.1")==0) {
00496        int port, port2;
00497        char tester[128];
00498        p=getenv("REMOTE_PORT"); if(p==NULL) goto mend;
00499        port=atoi(p); if(port<1024 || port>65535) goto mend;
00500        p=getenv("SERVER_PORT"); if(p==NULL) goto mend;
00501        port2=atoi(p); if(port2>=10000 || port2<=0) goto mend;
00502               /* this is very non-portable */
00503        manageable=1;
00504        accessfile(tmplbuf,"r","/proc/net/tcp");
00505        snprintf(tester,sizeof(tester)," 0100007F:%04X 0100007F:%04X ",
00506                port,port2);
00507        p=strstr(tmplbuf,tester); 
00508        if(p!=NULL) {
00509            pp=strchr(p,'\n'); if(pp!=NULL) *pp=0;
00510            if(strlen(p)>=75) {
00511               p=find_word_start(p+70); *find_word_end(p)=0;
00512               if(atoi(p)==geteuid()) manageable=2;
00513            }
00514        }
00515     }
00516     else manageable=1;
00517     i=stat(config_file,&confstat);
00518     if(i==0 && manageable>0 && (confstat.st_mode&(S_IRWXO|S_IRWXG))!=0) manageable=-1;
00519     if(manageable>0 && !trusted_module()) manageable=0;
00520     if(manageable==1) {
00521        accessfile(tmplbuf,"r","%s/.manager",session_prefix);
00522        if(strstr(tmplbuf,"yes")!=NULL) manageable=2;
00523     }
00524     if(manageable==1) {
00525        p=getvar(ro_name[ro_module]);
00526        if(p!=NULL && strncmp(p,"adm/manage",strlen("adm/manage"))==0) {
00527            struct stat pstat;
00528            if(stat("../log/.wimspass",&pstat)==0) {
00529               if((S_IFMT&pstat.st_mode)!=S_IFREG || 
00530                  ((S_IRWXO|S_IRWXG)&pstat.st_mode)!=0)
00531                 manageable=-2;
00532            }
00533        }
00534     }
00535     mend:
00536     mystrncpy(buf,int2str(manageable),sizeof(buf));
00537     force_setvar("wims_ismanager",buf);
00538     if(manageable>=2) {
00539        struct rlimit rlim;
00540        rlimit_cpu*=10;
00541        rlim.rlim_cur=rlim.rlim_max=rlimit_cpu;
00542        setrlimit(RLIMIT_CPU,&rlim);
00543        mystrncpy(buf,int2str(rlimit_cpu),sizeof(buf));
00544        setvar("wims_cpu_limit",buf);
00545        initalarm();
00546     }
00547 }
00548 
00549        /* check for robot access */
00550 void robot_check(void)
00551 {
00552     char *ua, *p, *ses, *c, *mod;
00553     int i;
00554 
00555     if(human_access) return;
00556     mod=getvar(ro_name[ro_module]);
00557     if(mod!=NULL && strcmp(mod,"adm/raw")==0) return;
00558     ses=getvar(ro_name[ro_session]);
00559        /* user has valid session; OK */
00560     if(ses!=NULL && strncmp(ses,robot_session,strlen(robot_session))!=0
00561        && strchr(ses,'/')==NULL
00562        && ftest(mkfname(NULL,"%s/%s",s2_dir,ses))==is_dir)
00563       return;
00564     ua=getenv("HTTP_USER_AGENT"); if(ua==NULL) ua="";
00565     ua=find_word_start(ua);
00566     if(strncasecmp(ua,"Mozilla",strlen("Mozilla"))==0 && 
00567        (p=strstr(ua,"compatible"))!=NULL) 
00568       ua=find_word_start(find_word_end(p));
00569     if(*ua) {
00570        for(i=0;i<good_agent_no 
00571            && strncasecmp(ua,good_agent[i],strlen(good_agent[i]));i++);
00572        if(i<good_agent_no) return;
00573        for(i=0;i<bad_agent_no 
00574            && strstr(ua,bad_agent[i])==NULL;i++);
00575        if(i<bad_agent_no) user_error("trapped");
00576     }
00577     force_setvar(ro_name[ro_session],robot_session);
00578     setsesdir(robot_session);
00579     c=getvar(ro_name[ro_cmd]);
00580     robot_access=1;
00581     if(c!=NULL && strcmp(c,"new") && strcmp(c,"intro")) {
00582        force_setvar(ro_name[ro_cmd],"robot_error");
00583        nph_header(450); put_special_page("robot");
00584        flushoutput(); flushlog(); exit(0);
00585     }
00586 }
00587 
00588        /* type=0: ordinary; type=1: multipart/form-data */
00589 void parse_query_string(int len, int type)
00590 {
00591     int i,j,l,v,cmd_defined;
00592     int parenth=-1, ll, lb, dlen;
00593     char *start, *p, *p1, *pt, *b1="";
00594     
00595     cmd_defined=0;
00596     setvar("wims_subsession","");
00597     ll=lb=0;
00598     if(type) {
00599        ll=strlen(mpboundary);
00600        start=strstr(var_str,mpboundary);
00601        if(start==NULL) start=var_str+strlen(var_str);
00602        if(strstr(var_str,"\r\n\r\n")!=NULL) b1="\r\n\r\n";
00603        else b1="\n\n";
00604        lb=strlen(b1);
00605     }
00606     else start=var_str;
00607     for(v=0, p1=start;p1<var_str+len;p1+=l) {
00608        if(type) {
00609            char *p2, *p3, *p4, *p5;
00610            p2=p1+ll; p3=memstr(p2,mpboundary,var_str+len-p2); l=p3-p1;
00611            p=memstr(p2,b1,var_str+len-p2); if(p>=p3) continue;
00612            p+=lb; if(p3<var_str+len) {
00613               while(*p3!='\n' && p3>p2) p3--; *p3=0;
00614               p3--; if(*p3=='\r') *p3=0;
00615            }
00616            dlen=p3-p;
00617            p2=memstr(p2,"name=",p3-p2); if(p2>=p3) continue;
00618            p2+=strlen("name="); if(*p2=='"') p2++;
00619            for(p3=p2; myisalnum(*p3) || strchr("._",*p3)!=NULL; p3++);
00620            if(p3==p2) continue;
00621            if(p3-p2==strlen("wims_deposit") &&
00622               strncmp(p2,"wims_deposit",p3-p2)==0) {
00623               p4=memstr(p1,"filename=",p-p1); if(p4<p) {
00624                   p4+=strlen("filename="); if(*p4=='"') {
00625                      p4++; p5=strchr(p4,'"');
00626                      if(p5==NULL || p5-p4>=MAX_FNAME) goto emptyquote;
00627                   }
00628                   else {
00629                      emptyquote: 
00630                      for(p5=p4; p5<p && !isspace(*p5) &&
00631                          strchr(";\"~#*?=,'",*p5)==NULL; p5++);
00632                   }
00633                   if(p5>p4) {
00634                      *p5=0;
00635                      for(p5--;
00636                          p5>=p4 && !isspace(*p5) && strchr("/\\:",*p5)==NULL;
00637                          p5--);
00638                      if(p5>=p4) p4=p5+1; if(*p4==0) goto noname;
00639                      if(strstr(p4,"..")!=NULL || *p4=='.')
00640                        p4="noname.file";
00641                      setvar("wims_deposit",p4);
00642                   }
00643                   else {
00644                      noname: setvar("wims_deposit","noname.file");
00645                   }
00646               }
00647               deplen=dlen;
00648            }
00649            *p3=0; l-=p2-p1; p1=p2;
00650        }
00651        else {
00652            p1=find_word_start(p1);
00653            l=strlen(p1)+1; p=strchr(p1,'='); 
00654            if(p==NULL) p=p1+strlen(p1);
00655            if(*p==0 && l>1) {
00656               user_variable[v].name="no_name";
00657               user_variable[v].value=p1;
00658               coord_input=1;
00659               goto nnext;
00660            }
00661            *p++=0;
00662        }
00663               /* empty name or empty value: ignore */
00664         if(*p1==0 || *p==0) continue;
00665               /* We do not treat names containing '.' */
00666        for(pt=strchr(p1,'.'); pt; pt=strchr(++pt,'.')) *pt='_';
00667               /* Restrictions on variable names */
00668        for(pt=p1; myisalnum(*pt) || *pt=='_'; pt++);
00669        if(*pt) continue;
00670        if(strcmp(p1,"wims_deposit")!=0) _tolinux(p);
00671               /* This is a restriction:
00672                * Every parameter must have matching parentheses. */
00673        if(parenth==-1 && strncmp(p1,"freepar_",strlen("freepar_"))!=0
00674           && strcmp(p1,"wims_deposit")!=0
00675           && check_parentheses(p,1)) parenth=v;
00676        if(strcmp(p1,"special_parm")==0 && strcmp(p,"wims")==0)
00677          human_access=1;
00678        j=search_list(ro_name,RO_NAME_NO,sizeof(ro_name[0]),p1);
00679        if(j>=0) {
00680            if(j==ro_session) {
00681               p=find_word_start(p); *find_word_end(p)=0;
00682               if(strlen(p)>MAX_SESSIONLEN) continue;
00683               if(strcmp(p,robot_session)==0) p="";
00684               if(strcasecmp(p,"popup")==0) {
00685                   mode=mode_popup;
00686                   force_setvar("wims_mode","popup");
00687                   force_setvar("session","");
00688                   continue;
00689               }
00690            }
00691            if(j==ro_module) module_defined=1;
00692            if(j==ro_cmd) {
00693               p=find_word_start(p); *find_word_end(p)=0;
00694               if(strlen(p)>16) continue;
00695               cmd_defined=1;
00696            }
00697            if(j==ro_lang) {
00698               if(strlen(p)!=2) continue;
00699               for(i=0;i<available_lang_no && strcmp(available_lang[i],p)!=0;i++);
00700               if(i<available_lang_no) {user_lang=1; strcpy(lang,p);}
00701               else continue;
00702            }
00703            /* strip leading and trailing '/'s in module name */
00704            if(j==ro_module) {
00705               p=find_word_start(p); *find_word_end(p)=0;
00706               while(*p=='/') p++;
00707               while(*p!=0 && *(p+strlen(p)-1)=='/') *(p+strlen(p)-1)=0;
00708               if(strlen(p)>MAX_MODULELEN) continue;
00709            }
00710            setvar(p1,p);
00711            if(j==ro_session && mode!=mode_popup) {
00712               char *pp, *pr;
00713               char buf[1024];
00714               mystrncpy(buf,p,sizeof(buf));
00715               if((pp=strchr(buf,'.'))!=NULL) {
00716                   *pp++=0; session_serial=atoi(pp);
00717                   if(pp<0) pp=0;
00718               }
00719               else session_serial=0;
00720               pp=strchr(buf,'_');
00721               if(pp!=NULL && (pr=strstr(pp,"_mhelp"))!=NULL) {
00722                   *pr=0; ismhelp=1; lastout_file=-1;
00723                   setvar("wims_inssub","mh");
00724               }
00725               force_setvar("wims_session",buf);
00726               if(pp!=NULL) force_setvar("wims_subsession",pp);
00727            }
00728            continue;
00729        }
00730        user_variable[v].name=p1;
00731        user_variable[v].value=p;
00732 nnext: v++; if(v>=MAX_VAR_NUM) user_error("too_many_variables");
00733     }
00734     user_var_no=v;
00735     if(parenth>=0) {
00736        char buf[16];
00737        mystrncpy(buf,int2str(user_var_no),sizeof(buf));
00738        setvar("user_var_no",buf);
00739        for(i=0;i<user_var_no;i++) {
00740            snprintf(buf,sizeof(buf),"name%d",i);
00741            setvar(buf,user_variable[i].name);
00742            snprintf(buf,sizeof(buf),"value%d",i);
00743            setvar(buf,user_variable[i].value);
00744        }
00745        mystrncpy(buf,int2str(parenth),sizeof(buf));
00746        setvar("bad_parentheses",buf);
00747        user_error("unmatched_parentheses");
00748     }
00749     p=getenv("SCRIPT_NAME"); 
00750     if(p!=NULL && (p=strstr(p,"/getfile/"))!=NULL) {
00751        p+=strlen("/getfile/");
00752        force_setvar(ro_name[ro_cmd],commands[cmd_getfile]);
00753        force_setvar("special_parm",p);
00754        cmd_defined=1;
00755     }
00756     if(module_defined && !cmd_defined) setvar(ro_name[ro_cmd],commands[cmd_intro]);
00757     robot_check(); cookie2session();
00758 }
00759 
00760        /* parse special commands */
00761 void special_cmds(void)
00762 {
00763     char *c, *p;
00764     int i;
00765     long int l=-1;
00766     
00767     c=getvar(ro_name[ro_cmd]);
00768     if(c==NULL || *c==0) {  /* no module name nor command */
00769        setvar(ro_name[ro_module],home_module);
00770        setvar(ro_name[ro_cmd],commands[cmd_new]);
00771        return;
00772     }
00773     for(i=0;i<CMD_NO && strcmp(commands[i],c)!=0; i++);
00774     switch(i) {
00775        case cmd_intro: {
00776            set_module_prefix();
00777            default_form_method="get";
00778            if(ftest(mkfname(NULL,"%s/%s",module_prefix,intro_file))<0) {
00779               force_setvar(ro_name[ro_cmd],commands[cmd_new]);
00780               return;
00781            }
00782            p=getvar("wims_session");
00783            if(p!=NULL && *p!=0) {
00784               if(set_session_prefix()==0) check_session();
00785               else {
00786                   trap_check(p);
00787                   if(strchr(p,'_')!=NULL && strchr(p,'/')==NULL) {
00788                      get_static_session_var();
00789                   }
00790               }
00791            }
00792            /* determine http protocol name. How to detect? */
00793            p=getenv("HTTPS"); if(p!=NULL && strcmp(p,"on")==0) {
00794               protocol="https"; set_protocol();
00795            }
00796            force_setvar("wims_protocol",protocol);
00797            determine_font(lang);
00798            main_phtml_put(intro_file); debug_output();
00799            introend: write_logs();free(var_str);
00800            delete_pid(); exit(0);
00801        }
00802        case cmd_ref: {
00803            set_module_prefix();
00804            default_form_method="get";
00805            p=getvar("wims_session");
00806            if(p!=NULL && *p!=0) {
00807               if(set_session_prefix()==0) check_session();
00808               else trap_check(p);
00809            }
00810            determine_font(lang);
00811            main_phtml_put(ref_file); goto introend;
00812        }
00813        case cmd_getins: {
00814            c=getvar(ro_name[ro_special_parm]);
00815            if(c==NULL || *c==0) {
00816               user_error_nolog=1; user_error("no_insnum");
00817            }
00818            if(*c=='/' || strstr(c,"..")!=NULL) goto badins;
00819            set_session_prefix();
00820            if(strstr(session_prefix,"robot")!=NULL) exit(0);
00821            l=filelength("%s/%s",s2_prefix,c);
00822            if(l<0) {
00823               badins: user_error_nolog=1; user_error("bad_insnum");
00824            }
00825            {
00826               char *fmt;
00827               fmt=strchr(c,'.');
00828               if(fmt==NULL) {
00829                   user_error_nolog=1; user_error("bad_insnum");
00830               }
00831               else fmt++;
00832               
00833               nph_header(200);
00834 /* insert format problem; bricolage */
00835               printf("Content-type: image/%s\r\n\
00836 Content-length: %ld\r\n\r\n",fmt,l);
00837               catfile(stdout,"%s/%s",s2_prefix,c); exit(0);
00838            }
00839        }
00840        case cmd_getfile: {
00841            char fname[MAX_FNAME+1];
00842            c=getvar(ro_name[ro_special_parm]);
00843            if(c==NULL || *c==0) {
00844               user_error_nolog=1; user_error("no_insnum");
00845            }
00846            if(*c=='/' || strstr(c,"..")!=NULL) goto badfile;
00847            
00848            set_session_prefix();
00849            if(strstr(session_prefix,"robot")!=NULL) exit(0);
00850            mkfname(fname,"%s/getfile/%s",session_prefix,c);
00851            l=filelength("%s",fname);
00852            if(l<0 && strchr(session_prefix,'_')!=NULL) {
00853               char *pt;
00854               mystrncpy(fname,session_prefix,sizeof(fname));
00855               pt=strrchr(fname,'_'); if(pt) *pt=0;
00856               snprintf(fname+(pt-fname),sizeof(fname)-(pt-fname),
00857                      "/getfile/%s",c);
00858               l=filelength("%s",fname);
00859            }
00860            if(l<0) {
00861               badfile: user_error_nolog=1; user_error("bad_insnum");
00862            }
00863            if(l>512*1024) {
00864               struct rlimit rlim;
00865               rlimit_cpu*=l/(10*1024);
00866               rlim.rlim_cur=rlim.rlim_max=rlimit_cpu;
00867               initalarm();
00868            }
00869            {
00870               char *p1;
00871               char mime[MAX_LINELEN+1];
00872               for(p1=c+strlen(c);p1>c && isalpha(*(p1-1)); p1--);
00873               strcpy(mime,"application/octet-stream");
00874               if(p1>c && *(p1-1)=='.') {
00875                   setvar("translator_unknown",mime);
00876                   setvar("dictionary","bases/sys/mime");
00877                   snprintf(mime,sizeof(mime),"translator %s",p1);
00878                   calc_exec(mime);
00879               }
00880               nph_header(200);
00881               printf("Content-type: %s\r\n\
00882 Content-length: %ld\r\n\r\n",mime,l);
00883               catfile(stdout,"%s",fname); exit(0);
00884            }
00885        }
00886        case cmd_close: {
00887            char *p, b2[32]; int w;
00888            char nbuf[MAX_FNAME+1], vbuf[MAX_LINELEN+1];
00889            p=getvar(ro_name[ro_session]);
00890            if(p==NULL || strlen(p)<10 ||
00891               strchr(p,'/')!=NULL) return;
00892            mystrncpy(b2,p,sizeof(b2));
00893            p=strchr(b2,'.'); if(p!=NULL) *p=0;
00894            mkfname(nbuf,"%s/%s/var.stat",session_dir,b2);
00895            getdef(nbuf,"wims_caller",vbuf);
00896            if(vbuf[0]!=0) force_setvar(ro_name[ro_session],vbuf);
00897            w=wrapexec; wrapexec=1;
00898            call_sh("rm -Rf %s/%s* %s/%s* >/dev/null 2>&1",session_dir,b2,s2_dir,b2);
00899            wrapexec=w; cookiegot[0]=0;
00900            force_setvar(ro_name[ro_cmd],"new");
00901        }
00902        default: return;
00903     }
00904 }
00905 
00906        /* This is run only when manually invoking the program.
00907         * Verifies the orderedness of various list tables. */
00908 int verify_tables(void)
00909 {
00910     if(verify_order(calc_routine,CALC_FN_NO,sizeof(calc_routine[0]))) return -1;
00911     if(verify_order(exec_routine,EXEC_FN_NO,sizeof(exec_routine[0]))) return -1;
00912     if(verify_order(main_config,MAIN_CONFIG_NO,sizeof(main_config[0]))) return -1;
00913     if(verify_order(mathname,mathname_no,sizeof(mathname[0]))) return -1;
00914     if(verify_order(hmname,hmname_no,sizeof(hmname[0]))) return -1;
00915     if(verify_order(ro_name,RO_NAME_NO,sizeof(ro_name[0]))) return -1;
00916     if(verify_order(distr_cmd,distr_cmd_no,sizeof(distr_cmd[0]))) return -1;
00917     if(verify_order(internal_name,INTERNAL_NAME_NO,
00918                   sizeof(internal_name[0]))) return -1;
00919     if(verify_order(tmathfn,tmathfn_no,sizeof(tmathfn[0]))) return -1;
00920     if(verify_order(tmathvar,tmathvar_no,sizeof(tmathvar[0]))) return -1;
00921     if(verify_order(modindex,MODINDEX_NO,sizeof(modindex[0]))) return -1;
00922     if(verify_order(exportvars,exportvarcnt,sizeof(exportvars[0]))) return -1;
00923     if(evaltab_verify()) return -1;
00924     if(textab_verify()) return -1;
00925     return 0;
00926 }
00927 
00928 void config_defaults(void)
00929 {
00930     int i, *pi;
00931     char **ps;
00932     
00933     for(i=0;i<MAIN_CONFIG_NO;i++) {
00934        pi=main_config[i].address; ps=main_config[i].address;
00935        if((1&main_config[i].is_integer)==1) 
00936          printf("DF_%s=%d\n",main_config[i].name, *pi);
00937        else
00938          printf("DF_%s=%s\n",main_config[i].name,*ps);
00939     }
00940 }
00941 
00942        /* get and set useroptions */
00943 void useropts(void)
00944 {
00945     char *p;
00946     setvar("lang",lang);
00947     p=getvar("useropts");
00948     if(p==NULL || *p==0) p=getvar("wims_useropts");
00949     if(p!=NULL && *p!=0) {
00950        if(myisdigit(p[0])) {
00951            usertexsize=p[0]-'0';
00952            if(p[1]!=0) {
00953               mathalign_base=p[1]-'0';
00954            }
00955        }
00956     }
00957     if(mathalign_base==1) {
00958        mathalign_sup1="<sup>"; mathalign_sup2="</sup>";
00959     }
00960     else mathalign_sup1=mathalign_sup2="";
00961 }
00962 
00963        /* popup module help */
00964 void mhelp(void)
00965 {
00966     char *p, buf[MAX_LINELEN+1];
00967     main_phtml_put(""); buf[0]=0;
00968     if(cmd_type!=cmd_help) {
00969        phtml_put_base("closemhelp.phtml",0);
00970     }
00971     else {
00972        phtml_put_base("mhelpheader.phtml",0);
00973        p=getvar("special_parm");
00974        if(p!=NULL && strcmp(p,"about")==0) 
00975          phtml_put("about.phtml",0);
00976        else phtml_put("help.phtml",0); phtml_put_base("mhelptail.phtml",0);
00977        exec_tail(buf);
00978     }
00979 }
00980 
00981 #define READSTDIN_WINDOW 4096
00982 
00983 void readstdin(int len)
00984 {
00985     int ll, l1, lt, lr;
00986     int cpulim;
00987     
00988     cpulim=rlimit_cpu; rlimit_cpu=3;
00989     lr=len; l1=0;
00990     while(lr>0) {
00991        nowtime=time(0); initalarm();
00992        ll=lr; if(ll>READSTDIN_WINDOW) ll=READSTDIN_WINDOW;
00993        lt=fread(stdinbuf+l1,1,ll,stdin);
00994        if(lt!=ll) user_error("parm_too_long");
00995        lr-=ll; l1+=ll;
00996     }
00997     if(l1!=len) user_error("parm_too_long");
00998     stdinbuf[len]=0; rlimit_cpu=cpulim;
00999 }
01000 
01001        /* input: p=QUERY_STRING. output: parameter length. */
01002        /* Netscape puts form content into /tmp. */
01003 int formdata(char *p)
01004 {
01005     char *pp;
01006     int inlen;
01007     char *ctype;
01008     inlen=0; ctype=getenv("CONTENT_TYPE");
01009     if(ctype==NULL || strstr(ctype,"multipart/form-data")==NULL
01010        || (p=strstr(ctype,"boundary="))==NULL) {
01011        bad: stdinbuf=""; return 0;
01012     }
01013     pp=getenv("CONTENT_LENGTH");
01014     if(pp==NULL) goto bad;
01015     inlen=atoi(pp); if(inlen<=10) goto bad;
01016     if(inlen>=MAX_DEPOSITLEN) user_error("parm_too_long");
01017     stdinbuf=xmalloc(inlen+1); readstdin(inlen);
01018     p+=strlen("boundary=");
01019     for(pp=p;myisalnum(*pp) || *pp=='-'; pp++);
01020     if(pp-p<sizeof(mpboundary)-2) {
01021        memmove(mpboundary,p,pp-p); mpboundary[pp-p]=0;
01022     }
01023               /* empty data */
01024     if(strstr(stdinbuf,mpboundary)==NULL || strstr(stdinbuf,"name=")==NULL) {
01025        free(stdinbuf); goto bad;
01026     }
01027     form_access=1; post_log();
01028     return inlen;
01029 }
01030 
01031        /* get the content of POST */
01032 void getpost(void)
01033 {
01034     int ll;
01035     char *pp;
01036     pp=getenv("CONTENT_LENGTH");
01037     if(pp==NULL || (ll=atoi(pp))<=0) {
01038        stdinbuf=xmalloc(16); stdinbuf[0]=0;
01039     }
01040     else {
01041        if(ll>QUERY_STRING_LIMIT) user_error("parm_too_long");
01042        stdinbuf=xmalloc(ll+16); readstdin(ll);
01043        if(ll>0) {
01044            setenv("QUERY_STRING",stdinbuf,1);
01045            form_access=1; post_log();
01046        }
01047     }
01048 }
01049 
01050 void buffer_init(void)
01051 {
01052     struct timeval tv;
01053     
01054     mcachecnt=readnest=0;
01055     mpboundary[0]=cookiegot[0]=cookieset[0]=cwdbuf[0]=0;
01056     rscore_class[0]=rscore_user[0]=multiexec_random[0]=0;
01057     lastftest[0]=0;
01058     lastdatafile[0]=0; lastdata=xmalloc(WORKFILE_LIMIT);
01059     outptr=outbuf;
01060     instex_src[0]=instex_fname[0]=module_prefix[0]=0;
01061     examlogf[0]=examlogd[0]=exam_sheetexo[0]=0;
01062     stdinbuf=NULL;
01063     mkfname(tmp_dir,"../tmp/forall");
01064     mkfname(session_dir,"../%s",SESSION_BASE);
01065     mkfname(s2_dir,"../%s",S2_BASE);
01066     if(gettimeofday(&tv,NULL)) startmtime=startmtime2=0;
01067     else {
01068        startmtime=((tv.tv_sec%10000)*1000+tv.tv_usec/1000);
01069        startmtime2=(tv.tv_sec%1000)*1000000+tv.tv_usec;
01070     }
01071 }
01072 
01073 int main(int argc, char *argv[], char *envp[])
01074 {
01075     char *p, homebuf[MAX_FNAME+1], lbuf[32];
01076     int inlen=0;
01077 /*    int mfd;
01078 */
01079     error1=user_error; error2=module_error; error3=internal_error;
01080     class_dir[0]=0;
01081     substitute=substit; buffer_init(); var_init();
01082        /* WIMS internal locale is always C. */
01083     setenv("LANG","C",1); umask(022);
01084     setenv("LANGUAGE","us",1);
01085     setenv("LC_ALL","C",1);
01086     if(argc>1) {
01087        if(strcasecmp(argv[1],"table")==0) {
01088            if(verify_tables()) internal_error("Table disorder.");
01089            else printf("Table orders OK.\n");
01090            return 0;
01091        }
01092        if(strcasecmp(argv[1],"version")==0) {
01093            printf("%s",wims_version); return 0;
01094        }
01095        if(strcasecmp(argv[1],"defaults")==0) {
01096            config_defaults(); return 0;
01097        }
01098     }
01099     p=getenv("SERVER_SOFTWARE"); if(p!=NULL && strcasecmp(p,"WIMS")==0)
01100       httpd_type=httpd_wims;
01101     p=getenv("REMOTE_ADDR"); if(p!=NULL) remote_addr=p;
01102     p=getenv("REMOTE_HOST"); if(p!=NULL) remote_host=p;
01103     nowtime=time(0); now=localtime(&nowtime);
01104     memmove(&Now, now, sizeof(Now)); now=&Now;
01105     snprintf(nowstr,sizeof(nowstr),"%04d%02d%02d.%02d:%02d:%02d",
01106             (now->tm_year)+1900,(now->tm_mon)+1,now->tm_mday,
01107             now->tm_hour,now->tm_min,now->tm_sec);
01108     p=getenv("QUERY_STRING");
01109     if(p==NULL || *p==0) getpost();
01110     else if(strncmp(p,"form-data",9)==0) inlen=formdata(p);
01111     
01112     force_setvar("wims_now",nowstr);
01113     snprintf(lbuf,sizeof(lbuf),"%lu",nowtime);
01114     force_setvar("wims_nowseconds",lbuf);
01115     nowtime=time(0);
01116     initalarm();
01117     
01118     executed_gotos=insert_no=output_length=0; ins_alt[0]=0;
01119     setvar("empty","");     /* lock this variable */
01120     setvar("wims_version",wims_version);
01121     setvar("wims_version_date",wims_version_date);
01122     setvar("wims_main_font","utf-8");
01123     take_httpd_vars();
01124 
01125     main_configure();
01126     checklogd();
01127 /*    mfd=shm_open(SHM_NAME,O_RDONLY,-1);
01128     if(mfd==-1) internal_error("Unable to find shared memory.");
01129     shmptr=mmap(0,SHM_SIZE,PROT_READ,MAP_SHARED,mfd,0);
01130     if(shmptr==MAP_FAILED) internal_error("Shared memory failure.");
01131 */
01132     getppid();       /* this is the first sysmask trigger, must be after checklogd() */
01133     predetermine_language();
01134     set_rlimits();
01135     init_random();
01136     module_configure();
01137     set_job_ident();
01138     m_file.name[0]=0;m_file.linecnt=m_file.linepointer=0;
01139     p=getenv("QUERY_STRING");
01140     if(p==NULL || strlen(p)==0) {
01141        setvar("lang",lang);
01142        snprintf(homebuf,sizeof(homebuf),"module=%s",home_module);
01143        p=homebuf;
01144     }
01145     if(strlen(p)>=QUERY_STRING_LIMIT) user_error("parm_too_long");
01146     if(mpboundary[0]==0) {
01147        var_str=xmalloc(strlen(p)+2);
01148        parse_query_string(http2env(var_str,p),0);
01149     }
01150     else {
01151        var_str=stdinbuf;
01152        parse_query_string(inlen,1);
01153     }
01154     if(ismhelp) {
01155        p=getvar(ro_name[ro_cmd]);
01156        if(p==NULL || (strcmp(p,"help")!=0 && strcmp(p,"getins")!=0)) {
01157            mhelp(); goto outgo;
01158        }
01159     }
01160     check_exam();
01161     useropts();
01162     special_cmds();
01163     parse_ro_names();
01164     manager_check();
01165     access_check(0);
01166     set_variables();
01167     determine_font(getvar("module_language"));
01168     if(!robot_access && session_prefix[0]!=0 && cmd_type!=cmd_help && !ismhelp)
01169       lastout_file=creat(mkfname(NULL,"%s/%s",s2_prefix,lastout),
01170                       S_IRUSR|S_IWUSR);
01171     p=getvar("module_category");
01172     if(p==NULL || strstr(p,"tool")==NULL) default_form_method="get";
01173     if(noout) {
01174        write_logs(); save_session_vars();
01175        goto outgo;
01176     }
01177     if(ismhelp) {
01178        mhelp();
01179     }
01180     else {
01181        main_phtml_put(html_file);
01182        if(lastout_file!=-1) {
01183            flushoutput(); close(lastout_file); putlastout();
01184        }
01185        write_logs(); save_session_vars();
01186     }
01187     outgo:
01188     debug_output();
01189     if(var_str!=stdinbuf) free(var_str);
01190     delete_pid();
01191     if(mode!=mode_popup && trusted_module()) {
01192        p=getvar("wims_mode");
01193        if(p!=NULL && strcmp(p,"popup")==0) mode=mode_popup;
01194     }
01195     if(mode==mode_popup && insert_no==0) {
01196        p=getvar("wims_mode");
01197        if(p!=NULL && strcmp(p,"popup")==0) {
01198            remove_tree(session_prefix); 
01199            
01200            remove_tree(s2_prefix);
01201        }
01202     }
01203     return 0;
01204 }
01205