Subversion Repositories wimsdev

Rev

Rev 1070 | Rev 1670 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
  2.  *
  3.  *  This program is free software; you can redistribute it and/or modify
  4.  *  it under the terms of the GNU General Public License as published by
  5.  *  the Free Software Foundation; either version 2 of the License, or
  6.  *  (at your option) any later version.
  7.  *
  8.  *  This program is distributed in the hope that it will be useful,
  9.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.  *  GNU General Public License for more details.
  12.  *
  13.  *  You should have received a copy of the GNU General Public License
  14.  *  along with this program; if not, write to the Free Software
  15.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16.  */
  17.  
  18.       /* This file contains various configuration routines for wims. */
  19.  
  20.         /* Limitations are essentially for security reasons:
  21.          * to curb attacks by resource exhaustion of the server. */
  22.  
  23.         /* maximal length of any module's variable definition file. */
  24. int VAR_DEF_LENGTH_LIMIT=50000;
  25.         /* maximal nesting level of substitutions. */
  26. int SUBST_LIMIT=16;
  27.         /* We fix a limit for the number of goto's (or for jumps) executed,
  28.          * in order to avoid infinite loop or DOS attack. */
  29. int GOTO_LIMIT=500000;
  30.         /* Limit for instex, insplot, insPLOT. */
  31. int INS_LIMIT=500;
  32.         /* Limit for frames in an animation. */
  33. int ANIM_LIMIT=400;
  34.         /* module log file length */
  35. int MODULE_LOG_LIMIT=102400;
  36.         /* general log file length */
  37. int GEN_LOG_LIMIT=1024000;
  38.         /* number of old log files */
  39. int OLD_LOG_FILES=2;
  40.  
  41.         /* Resource limits */
  42. int threshold1=150;     /* First load shreshold */
  43. int threshold2=300;     /* Second load shreshold */
  44. int ispriority=0;       /* whether the connection is from priority sites */
  45.  
  46.         /* sessions not accessed more than these seconds will be erased. */
  47. int idle_time=5400;
  48.         /* non-class sessions not accessed more than these seconds will be erased. */
  49. int idle_time2=2400;
  50.         /* first-time sessions not accessed more than these seconds will be erased. */
  51. int idle_time3=900;
  52.  
  53. int rafalvl=10;         /* anti-rapidfire severity */
  54.  
  55.         /* Explanation: two real numbers a,b such that
  56.          * |a+b|>|a-b|*compare_precision
  57.          * will be considered equal in !ifvalue comparisons. */
  58. int DEFAULT_COMPARE_PRECISION=10000;
  59.         /* Precision of printing (hence of all evaluations). */
  60. int DEFAULT_PRINT_PRECISION=8;
  61.         /* Defaults for instex, insplot, etc. */
  62. char *DEFAULT_INS_FORMAT="gif";
  63. char *DEFAULT_ANIM_FORMAT="gif";
  64. char *DEFAULT_INS_DENSITY="100x100";
  65. char *DEFAULT_INSPLOT_FONT="small";
  66.  
  67.         /* gnuplot intermediate graphics format */
  68. char *gnuplot_format="gif";
  69.  
  70.   /* electronic address of site manager. */
  71. char *site_manager="wims@$httpd_HTTP_HOST";
  72.   /* Main configure file, this name cannot be configured! */
  73. char *config_file="../log/wims.conf";
  74. char PATH[512];  /* directory settings */
  75. #ifdef MACOSX
  76.  char *commonpath="/usr/local/bin:/usr/bin:/usr/games:/bin:/sw/bin:/usr/bin/X11:/usr/X11R6/bin";
  77. #else
  78.  char *commonpath="/usr/local/bin:/usr/bin:/usr/games:/bin:/usr/bin/X11:/usr/X11R6/bin:/opt/teTeX/bin";
  79. #endif
  80. char *gap_command="gap.sh -T";
  81. char *maxima_command="maxima";
  82. char *mupad_command="/usr/local/lib/mupad/share/bin/mupad";
  83. char *pari_command="gp -f -q -p 150000";
  84.  
  85.   /* default languages */
  86. char site_langbuf[]="en fr cn es it nl";
  87. char *site_languages=site_langbuf;
  88.   /* Statistics shows up? */
  89. char *show_stat="no";
  90.   /* Author names show up in search result? */
  91. char *show_author="no";
  92.   /* Show user IP adress to supervisor */
  93. char *show_ip="yes";
  94.   /* busy hours definition */
  95. char *busyhours="";
  96.   /* Presentation theme */
  97. char *theme="default";
  98.   /* directory of session files */     
  99. char session_dir[MAX_FNAME+1], s2_dir[MAX_FNAME+1];
  100.   /* standardised header model for modules' output. Will be stored
  101.    * into the variable $wims_html_header. */
  102. char *html_header="html/header.phtml";
  103.   /* standardised about table for modules */
  104. char *module_about_file="html/module_about";
  105.   /* title definition page */
  106. char *title_page="title.phtml";
  107.   /* stardardised header menu bar, to be included in module pages
  108.    * via command !headmenu */
  109. char *header_menu="headmenu.phtml";
  110. char *header_menu_user="headmenu_user.phtml";
  111. char *header_menu_supervisor="headmenu_supervisor.phtml";
  112.   /* standardised referer to wims home, to be included in
  113.    * module pages via command !homeref */
  114. char *home_referer="homeref.phtml";
  115. char *home_referer_user="homeref_user.phtml";
  116. char *home_referer_supervisor="homeref_supervisor.phtml";
  117.   /* background color in standard reference tables */
  118. char *ref_bgcolor="#d0c080";
  119.   /* module log disabled by default */
  120. int modlog=0;
  121.   /* name of the variable definition file for every module.
  122.    * It is this file which defines the presence of the module.
  123.    * Better do not make it configurable. */
  124. char var_def_file[256];
  125.   /* name of variable init file. Processed only when cmd=new or renew. */
  126. char *var_init_file="var.init";
  127.   /* name of variable calculation file. Parsed at each call. */
  128. char *main_var_proc_file="var.proc";
  129.   /* name of the main (programmable) html file. */
  130. char *html_file="main.phtml";
  131.   /* Introduction page name */
  132. char *intro_file="intro.phtml";
  133.   /* Reference page */
  134. char *ref_file="wims_ref.phtml";
  135.   /* script to process different inserts.
  136.    * The two consecutive points in the name prohibits ordinary
  137.    * user execution of the script. */
  138. char *insdraw_processor="insdraw..processor";
  139. char *insplot_processor="insplot..processor";
  140. char *tex2gif="bin/tex..gif";
  141. char *priority="";              /* IPs of priority sites */
  142. char *texgif_fontdir="w/texgif";
  143. char *texgif_texheader="mathfonts/header";
  144. char *bgcolor="#E8E8E8";        /* page background color */
  145. char *bgimg="";                 /* page background image file */
  146. char *pagecss="-theme-";                /* style sheet file */
  147. char *usecookie="no";           /* whether to send cookies to anon requests */
  148. char *mail_opt="";              /* !mailto options */
  149. char nodeip[256]="";            /* ip of cluster node if relevant */
  150. char temp_log[MAX_FNAME+1];     /* temp log file name */
  151.         /* 0: low; 1: high; 2: MathML */
  152. int mathalign_base=0;           /* Not use <sup> for middle alignment */
  153. int backup_hour=-1;             /* Hour for daily backup; -1 means no backup. */
  154. int site_accounting=0;          /* whether accounting should be activated */
  155. int examlog_limit=7;            /* number of logged exam sessions for each student */
  156.  
  157.   /* Automatic module update */
  158. char *mu_auto="none";
  159. char *mu_cat="all";
  160. char *mu_delay="20";
  161. char *mu_site="http://wims.unice.fr/download/modules";
  162. char *mu_zone="all";
  163.  
  164.   /* keywords destinated to robots */
  165. char *site_keywords="interactive mathematics, interactive math, server side interactivity";
  166. char *site_description="interactive exercises, online calculators and plotters, mathematical recreation and games";
  167.  
  168.   /* class and document authorization */
  169. int class_quota=100;
  170. int superclass_quota=100;
  171. int doc_quota=32;
  172. char *class_regpass="email,email,deny";
  173. char *doc_regpass="";
  174.  
  175.   /* Where to find programs; if your httpd sets /bin:/usr/bin in PATH,
  176.    * this should be OK. */
  177. char *sed_prog="sed";
  178. char *tr_prog="tr";
  179. char *awk_prog="awk";
  180.  
  181.   /* myname */
  182. char *cgi_name="wims.cgi";
  183. char *aliased_cgi="no";
  184. char *aliased_getfile="yes";
  185.  
  186.   /* Limits for classes and participants */
  187. int class_limit=200; /* limit of number of classes */
  188. int user_limit=5000; /* limit of total number of registered users */
  189. int class_user_limit=300; /* limit of users in one class */
  190. int forum_limit=100;  /* Limit of message boards */
  191.  
  192. typedef struct {
  193.     char *name;
  194.     int is_integer;
  195.     void  *address;
  196. } CONFIG_DATA;
  197.  
  198. CONFIG_DATA main_config[]={
  199.       {"PATH",                  0, &commonpath},
  200.       {"aliased_cgi",           0, &aliased_cgi},
  201.       {"aliased_getfile",       0, &aliased_getfile},
  202.       {"backup_hour",           1, &backup_hour},
  203.       {"busyhours",             0, &busyhours},
  204.       {"cgi_name",              0, &cgi_name},
  205.       {"class_limit",           1, &class_limit},
  206.       {"class_quota",           1, &class_quota},
  207.       {"class_regpass",         0, &class_regpass},
  208.       {"class_user_limit",      1, &class_user_limit},
  209.       {"css",                   0, &pagecss},
  210.       {"default_anim_format",   0, &DEFAULT_ANIM_FORMAT},
  211.       {"default_ins_format",    0, &DEFAULT_INS_FORMAT},
  212.       {"default_insplot_font",  0, &DEFAULT_INSPLOT_FONT},
  213.       {"default_texposition",   1, &mathalign_base},
  214.       {"devel_modules",         0, &devel_modules},
  215.       {"doc_quota",             1, &doc_quota},
  216.       {"doc_regpass",           0, &doc_regpass},
  217.       {"examlog_limit",         1, &examlog_limit},
  218.       {"forum_limit",           1, &forum_limit},
  219.       {"gap_command",           2, &gap_command},
  220.       {"general_log_limit",     1, &GEN_LOG_LIMIT},
  221.       {"gnuplot_format",        0, &gnuplot_format},
  222.       {"home_module",           0, &home_module},
  223.       {"idle_time",             1, &idle_time},
  224.       {"idle_time2",            1, &idle_time2},
  225.       {"idle_time3",            1, &idle_time3},
  226.       {"insdraw_processor",     0, &insdraw_processor},
  227.       {"mail_opt",              0, &mail_opt},
  228.       {"manager_https",         1, &manager_https},
  229.       {"manager_site",          0, &manager_site},
  230.       {"maxima_command",        2, &maxima_command},
  231.       {"module_log",            1, &modlog},
  232.       {"module_log_limit",      1, &MODULE_LOG_LIMIT},
  233.       {"mu_auto",               0, &mu_auto},
  234.       {"mu_cat",                0, &mu_cat},
  235.       {"mu_delay",              0, &mu_delay},
  236.       {"mu_site",               0, &mu_site},
  237.       {"mu_zone",               0, &mu_zone},
  238.       {"mupad_command",         2, &mupad_command},
  239.       {"old_log_files",         1, &OLD_LOG_FILES},
  240.       {"page_bgcolor",          0, &bgcolor},
  241.       {"page_bgimg",            0, &bgimg},
  242.       {"pari_command",          2, &pari_command},
  243.       {"priority",              0, &priority},
  244.       {"rafale_level",          1, &rafalvl},
  245.       {"ref_bgcolor",           0, &ref_bgcolor},
  246.       {"rlimit_cpu",            1, &rlimit_cpu},
  247.       {"show_author",           0, &show_author},
  248.       {"show_ip",               0, &show_ip},      
  249.       {"show_stat",             0, &show_stat},
  250.       {"site_accounting",       1, &site_accounting},
  251.       {"site_description",      0, &site_description},
  252.       {"site_keywords",         0, &site_keywords},
  253.       {"site_languages",        0, &site_languages},
  254.       {"site_manager",          0, &site_manager},
  255.       {"superclass_quota",      1, &superclass_quota},
  256.       {"texbasesize",           1, &texbasesize},
  257.       {"theme",                 0, &theme},
  258.       {"threshold1",            1, &threshold1},
  259.       {"threshold2",            1, &threshold2},
  260.       {"tmp_debug",             0, &tmp_debug},
  261.       {"trusted_modules",       0, &trusted_modules},
  262.       {"usecookie",             0, &usecookie},
  263.       {"user_limit",            1, &user_limit},
  264.       {"var_def_length_limit",  1, &VAR_DEF_LENGTH_LIMIT},
  265.       {"workfile_limit",        1, &WORKFILE_LIMIT}
  266. };
  267. #define MAIN_CONFIG_NO (sizeof(main_config)/sizeof(main_config[0]))
  268.  
  269.         /* processes the list of languages supported on the site */
  270. void language_list(void)
  271. {
  272.     int i,k;
  273.     char *lbuf[MAX_LANGUAGES];
  274.     calc_tolower(site_languages); items2words(site_languages);
  275.     setvar("wims_site_languages",site_languages);
  276.     i=cutwords(site_languages,lbuf,MAX_LANGUAGES);
  277.     available_lang_no=i;
  278.     for(i=k=0;i<available_lang_no;i++) {
  279.         if(strlen(lbuf[i])==2) memmove(available_lang[k++],lbuf[i],3);
  280.     }
  281.     if(k>0) memmove(lang,available_lang[0],3);
  282. }
  283.  
  284. char hostname[256];
  285. int html_call=0;
  286.  
  287.         /* determine the http reference name of the server */
  288. void determine_ref_name(void)
  289. {
  290.     char *s1, *s2, *p, *pl;
  291.     char buf[MAX_LINELEN+1];
  292.  
  293.     hostname[0]=0;
  294.     s1=getvar("httpd_HTTP_HOST");s2=getvar("httpd_SCRIPT_NAME");
  295.     gethostname(hostname,sizeof(hostname));
  296.     if(hostname[0]==0 && s1 && *s1!=0) mystrncpy(hostname,s1,sizeof(hostname));
  297.     if(s1==NULL || *s1==0) s1=hostname;
  298.     setvar("wims_myhostname",hostname);
  299.     ref_base[0]=0;
  300.     if(s2!=NULL) mystrncpy(buf,s2,sizeof(buf));
  301.     else buf[0]=0;
  302.     if(s1!=NULL && *buf=='/') {
  303.         p=strrchr(buf,'/'); if(p==NULL) p=buf; else *p++=0;
  304.         if(strcmp(p,cgi_name)!=0 && strlen(p)>4 &&
  305.            p[2]=='_' && islower(p[0]) && islower(p[1])) {
  306.             pre_language[0]=p[0];pre_language[1]=p[1];pre_language[2]=0;
  307.             p[2]=0; setenv("HTTP_ACCEPT_LANGUAGE",p,1); pl=p; p+=3;
  308.             s2=strrchr(p,'.'); if(s2!=NULL) {
  309.                 *s2=0; if(strcasecmp(s2+1,"cgi")!=0) html_call=1;
  310.             }
  311.             s2=p; while((s2=strpbrk(s2,"@~"))!=NULL) *s2='/';
  312.             if(strncmp(p,"doc/",4)==0) {
  313.                 char *pd, *pb;
  314.                 pd=p+4;
  315.                 if(*pd) {
  316.                     pb=strchr(pd,'/');
  317.                     if(pb) *pb++=0; else pb="main";
  318.                     setvar("doc",pd); setvar("block",pb); setvar("job","read");
  319.                 }
  320.                 setvar(ro_name[ro_module],mkfname(NULL,"adm/doc.%s",pl));
  321.             }
  322.             else setvar(ro_name[ro_module],p);
  323.             module_defined=1;
  324.         }
  325.         p=strchr(buf,'_');
  326.         if(p!=NULL && p>buf+3 && myislower(*(p-1)) && myislower(*(p-2))
  327.            && *(p-3)=='/' && myisalpha(*(p+1))) {
  328.             char *pp;
  329.             for(pp=p+1; myisalnum(*pp); pp++); if(*pp=='/') *(p-3)=0;
  330.         }
  331.         snprintf(ref_name,sizeof(ref_name)-2,"http://%s%s/%s",s1,buf,cgi_name);
  332.         mystrncpy(ref_base,ref_name,sizeof(ref_base)-2);
  333.         p=strrchr(ref_base,'/');
  334.         if(p!=NULL) *(p+1)=0;
  335.     }
  336.     else mystrncpy(ref_name,cgi_name,sizeof(ref_name)-1);
  337.     setvar("wims_ref_name",ref_name);
  338. }
  339.  
  340.         /* Read and interprete wims configuration file. */
  341. void main_configure(void)
  342. {
  343.     int i;
  344.     char *conf_buf,*e,*p,*p2,*p3;
  345.     char buf[MAX_LINELEN+1];
  346.    
  347.     conf_buf=readfile(config_file,NULL,WORKFILE_LIMIT);
  348.     if(conf_buf==NULL) goto fileend;
  349.     e=conf_buf-1; while(e) {
  350.         p=e+1; e=strchr(p,'\n'); if(e) *e=0;
  351.         p=find_word_start(p);
  352.         if(*p==0 || *p==comment_prefix_char) continue; /* empty or comment line */
  353.         p2=strchr(p,'=');
  354.         if(p2==NULL) continue; /* syntax error */
  355.         *p2=0; *find_word_end(p)=0; p2=find_word_start(p2+1);
  356.         p3=p2+strlen(p2); while(myislspace(p3[-1])) p3--;
  357.         while(p3[-1]=='\\') p3--; *p3=0;
  358.         i=search_list(main_config,MAIN_CONFIG_NO,sizeof(main_config[0]),p);
  359.         if(i<0) continue; /* name non-defined */
  360.         if(main_config[i].is_integer==1) {
  361.             int *ip;
  362.             ip=main_config[i].address;
  363.             *ip=atoi(p2); if(*ip<0) *ip=0;
  364.         }
  365.         else {
  366.             char **cp;
  367.             cp=main_config[i].address;
  368.             *cp=p2;
  369.         }
  370.     }
  371.     fileend:
  372.     setenv("session_base_dir",session_dir,1);
  373.     determine_ref_name();
  374.     language_list();
  375.     for(i=0;i<MAIN_CONFIG_NO;i++) {
  376.         char **pp;
  377.         if(main_config[i].is_integer==2) {
  378.             pp=main_config[i].address;
  379.             setenv(main_config[i].name,*pp,1);
  380.         }
  381.     }
  382.         /* check priority */
  383.     if(priority[0] && checkhost(priority)>0) ispriority=1;
  384.     getcwd(cwdbuf,sizeof(cwdbuf)); setvar("httpd_PWD",cwdbuf);
  385.     setenv("wims_server_base",cwdbuf,1);
  386.     p=strrchr(cwdbuf,'/');
  387.     if(p!=NULL && strcmp(p,"/public_html")==0) {
  388.         *p=0; snprintf(PATH,sizeof(PATH),"%s/other/bin:%s",cwdbuf,commonpath);
  389.         force_setvar("wims_home",cwdbuf);
  390.         *p='/';
  391.     }
  392.     else {
  393.         snprintf(PATH,sizeof(PATH),"%s/../other/bin:%s",cwdbuf,commonpath);
  394.         force_setvar("wims_home",cwdbuf);
  395.     }
  396.     setenv("PATH",PATH,1);
  397.     p=getvar("httpd_SERVER_SOFTWARE");
  398.     if(p && (p2=strstr(p,"Apache"))!=NULL && strcmp(p2,"Apache/1.3")>=0
  399.        && strstr(aliased_getfile,"yes")!=NULL)
  400.       good_httpd=1;
  401.     accessfile(buf,"r","../tmp/log/myip");
  402.     *find_word_end(buf)=0;
  403.     if(buf[0]) {
  404.         snprintf(nodeip,sizeof(nodeip),"%s",buf);
  405.         snprintf(temp_log,sizeof(temp_log),"%s.%s",TEMP_LOG_FILE,nodeip);
  406.         force_setvar("wims_priv_nodeip",nodeip);
  407.     }
  408.     else {
  409.         nodeip[0]=0;
  410.         snprintf(temp_log,sizeof(temp_log),"%s",TEMP_LOG_FILE);
  411.     }
  412. }
  413.  
  414. struct {
  415.     int rname;
  416.     int *rval;
  417. } resource_table[]={
  418. #ifdef RLIMIT_CPU
  419.       {RLIMIT_CPU,      &rlimit_cpu},
  420. #endif
  421. #ifdef RLIMIT_FSIZE
  422.       {RLIMIT_FSIZE,    &rlimit_fsize},
  423. #endif
  424. #ifdef RLIMIT_AS
  425.       {RLIMIT_AS,       &rlimit_as},
  426. #endif
  427. #ifdef RLIMIT_DATA
  428.       {RLIMIT_DATA,     &rlimit_data},
  429. #endif
  430. #ifdef RLIMIT_STACK
  431.       {RLIMIT_STACK,    &rlimit_stack},
  432. #endif
  433. #ifdef RLIMIT_CORE
  434.       {RLIMIT_CORE,     &rlimit_core},
  435. #endif
  436. #ifdef RLIMIT_RSS
  437.       {RLIMIT_RSS,      &rlimit_rss},
  438. #endif
  439. #ifdef RLIMIT_NPROC
  440.       {RLIMIT_NPROC,    &rlimit_nproc},
  441. #endif
  442. #ifdef RLIMIT_NOFILE
  443.       {RLIMIT_NOFILE,   &rlimit_nofile},
  444. #endif
  445. #ifdef RLIMIT_MEMLOCK
  446.       {RLIMIT_MEMLOCK,  &rlimit_memlock}
  447. #endif
  448. };
  449. #define RESOURCE_NO (sizeof(resource_table)/sizeof(resource_table[0]))
  450.  
  451.         /* set system resource limits */
  452. void set_rlimits(void)
  453. {
  454.     int i;
  455.     struct rlimit rlim;
  456.    
  457.     for(i=0;i<RESOURCE_NO;i++) {
  458.         rlim.rlim_cur=rlim.rlim_max=*(resource_table[i].rval);
  459.         setrlimit(resource_table[i].rname,&rlim);
  460.         if(resource_table[i].rname==RLIMIT_CPU) {
  461.             setvar("wims_cpu_limit",int2str(rlim.rlim_max));
  462.             initalarm();
  463.         }
  464.     }
  465. }
  466.  
  467. struct {
  468.     char *name;
  469.     int is_integer;
  470.     void *default_value;
  471. } module_default[]={
  472.       {"anim_format",           0, &DEFAULT_ANIM_FORMAT},
  473.       {"gnuplot_format",        0, &gnuplot_format},
  474.       {"ins_anim_limit",        1, &ANIM_LIMIT},
  475.       {"ins_density",           0, &DEFAULT_INS_DENSITY},
  476.       {"ins_format",            0, &DEFAULT_INS_FORMAT},
  477.       {"insplot_font",          0, &DEFAULT_INSPLOT_FONT},
  478.       {"wims_busyhours",        0, &busyhours},
  479.       {"wims_class_limit",      1, &class_limit},
  480.       {"wims_class_quota",      1, &class_quota},
  481.       {"wims_class_regpass",    0, &class_regpass},
  482.       {"wims_class_user_limit", 1, &class_user_limit},
  483.       {"wims_compare_precision",1, &DEFAULT_COMPARE_PRECISION},
  484.       {"wims_devel_modules",    0, &devel_modules},
  485.       {"wims_doc_quota",        1, &doc_quota},
  486.       {"wims_doc_regpass",      0, &doc_regpass},
  487.       {"wims_examlog_limit",    1, &examlog_limit},
  488.       {"wims_forum_limit",      1, &forum_limit},
  489.       {"wims_bgcolor",          0, &bgcolor},
  490.       {"wims_bgimg",            0, &bgimg},
  491.       {"wims_css",              0, &pagecss},
  492.       {"wims_print_precision",  1, &DEFAULT_PRINT_PRECISION},
  493.       {"wims_ref_bgcolor",      0, &ref_bgcolor},
  494.       {"wims_show_author",      0, &show_author},
  495.       {"wims_show_ip",          0, &show_ip},
  496.       {"wims_show_stat",        0, &show_stat},
  497.       {"wims_site_description", 0, &site_description},
  498.       {"wims_site_keywords",    0, &site_keywords},
  499.       {"wims_site_manager",     0, &site_manager},
  500.       {"wims_texalign",         1, &mathalign_base},
  501.       {"wims_texbasesize",      1, &texbasesize},
  502.       {"wims_theme",            0, &theme},
  503.       {"wims_tmp_debug",        0, &tmp_debug},
  504.       {"wims_usecookie",        0, &usecookie},
  505.       {"wims_user_limit",       1, &user_limit},
  506.       {"wims_superclass_quota", 1, &superclass_quota}
  507. };
  508. #define MODULE_DEFAULT_NO (sizeof(module_default)/sizeof(module_default[0]))
  509.  
  510.         /* Set defaults for module, and set corresponding variables. */
  511. void module_configure(void)
  512. {
  513.     int i;
  514.     confset=1;
  515.     for(i=0;i<MODULE_DEFAULT_NO;i++) {
  516.         if(module_default[i].is_integer) {
  517.             int j, *jp;
  518.             jp=module_default[i].default_value;
  519.             j=*jp; if(j<0) j=0;
  520.             setvar(module_default[i].name,int2str(j));
  521.         }
  522.         else {
  523.             char **cp;
  524.             cp=module_default[i].default_value;
  525.             setvar(module_default[i].name,*cp);
  526.         }
  527.     }
  528.     setenv("texgif_fontdir",texgif_fontdir,1);
  529.     setenv("texgif_texheader",texgif_texheader,1);
  530.     setvar("wims_texsize","0");
  531.     confset=0;
  532. }
  533.  
  534. char *modindex[]={
  535.       "address",
  536.       "author",
  537.       "category",
  538.       "copyright",
  539.       "data",
  540.       "description",
  541.       "domain",
  542.       "help",
  543.       "keywords",
  544.       "language",
  545.       "level",
  546.       "mode",
  547.       "require",
  548.       "scoring",
  549.       "title",
  550.       "translator",
  551.       "translator_address",
  552.       "vardef",
  553.       "version",
  554.       "wims_version",
  555. };
  556. #define MODINDEX_NO (sizeof(modindex)/sizeof(modindex[0]))
  557. char *module_special_file[]={
  558.     "intro","help"
  559. };
  560. #define MODSPEC_NO (sizeof(module_special_file)/sizeof(module_special_file[0]))
  561.  
  562. #ifdef WEBMATH
  563.  
  564.         /* read and treat module's INDEX file */
  565. void module_index(void)
  566. {
  567.     char buf[MAX_NAMELEN+1], ind_buf[MAX_LINELEN+1];
  568.     char *e, *p, *p2, *ft;
  569.     double v1, v2;
  570.     int i,l;
  571.     long indf_len;
  572.    
  573.     memmove(var_def_file,default_var_def,strlen(default_var_def)+1);
  574.     ft=readfile(mkfname(NULL,"%s/INDEX",module_prefix),
  575.                 ind_buf,sizeof(ind_buf));
  576.     if(ft==NULL) ft=readfile(mkfname(NULL,"%s/index",module_prefix),
  577.                              ind_buf,sizeof(ind_buf));
  578.     if(ft==NULL) return;
  579.     e=ind_buf-1; indf_len=strlen(ind_buf);
  580.     for(l=0; e<ind_buf+indf_len && e!=NULL ;l++) {
  581.         p=e+1; e=strchr(p,'\n'); if(e!=NULL) *e=0;
  582.         strip_trailing_spaces(p); p=find_word_start(p);
  583.         if(*p==0 || *p==comment_prefix_char) continue; /* empty or comment line */
  584.         p2=strchr(p,'=');
  585.         if(p2==NULL) continue; /* syntax error */
  586.         *p2=0; *find_word_end(p)=0; p2=find_word_start(p2+1);
  587.         i=search_list(modindex,MODINDEX_NO,sizeof(modindex[0]),p);
  588.         if(i<0) continue; /* name not in list */
  589.         snprintf(buf,sizeof(buf),"module_%s",p);
  590.         setvar(buf,p2);
  591.     }
  592.     if(mode!=mode_default) {
  593.         char *s;
  594.         s=getvar("module_mode");
  595.         if(s==NULL) {
  596.             nomode: mode=mode_default; force_setvar("wims_mode","");
  597.         }
  598.         else switch(mode) {
  599.             case mode_popup: {
  600.                 if(strstr(s,"popup")==NULL) goto nomode;
  601.                 else break;
  602.             }
  603.             case mode_raw: {
  604.                 if(strstr(s,"raw")==NULL) goto nomode;
  605.                 else break;
  606.             }
  607.             default: break;
  608.         }
  609.     }
  610.         /* test for existence of some special files in module's directory */
  611.     for(i=0;i<MODSPEC_NO;i++) {
  612.         if(ftest(mkfname(NULL,"%s/%s.phtml",module_prefix,module_special_file[i]))
  613.            ==is_file) {
  614.             snprintf(buf,sizeof(buf),"module_has_%s",module_special_file[i]);
  615.             setvar(buf,"yes");
  616.         }
  617.     }
  618.     p=getvar("module_language"); if(p==NULL || *p==0) setvar("module_language","en");
  619.     setvar("module_has_about","yes"); /* now we have default about.phtml */
  620.         /* Set var_def */
  621.     p=getvar("module_vardef");
  622.     if(p!=NULL && *p!=0) mystrncpy(var_def_file,p,sizeof(var_def_file));
  623.     p=getvar("module_wims_version"); if(p!=NULL && *p!=0) {
  624.         v1=atof(p); v2=atof(wims_version);
  625.         if(finite(v1) && finite(v2) &&
  626.            (v1>v2 || (v1==v2 && strcmp(find_word_start(p),wims_version)>0))) {
  627.             setvar("module_wims_version",p);
  628.             setvar("wims_version",wims_version);
  629.             module_error("antidated_version");
  630.         }
  631.     }
  632.     if(isdevelmodule) {
  633.         p=getvar("module_scoring");
  634.         if(p==NULL || strcasecmp(p,"yes")!=0) isdevelmodule=0;
  635.     }
  636. }
  637.  
  638. #endif
  639.  
  640.         /* Set up a unique job identity */
  641. unsigned long create_job_ident(void)
  642. {
  643.     unsigned long it;
  644.     int i;
  645.         /* Is this enough to guarantee uniqueness? */
  646.    
  647.     it=(nowtime<<16)+(getpid()&0xffff);
  648.         /* The encryption is very simple. */
  649.     it=it^0x5a3c9671;
  650.     for(i=0;i<MAX_SESRANDOM;i++) sesrandomtab[i]=random();
  651.     return it;
  652. }
  653.  
  654.         /* Setup a job identifier */
  655. void set_job_ident(void)
  656. {
  657.     unsigned long l,r;
  658.    
  659.     l=create_job_ident();
  660.     /* the last 4 bits always make 0xA. A bug of glibc random()? */
  661.     r=random()>>4;
  662.     snprintf(job_identifier,sizeof(job_identifier),"%lX%08lX",r,l);
  663.     var_noexport=1;
  664.     setvar("job_identifier",job_identifier);
  665.     var_noexport=0;
  666. }
  667.  
  668.         /* define the variable $wims_html_header */
  669. void define_html_header(void)
  670. {
  671.     char *expir, *sp, *cp, *mp;
  672.     char buf[MAX_LINELEN+1],ebuf[128];
  673.     char *nocache="<meta http-equiv=\"Pragma\" content=\"no-cache\">\n\
  674. <meta http-equiv=\"Cache-Control\" content=\"no-cache\">\n";
  675.     int noc;
  676.     time_t t;
  677.  
  678.     noc=0;
  679.     cp=getvar("wims_expire"); if(cp!=NULL) goto css;
  680.     if(!robot_access && cmd_type==cmd_intro && isclassmodule) {
  681.         sp=getvar("special_parm"); if(sp==NULL) sp="";
  682.         if(strcmp(sp,".nocache.")==0) {
  683.             force_setvar("special_parm",""); noc=1;
  684.         }
  685.         if(!noc) {
  686.             mp=getvar(ro_name[ro_module]);
  687.             if(mp!=NULL && strncmp(mp,"devel/",strlen("devel/"))==0) noc=1;
  688.         }
  689.     }
  690.     if(mode==mode_default) {
  691.         if(!robot_access && (cmd_type!=cmd_intro || noc)) {
  692.             if(html_call) {
  693.                 /* expiration in 1 day for html call. */
  694.                 t=nowtime+(long) 24*3600; expir=ctime(&t);
  695.                 nocache="";
  696.             }
  697.             else expir="1 Jan 1990";
  698.         }
  699.         else {
  700.             /* expiration in 10 days for robot access or intro page. */
  701.             t=nowtime+(long) 10*24*3600; expir=ctime(&t); nocache="";
  702.         }
  703.         snprintf(ebuf,sizeof(ebuf),"%s",expir); strip_trailing_spaces(ebuf);
  704.         snprintf(buf,sizeof(buf),
  705.                  "<meta http-equiv=\"expires\" content=\"%s\">\n%s",ebuf,nocache);
  706.         setvar("wims_expire",buf);
  707.     }
  708.     css: setvar("wims_CSS","");
  709.     cp=getvar("wims_css");
  710.     if(!robot_access && cp!=NULL && *cp!=0 && strstr(cp,"---")==NULL) {
  711.         char *nbuf;
  712.         cp=find_word_start(cp);
  713.         if(strchr(cp,'/')==NULL) {
  714.             char *pc, *th; int st=0;
  715.             pc=getvar("wims_class");
  716.             if(pc!=NULL && *pc!=0 && strcmp(cp,"class")==0) {
  717.                  nbuf=mkfname(NULL,"%s/%s/css",class_base,pc);
  718.                 th=getvar("class_theme");
  719.                 if(th==NULL || *th==0) th=getvar("wims_theme"); st=1;
  720.             }
  721.             else {
  722.                 nbuf=mkfname(NULL,"html/css/%s/%s.css",lang,cp);
  723.                 th=getvar("wims_theme");
  724.             }
  725.             if(strcmp(cp,"-theme-")==0 && strchr(th,'.')==NULL) {
  726.                 if(th==NULL || *th==0) th="default";
  727.                 nbuf=mkfname(NULL,"html/themes/%s/css.css",th);
  728.             }
  729.             if(readfile(nbuf,tmplbuf,sizeof(tmplbuf))) {
  730.               if (st) {snprintf(buf,sizeof(buf),"<style type=\"text/css\"><!--\n\
  731. %s\n\
  732. --></style>",tmplbuf); }
  733.                   else {snprintf(buf,sizeof(buf),"<link href=\"%s\" rel=\"stylesheet\" type=\"text/css\">",nbuf);
  734.                 }
  735.                 setvar("wims_CSS",buf);
  736.             }
  737.             else {
  738.                
  739.                
  740.             }
  741.         }
  742.     }
  743.     if(readfile(html_header,buf,sizeof(buf))) setvar("wims_html_header",buf);
  744. }
  745.  
  746. void setsesdir(char *d)
  747. {
  748.     char buf[MAX_FNAME+1];
  749.     if(strstr(d,parent_dir_string)!=NULL) {
  750.         force_setvar("wims_session",robot_session);
  751.         mystrncpy(buf,robot_session,sizeof(buf));
  752.         mkfname(session_dir,"../tmp");
  753.         mkfname(s2_dir,"../tmp");
  754.     }
  755.     else {
  756.         force_setvar("wims_session",d);
  757.         snprintf(buf,sizeof(buf),"%s/%s",SESSION_BASE,d);
  758.         mkfname(session_dir,"../%s",SESSION_BASE);
  759.         /* mkfname(s2_dir,"../%s",S2_BASE); */
  760.     }
  761.     force_setvar("wims_sesdir",buf);
  762. }
  763.  
  764.