Subversion Repositories wimsdev

Rev

Rev 8124 | Rev 8185 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
10 reyssat 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"
8124 bpr 62
#include "wimslogdlines.c"
10 reyssat 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
 
8155 bpr 71
/* check whether there is anything to execute */
10 reyssat 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
 
8155 bpr 132
/* This is run only when manually invoking the program.
133
 * Verifies the orderedness of various list tables.
134
 */
10 reyssat 135
int verify_tables(void)
136
{
137
    if(verify_order(cmdlist,cmdcnt,sizeof(cmdlist[0]))) return -1;
138
    return 0;
139
}
140
 
141
int main(int argc, char *argv[])
142
{
143
    char *p;
144
    struct stat st;
145
    uid_t myid;
146
    int /*mfd,*/rsock,mincnt;
147
    char buf[MAX_LINELEN+1];
148
 
149
    error1=error; error2=error; error3=error;
150
    forkcnt=0; exec_wait=1; mincnt=0;
151
    classcaches=sheetcaches=0;
3836 kbelabas 152
    (void)freopen("/dev/null","r",stdin);
153
    (void)freopen("../tmp/log/wimslogd.out","w",stdout);
154
    (void)freopen("../tmp/log/wimslogd.err","w",stderr);
10 reyssat 155
/*    mfd=shm_open(SHM_NAME,O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
156
    write(mfd,buf,SHM_SIZE);
157
    shmptr=mmap(0,SHM_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,mfd,0);
158
    if(shmptr==MAP_FAILED) {
159
        fprintf(stderr,"wimslogd: mmap() failure. %s\n",
160
                strerror(errno));
161
        exit(1);
162
    }
7491 bpr 163
*/
10 reyssat 164
    verify_tables();
165
    init_random();
166
    modupdatetime=(double) random()*350/RAND_MAX;
167
    rshift=(double) random()*MINLENGTH/RAND_MAX;
168
    parms();
169
    if(getcwd(cwd,sizeof(cwd))==NULL) { /* directory missing */
170
        fprintf(stderr,"wimslogd: getcwd() failure. %s\n",
171
                strerror(errno));
172
        return 1;
173
    }
174
    p=strstr(cwd,"/public_html");
175
    if(p!=NULL && *(p+strlen("/public_html"))==0) {
176
        *p=0; if(chdir(cwd)<0) {        /* strong error */
177
            fprintf(stderr,"wimslogd: Unable to change directory. %s\n",
178
                    strerror(errno));
179
            return 1;
180
        }
181
    }
182
    opensock();
183
    mypid=getpid();
184
    myid=geteuid(); setreuid(myid,myid);
185
    myid=getegid(); setregid(myid,myid);
186
    stat("/sysmask/notice/init-end",&st);
187
    snprintf(pidstr,sizeof(pidstr),"%u",mypid);
188
    getnow(); printf("wimslogd %s started at %s.\n",pidstr,nowstr);
189
    startdate=nowday;
190
    fflush(NULL);
191
    starttime=nowtime; startmin=lastmin=thismin;
192
    accessfile(qbuf,"r","log/cquota/lim.host");
193
    accessfile(buf,"r","log/myip"); mystrncpy(ipbuf,find_word_start(buf),sizeof(ipbuf));
194
    accessfile(buf,"r","tmp/log/wimslogd.relax"); /* if yes then it is a cluster child */
195
    if(strstr(buf,"yes")!=NULL) {       /* register my real IP */
7491 bpr 196
        accessfile(nodeipbuf,"r","/etc/myip");
10 reyssat 197
        accessfile(nodeipbuf,"w","tmp/log/myip");
198
    }
199
    do {
200
        fd_set rset;
201
        struct timeval tv;
202
        int t, selectcnt;
203
 
204
        if(getpid()!=mypid) return 0;   /* leaked child */
205
        if(stat(debugfile,&st)==0 && st.st_size<MAX_DEBUGLENGTH) debugging=1;
206
        else debugging=0;
207
        accessfile(loadavg,"r","/proc/loadavg");
208
        for(selectcnt=0; selectcnt<100; selectcnt++) {
209
            tv.tv_sec=0; tv.tv_usec=50000; /* a pause every 50 ms. */
210
            FD_ZERO(&rset); FD_SET(commsock,&rset);
211
            t=select(commsock+1,&rset,NULL,NULL,&tv);
212
            if(t==0) {forkman(0); continue;}
213
            if(t<0) {error("select() error."); continue;}
214
            rsock=accept(commsock,NULL,NULL);
215
            if(rsock==-1) {error("accept() error."); continue;}
216
            answer(rsock);
217
        }
218
        forkman(1);
219
        getnow();
220
        if(thismin==lastmin) continue;
221
        mincnt++; /* if(mincnt>MAX_MIN) return 0; Refreshment. */
222
        if(nowday!=startdate) return 0; /* Daily refreshment. */
223
        lastmin=thismin;
224
        accessfile(buf,"r",pidfile); strip_trailing_spaces(buf);
225
        if(strcmp(buf,pidstr)!=0) {     /* wrong pid: abandon. */
226
            wait_children();
227
            return 0;
228
        }
229
 
230
        if(getpid()!=mypid) return 0;   /* leaked child */
231
        accessfile(qbuf,"r","log/cquota/lim.host");
232
        accessfile(buf,"r","log/myip"); mystrncpy(ipbuf,find_word_start(buf),sizeof(ipbuf));
233
        cleancache();
234
        if((thismin%127)==6) homedir(); /* update home directory setup */
235
        accessfile(buf,"r","tmp/log/wimslogd.relax"); /* if yes then no housekeeping */
236
        if(strstr(buf,"yes")==NULL) {
237
            dispatch_log();
238
            if((thismin%2)==1) local();
239
            /* if((thismin%9)==0) */ cleaning(1);       /* clean up session directories */
240
            if((thismin%5)==0 && nowmin>15) housekeep();        /* daily housekeeping */
241
            if(getpid()!=mypid) return 0;       /* leaked child */
242
            if(nowhr*60+nowmin>modupdatetime && (thismin%17)==11) modupdate();
243
            if(backup_hour>0 && backup_hour<23 && (thismin%17)==3 && nowhr>=backup_hour)
244
              backup(); /* daily backup */
245
            fflush(NULL);
246
            logexec();
247
        }
248
        else {  /* cluster child */
249
            if((thismin%9)==0) cleaning(0);     /* clean up session directories */
250
        }
251
    }
252
    while(1==1);
253
    return 0;
254
}
255