Back to index

wims  3.65+svn20090927
wimslogd.c
Go to the documentation of this file.
00001 /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
00002  *
00003  *  This program is free software; you can redistribute it and/or modify
00004  *  it under the terms of the GNU General Public License as published by
00005  *  the Free Software Foundation; either version 2 of the License, or
00006  *  (at your option) any later version.
00007  *
00008  *  This program is distributed in the hope that it will be useful,
00009  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  *  GNU General Public License for more details.
00012  *
00013  *  You should have received a copy of the GNU General Public License
00014  *  along with this program; if not, write to the Free Software
00015  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00016  */
00017 
00018 /* WIMS log daemon */
00019 
00020 #include "wimslogd.h"
00021 
00022 extern char **environ;
00023 
00024 char cwd[MAX_FNAME+1];
00025 char pidstr[32];
00026 char keepdate[32]="0";
00027 char mupdate[32]="0";
00028 char backdate[32]="0";
00029 char loadavg[MAX_LINELEN+1];
00030 char qbuf[MAX_LINELEN+1];   /* quota buffer */
00031 time_t nowtime, starttime, lastcleantime=0;
00032 time_t thismin, lastmin, startmin;
00033 struct tm *now;
00034 int nowsec, nowmin, nowhr, nowday, nowwday,nowmon,nowyear;
00035 int startdate;
00036 char nowstr[64];
00037 pid_t mypid;
00038 int idle_time=5000;
00039 int idle_time2=5000;
00040 int idle_time3=5000;
00041 int anti_time=3600*24;      /* antidate tolerance */
00042 int OLD_LOG_FILES=2;
00043 int GEN_LOG_LIMIT=1024000;
00044 int MODULE_LOG_LIMIT=102400;
00045 int backup_hour=-1;
00046 int site_accounting=0;
00047 int modupdatetime=0;
00048 int rshift;   /* shift minute start */
00049 int commsock;
00050 int answerlen;
00051 int debugging;
00052 char ipbuf[64];
00053 char nodeipbuf[MAX_LINELEN+1];
00054 char commbuf[BUFFERLEN+1];
00055 #define textbuf (commbuf+sizeof(int))
00056 char *textptr;
00057 
00058 int cwdtype;
00059 enum {dir_home, dir_class, dir_session, dir_module};
00060 
00061 #include "fork.c"
00062 #include "lines.c"
00063 #include "cache.c"
00064 #include "files.c"
00065 #include "socket.c"
00066 #include "log.c"
00067 #include "cleaning.c"
00068 #include "housekeep.c"
00069 #include "homedir.c"
00070 
00071        /* check whether there is anything to execute */
00072 void logexec(void)
00073 {
00074     struct stat st;
00075     pid_t pid;
00076     if(stat("log/wimslogd.exec",&st)) return;
00077     fflush(NULL);
00078     pid=fork(); if(pid>0) {addfork(pid,1); return;}
00079     close(commsock); msleep(100);
00080     call_ssh(1,"sh log/wimslogd.exec >tmp/log/wimslogdexec.out 2>tmp/log/wimslogdexec.err");
00081     unlink("log/wimslogd.exec"); exit(0);
00082 }
00083 
00084 void local(void)
00085 {
00086     struct stat st;
00087     if(stat("log/wimslogd.local",&st)) return;
00088     if(!(S_IXUSR&st.st_mode)) return;
00089     call_ssh(0,"sh log/wimslogd.local");
00090 }
00091 
00092 void getnow(void)
00093 {
00094     nowtime=time(NULL); thismin=(nowtime-rshift)/MINLENGTH;
00095     now=localtime(&nowtime);
00096     nowsec=now->tm_sec;
00097     nowmin=now->tm_min; nowhr=now->tm_hour;
00098     nowday=now->tm_mday; nowwday=now->tm_wday;
00099     nowmon=now->tm_mon+1; nowyear=now->tm_year+1900;
00100     snprintf(nowstr,sizeof(nowstr),"%04d%02d%02d.%02d:%02d:%02d",
00101             nowyear,nowmon,nowday,nowhr,nowmin,nowsec);
00102 }
00103 
00104 void parms(void)
00105 {
00106     char *p, *p1, *p2, *parm[16];
00107     char buf[16];
00108     int t,r;
00109     p=getenv("wimslogd");
00110     if(p==NULL || *p==0) return;
00111     for(t=0, p1=find_word_start(p); *p1; p1=find_word_start(p2)) {
00112        p2=find_word_end(p1); if(*p2) *p2++=0;
00113        parm[t++]=p1;
00114     }
00115     idle_time=atoi(parm[0]); if(idle_time<=10) idle_time=5000;
00116     idle_time2=atoi(parm[1]); if(idle_time2<=10) idle_time2=idle_time;
00117     idle_time3=atoi(parm[2]); if(idle_time3<=10) idle_time3=idle_time2;
00118     if(idle_time2>idle_time) idle_time2=idle_time;
00119     if(idle_time3>idle_time2) idle_time3=idle_time2;
00120     OLD_LOG_FILES=atoi(parm[3]);
00121     if(OLD_LOG_FILES>100) OLD_LOG_FILES=100;
00122     if(parm[4]) GEN_LOG_LIMIT=atoi(parm[4]);
00123     if(parm[5]) MODULE_LOG_LIMIT=atoi(parm[5]);
00124     if(parm[6]) backup_hour=atoi(parm[6]);
00125     if(parm[7]) site_accounting=atoi(parm[7]);
00126     if(parm[8]) r=atoi(parm[8])+1; else r=8;
00127     if(r<2) r=2; if(r>100) r=100;
00128     snprintf(buf,sizeof(buf),"%d",r); setenv("examlog_lim2",buf,1);
00129     if(site_accounting>0) setenv("site_accounting","yes",1);
00130 }
00131 
00132        /* This is run only when manually invoking the program.
00133         * Verifies the orderedness of various list tables. */
00134 int verify_tables(void)
00135 {
00136     if(verify_order(cmdlist,cmdcnt,sizeof(cmdlist[0]))) return -1;
00137     return 0;
00138 }
00139 
00140 int main(int argc, char *argv[])
00141 {
00142     char *p;
00143     struct stat st;
00144     uid_t myid;
00145     int /*mfd,*/rsock,mincnt;
00146     char buf[MAX_LINELEN+1];
00147 
00148     error1=error; error2=error; error3=error;
00149     forkcnt=0; exec_wait=1; mincnt=0;
00150     classcaches=sheetcaches=0;
00151     freopen("/dev/null","r",stdin);
00152     freopen("../tmp/log/wimslogd.out","w",stdout);
00153     freopen("../tmp/log/wimslogd.err","w",stderr);
00154 /*    mfd=shm_open(SHM_NAME,O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
00155     write(mfd,buf,SHM_SIZE);
00156     shmptr=mmap(0,SHM_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,mfd,0);
00157     if(shmptr==MAP_FAILED) {
00158        fprintf(stderr,"wimslogd: mmap() failure. %s\n",
00159               strerror(errno));
00160        exit(1);
00161     }
00162 */    
00163     verify_tables();
00164     init_random();
00165     modupdatetime=(double) random()*350/RAND_MAX;
00166     rshift=(double) random()*MINLENGTH/RAND_MAX;
00167     parms();
00168     if(getcwd(cwd,sizeof(cwd))==NULL) {   /* directory missing */
00169        fprintf(stderr,"wimslogd: getcwd() failure. %s\n",
00170               strerror(errno));
00171        return 1;
00172     }
00173     p=strstr(cwd,"/public_html");
00174     if(p!=NULL && *(p+strlen("/public_html"))==0) {
00175        *p=0; if(chdir(cwd)<0) {    /* strong error */
00176            fprintf(stderr,"wimslogd: Unable to change directory. %s\n",
00177                   strerror(errno));
00178            return 1;
00179        }
00180     }
00181     opensock();
00182     mypid=getpid();
00183     myid=geteuid(); setreuid(myid,myid);
00184     myid=getegid(); setregid(myid,myid);
00185     stat("/sysmask/notice/init-end",&st);
00186     snprintf(pidstr,sizeof(pidstr),"%u",mypid);
00187     getnow(); printf("wimslogd %s started at %s.\n",pidstr,nowstr);
00188     startdate=nowday;
00189     fflush(NULL);
00190     starttime=nowtime; startmin=lastmin=thismin;
00191     accessfile(qbuf,"r","log/cquota/lim.host");
00192     accessfile(buf,"r","log/myip"); mystrncpy(ipbuf,find_word_start(buf),sizeof(ipbuf));
00193     accessfile(buf,"r","tmp/log/wimslogd.relax"); /* if yes then it is a cluster child */
00194     if(strstr(buf,"yes")!=NULL) {  /* register my real IP */
00195        accessfile(nodeipbuf,"r","/etc/myip"); 
00196        accessfile(nodeipbuf,"w","tmp/log/myip");
00197     }
00198     do {
00199        fd_set rset;
00200        struct timeval tv;
00201        int t, selectcnt;
00202 
00203        if(getpid()!=mypid) return 0;      /* leaked child */
00204        if(stat(debugfile,&st)==0 && st.st_size<MAX_DEBUGLENGTH) debugging=1;
00205        else debugging=0;
00206        accessfile(loadavg,"r","/proc/loadavg");
00207        for(selectcnt=0; selectcnt<100; selectcnt++) {
00208            tv.tv_sec=0; tv.tv_usec=50000; /* a pause every 50 ms. */
00209            FD_ZERO(&rset); FD_SET(commsock,&rset);
00210            t=select(commsock+1,&rset,NULL,NULL,&tv);
00211            if(t==0) {forkman(0); continue;}
00212            if(t<0) {error("select() error."); continue;}
00213            rsock=accept(commsock,NULL,NULL);
00214            if(rsock==-1) {error("accept() error."); continue;}
00215            answer(rsock);
00216        }
00217        forkman(1);
00218        getnow();
00219        if(thismin==lastmin) continue;
00220        mincnt++; /* if(mincnt>MAX_MIN) return 0; Refreshment. */
00221        if(nowday!=startdate) return 0; /* Daily refreshment. */
00222        lastmin=thismin;
00223         accessfile(buf,"r",pidfile); strip_trailing_spaces(buf);
00224        if(strcmp(buf,pidstr)!=0) { /* wrong pid: abandon. */
00225            wait_children();
00226            return 0;
00227        }
00228 
00229        if(getpid()!=mypid) return 0;      /* leaked child */
00230        accessfile(qbuf,"r","log/cquota/lim.host");
00231        accessfile(buf,"r","log/myip"); mystrncpy(ipbuf,find_word_start(buf),sizeof(ipbuf));
00232        cleancache();
00233        if((thismin%127)==6) homedir();    /* update home directory setup */
00234        accessfile(buf,"r","tmp/log/wimslogd.relax"); /* if yes then no housekeeping */
00235        if(strstr(buf,"yes")==NULL) {
00236            dispatch_log();
00237            if((thismin%2)==1) local();
00238            /* if((thismin%9)==0) */ cleaning(1);        /* clean up session directories */
00239            if((thismin%5)==0 && nowmin>15) housekeep(); /* daily housekeeping */
00240            if(getpid()!=mypid) return 0;  /* leaked child */
00241            if(nowhr*60+nowmin>modupdatetime && (thismin%17)==11) modupdate();
00242            if(backup_hour>0 && backup_hour<23 && (thismin%17)==3 && nowhr>=backup_hour)
00243              backup();      /* daily backup */
00244            fflush(NULL);
00245            logexec();
00246        }
00247        else { /* cluster child */
00248            if((thismin%9)==0) cleaning(0);       /* clean up session directories */
00249        }
00250     }
00251     while(1==1);
00252     return 0;
00253 }
00254