]> git.ipfire.org Git - thirdparty/sarg.git/blob - index.c
Sarg.conf can use multiple access_log lines.
[thirdparty/sarg.git] / index.c
1 /*
2 * AUTHOR: Pedro Lineu Orso pedro.orso@gmail.com
3 * 1998, 2008
4 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
5 *
6 * SARG donations:
7 * please look at http://sarg.sourceforge.net/donations.php
8 * ---------------------------------------------------------------------
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
23 *
24 */
25
26 #include "include/conf.h"
27 #include "include/defs.h"
28
29 void make_index(void)
30 {
31
32 FILE *fp_ou, *fp_ou2, *fp_ou3, *fp_tmp, *fp_tmp2, *fp_tmp3;
33 DIR *dirp, *dirp2, *dirp3;
34 struct dirent *direntp;
35 struct dirent *direntp2;
36 struct dirent *direntp3;
37 char html[MAXLEN];
38 char wdir[MAXLEN];
39 char wdir_tmp[MAXLEN];
40 char wdir_tmp2[MAXLEN];
41 char wdir_tmp3[MAXLEN];
42 char newname[512];
43 char month[4];
44 char period[80];
45 char data[80];
46 char tuser[20];
47 char tbytes[20];
48 char media[20];
49 char ftime[128];
50 char day[16], mon[16], year[40], hour[10];
51 char *str;
52 int cstatus;
53 int iyear, imonth, iday, ihour, iminute, isecond, idst;
54 char y1[5], y2[5];
55 char d1[3], d2[3];
56 char m1[4], m2[4];
57 struct getwordstruct gwarea;
58
59 if(LastLog[0] != '\0') mklastlog(outdir);
60
61 sprintf(wdir,"%sindex.html",outdir);
62 sprintf(wdir_tmp,"%sindex.unsort",outdir);
63 sprintf(wdir_tmp2,"%sindex.sort",outdir);
64 strcpy(hbc1,"class=\"header\"");
65
66 if(strcmp(Index,"no") == 0) {
67 if(access(wdir, R_OK) == 0) unlink(wdir);
68 return;
69 }
70
71 if(debug) debuga("%s",text[53]);
72
73 // Root dir
74 dirp = opendir(outdir);
75 while ((direntp = readdir( dirp )) != NULL) {
76 if(strcmp(IndexTree,"date") == 0) {
77 if(!isdigit(direntp->d_name[0]) && !isdigit(direntp->d_name[1])) continue;
78 if(strlen(direntp->d_name) > 4) {
79 bzero(y1,5);
80 bzero(y2,5);
81 bzero(m1,4);
82 bzero(m2,4);
83 bzero(d1,3);
84 bzero(d2,3);
85 if(strcmp(df,"u") == 0) {
86 strncpy(y1,direntp->d_name,4);
87 strncpy(m1,direntp->d_name+4,3);
88 strncpy(d1,direntp->d_name+7,2);
89 strncpy(y2,direntp->d_name+10,4);
90 strncpy(m2,direntp->d_name+14,3);
91 strncpy(d2,direntp->d_name+17,2);
92 } else if(strcmp(df,"e") == 0) {
93 strncpy(y1,direntp->d_name+5,4);
94 strncpy(m1,direntp->d_name+2,3);
95 strncpy(d1,direntp->d_name,2);
96 strncpy(y2,direntp->d_name+15,4);
97 strncpy(m2,direntp->d_name+12,3);
98 strncpy(d2,direntp->d_name+10,2);
99 }
100 conv_month(m1);
101 conv_month(m2);
102 }
103 sprintf(val1,"%s%s",outdir,y1);
104 if(access(val1, R_OK) != 0) mkdir(val1,0755);
105 if(strcmp(m1,m2) != 0) sprintf(val2,"%s/%s-%s",val1,m1,m2);
106 else sprintf(val2,"%s/%s",val1,m1);
107 if(access(val2, R_OK) != 0) mkdir(val2,0755);
108 if(strcmp(d1,d2) != 0) sprintf(val3,"%s/%s-%s",val2,d1,d2);
109 else sprintf(val3,"%s/%s",val2,d1);
110 sprintf(val4,"%s%s",outdir,direntp->d_name);
111 rename(val4,val3);
112 sprintf(val5,"%s/images",val2);
113 if(access(val5, R_OK) != 0) {
114 sprintf(val5,"ln -s \"%simages\" \"%s/images\"",outdir,val2);
115 cstatus=system(val5);
116 if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
117 fprintf(stderr, "SARG: command return status %d\n",WEXITSTATUS(cstatus));
118 fprintf(stderr, "SARG: command: %s\n",val5);
119 exit(1);
120 }
121 }
122 } else {
123 if(!isdigit(direntp->d_name[0]) && !isdigit(direntp->d_name[1])) continue;
124 if(strlen(direntp->d_name) == 4) {
125 strcpy(y1,direntp->d_name);
126 sprintf(val1,"%s%s",outdir,direntp->d_name);
127 dirp2 = opendir(val1);
128 while ((direntp2 = readdir( dirp2 )) != NULL) {
129 if(!isdigit(direntp2->d_name[0]) && !isdigit(direntp2->d_name[1])) continue;
130 sprintf(val2,"%s/%s",val1,direntp2->d_name);
131 dirp3 = opendir(val2);
132 while ((direntp3 = readdir( dirp3 )) != NULL) {
133 if(!isdigit(direntp3->d_name[0]) && !isdigit(direntp3->d_name[1])) continue;
134 bzero(newname,512);
135 strcpy(warea,direntp2->d_name);
136 if((str = strchr(warea,'-')) != 0) {
137 *str++ = '\0';
138 strcpy(m1,warea);
139 strcpy(m2,str);
140 conv_month_name(m1);
141 conv_month_name(m2);
142 } else {
143 strcpy(m1,warea);
144 conv_month_name(m1);
145 strcpy(m2,m1);
146 }
147 strcpy(warea,direntp3->d_name);
148 if((str = strchr(warea,'-')) != 0) {
149 *str++ = '\0';
150 strcpy(d1,warea);
151 strcpy(d2,warea);
152 } else {
153 strcpy(d1,warea);
154 strcpy(d2,warea);
155 }
156 if(strcmp(df,"u") == 0) sprintf(val4,"%s%s%s%s-%s%s%s",outdir,y1,m1,d1,y1,m2,d2);
157 else if(strcmp(df,"e") == 0) sprintf(val4,"%s%s%s%s-%s%s%s",outdir,d1,m1,y1,d2,m2,y1);
158 sprintf(val5,"%s%s/%s/%s",outdir,y1,direntp2->d_name,direntp3->d_name);
159 if(rename(val5,val4)) {
160 fprintf(stderr, "SARG: (index) rename error - %s\n",strerror(errno));
161 exit(1);
162 }
163 }
164 (void)rewinddir( dirp3 );
165 (void)closedir( dirp3 );
166 }
167 (void)rewinddir( dirp2 );
168 (void)closedir( dirp2 );
169 }
170 // sprintf(cmd,"rm -rf %s%s\n",outdir,direntp->d_name);
171 // system(cmd);
172 }
173 }
174 (void)rewinddir( dirp );
175 (void)closedir( dirp );
176
177 if((fp_tmp=fopen(wdir_tmp,"w"))==NULL) {
178 fprintf(stderr, "SARG: (index) %s: %s\n",text[45],wdir_tmp);
179 exit(1);
180 }
181
182 dirp = opendir(outdir);
183 while ((direntp = readdir( dirp )) != NULL) {
184 if(strcmp(IndexTree,"date") == 0) {
185 if(strlen(direntp->d_name) > 4 || (!isdigit(direntp->d_name[0]) && !isdigit(direntp->d_name[1]))) continue;
186 fprintf(fp_tmp,"%s\t%s\n",direntp->d_name,get_size(outdir,direntp->d_name));
187 continue;
188 } else {
189 if(strstr(direntp->d_name,"-") == 0) continue;
190 bzero(newname, 512);
191 if(strcmp(df,"u") == 0) {
192 strncat(newname,direntp->d_name,4);
193 strncpy(month,direntp->d_name+4,3);
194 } else {
195 strncat(newname,direntp->d_name+5,4);
196 strncpy(month,direntp->d_name+2,3);
197 }
198 month[3]='\0';
199 conv_month(month);
200 strcat(newname,month);
201 if(strcmp(df,"u") == 0) strncat(newname,direntp->d_name+7,2);
202 else strncat(newname,direntp->d_name,2);
203 obtdate(outdir,direntp->d_name,data);
204 obtuser(outdir,direntp->d_name,tuser);
205 obttotal(outdir,direntp->d_name,tbytes,tuser,media);
206 if (sscanf(data,"%d-%d-%d %d:%d:%d %d",&iyear,&imonth,&iday,&ihour,&iminute,&isecond,&idst)==7) {
207 formatdate(data,sizeof(data),iyear,imonth,iday,ihour,iminute,isecond,idst);
208 fprintf(fp_tmp,"%04d%02d%02d%02d%02d%02d;%s;%s;%s;%s;%s;%s\n",iyear,imonth,iday,ihour,iminute,isecond, direntp->d_name, data, tuser, tbytes, media,newname);
209 } else {
210 /*
211 Old code to parse a date stored by sarg before 2.2.6.1 in the sarg-date file of each report directory.
212 */
213 getword_start(&gwarea,data);
214 if (getword_multisep(mon,sizeof(mon),&gwarea,' ')<0) {
215 printf("SARG: Maybe you have a broken week day in your %s%s/sarg-date file.\n",outdir,direntp->d_name);
216 exit(1);
217 }
218 if (getword_multisep(mon,sizeof(mon),&gwarea,' ')<0) {
219 printf("SARG: Maybe you have a broken month in your %s%s/sarg-date file.\n",outdir,direntp->d_name);
220 exit(1);
221 }
222 if (getword_multisep(day,sizeof(day),&gwarea,' ')<0) {
223 printf("SARG: Maybe you have a broken day in your %s%s/sarg-date file.\n",outdir,direntp->d_name);
224 exit(1);
225 }
226 if (getword_multisep(hour,sizeof(hour),&gwarea,' ')<0) {
227 printf("SARG: Maybe you have a broken time in your %s%s/sarg-date file.\n",outdir,direntp->d_name);
228 exit(1);
229 }
230 do {
231 if (getword_multisep(year,sizeof(year),&gwarea,' ')<0) {
232 printf("SARG: Maybe you have a broken year in your %s%s/sarg-date file.\n",outdir,direntp->d_name);
233 exit(1);
234 }
235 } while (year[0] && !isdigit(year[0])); //skip time zone information with spaces until the year is found
236 strcpy(html,hour);
237 if (sscanf(hour,"%d:%d:%d",&ihour,&iminute,&isecond)!=3) {
238 printf("SARG: Maybe you have a broken time in your %s%s/sarg-date file.\n",outdir,direntp->d_name);
239 exit(1);
240 }
241 buildymd(day,mon,year,ftime);
242 fprintf(fp_tmp,"%s%02d%02d%02d;%s;%s;%s;%s;%s;%s\n",ftime, ihour, iminute, isecond, direntp->d_name, data, tuser, tbytes, media,newname);
243 }
244 continue;
245 }
246 }
247
248 if(fp_tmp) fclose(fp_tmp);
249 if(strcmp(IndexTree,"file") == 0) {
250 (void)rewinddir( dirp );
251 (void)closedir( dirp );
252 }
253
254 if(strcmp(IndexTree,"date") == 0) {
255 if(strcmp(IndexSortOrder,"A") == 0) sprintf(warea,"sort -k 1,1 \"%s\" -o \"%s\"", wdir_tmp, wdir_tmp2);
256 else sprintf(warea,"sort -r -k 1,1 \"%s\" -o \"%s\"", wdir_tmp, wdir_tmp2);
257 cstatus=system(warea);
258 if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
259 fprintf(stderr, "SARG: sort command return status %d\n",WEXITSTATUS(cstatus));
260 fprintf(stderr, "SARG: sort command: %s\n",warea);
261 exit(1);
262 }
263 if((fp_tmp=fopen(wdir_tmp2,"r"))==NULL) {
264 fprintf(stderr, "SARG: (index) %s: %s\n",text[45],wdir_tmp2);
265 fprintf(stderr, "SARG: sort command: %s\n",warea);
266 exit(1);
267 }
268 unlink(wdir_tmp);
269 if((fp_ou=fopen(wdir,"w"))==NULL) {
270 fprintf(stderr, "SARG: (index) %s: %s\n",text[45],wdir);
271 exit(1);
272 }
273 write_html_header(fp_ou, ".");
274 fprintf(fp_ou,"<tr><th %s>%s</th><th %s>%s</th></tr>\n",hbc1,text[130],hbc1,text[132]);
275 while(fgets(wwork1,sizeof(wwork1),fp_tmp)!=NULL) {
276 getword_start(&gwarea,wwork1);
277 if (getword(tmp4,sizeof(tmp4),&gwarea,'\t')<0) {
278 printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wdir_tmp2);
279 exit(1);
280 }
281 fprintf(fp_ou,"<tr><td class=\"data2\"><a href=\"%s\">%s</a></td><td class=\"data2\">%s</td></tr>\n",tmp4,tmp4,gwarea.current);
282 sprintf(tmp2,"%s%s",outdir,tmp4);
283 sprintf(tmp3,"%s%s/index.unsort",outdir,tmp4);
284 // Year dir
285 if((fp_ou2=fopen(tmp3,"w"))==NULL) {
286 fprintf(stderr, "SARG: (index) %s: %s\n",text[45],tmp3);
287 exit(1);
288 }
289 dirp2 = opendir(tmp2);
290 while ((direntp2 = readdir( dirp2 )) != NULL) {
291 if(!isdigit(direntp2->d_name[0]) && !isdigit(direntp2->d_name[1])) continue;
292 fprintf(fp_ou2,"%s\n",direntp2->d_name);
293 }
294 if(fp_ou2) fclose(fp_ou2);
295 (void)rewinddir(dirp2);
296 (void)closedir(dirp2);
297 sprintf(wdir_tmp3,"%s%s/index.sort",outdir,tmp4);
298 if(strcmp(IndexSortOrder,"A") == 0) sprintf(csort,"sort -n \"%s\" -o \"%s\"", tmp3, wdir_tmp3);
299 else sprintf(csort,"sort -n -r \"%s\" -o \"%s\"", tmp3, wdir_tmp3);
300 cstatus=system(csort);
301 if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
302 fprintf(stderr, "SARG: sort command return status %d\n",WEXITSTATUS(cstatus));
303 fprintf(stderr, "SARG: sort command: %s\n",csort);
304 exit(1);
305 }
306 unlink(tmp3);
307 if((fp_tmp2=fopen(wdir_tmp3,"r"))==NULL) {
308 fprintf(stderr, "SARG: (index) %s: %s\n",text[45],wdir_tmp3);
309 exit(1);
310 }
311 sprintf(tmp3,"%s%s/index.html",outdir,tmp4);
312 if((fp_ou2=fopen(tmp3,"w"))==NULL) {
313 fprintf(stderr, "SARG: (index) %s: %s\n",text[45],wdir);
314 exit(1);
315 }
316 write_html_header(fp_ou2,"..");
317 fprintf(fp_ou2,"<tr><th %s>%s/%s</th></tr>\n",hbc1,text[130],text[131]);
318 while(fgets(wwork1,sizeof(wwork1),fp_tmp2)!=NULL) {
319 fixendofline(wwork1);
320 strcpy(tmp5,wwork1);
321 if((str = strchr(tmp5,'-')) != 0) {
322 *str++ = '\0';
323 strcpy(tmp6,str);
324 name_month(tmp5,sizeof(tmp5));
325 name_month(tmp6,sizeof(tmp6));
326 sprintf(nmonth,"%s-%s",tmp5,tmp6);
327 } else {
328 strcpy(nmonth,tmp5);
329 name_month(nmonth,sizeof(nmonth));
330 }
331 fprintf(fp_ou2,"<tr><td class=\"data2\"><a href=\"%s\">%s %s</a></td></tr>\n",wwork1,tmp4,nmonth);
332
333 sprintf(val1,"%s%s/%s",outdir,tmp4,wwork1);
334 sprintf(tmp5,"%s%s/%s/index.unsort",outdir,tmp4,wwork1);
335 if((fp_ou3=fopen(tmp5,"w"))==NULL) {
336 fprintf(stderr, "SARG: (index) %s: %s\n",text[45],tmp5);
337 exit(1);
338 }
339 // month dir
340 dirp3 = opendir(val1);
341 while ((direntp3 = readdir( dirp3 )) != NULL) {
342 if(!isdigit(direntp3->d_name[0]) && !isdigit(direntp3->d_name[1])) continue;
343 fprintf(fp_ou3,"%s\n",direntp3->d_name);
344 }
345 if(fp_ou3) fclose(fp_ou3);
346 (void)rewinddir(dirp3);
347 (void)closedir(dirp3);
348 unlink(wdir_tmp3);
349 sprintf(tmp6,"%s%s/%s/index.sort",outdir,tmp4,wwork1);
350 if(strcmp(IndexSortOrder,"A") == 0) sprintf(csort,"sort -n \"%s\" -o \"%s\"", tmp5, tmp6);
351 else sprintf(csort,"sort -n -r \"%s\" -o \"%s\"", tmp5, tmp6);
352 cstatus=system(csort);
353 if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
354 fprintf(stderr, "SARG: sort command return status %d\n",WEXITSTATUS(cstatus));
355 fprintf(stderr, "SARG: sort command: %s\n",csort);
356 exit(1);
357 }
358 unlink(tmp5);
359 sprintf(val2,"%s%s/%s/index.html",outdir,tmp4,wwork1);
360 sprintf(val3,"%s/%s",tmp4,wwork1);
361 unlink(val2);
362 if((fp_ou3=fopen(val2,"w"))==NULL) {
363 fprintf(stderr, "SARG: (index) %s: %s\n",text[45],val2);
364 exit(1);
365 }
366 if((fp_tmp3=fopen(tmp6,"r"))==NULL) {
367 fprintf(stderr, "SARG: (index) %s: %s\n",text[45],tmp6);
368 exit(1);
369 }
370 write_html_header(fp_ou3,"../..");
371 fprintf(fp_ou3,"<tr><th %s>%s/%s/%s</th></tr>\n",hbc1,text[130],text[131],text[127]);
372 while(fgets(warea,MAXLEN,fp_tmp3)!=NULL) {
373 warea[strlen(warea)-1]='\0';
374 fprintf(fp_ou3,"<tr><td class=\"data2\"><a href=\"%s\">%s %s %s</a></td></tr>\n",warea,tmp4,nmonth,warea);
375 }
376 if(fp_tmp3) fclose(fp_tmp3);
377 write_html_trailer(fp_ou3);
378 if(fp_ou3) fclose(fp_ou3);
379 unlink(tmp6);
380 }
381 write_html_trailer(fp_ou2);
382 if(fp_ou2) fclose(fp_ou2);
383 }
384 (void)rewinddir(dirp);
385 (void)closedir(dirp);
386 if(fp_tmp) fclose(fp_tmp);
387 unlink(tmp6);
388 unlink(wdir_tmp2);
389 } else {
390 if(strcmp(IndexSortOrder,"A") == 0) sprintf(warea,"sort -t\";\" -k 7,7 -k 1,1 \"%s\" -o \"%s\"", wdir_tmp, wdir_tmp2);
391 else sprintf(warea,"sort -r -t\";\" -k 7,7 -k 1,1 \"%s\" -o \"%s\"", wdir_tmp, wdir_tmp2);
392 cstatus=system(warea);
393 if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
394 fprintf(stderr, "SARG: sort command return status %d\n",WEXITSTATUS(cstatus));
395 fprintf(stderr, "SARG: sort command: %s\n",warea);
396 exit(1);
397 }
398 if((fp_tmp2=fopen(wdir_tmp2,"r"))==NULL) {
399 fprintf(stderr, "SARG: (index) %s: %s\n",text[45],wdir_tmp2);
400 fprintf(stderr, "SARG: sort command: %s\n",warea);
401 exit(1);
402 }
403 unlink(wdir_tmp);
404 if((fp_ou=fopen(wdir,"w"))==NULL) {
405 fprintf(stderr, "SARG: (index) %s: %s\n",text[45],wdir);
406 exit(1);
407 }
408 write_html_header(fp_ou,".");
409 fprintf(fp_ou,"<tr><th %s>%s</th><th %s>%s</th><th %s>%s</th><th %s>%s</th><th %s>%s</th></tr>\n",hbc1,text[101],hbc1,text[102],hbc1,text[103],hbc1,text[93],hbc1,text[96]);
410 while(fgets(buf,sizeof(buf),fp_tmp2)!=NULL) {
411 getword_start(&gwarea,buf);
412 if (getword_multisep(period,sizeof(period),&gwarea,';')<0) {
413 printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wdir_tmp2);
414 exit(1);
415 }
416 if (getword_multisep(period,sizeof(period),&gwarea,';')<0) {
417 printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wdir_tmp2);
418 exit(1);
419 }
420 if (getword_multisep(data,sizeof(data),&gwarea,';')<0) {
421 printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wdir_tmp2);
422 exit(1);
423 }
424 if (getword_multisep(tuser,sizeof(tuser),&gwarea,';')<0) {
425 printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wdir_tmp2);
426 exit(1);
427 }
428 if (getword_multisep(tbytes,sizeof(tbytes),&gwarea,';')<0) {
429 printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wdir_tmp2);
430 exit(1);
431 }
432 if (getword_multisep(media,sizeof(media),&gwarea,';')<0) {
433 printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wdir_tmp2);
434 exit(1);
435 }
436 fprintf(fp_ou,"<tr><td class=\"data2\"><a href='%s/%s'>%s</a></td><td class=\"data2\">%s</td><td class=\"data\">%s</td><td class=\"data\">%s</td><td class=\"data\">%s</td></tr>\n",period,ReplaceIndex,period,data,tuser,tbytes,media);
437 }
438 if(fp_tmp2) fclose(fp_tmp2);
439 unlink(wdir_tmp2);
440 }
441
442 write_html_trailer(fp_ou);
443 if(fp_ou) fclose(fp_ou);
444 }