Subversion Repositories wimsdev

Rev

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