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

log.c

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

/* extern int MODULE_LOG_LIMIT */

      /* move oversized log file. */
void write_logfile(char *fname, char *str, int lim)
{
    size_t l;
    FILE *f;
    char buf[1024];
    snprintf(buf,sizeof(buf),"%s/%s",log_dir,fname);
    f=fopen(buf,"a");
    if(f==NULL) {
      char *p;
      p=strrchr(buf,'/'); if(p==NULL) return;
      *p=0;mkdirs(buf);*p='/';f=fopen(buf,"a");
      if(f==NULL) return;
    }
    l=ftell(f);
    if(l>lim) {
      fclose(f); if(chmod(buf,S_IRUSR|S_IRGRP|S_IROTH)==0) {
          char b2[1024], b3[1024], b4[1024];
          int i;
          snprintf(b2,sizeof(b2),"%s.old",buf);
          if(rename(buf,b2)!=0) goto suspend;
          chmod(b2,S_IRUSR|S_IWUSR);
          if(OLD_LOG_FILES>50) OLD_LOG_FILES=10;
          for(i=OLD_LOG_FILES-1;i>0;i--) {
            snprintf(b3,sizeof(b3),"%s.old%d",buf,i);
            snprintf(b4,sizeof(b4),"%s.old%d",buf,i+1);
            rename(b3,b4);
          }
          if(OLD_LOG_FILES>0) {
            snprintf(b3,sizeof(b3),"%s.old1",buf);
            rename(b2,b3);
          }
          else unlink(b2);
          f=fopen(buf,"w"); if(f==NULL) return;
      }
      else suspend: f=fopen(buf,"a");
    }
    fseek(f,0,SEEK_END); fprintf(f,"%s\n",str); fclose(f);
    if(l==0) chmod(buf,S_IRUSR|S_IWUSR);
}

      /* Write module log file. */
void module_log(void)
{
    int n;
    char *logstr, *ip, *sess, fnamebuf[1024], *p;
    char logbuf[1024];
    if(robot_access || !modlog) return;
    logstr=getvar("wims_module_log");
    if(logstr==NULL || *logstr==0) return;
    ip=remote_addr; 
    if(mode==mode_default) sess=getvar("wims_session");
    else sess="popup";
    if(ip==NULL || sess==NULL) return;
      /* log string is limited to 100 characters. */
    snprintf(fnamebuf,100,"%s",logstr);
    p=strchr(sess,'_'); if(p==NULL) p=sess+strlen(sess);
    if(p<sess+4) p=sess; else p=p-4;
    snprintf(logbuf,sizeof(logbuf),"%s.%s %.6s %s\11%s",
           log_date,log_time, p, ip, fnamebuf);
    p=getvar(ro_name[ro_module]);
    if(p==NULL || *p==0) internal_error("module_log(): module name vanishes.");
    snprintf(fnamebuf,sizeof(fnamebuf),"%s/%s",module_dir,p);
    n=strlen(fnamebuf);
    write_logfile(fnamebuf,logbuf,MODULE_LOG_LIMIT);
}

      /* log http referers */
void referer_log(void)
{
    char logbuf[1024], *c,*s,*ip,*r,*h,refstr[1024];

    if(robot_access) return;
    c=getvar(ro_name[ro_cmd]);
    if(c==NULL) c="";
    if(mode==mode_default) s=getvar("wims_session"); else s="popup";
    if(s==NULL) s="----------";
    else if(!new_session && strcmp(c,"intro")!=0) return;
    if(strchr(s,'_')!=NULL) return;
    ip=remote_addr; if(*ip==0) return;
    r=getenv("HTTP_REFERER");
    if(r==NULL || *r==0) r="??";
      /* skip some useless referers */
    else {
      if(strstr(r,cgi_name)!=NULL) return;
      if(strstr(r,"file:")!=NULL || strchr(r,'.')==NULL) r="??";
      if(strstr(r,"http")==NULL && strchr(r,'.')==NULL && 
         strstr(r,"bookmark")!=NULL) r="??bookmark";
    }
    if(strncmp(r,"http://",strlen("http://"))==0) r+=strlen("http://");
      /* Take references from the same site or not? No. */
    h=getenv("HTTP_HOST");
    if(h!=NULL && *h!=0 && strncmp(r,h,strlen(h))==0) return;
      /* stop before '#' */
    snprintf(refstr,sizeof(refstr),"%s",r);
    r=strchr(refstr,'#'); if(r!=NULL) *r=0;
    for(r=refstr;r<refstr+strlen(refstr);r++) {
      if(*r=='%' && *(r+1)=='7' && *(r+2)=='E') {
          *r='~'; strcpy(r+1,r+3);
      }
    }
    snprintf(logbuf,sizeof(logbuf),"%s %s %s\11%s",
           log_date,s+strlen(s)-4,ip,refstr);
    write_logfile("referer.log",logbuf,GEN_LOG_LIMIT);
}

      /* Log new creation of sessions. For server counting use. */
