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