]>
git.ipfire.org Git - thirdparty/sarg.git/blob - index.c
2 * AUTHOR: Pedro Lineu Orso pedro.orso@gmail.com
4 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
7 * please look at http://sarg.sourceforge.net/donations.php
8 * ---------------------------------------------------------------------
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.
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.
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.
26 #include "include/conf.h"
27 #include "include/defs.h"
29 static void make_date_index(void);
30 static void make_file_index(void);
31 static void file_index_to_date_index(const char *entry
);
32 static void date_index_to_file_index(const char *entry
);
37 struct dirent
*direntp
;
40 if(LastLog
> 0) mklastlog(outdir
);
42 if(strcmp(Index
,"no") == 0) {
43 sprintf(wdir
,"%sindex.html",outdir
);
44 if(access(wdir
, R_OK
) == 0) unlink(wdir
);
48 if(debug
) debuga("%s",text
[53]);
50 // convert any old report hierarchy
51 dirp
= opendir(outdir
);
52 while ((direntp
= readdir( dirp
)) != NULL
) {
53 if(isdigit(direntp
->d_name
[0]) && isdigit(direntp
->d_name
[1])) {
54 if(strcmp(IndexTree
,"date") == 0)
55 file_index_to_date_index(direntp
->d_name
);
57 date_index_to_file_index(direntp
->d_name
);
62 if(strcmp(IndexTree
,"date") == 0) {
69 static void make_date_index(void)
71 FILE *fp_ou
, *fp_ou2
, *fp_ou3
;
72 DIR *dirp
, *dirp2
, *dirp3
;
73 struct dirent
*direntp
;
74 struct dirent
*direntp2
;
75 struct dirent
*direntp3
;
77 char yearindex
[MAXLEN
];
80 char monthindex
[MAXLEN
];
81 char monthdir
[MAXLEN
];
82 char monthname1
[9], monthname2
[9];
85 char dayindex
[MAXLEN
];
99 sprintf(yearindex
,"%sindex.html",outdir
);
100 strcpy(hbc1
,"class=\"header\"");
103 dirp
= opendir(outdir
);
104 while ((direntp
= readdir( dirp
)) != NULL
) {
105 if(strlen(direntp
->d_name
) > 4 || !isdigit(direntp
->d_name
[0]) || !isdigit(direntp
->d_name
[1]) ||
106 !isdigit(direntp
->d_name
[2]) || !isdigit(direntp
->d_name
[3])) continue;
107 year
=atoi(direntp
->d_name
);
108 if (nyears
>=sizeof(yearsort
)/sizeof(yearsort
[0])) {
110 If too many years are listed in the directory, we ignore the earliest years. The yearsort array
111 is big enough to accomodate the most ambitious use of sarg but this safety is added to prevent
112 a crash should the directory be polluted by other entries.
114 if (year
>yearsort
[0]) {
115 for (i
=1 ; i
<nyears
&& year
>yearsort
[i
] ; i
++)
116 yearsort
[i
-1]=yearsort
[i
];
120 for (i
=nyears
; i
>0 && year
<yearsort
[i
-1] ; i
--) {
121 yearsort
[i
]=yearsort
[i
-1];
127 (void)closedir( dirp
);
129 order
=(strcmp(IndexSortOrder
,"A") == 0) ? 1 : -1;
131 if((fp_ou
=fopen(yearindex
,"w"))==NULL
) {
132 fprintf(stderr
, "SARG: (index) %s: %s - %s\n",text
[45],yearindex
,strerror(errno
));
135 write_html_header(fp_ou
, ".");
136 fprintf(fp_ou
,"<tr><th %s>%s</th><th %s>%s</th></tr>\n",hbc1
,text
[130],hbc1
,text
[132]);
137 for (y
=0 ; y
<nyears
; y
++) {
141 year
=yearsort
[nyears
-1-y
];
142 sprintf(yearnum
,"%04d",year
);
143 fprintf(fp_ou
,"<tr><td class=\"data2\"><a href=\"%s/index.html\">%s</a></td><td class=\"data2\">%s</td></tr>\n",yearnum
,yearnum
,get_size(outdir
,yearnum
));
144 sprintf(yeardir
,"%s%s",outdir
,yearnum
);
147 dirp2
= opendir(yeardir
);
148 while ((direntp2
= readdir( dirp2
)) != NULL
) {
149 if(!isdigit(direntp2
->d_name
[0]) || !isdigit(direntp2
->d_name
[1])) continue;
151 if (sscanf(direntp2
->d_name
,"%d%n",&m1
,&i
)!=1 || m1
<=0 || m1
>12 || i
<0) continue;
152 if (direntp2
->d_name
[i
]=='-') {
153 if (sscanf(direntp2
->d_name
+i
+1,"%d",&m2
)!=1 || m2
<m1
|| m2
>12) continue;
154 } else if (direntp2
->d_name
[i
]!='\0') {
159 if (nmonths
>=sizeof(monthsort
)/sizeof(monthsort
[0])) {
160 fprintf(stderr
,"SARG: Too many month directories in %s\nSupernumerary entries are ignored\n",yeardir
);
164 for (i
=nmonths
; i
>0 && month
<monthsort
[i
-1] ; i
--) {
165 monthsort
[i
]=monthsort
[i
-1];
170 (void)closedir(dirp2
);
171 sprintf(monthindex
,"%s/index.html",yeardir
);
172 if((fp_ou2
=fopen(monthindex
,"w"))==NULL
) {
173 fprintf(stderr
, "SARG: (index) %s: %s - %s\n",text
[45],monthindex
,strerror(errno
));
176 write_html_header(fp_ou2
,"..");
177 fprintf(fp_ou2
,"<tr><th %s>%s/%s</th></tr>\n",hbc1
,text
[130],text
[131]);
178 for (m
=0 ; m
<nmonths
; m
++) {
182 month
=monthsort
[nmonths
-1-m
];
184 if(month
% 16 != 0) {
186 sprintf(monthnum
,"%02d-%02d",m1
,m2
);
187 sprintf(monthname1
,"%02d",m1
);
188 sprintf(monthname2
,"%02d",m2
);
189 name_month(monthname1
,sizeof(monthname1
));
190 name_month(monthname2
,sizeof(monthname2
));
191 sprintf(nmonth
,"%s-%s",monthname1
,monthname2
);
193 sprintf(nmonth
,"%02d",m1
);
194 sprintf(monthnum
,"%02d",m1
);
195 name_month(nmonth
,sizeof(nmonth
));
197 fprintf(fp_ou2
,"<tr><td class=\"data2\"><a href=\"%s/index.html\">%s %s</a></td></tr>\n",monthnum
,yearnum
,nmonth
);
199 sprintf(monthdir
,"%s/%s",yeardir
,monthnum
);
202 dirp3
= opendir(monthdir
);
203 while ((direntp3
= readdir( dirp3
)) != NULL
) {
204 if(!isdigit(direntp3
->d_name
[0]) && !isdigit(direntp3
->d_name
[1])) continue;
206 if (sscanf(direntp3
->d_name
,"%d%n",&d1
,&i
)!=1 || d1
<=0 || d1
>31 || i
<0) continue;
207 if (direntp3
->d_name
[i
]=='-') {
208 if (sscanf(direntp3
->d_name
+i
+1,"%d",&d2
)!=1 || d2
<d1
|| d2
>31) continue;
209 } else if (direntp3
->d_name
[i
]!='\0') {
214 if (ndays
>=sizeof(daysort
)/sizeof(daysort
[0])) {
215 fprintf(stderr
,"SARG: Too many day directories in %s\nSupernumerary entries are ignored\n",monthdir
);
219 for (i
=ndays
; i
>0 && day
<daysort
[i
-1] ; i
--) {
220 daysort
[i
]=daysort
[i
-1];
225 (void)closedir(dirp3
);
226 sprintf(dayindex
,"%s/index.html",monthdir
);
227 if((fp_ou3
=fopen(dayindex
,"w"))==NULL
) {
228 fprintf(stderr
, "SARG: (index) %s: %s - %s\n",text
[45],dayindex
,strerror(errno
));
231 write_html_header(fp_ou3
,"../..");
232 fprintf(fp_ou3
,"<tr><th %s>%s/%s/%s</th></tr>\n",hbc1
,text
[130],text
[131],text
[127]);
233 for (d
=0 ; d
<ndays
; d
++) {
237 day
=daysort
[ndays
-1-d
];
241 sprintf(daynum
,"%02d-%02d",d1
,d2
);
243 sprintf(daynum
,"%02d",d1
);
245 fprintf(fp_ou3
,"<tr><td class=\"data2\"><a href=\"%s/index.html\">%s %s %s</a></td></tr>\n",daynum
,yearnum
,nmonth
,daynum
);
247 write_html_trailer(fp_ou3
);
250 write_html_trailer(fp_ou2
);
254 write_html_trailer(fp_ou
);
258 static void make_file_index(void)
260 #define MAX_CREATION_DATE 15
261 #define MAX_DIR_NAME 30
264 struct dirent
*direntp
;
272 char day
[6], mon
[8], year
[40], hour
[10];
273 int iyear
, imonth
, iday
, ihour
, iminute
, isecond
, idst
;
279 struct getwordstruct gwarea
;
283 char creationdate
[MAX_CREATION_DATE
];
284 char dirname
[MAX_DIR_NAME
];
286 } **sortlist
, *item
, **tempsort
;
288 sprintf(wdir
,"%sindex.html",outdir
);
289 strcpy(hbc1
,"class=\"header\"");
291 order
=(strcmp(IndexSortOrder
,"A") == 0) ? 1 : -1;
293 dirp
= opendir(outdir
);
298 while ((direntp
= readdir( dirp
)) != NULL
) {
299 if (strchr(direntp
->d_name
,'-') == 0) continue;
300 if (strlen(direntp
->d_name
)>MAX_DIR_NAME
) continue;
301 item
=malloc(sizeof(*item
));
303 fprintf(stderr
,"SARG: not enough memory to sort the index\n");
306 if(strcmp(df
,"u") == 0) {
307 strncpy(item
->sortname
,direntp
->d_name
,4);
308 strncpy(month
,direntp
->d_name
+4,3);
310 strncpy(item
->sortname
,direntp
->d_name
+5,4);
311 strncpy(month
,direntp
->d_name
+2,3);
313 item
->sortname
[4]='\0';
316 strcat(item
->sortname
,month
);
317 if(strcmp(df
,"u") == 0) strncat(item
->sortname
,direntp
->d_name
+7,2);
318 else strncat(item
->sortname
,direntp
->d_name
,2);
319 obtdate(outdir
,direntp
->d_name
,data
);
320 if (sscanf(data
,"%d-%d-%d %d:%d:%d %d",&iyear
,&imonth
,&iday
,&ihour
,&iminute
,&isecond
,&idst
)==7) {
321 formatdate(data
,sizeof(data
),iyear
,imonth
,iday
,ihour
,iminute
,isecond
,idst
);
322 snprintf(item
->creationdate
,sizeof(item
->creationdate
),"%04d%02d%02d%02d%02d%02d",iyear
,imonth
,iday
,ihour
,iminute
,isecond
);
325 Old code to parse a date stored by sarg before 2.2.6.1 in the sarg-date file of each report directory.
327 getword_start(&gwarea
,data
);
328 if (getword_skip(16,&gwarea
,' ')<0) {
329 printf("SARG: Maybe you have a broken week day in your %s%s/sarg-date file.\n",outdir
,direntp
->d_name
);
332 if (getword_multisep(mon
,sizeof(mon
),&gwarea
,' ')<0) {
333 printf("SARG: Maybe you have a broken month in your %s%s/sarg-date file.\n",outdir
,direntp
->d_name
);
336 if (getword_multisep(day
,sizeof(day
),&gwarea
,' ')<0) {
337 printf("SARG: Maybe you have a broken day in your %s%s/sarg-date file.\n",outdir
,direntp
->d_name
);
340 if (getword_multisep(hour
,sizeof(hour
),&gwarea
,' ')<0) {
341 printf("SARG: Maybe you have a broken time in your %s%s/sarg-date file.\n",outdir
,direntp
->d_name
);
345 if (getword_multisep(year
,sizeof(year
),&gwarea
,' ')<0) {
346 printf("SARG: Maybe you have a broken year in your %s%s/sarg-date file.\n",outdir
,direntp
->d_name
);
349 } while (year
[0] && !isdigit(year
[0])); //skip time zone information with spaces until the year is found
350 if (sscanf(hour
,"%d:%d:%d",&ihour
,&iminute
,&isecond
)!=3) {
351 printf("SARG: Maybe you have a broken time in your %s%s/sarg-date file.\n",outdir
,direntp
->d_name
);
354 buildymd(day
,mon
,year
,ftime
);
355 snprintf(item
->creationdate
,sizeof(item
->creationdate
),"%s%02d%02d%02d",ftime
, ihour
, iminute
, isecond
);
357 strcpy(item
->dirname
,direntp
->d_name
);
358 strncpy(item
->date
,data
,sizeof(item
->date
));
359 if (nsort
+1>nallocated
) {
361 tempsort
=realloc(sortlist
,nallocated
*sizeof(*item
));
363 fprintf(stderr
,"SARG: not enough memory to sort the index\n");
368 for (i
=nsort
; i
>0 ; i
--) {
369 cmp
=strcmp(item
->sortname
,sortlist
[i
-1]->sortname
);
370 if (cmp
==0) cmp
=strcmp(item
->creationdate
,sortlist
[i
-1]->creationdate
);
374 sortlist
[i
]=sortlist
[i
-1];
380 (void)closedir( dirp
);
382 if((fp_ou
=fopen(wdir
,"w"))==NULL
) {
383 fprintf(stderr
, "SARG: (index) %s: %s\n",text
[45],wdir
);
386 write_html_header(fp_ou
,".");
387 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]);
388 for (i
=0 ; i
<nsort
; i
++) {
392 item
=sortlist
[nsort
-i
-1];
393 obtuser(outdir
,item
->dirname
,tuser
);
394 obttotal(outdir
,item
->dirname
,tbytes
,tuser
,media
);
395 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",item
->dirname
,ReplaceIndex
,item
->dirname
,item
->date
,tuser
,tbytes
,media
);
397 write_html_trailer(fp_ou
);
401 for (i
=0 ; i
<nsort
; i
++)
407 static void file_index_to_date_index(const char *entry
)
414 char olddir
[MAXLEN
], newdir
[MAXLEN
];
416 if(strlen(entry
) < 19) return;
420 memset(m1
,0,sizeof(m1
));
421 memset(m2
,0,sizeof(m2
));
425 if(strcmp(df
,"u") == 0) {
426 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
427 y1
=y1
*10+(entry
[i
++]-'0');
429 for (j
=0 ; j
<sizeof(m1
)-1 && entry
[i
] && isalpha(entry
[i
]) ; j
++)
433 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
434 d1
=d1
*10+(entry
[i
++]-'0');
437 if (entry
[i
++]!='-') return;
439 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
440 y2
=y2
*10+(entry
[i
++]-'0');
442 for (j
=0 ; j
<sizeof(m2
)-1 && entry
[i
] && isalpha(entry
[i
]) ; j
++)
446 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
447 d2
=d2
*10+(entry
[i
++]-'0');
449 } else if(strcmp(df
,"e") == 0) {
450 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
451 d1
=d1
*10+(entry
[i
++]-'0');
453 for (j
=0 ; j
<sizeof(m1
)-1 && entry
[i
] && isalpha(entry
[i
]) ; j
++)
457 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
458 y1
=y1
*10+(entry
[i
++]-'0');
461 if (entry
[i
++]!='-') return;
463 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
464 d2
=d2
*10+(entry
[i
++]-'0');
466 for (j
=0 ; j
<sizeof(m2
)-1 && entry
[i
] && isalpha(entry
[i
]) ; j
++)
470 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
471 y2
=y2
*10+(entry
[i
++]-'0');
478 ndirlen
=sprintf(newdir
,"%s%04d",outdir
,y1
);
479 if(access(newdir
, R_OK
) != 0) mkdir(newdir
,0755);
480 if(strcmp(m1
,m2
) != 0) ndirlen
+=sprintf(newdir
+ndirlen
,"/%s-%s",m1
,m2
);
481 else ndirlen
+=sprintf(newdir
+ndirlen
,"/%s",m1
);
482 if(access(newdir
, R_OK
) != 0) mkdir(newdir
,0755);
484 if(d1
!=d2
) ndirlen
+=sprintf(newdir
+ndirlen
,"/%02d-%02d",d1
,d2
);
485 else ndirlen
+=sprintf(newdir
+ndirlen
,"/%02d",d1
);
487 sprintf(olddir
,"%s%s",outdir
,entry
);
488 if (rename(olddir
,newdir
)) {
489 fprintf(stderr
, "SARG: (index) rename error from \"%s\" to \"%s\" - %s\n",olddir
,newdir
,strerror(errno
));
493 strcpy(newdir
+monthlen
,"/images");
494 if(access(newdir
, R_OK
) != 0) {
496 char linkdir
[MAXLEN
];
498 sprintf(linkdir
,"%simages",outdir
);
499 if (symlink(linkdir
,newdir
)) {
500 fprintf(stderr
, "SARG: failed to create link \"%s\" to \"%s\" - %s\n",linkdir
,newdir
,strerror(errno
));
507 sprintf(cmd
,"ln -s \"%simages\" \"%s/images\"",outdir
,newdir
);
509 if (!WIFEXITED(cstatus
) || WEXITSTATUS(cstatus
)) {
510 fprintf(stderr
, "SARG: command return status %d\n",WEXITSTATUS(cstatus
));
511 fprintf(stderr
, "SARG: command: %s\n",cmd
);
518 static void date_index_to_file_index(const char *entry
)
527 char newdir
[MAXLEN
], olddir
[MAXLEN
];
529 struct dirent
*direntp2
;
530 struct dirent
*direntp3
;
532 if(strlen(entry
) != 4) return;
535 if (sscanf(entry
,"%d%n",&y1
,&next
)!=1 || next
<0 || entry
[next
]) return;
537 val1len
=sprintf(val1
,"%s%s",outdir
,entry
);
538 dirp2
= opendir(val1
);
540 while ((direntp2
= readdir( dirp2
)) != NULL
) {
541 if(!isdigit(direntp2
->d_name
[0]) || !isdigit(direntp2
->d_name
[1])) continue;
543 str
=direntp2
->d_name
;
544 for (j
=0 ; j
<sizeof(m1
) && str
[i
] && isdigit(str
[i
]) ; j
++)
546 if (j
>=sizeof(m1
)) continue;
551 for (j
=0 ; j
<sizeof(m2
) && str
[i
] && isdigit(str
[i
]) ; j
++)
553 if (j
>=sizeof(m2
)) continue;
556 } else if (!str
[i
]) {
562 sprintf(val1
+val1len
,"/%s",direntp2
->d_name
);
563 dirp3
= opendir(val1
);
564 if (!dirp3
) continue;
565 while ((direntp3
= readdir( dirp3
)) != NULL
) {
566 if(!isdigit(direntp3
->d_name
[0]) || !isdigit(direntp3
->d_name
[1])) continue;
568 str
=direntp3
->d_name
;
570 for (j
=0 ; str
[i
] && isdigit(str
[i
]) ; j
++)
571 d1
=d1
*10+(str
[i
++]-'0');
576 for (j
=0 ; str
[i
] && isdigit(str
[i
]) ; j
++)
577 d2
=d2
*10+(str
[i
++]-'0');
579 } else if (!str
[i
]) {
585 if(strcmp(df
,"u") == 0) sprintf(newdir
,"%s%04d%s%02d-%04d%s%02d",outdir
,y1
,m1
,d1
,y1
,m2
,d2
);
586 else if(strcmp(df
,"e") == 0) sprintf(newdir
,"%s%02d%s%04d-%02d%s%04d",outdir
,d1
,m1
,y1
,d2
,m2
,y1
);
588 sprintf(olddir
,"%s%04d/%s/%s",outdir
,y1
,direntp2
->d_name
,direntp3
->d_name
);
589 if(rename(olddir
,newdir
)) {
590 fprintf(stderr
, "SARG: (index) rename error from \"%s\" to \"%s\" - %s\n",olddir
,newdir
,strerror(errno
));
594 (void)closedir( dirp3
);
596 (void)closedir( dirp2
);
599 \bug The links to the images in the reports are broken after moving the directories
600 as the the HTML files are not at the right level for the images any more.