void session_log(char *c)
{
    int i;
    char *ip, *p, *agent, *s, *sess;
    char logbuf[1024];
    
    ip=remote_addr; if(*ip==0) return;
    if(mode==mode_default) {
      sess=getvar("wims_session"); 
      if(sess==NULL) return;
      if(strchr(sess,'_')!=NULL) return;
    }
    else sess="popup";
    p=getenv("REMOTE_HOST"); if(p==NULL) p="";
    i=strlen(p); if(i>40) p+=i-40;
    agent=getenv("HTTP_USER_AGENT"); if(agent==NULL) agent="";
      /* limit agent name to 40 chars */
    if(strlen(agent)>40) agent[40]=0;
    s=strchr(sess,'_'); if(s==NULL) s=sess+strlen(sess);
    if(s<sess+4) s=sess; else s=s-4;
    snprintf(logbuf,sizeof(logbuf),"%s %s %s\11%s\11%s",
           log_date, s, ip, p, agent);
    write_logfile("session.log",logbuf,GEN_LOG_LIMIT);
}

      /* Log user information. */
void user_log(char *c)
{
    char fname[1024], logbuf[MAX_LINELEN+1], cbuf[256], sbuf[32], shbuf[32];
    char *user, *classe, *sh, *sess, *exo, *cc, *ip, *allow, *pend;
    char *ex;
    double sc;
    int i;
    
    if(robot_access) return;
    sc=0;
    if(isexam) {
      sh=getvar("worksheet"); if(sh==NULL) return;
      snprintf(shbuf,sizeof(shbuf),"%s",sh);
      exo=strchr(shbuf,'.'); if(exo==NULL) return;
      *exo++=0; sh=shbuf;
      if(mode==mode_default) sess=getvar("wims_session");
      else sess="popup";
      if(sess==NULL) return;
      snprintf(sbuf,sizeof(sbuf),"%s",sess);
      sess=strchr(sbuf,'_'); if(sess==NULL) return;
      *sess=0; sess=sbuf; ex="E";
    }
    else {
      sh=getvar("wims_sheet");
      if(sh==NULL || *sh==0) return;
      exo=getvar("wims_exo"); if(exo==NULL) return;
      sess=getvar("wims_session");
      if(sess==NULL) return;
      ex="";
    
    }
    if(strcmp(c,"new")!=0 && strcmp(c,"renew")!=0
       && strcmp(c,"hint")!=0 && parm_restore==0) {
      char *s;
      s=getvar("module_score");
      if(s==NULL || *s==0) return;
      sc=atof(s); if(!finite(sc)) {sc=0; return;}
      snprintf(cbuf,sizeof(cbuf),"score %s",s);
      cc=cbuf; if(sc<0) sc=0; if(sc>10) sc=10;
    }
    else cc=c;
    user=getvar("wims_user"); classe=getvar("wims_class");
    if(classe==NULL || *classe==0) i=1;
    else i=getscorestatus(atoi(classe),atoi(sh));
    pend=getvar("wims_scoring"); if(pend==NULL) pend="";
    if(i==0 || !exodepOK || strcmp(pend,"pending")!=0) allow="    noscore";
    else allow="";
    if(user==NULL || *user==0) {
      classe="0"; allow="";
      snprintf(fname,sizeof(fname),"../sessions/%s/.score",sess);
    }
    else {
      if(classe==NULL || *classe==0) return;
      if(allow[0]==0 && *ex!='E') 
        snprintf(fname,sizeof(fname),"classes/%s/score/%s",classe,user);
      else
        snprintf(fname,sizeof(fname),"classes/%s/noscore/%s",classe,user);
    }
    ip=remote_addr; if(*ip==0) ip="-";
    if(isexam && user!=NULL && *user!=0) {
      char fbuf[1024];
      snprintf(logbuf,sizeof(logbuf),":%s.%s %2s %s   %s%s\n",
             log_date,log_time,exo,cc,ip,allow);
      snprintf(fbuf,sizeof(fbuf),"%s/%s/examscore.%s", session_dir,sess,sh);
      accessfile(logbuf,"a","%s", fbuf);
      if(sc>0) {
          sc=currexamscore(atoi(sh));
          accessfile(logbuf,"r","%s/classes/%s/.E%s",log_dir,classe,sh);
          if(strchr(logbuf,'#')==NULL && sc>0) {      /* not simulation */
            snprintf(logbuf,sizeof(logbuf),
                   "%s %.2f -1 %u %s %s\n",
                   sh,sc,(unsigned int) nowtime,ip,sess);
            accessfile(logbuf,"a","%s/classes/%s/score/%s.exam",
                     log_dir,classe,user);
          }
      }
    }
    snprintf(logbuf,sizeof(logbuf),"%s%s.%s %s %2s %2s %s   %s%s",
           ex,log_date,log_time,sess,sh,exo,cc,ip,allow);
    write_logfile(fname,logbuf,GEN_LOG_LIMIT);
}

      /* Log class information. */
