Subversion Repositories wimsdev

Rev

Rev 16711 | 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. /* Routines to write log files. */
  18. #include <sys/socket.h>
  19. #include <sys/un.h>
  20.  
  21. #include "wims.h"
  22.  
  23. char logbuf[4*(MAX_LINELEN+1)];
  24. char *logp=logbuf;
  25.  
  26. void write_logfile(char *fname, char *str)
  27. {
  28.   char *p;
  29.   if((p=strchr(str,'\n'))!=NULL) *p=0;
  30.   snprintf(logp,sizeof(logbuf)-(logp-logbuf),"%s %s\n",fname,str);
  31.   logp+=strlen(logp);
  32. }
  33.  
  34. void flushlog(void)
  35. {
  36.   int n, fd;
  37.   n=logp-logbuf; logp=logbuf;
  38.   if(n<=0) return;
  39.   fd=open(temp_log,O_WRONLY|O_APPEND|O_CREAT,S_IRUSR|S_IWUSR);
  40.   if(fd==-1) return;
  41.   (void)write(fd,logbuf,n); close(fd);
  42. }
  43.  
  44. /* Write module log file. */
  45. void module_log(void)
  46. {
  47.   /* log string is limited to 100 characters. */
  48.   char *logstr, *ip, *sess, lbuf[100], *p;
  49.  
  50.   if(robot_access || !modlog || strstr(session_prefix,"_check")!=NULL) return;
  51.   logstr=getvar("wims_module_log");
  52.   if(logstr==NULL || *logstr==0) return;
  53.   ip=remote_addr;
  54.   if(mode==mode_default) sess=getvar("wims_session");
  55.   else sess="popup";
  56.   if(ip==NULL || sess==NULL) return;
  57.   mystrncpy(lbuf,logstr,sizeof(lbuf));
  58.   p=strchr(sess,'_'); if(p==NULL) p=sess+strlen(sess);
  59.   if(p<sess+4) p=sess; else p=p-4;
  60.   snprintf(tmplbuf,sizeof(tmplbuf),"%s %.6s %s\11%s",
  61.    nowstr, p, ip, lbuf);
  62.   p=getvar(ro_name[ro_module]);
  63.   if(p==NULL || *p==0) return;
  64.   write_logfile(mkfname(NULL,"%s/%s",module_dir,p),tmplbuf);
  65. }
  66.  
  67. /* log http referers */
  68. void referer_log(void)
  69. {
  70.   char *c,*s,*ip,*r,*h,refstr[256];
  71.  
  72.   if(robot_access) return;
  73.   c=getvar(ro_name[ro_cmd]);
  74.   if(c==NULL) c="";
  75.   if(mode==mode_default) s=getvar("wims_session"); else s="popup";
  76.   if(s==NULL) s="----";
  77.   else if(!new_session && strcmp(c,"intro")!=0) return;
  78.   if(strlen(s)<4) s="----";
  79.   if(strchr(s,'_')!=NULL) return;
  80.   ip=remote_addr; if(*ip==0) return;
  81.   r=getenv("HTTP_REFERER");
  82.   if(r==NULL || *r==0) r="??";
  83.   /* skip some useless referers */
  84.   else {
  85.     if(strstr(r,cgi_name)!=NULL) return;
  86.     if(strstr(r,"file:")!=NULL || strchr(r,'.')==NULL) r="??";
  87.     if(strstr(r,"http")==NULL && strchr(r,'.')==NULL &&
  88.      strstr(r,"bookmark")!=NULL) r="??bookmark";
  89.   }
  90.   if(strncmp(r,"http://",strlen("http://"))==0) r+=strlen("http://");
  91.   /* Take references from the same site or not? No. */
  92.   h=getenv("HTTP_HOST");
  93.   if(h!=NULL && *h!=0 && strncmp(r,h,strlen(h))==0) return;
  94.     /* stop before '#' */
  95.   mystrncpy(refstr,r,sizeof(refstr));
  96.   r=strchr(refstr,'#'); if(r!=NULL) *r=0;
  97.   for(r=refstr;r<refstr+strlen(refstr);r++) {
  98.     if(*r=='%' && *(r+1)=='7' && *(r+2)=='E') {
  99.     *r='~'; ovlstrcpy(r+1,r+3);
  100.     }
  101.   }
  102.   snprintf(tmplbuf,sizeof(tmplbuf),"%s %s %s\11%s",
  103.      nowstr,s+strlen(s)-4,ip,refstr);
  104.   write_logfile("referer.log",tmplbuf);
  105. }
  106.  
  107. /* Log new creation of sessions. For server counting use. */
  108. void session_log(char *c)
  109. {
  110.   int i;
  111.   char *ip, *p, *agent, *s, *sess;
  112.  
  113.   ip=remote_addr; if(*ip==0) return;
  114.   if(mode==mode_default) {
  115.     sess=getvar("wims_session");
  116.     if(sess==NULL) return;
  117.     if(strchr(sess,'_')!=NULL) return;
  118.   }
  119.   else sess="popup";
  120.   p=getenv("REMOTE_HOST"); if(p==NULL) p="";
  121.   i=strlen(p); if(i>40) p+=i-40;
  122.   agent=getenv("HTTP_USER_AGENT"); if(agent==NULL) agent="";
  123.   s=strchr(sess,'_'); if(s==NULL) s=sess+strlen(sess);
  124.   if(s<sess+4) s=sess; else s=s-4;
  125.     /* limit agent name to 80 chars */
  126.   snprintf(tmplbuf,sizeof(tmplbuf),"%s %s %s\11%s\11%.80s",
  127.      nowstr, s, ip, p, agent);
  128.   write_logfile("session.log",tmplbuf);
  129. }
  130.  
  131. /* Log user information. */
  132. void user_log(char *c)
  133. {
  134.   char fname[MAX_FNAME+1], logbuf[MAX_LINELEN+1], cbuf[256], sbuf[32], shbuf[32];
  135.   char *user, *classe, *sh, *sess, *exo, *cc, *ip, *allow, *pend, *se;
  136.   char *ex;
  137.   double sc,Sc;
  138.   int i, scorelog, testmax;
  139.  
  140.   if(robot_access || strstr("session_prefix","_check")!=NULL) return;
  141.   user=getvar("wims_user"); classe=getvar("wims_class");
  142.   sc=0;
  143.   if(isexam) {
  144.     if(user==NULL || classe==NULL || *user==0 || *classe==0) return;
  145.     sh=getvar("worksheet"); if(sh==NULL) return;
  146.     mystrncpy(shbuf,sh,sizeof(shbuf));
  147.     exo=strchr(shbuf,'.'); if(exo==NULL) return;
  148.     *exo++=0; sh=shbuf;
  149.     if(mode==mode_default) sess=getvar("wims_session");
  150.     else sess="popup";
  151.     if(sess==NULL) return;
  152.     mystrncpy(sbuf,sess,sizeof(sbuf));
  153.     sess=strchr(sbuf,'_'); if(sess==NULL) return;
  154.     *sess=0; sess=sbuf; ex="E";
  155.     accessfile(logbuf,"r","%s/.E%s",class_dir,sh);
  156.     if(strchr(logbuf,'#')!=NULL || strcmp(user,"supervisor")==0) simuxam=1;
  157.     else {
  158.       accessfile(logbuf,"r","%s/%s/examsimu.%d", session_dir,sess,sh);
  159.       if(strstr(logbuf,"yes")!=NULL) user_error("expired_exam");
  160.     }
  161.     mkfname(examlogd,"%s/examlog/%s/%s",class_dir,user,sess);
  162.     mkfname(examlogf,"%s/%s.%s",examlogd,sh,exo);
  163.   }
  164.   else {
  165.     sh=getvar("wims_sheet");
  166.     if(sh==NULL || *sh==0) {
  167.       sh=getvar("wims_fwnumber");
  168.       if(sh==NULL || *sh==0) return;
  169.       ex="F";
  170.       exo=getvar("wims_fwexo");
  171.     }
  172.     else {
  173.       exo=getvar("wims_exo"); if(exo==NULL) return;
  174.       ex="";
  175.     }
  176.     sess=getvar("wims_session");
  177.     if(sess==NULL) return;
  178.   }
  179.   if(strcmp(c,"new")!=0 && strcmp(c,"renew")!=0
  180.      && strcmp(c,"rafale")!=0
  181.      && strcmp(c,"hint")!=0 && parm_restore==0) {
  182.     char *s;
  183.     s=getvar("module_score");
  184.     if(s==NULL || *s==0) return;
  185.     sc=atof(s); if(!isfinite(sc)) {sc=0; return;}
  186.     snprintf(cbuf,sizeof(cbuf),"score %s",s);
  187.     cc=cbuf;
  188.   }
  189.   else cc=c;
  190.   if(classe==NULL || *classe==0) i=1;
  191.   else i=getscorestatus(classe,atoi(sh));
  192.   testmax=gettrycheck(classe,user,atoi(sh),atoi(exo))==1;
  193.   pend=getvar("wims_scoring"); if(pend==NULL) pend="";
  194.   if((i==0 || !exodepOK || strcmp(pend,"pending")!=0 || testmax) && strcmp(cc,"rafale")!=0 && *ex!='F')
  195.     if(testmax) allow="maxtry noscore"; else allow="noscore";
  196.   else allow="";
  197.   ip=remote_addr; if(*ip==0) ip="-"; scorelog=0;
  198.   if(user==NULL || *user==0) {
  199.     classe="0"; allow="";
  200.     mkfname(fname,"../sessions/%s/.score",sess);
  201.   }
  202.   else {
  203.     char *pp;
  204.     if(classe==NULL || *classe==0) return;
  205.     pp=getvar("wims_scorereg"); /* contains suspend or exotrymax */
  206.     if((allow[0]==0 || i!=0 || (pp!=NULL && strcmp(pp,"suspend")==0)) && *ex!='E' && *ex!='F')
  207.       scorelog=1;
  208.     else {
  209.       if (*ex=='F') {
  210.        char *s;
  211.        /* freework activity logged to different file */
  212.         mkfname(fname,"classes/%s/freeworksdata/%s.freework",classe,user);
  213.         /* log exercise activity in case of score is enough */        
  214.         s=getvar("module_score");
  215.         if(s!=NULL && *s!=0) {
  216.           char *ms;
  217.           int ims;
  218.           ms=getvar("wims_fwminscore");
  219.           ims=atof(ms);
  220.           if (ims<0 && -1*atof(s)<=ims) {
  221.             char nbuf[MAX_FNAME+1];
  222.             snprintf(nbuf,sizeof(nbuf),"%s/freeworksdata/%s/work/%s-wimsexo/%s",class_dir,sh,user,exo);
  223.             if (ftest(mkfname(NULL,"%s",nbuf))!=is_file) {
  224.               mkfname(freeworklogd,"%s/freeworksdata/%s/work/%s-wimsexo",class_dir,sh,user);
  225.               mkfname(freeworklogf,"%s/%s",freeworklogd,exo);
  226.             }
  227.           }
  228.         }
  229.       }
  230.       else mkfname(fname,"classes/%s/noscore/%s",classe,user);
  231.     }
  232.   }
  233.   if(isexam && user!=NULL && *user!=0) {
  234.     allow=exam_sheetexo;
  235.     snprintf(logbuf,sizeof(logbuf),":%s %2s %s  \t%s%s\n",
  236.     nowstr,exo,cc,ip,allow);
  237.     accessfile(logbuf,"a","%s/%s/examscore.%s", session_dir,sess,sh);
  238.     Sc=currexamscore(atoi(sh));
  239.     accessfile(logbuf,"r","%s/.E%s",class_dir,sh);
  240.     if(simuxam==0) {   /* not simulation */
  241.       if(sc>0) {
  242.         snprintf(logbuf,sizeof(logbuf),
  243.         "%s %.5f -1 %u %s %s\n",
  244.         sh,Sc,(unsigned int) nowtime,ip,sess);
  245.         accessfile(logbuf,"a","%s/score/%s.exam", class_dir,user);
  246.       }
  247.     }
  248.     else snprintf(exam_sheetexo+strlen(exam_sheetexo),
  249.         sizeof(exam_sheetexo)-strlen(exam_sheetexo), "\tS");
  250.   }
  251.   if(strcmp(c,"new")==0 || strcmp(c,"renew")==0)
  252.     se=getvar("wims_seed"); else se="";
  253.   snprintf(logbuf,sizeof(logbuf),"%s%s %s %2s %2s %s  \t%s\t%s\t%s",
  254.       ex,nowstr,sess,sh,exo,cc,ip,se,allow);
  255.   if(scorelog) {
  256.     snprintf(tmplbuf,sizeof(tmplbuf),"-c%s -u%s scorelog %s",
  257.        classe,user,logbuf);
  258.     _daemoncmd(tmplbuf);
  259.   }
  260.   else write_logfile(fname,logbuf);
  261. }
  262.  
  263. /* Log class information. */
  264. void class_log(char *cl, char *l, char *ip)
  265. {
  266.   char logbuf[1024];
  267.  
  268.   if(robot_access) return;
  269.   snprintf(logbuf,sizeof(logbuf),"%s %s   \t%s",
  270.       nowstr,ip,l);
  271.   write_logfile(mkfname(NULL,"classes/%s/.log",cl),logbuf);
  272. }
  273.  
  274. /* Log accesses to modules. For server counting use. */
  275. void access_log(char *c)
  276. {
  277.   int i;
  278.   char *ip, *p, *sess, *s, *agent, *u, *cl;
  279.   time_t logtime;
  280.   char ag[128], tm[64];
  281.  
  282.   ip=remote_addr;
  283.   if(*ip==0) ip="????????";
  284.   if(mode==mode_default) sess=getvar("wims_session");
  285.   else sess="popup";
  286.   if(sess==NULL) sess="----------";
  287.   p=getvar(ro_name[ro_module]);
  288.   if(p==NULL || *p==0) p="-";
  289. /* limit module name to 40 chars */
  290.   i=strlen(p); if(i>40) p+=i-40;
  291.   if(robot_access) {
  292.    agent=getenv("HTTP_USER_AGENT"); if(agent==NULL) agent="-";
  293.    snprintf(ag,sizeof(ag)," %s",agent);
  294.   }
  295.   else {
  296.    u=getvar("wims_user");
  297.    if(u!=NULL && *u!=0) snprintf(ag,sizeof(ag)," %s,%s",u,getvar("wims_class"));
  298.    else ag[0]=0;
  299.   }
  300.   s=strchr(sess,'_'); if(s==NULL) s=sess+strlen(sess);
  301.   if(s<sess+4) s=sess; else s=s-4;
  302.   tm[0]=0; logtime=time(0); if(logtime>nowtime+2) {
  303.    snprintf(tm,sizeof(tm)," (%lus)", logtime-nowtime);
  304.   }
  305.   snprintf(tmplbuf,sizeof(tmplbuf),"%s %.6s %s\11%s\11%s%s%s",
  306.       nowstr, s, ip, c, p, tm, ag);
  307.   write_logfile("access.log",tmplbuf);
  308.   user_log(c);
  309.   cl=getvar("wims_class");
  310.   if(cl!=NULL && *cl!=0) {
  311.     char *l;
  312.     l=getvar("wims_class_log");
  313.     if(l!=NULL && *l!=0) class_log(cl, l, ip);
  314.   }
  315. }
  316.  
  317. /* Log of mails. */
  318. void mail_log(char *c)
  319. {
  320.   int i;
  321.   char *ip, *p, *sess, *s, *cl;
  322.  
  323.   ip=remote_addr;
  324.   if(*ip==0) ip="????????";
  325.   if(mode==mode_default) sess=getvar("wims_session");
  326.   else sess="popup";
  327.   if(sess==NULL) sess="----------";
  328.   p=getvar(ro_name[ro_module]);
  329.   if(p==NULL || *p==0) p="-";
  330. /* limit module name to 40 chars */
  331.   i=strlen(p); if(i>40) p+=i-40;
  332.   s=strchr(sess,'_'); if(s==NULL) s=sess+strlen(sess);
  333.   if(s<sess+4) s=sess; else s=s-4;
  334.   cl=getvar("wims_class"); if(cl==NULL) cl="";
  335.   snprintf(tmplbuf,sizeof(tmplbuf),"%s %.6s %s\11%s\11%s\11%s",
  336.       nowstr, s, ip, c, cl, p);
  337.   write_logfile("mail.log",tmplbuf);
  338. }
  339.  
  340. /* log posted data */
  341. void post_log(void)
  342. {
  343.   char *h, *l, logstr[2*MAX_LINELEN+2];
  344.   char *authpwd, *p, *ll, *l1 ;
  345.   static char *obliterate[]={"auth_password=","passwd=","passsup=","password="};
  346.   int i, oblicnt=sizeof(obliterate)/sizeof(char*);;
  347.  
  348.   h=remote_addr;
  349.   if(mpboundary[0]!=0) l="multipart/form-data"; else l=stdinbuf;
  350.  
  351.   ll=strdup(l);
  352.   for(i=0;i<oblicnt;++i){
  353.     authpwd=obliterate[i];
  354.     if((p=strstr(ll,authpwd))!=NULL ) {
  355.       l1=strdup(ll);
  356.       mystrncpy(ll,l1,p-ll+strlen(authpwd)+1);
  357.       strcat(ll,"xxxx");
  358.       l1+=(p-ll)+strlen(authpwd);
  359.       if((p=strstr(l1,"&"))!=NULL) strcat(ll,p);
  360.     }
  361.   }
  362.   snprintf(logstr,sizeof(logstr),"%s %s\t%s",
  363.      nowstr, h, ll);
  364.   write_logfile("post.log",logstr);
  365. }
  366.  
  367. /* It is this routine which is called by main(). */
  368. void write_logs(void)
  369. {
  370.   char *p;
  371.   p=getvar(ro_name[ro_cmd]); if(p==NULL || *p==0) p="no_cmd";
  372.   access_log(p);
  373.   if(strstr(session_prefix,"_check")!=NULL) return;
  374.   module_log(); referer_log();
  375.   if(new_session) session_log(p);
  376. }
  377.  
  378. void user_error_log(char msg[])
  379. {
  380.   char *s, *m, *c, *h, *q, *r, *sess, logstr[512];
  381.   if(mode==mode_default) sess=getvar("wims_session");
  382.   else sess="popup";
  383.   if(sess==NULL) sess="----------";
  384.   m=getvar(ro_name[ro_module]);if(m==NULL) m="";
  385.   c=getvar(ro_name[ro_cmd]);if(c==NULL) c="";
  386.   h=remote_addr;
  387.   q=getenv("QUERY_STRING");if(q==NULL) q="";
  388.   r=getenv("HTTP_REFERER");
  389.   if(r==NULL || strstr(r,cgi_name)!=NULL) r="";
  390.   s=strchr(sess,'_'); if(s==NULL) s=sess+strlen(sess);
  391.   if(s<sess+4) s=sess; else s=s-4;
  392.   snprintf(logstr,sizeof(logstr),"%s %.5s %s %s, module=%s cmd=%s: %s %s",
  393.      nowstr, s, h, msg, m, c, r, q);
  394.   write_logfile("user_error.log",logstr);
  395.   if(user_error_nolog) return;
  396.   access_log("user_error");referer_log();
  397. }
  398.  
  399. void module_error_log(char msg[])
  400. {
  401.   char *s, *m, *c, logstr[256];
  402.   if(strstr(msg,"debug")!=NULL || strstr(msg,"timeup")!=NULL) return;
  403.   if(strstr(m_file.name,"sessions/")!=NULL) return;
  404.   s=getvar(ro_name[ro_module]);
  405.   if(s!=NULL) {
  406.    if(strncmp(s,"classes/",strlen("classes/"))==0 ||
  407.     strncmp(s,"devel/",strlen("devel/"))==0) return;
  408.   }
  409.   s=getvar("wims_session"); if(s==NULL) s="  ";
  410.   m=getvar(ro_name[ro_module]);if(m==NULL) m="";
  411.   c=getvar(ro_name[ro_cmd]);if(c==NULL) c="";
  412.   snprintf(logstr,sizeof(logstr),"%s %.10s %s in %s/%s, line %d",
  413.      nowstr, s+2, msg, m, m_file.name, m_file.l+1);
  414.   write_logfile("module_error.log",logstr);
  415.   access_log("module_error");
  416. }
  417.  
  418. /* Refused users due to threshold excess */
  419. void refuse_log(int th)
  420. {
  421.   char *load, *h;
  422.  
  423.   load=getvar("wims_server_load"); if(load==NULL) load="??";
  424.   h=remote_addr;
  425.   snprintf(tmplbuf,sizeof(tmplbuf),"%s %s\11%d:%s",
  426.       nowstr, h, th, load);
  427.   write_logfile("refuse.log",tmplbuf);
  428. }
  429.  
  430. #define logdpid "../tmp/log/wimslogd.pid"
  431. #define newlogd "../tmp/log/wimslogd.new"
  432.  
  433. void bringuplogd(void)
  434. {
  435.   char *arg[]={"../bin/wimslogd",NULL};
  436.   struct stat st;
  437.   pid_t pid;
  438.  
  439. /* need to update wimslogd? */
  440.   if(stat(newlogd,&st)==0) {
  441.    if((S_IXUSR&st.st_mode)!=0 && st.st_size>40000 && st.st_size<200000)
  442.      call_ssh("mv %s %s",newlogd,arg[0]);
  443.    else call_ssh("rm -f %s",newlogd);
  444.   }
  445.   pid=fork(); if(pid) return;   /* parent */
  446. /* double fork to escape sysmask orphan. */
  447.   pid=fork(); if(pid) {   /* secondary parent */
  448.    snprintf(tmplbuf,sizeof(tmplbuf),"%u",pid);
  449.    mkdirs("../tmp/log");
  450.    chmod("../tmp/log",S_IRUSR|S_IWUSR|S_IXUSR);
  451.    accessfile(tmplbuf,"w",logdpid);
  452.    exit(0);
  453.   }
  454. // don't change the order: use in Wimslogd/wimslogd.c in parms()
  455.   setreuid(geteuid(),geteuid());setregid(getegid(),getegid());
  456.   snprintf(tmplbuf,sizeof(tmplbuf),"%u %u %u %u %u %u %d %d %d %d",
  457.       idle_time,idle_time2,idle_time3,
  458.       OLD_LOG_FILES,GEN_LOG_LIMIT,
  459.       MODULE_LOG_LIMIT,backup_hour,site_accounting,
  460.       examlog_limit,LOG_DELETE);
  461.  
  462.   setenv("wimslogd",tmplbuf,1);
  463.   execve(arg[0],arg,environ);
  464.   fprintf(stderr,"Unable to execute wimslogd: %s\n",strerror(errno));
  465.   exit(1);
  466. }
  467.  
  468. void checklogd(void)
  469. {
  470.   int i,t;
  471.   char *p1, *p2, *p, buf[MAX_LINELEN+1];
  472.   sun.sun_family=PF_UNIX;
  473.   snprintf(sun.sun_path,sizeof(sun.sun_path),"%s",ksockfile);
  474.   p=getenv("REMOTE_ADDR"); if(p==NULL) p="";
  475.   snprintf(buf+sizeof(int),sizeof(buf)-sizeof(int),"ping %s",p);
  476.   t=kerneld(buf,sizeof(buf)); if(t<0) {
  477.     bringuplogd();
  478.     for(i=0; i<10 && t<0; i++) {
  479.       msleep(100);
  480.         snprintf(buf+sizeof(int),sizeof(buf)-sizeof(int),"ping %s",p);
  481.      t=kerneld(buf,sizeof(buf));
  482.     }
  483.   }
  484.   if(t<0) internal_error("Unable to bring up wimslogd.");
  485.   p1=find_word_start(buf+sizeof(int)); p2=find_word_end(p1);
  486.   if(*p2) *p2++=0;
  487.   if(strcmp(p1,"OK")!=0) internal_error("wimslogd error.");
  488.   if(*p2=='1') hostcquota=1; else hostcquota=0;
  489.   p1=find_word_start(find_word_end(p2));
  490.   p2=strchr(p1,'\n'); if(p2) *p2++=0; else p2=p1+strlen(p1);
  491.   mystrncpy(loadavg,p1,sizeof(loadavg));
  492.   p2=find_word_start(p2);
  493.   p1=find_word_end(p2); if(*p1) *p1++=0;
  494.  
  495.   p=getenv("SERVER_ADDR");
  496.   if(*p2!=0 && memcmp(p,"10.",3)==0) p=p2;
  497.   if(p!=NULL) {
  498.     i=strlen(cookieheader);
  499.     snprintf(cookieheader+i, sizeof(cookieheader)-i,"%s/",p);
  500.   }
  501.   p=getenv("HTTP_COOKIE"); cookiegot[0]=0;
  502.   if(p!=NULL && (p2=strstr(p,cookieheader))!=NULL) {
  503.     mystrncpy(cookiegot,find_word_start(p+strlen(cookieheader)),sizeof(cookiegot));
  504.     *find_word_end(cookiegot)=0;
  505.   }
  506. }
  507.