Subversion Repositories wimsdev

Rev

Rev 7491 | 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. /* WIMS log daemon */
  19.  
  20. #include "wimslogd.h"
  21.  
  22. extern char **environ;
  23.  
  24. char cwd[MAX_FNAME+1];
  25. char pidstr[32];
  26. char keepdate[32]="0";
  27. char mupdate[32]="0";
  28. char backdate[32]="0";
  29. char loadavg[MAX_LINELEN+1];
  30. char qbuf[MAX_LINELEN+1];       /* quota buffer */
  31. time_t nowtime, starttime, lastcleantime=0;
  32. time_t thismin, lastmin, startmin;
  33. struct tm *now;
  34. int nowsec, nowmin, nowhr, nowday, nowwday,nowmon,nowyear;
  35. int startdate;
  36. char nowstr[64];
  37. pid_t mypid;
  38. int idle_time=5000;
  39. int idle_time2=5000;
  40. int idle_time3=5000;
  41. int anti_time=3600*24;  /* antidate tolerance */
  42. int OLD_LOG_FILES=2;
  43. int GEN_LOG_LIMIT=1024000;
  44. int MODULE_LOG_LIMIT=102400;
  45. int backup_hour=-1;
  46. int site_accounting=0;
  47. int modupdatetime=0;
  48. int rshift;     /* shift minute start */
  49. int commsock;
  50. int answerlen;
  51. int debugging;
  52. char ipbuf[64];
  53. char nodeipbuf[MAX_LINELEN+1];
  54. char commbuf[BUFFERLEN+1];
  55. #define textbuf (commbuf+sizeof(int))
  56. char *textptr;
  57.  
  58. int cwdtype;
  59. enum {dir_home, dir_class, dir_session, dir_module};
  60.  
  61. #include "fork.c"
  62. #include "lines.c"
  63. #include "cache.c"
  64. #include "files.c"
  65. #include "socket.c"
  66. #include "log.c"
  67. #include "cleaning.c"
  68. #include "housekeep.c"
  69. #include "homedir.c"
  70.  
  71.         /* check whether there is anything to execute */
  72. void logexec(void)
  73. {
  74.     struct stat st;
  75.     pid_t pid;
  76.     if(stat("log/wimslogd.exec",&st)) return;
  77.     fflush(NULL);
  78.     pid=fork(); if(pid>0) {addfork(pid,1); return;}
  79.     close(commsock); msleep(100);
  80.     call_ssh(1,"sh log/wimslogd.exec >tmp/log/wimslogdexec.out 2>tmp/log/wimslogdexec.err");
  81.     unlink("log/wimslogd.exec"); exit(0);
  82. }
  83.  
  84. void local(void)
  85. {
  86.     struct stat st;
  87.     if(stat("log/wimslogd.local",&st)) return;
  88.     if(!(S_IXUSR&st.st_mode)) return;
  89.     call_ssh(0,"sh log/wimslogd.local");
  90. }
  91.  
  92. void getnow(void)
  93. {
  94.     nowtime=time(NULL); thismin=(nowtime-rshift)/MINLENGTH;
  95.     now=localtime(&nowtime);
  96.     nowsec=now->tm_sec;
  97.     nowmin=now->tm_min; nowhr=now->tm_hour;
  98.     nowday=now->tm_mday; nowwday=now->tm_wday;
  99.     nowmon=now->tm_mon+1; nowyear=now->tm_year+1900;
  100.     snprintf(nowstr,sizeof(nowstr),"%04d%02d%02d.%02d:%02d:%02d",
  101.              nowyear,nowmon,nowday,nowhr,nowmin,nowsec);
  102. }
  103.  
  104. void parms(void)
  105. {
  106.     char *p, *p1, *p2, *parm[16];
  107.     char buf[16];
  108.     int t,r;
  109.     p=getenv("wimslogd");
  110.     if(p==NULL || *p==0) return;
  111.     for(t=0, p1=find_word_start(p); *p1; p1=find_word_start(p2)) {
  112.         p2=find_word_end(p1); if(*p2) *p2++=0;
  113.         parm[t++]=p1;
  114.     }
  115.     idle_time=atoi(parm[0]); if(idle_time<=10) idle_time=5000;
  116.     idle_time2=atoi(parm[1]); if(idle_time2<=10) idle_time2=idle_time;
  117.     idle_time3=atoi(parm[2]); if(idle_time3<=10) idle_time3=idle_time2;
  118.     if(idle_time2>idle_time) idle_time2=idle_time;
  119.     if(idle_time3>idle_time2) idle_time3=idle_time2;
  120.     OLD_LOG_FILES=atoi(parm[3]);
  121.     if(OLD_LOG_FILES>100) OLD_LOG_FILES=100;
  122.     if(parm[4]) GEN_LOG_LIMIT=atoi(parm[4]);
  123.     if(parm[5]) MODULE_LOG_LIMIT=atoi(parm[5]);
  124.     if(parm[6]) backup_hour=atoi(parm[6]);
  125.     if(parm[7]) site_accounting=atoi(parm[7]);
  126.     if(parm[8]) r=atoi(parm[8])+1; else r=8;
  127.     if(r<2) r=2; if(r>100) r=100;
  128.     snprintf(buf,sizeof(buf),"%d",r); setenv("examlog_lim2",buf,1);
  129.     if(site_accounting>0) setenv("site_accounting","yes",1);
  130. }
  131.  
  132.         /* This is run only when manually invoking the program.
  133.          * Verifies the orderedness of various list tables. */
  134. int verify_tables(void)
  135. {
  136.     if(verify_order(cmdlist,cmdcnt,sizeof(cmdlist[0]))) return -1;
  137.     return 0;
  138. }
  139.  
  140. int main(int argc, char *argv[])
  141. {
  142.     char *p;
  143.     struct stat st;
  144.     uid_t myid;
  145.     int /*mfd,*/rsock,mincnt;
  146.     char buf[MAX_LINELEN+1];
  147.  
  148.     error1=error; error2=error; error3=error;
  149.     forkcnt=0; exec_wait=1; mincnt=0;
  150.     classcaches=sheetcaches=0;
  151.     freopen("/dev/null","r",stdin);
  152.     freopen("../tmp/log/wimslogd.out","w",stdout);
  153.     freopen("../tmp/log/wimslogd.err","w",stderr);
  154. /*    mfd=shm_open(SHM_NAME,O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
  155.     write(mfd,buf,SHM_SIZE);
  156.     shmptr=mmap(0,SHM_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,mfd,0);
  157.     if(shmptr==MAP_FAILED) {
  158.         fprintf(stderr,"wimslogd: mmap() failure. %s\n",
  159.                 strerror(errno));
  160.         exit(1);
  161.     }
  162. */    
  163.     verify_tables();
  164.     init_random();
  165.     modupdatetime=(double) random()*350/RAND_MAX;
  166.     rshift=(double) random()*MINLENGTH/RAND_MAX;
  167.     parms();
  168.     if(getcwd(cwd,sizeof(cwd))==NULL) { /* directory missing */
  169.         fprintf(stderr,"wimslogd: getcwd() failure. %s\n",
  170.                 strerror(errno));
  171.         return 1;
  172.     }
  173.     p=strstr(cwd,"/public_html");
  174.     if(p!=NULL && *(p+strlen("/public_html"))==0) {
  175.         *p=0; if(chdir(cwd)<0) {        /* strong error */
  176.             fprintf(stderr,"wimslogd: Unable to change directory. %s\n",
  177.                     strerror(errno));
  178.             return 1;
  179.         }
  180.     }
  181.     opensock();
  182.     mypid=getpid();
  183.     myid=geteuid(); setreuid(myid,myid);
  184.     myid=getegid(); setregid(myid,myid);
  185.     stat("/sysmask/notice/init-end",&st);
  186.     snprintf(pidstr,sizeof(pidstr),"%u",mypid);
  187.     getnow(); printf("wimslogd %s started at %s.\n",pidstr,nowstr);
  188.     startdate=nowday;
  189.     fflush(NULL);
  190.     starttime=nowtime; startmin=lastmin=thismin;
  191.     accessfile(qbuf,"r","log/cquota/lim.host");
  192.     accessfile(buf,"r","log/myip"); mystrncpy(ipbuf,find_word_start(buf),sizeof(ipbuf));
  193.     accessfile(buf,"r","tmp/log/wimslogd.relax"); /* if yes then it is a cluster child */
  194.     if(strstr(buf,"yes")!=NULL) {       /* register my real IP */
  195.         accessfile(nodeipbuf,"r","/etc/myip");
  196.         accessfile(nodeipbuf,"w","tmp/log/myip");
  197.     }
  198.     do {
  199.         fd_set rset;
  200.         struct timeval tv;
  201.         int t, selectcnt;
  202.  
  203.         if(getpid()!=mypid) return 0;   /* leaked child */
  204.         if(stat(debugfile,&st)==0 && st.st_size<MAX_DEBUGLENGTH) debugging=1;
  205.         else debugging=0;
  206.         accessfile(loadavg,"r","/proc/loadavg");
  207.         for(selectcnt=0; selectcnt<100; selectcnt++) {
  208.             tv.tv_sec=0; tv.tv_usec=50000; /* a pause every 50 ms. */
  209.             FD_ZERO(&rset); FD_SET(commsock,&rset);
  210.             t=select(commsock+1,&rset,NULL,NULL,&tv);
  211.             if(t==0) {forkman(0); continue;}
  212.             if(t<0) {error("select() error."); continue;}
  213.             rsock=accept(commsock,NULL,NULL);
  214.             if(rsock==-1) {error("accept() error."); continue;}
  215.             answer(rsock);
  216.         }
  217.         forkman(1);
  218.         getnow();
  219.         if(thismin==lastmin) continue;
  220.         mincnt++; /* if(mincnt>MAX_MIN) return 0; Refreshment. */
  221.         if(nowday!=startdate) return 0; /* Daily refreshment. */
  222.         lastmin=thismin;
  223.         accessfile(buf,"r",pidfile); strip_trailing_spaces(buf);
  224.         if(strcmp(buf,pidstr)!=0) {     /* wrong pid: abandon. */
  225.             wait_children();
  226.             return 0;
  227.         }
  228.  
  229.         if(getpid()!=mypid) return 0;   /* leaked child */
  230.         accessfile(qbuf,"r","log/cquota/lim.host");
  231.         accessfile(buf,"r","log/myip"); mystrncpy(ipbuf,find_word_start(buf),sizeof(ipbuf));
  232.         cleancache();
  233.         if((thismin%127)==6) homedir(); /* update home directory setup */
  234.         accessfile(buf,"r","tmp/log/wimslogd.relax"); /* if yes then no housekeeping */
  235.         if(strstr(buf,"yes")==NULL) {
  236.             dispatch_log();
  237.             if((thismin%2)==1) local();
  238.             /* if((thismin%9)==0) */ cleaning(1);       /* clean up session directories */
  239.             if((thismin%5)==0 && nowmin>15) housekeep();        /* daily housekeeping */
  240.             if(getpid()!=mypid) return 0;       /* leaked child */
  241.             if(nowhr*60+nowmin>modupdatetime && (thismin%17)==11) modupdate();
  242.             if(backup_hour>0 && backup_hour<23 && (thismin%17)==3 && nowhr>=backup_hour)
  243.               backup(); /* daily backup */
  244.             fflush(NULL);
  245.             logexec();
  246.         }
  247.         else {  /* cluster child */
  248.             if((thismin%9)==0) cleaning(0);     /* clean up session directories */
  249.         }
  250.     }
  251.     while(1==1);
  252.     return 0;
  253. }
  254.  
  255.