void class_log(char *cl, char *l, char *ip)
{
    char logbuf[1024], fname[1024];
    
    if(robot_access) return;
    snprintf(logbuf,sizeof(logbuf),"%s.%s %s    %s",
           log_date, log_time,ip,l);
    snprintf(fname,sizeof(fname),"classes/%s/.log",cl);
    write_logfile(fname,logbuf,MODULE_LOG_LIMIT);
}

      /* Log accesses to modules. For server counting use. */
void access_log(char *c)
{
    int i;
    char *ip, *p, *sess, *s, *agent, *u, *cl;
    char logbuf[1024], ag[1024];
    
    ip=remote_addr; 
    if(*ip==0) ip="????????";
    if(mode==mode_default) sess=getvar("wims_session");
    else sess="popup";
    if(sess==NULL) sess="----------";
    p=getvar(ro_name[ro_module]);
    if(p==NULL || *p==0) p="-";
      /* limit module name to 40 chars */
    i=strlen(p); if(i>40) p+=i-40;
    if(robot_access) {
      agent=getenv("HTTP_USER_AGENT"); if(agent==NULL) agent="-";
      snprintf(ag,20," %s",agent);
    }
    else {
      u=getvar("wims_user");
      if(u!=NULL && *u!=0) snprintf(ag,sizeof(ag)," %s,%s",u,getvar("wims_class"));
      else ag[0]=0;
    }
    s=strchr(sess,'_'); if(s==NULL) s=sess+strlen(sess);
    if(s<sess+4) s=sess; else s=s-4;
    snprintf(logbuf,sizeof(logbuf),"%s.%s %.6s %s\11%s\11%s%s",
           log_date, log_time, s, ip, c, p, ag);
    write_logfile("access.log",logbuf,GEN_LOG_LIMIT);
    user_log(c);
    cl=getvar("wims_class");
    if(cl!=NULL && *cl!=0) {
      char *l;
      l=getvar("wims_class_log");
      if(l!=NULL && *l!=0) class_log(cl, l, ip);
    }
}

      /* log posted data */
void post_log(void)
{
    char *h, *l, logstr[2*MAX_LINELEN+2];

    log_date_time();
    h=remote_addr;
    if(mpboundary[0]!=0) l="multipart/form-data"; else l=stdinbuf;
    snprintf(logstr,sizeof(logstr),"%s.%s %s    %s",
          log_date, log_time, h, l);
    write_logfile("post.log",logstr,GEN_LOG_LIMIT);
}

      /* It is this routine which is called by main(). */
void write_logs(void)
{
    char *p;
    log_date_time();
    module_log();
    p=getvar(ro_name[ro_cmd]); if(p==NULL || *p==0) p="no_cmd";
    access_log(p); referer_log();
    if(new_session) session_log(p);
}

void user_error_log(char msg[])
{
    char *s, *m, *c, *h, *q, *r, *sess, logstr[512];
    log_date_time();
    if(mode==mode_default) sess=getvar("wims_session");
    else sess="popup";
    if(sess==NULL) sess="----------";
    m=getvar(ro_name[ro_module]);if(m==NULL) m="";
    c=getvar(ro_name[ro_cmd]);if(c==NULL) c="";
    h=remote_addr;
    q=getenv("QUERY_STRING");if(q==NULL) q="";
    r=getenv("HTTP_REFERER");
    if(r==NULL || strstr(r,cgi_name)!=NULL) r="";
    s=strchr(sess,'_'); if(s==NULL) s=sess+strlen(sess);
    if(s<sess+4) s=sess; else s=s-4;
    snprintf(logstr,sizeof(logstr),"%s.%s %.5s %s %s, module=%s cmd=%s: %s %s",
          log_date, log_time, s, h, msg, m, c, r, q);
    write_logfile("user_error.log",logstr,MODULE_LOG_LIMIT);
    if(user_error_nolog) return;
    access_log("user_error");referer_log();
}

void module_error_log(char msg[])
{
    char *s, *m, *c, logstr[256];
    if(strstr(msg,"debug")!=NULL || strstr(msg,"timeup")!=NULL) return;
    if(strstr(m_file.name,"sessions/")!=NULL) return;
    s=getvar(ro_name[ro_module]);
    if(s!=NULL) {
      if(strncmp(s,"classes/",strlen("classes/"))==0 ||
         strncmp(s,"devel/",strlen("devel/"))==0) return;
    }
    log_date_time();
    s=getvar("wims_session"); if(s==NULL) s="";
    m=getvar(ro_name[ro_module]);if(m==NULL) m="";
    c=getvar(ro_name[ro_cmd]);if(c==NULL) c="";
    snprintf(logstr,sizeof(logstr),"%s.%s %.10s %s in %s/%s, line %d",
          log_date, log_time, s+2, msg, m, m_file.name, m_file.l);
    write_logfile("module_error.log",logstr,MODULE_LOG_LIMIT);
    access_log("module_error");
}

      /* Refused users due to threshold excess */
void refuse_log(int th)
{
    char lbuf[1024];
    char *load, *h;
    
    log_date_time();
    load=getvar("wims_server_load"); if(load==NULL) load="??";
    h=remote_addr;
    snprintf(lbuf,sizeof(lbuf),"%s.%s %s\11%d:%s",
           log_date, log_time, h, th, load);
    write_logfile("refuse.log",lbuf,MODULE_LOG_LIMIT);
}

      /* Housekeeping jobs, to avoid using cron. */
void housekeep(void)
{
    char fname[1024], olddate[64];
    FILE *keeplog;
    log_date_time();
    snprintf(fname,sizeof(fname),"%s/keepdate",log_dir);
    keeplog=fopen(fname,"r");
    if(keeplog==NULL) goto dokeep;
    fread(olddate,8,1,keeplog); olddate[8]=0; fclose(keeplog);
    if(strcmp(olddate,log_date)==0) return;
    dokeep:
    keeplog=fopen(fname,"w");
    if(keeplog!=NULL) {
      fwrite(log_date,8,1,keeplog);fclose(keeplog);
    }
    wrapexec=1; exec_wait=0;
    call_ssh("../bin/housekeep.daily &>%s/housekeep.log",log_dir);
    exec_wait=1;
}


Generated by  Doxygen 1.6.0   Back to index