]>
git.ipfire.org Git - thirdparty/sarg.git/blob - index.c
5a50d682640c33eaf4abdc4fdd9ff88ca1e5c39f
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
6 * please look at http://sarg.sourceforge.net/donations.php
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
9 * ---------------------------------------------------------------------
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
27 #include "include/conf.h"
28 #include "include/defs.h"
30 static void make_date_index(void);
31 static void make_file_index(void);
32 static void file_index_to_date_index(const char *entry
);
33 static void date_index_to_file_index(const char *entry
);
38 struct dirent
*direntp
;
41 if(LastLog
> 0) mklastlog(outdir
);
43 if(Index
== INDEX_NO
) {
44 sprintf(wdir
,"%sindex.html",outdir
);
45 if(access(wdir
, R_OK
) == 0) unlink(wdir
);
49 if(debug
) debuga("%s",text
[53]);
51 // convert any old report hierarchy
52 dirp
= opendir(outdir
);
53 while ((direntp
= readdir( dirp
)) != NULL
) {
54 if(isdigit(direntp
->d_name
[0]) && isdigit(direntp
->d_name
[1])) {
55 if(IndexTree
== INDEX_TREE_DATE
)
56 file_index_to_date_index(direntp
->d_name
);
58 date_index_to_file_index(direntp
->d_name
);
63 if(IndexTree
== INDEX_TREE_DATE
) {
70 static void make_date_index(void)
72 FILE *fp_ou
, *fp_ou2
, *fp_ou3
;
73 DIR *dirp
, *dirp2
, *dirp3
;
74 struct dirent
*direntp
;
75 struct dirent
*direntp2
;
76 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
);
102 dirp
= opendir(outdir
);
103 while ((direntp
= readdir( dirp
)) != NULL
) {
104 if(strlen(direntp
->d_name
) > 4 || !isdigit(direntp
->d_name
[0]) || !isdigit(direntp
->d_name
[1]) ||
105 !isdigit(direntp
->d_name
[2]) || !isdigit(direntp
->d_name
[3])) continue;
106 year
=atoi(direntp
->d_name
);
107 if (nyears
>=sizeof(yearsort
)/sizeof(yearsort
[0])) {
109 If too many years are listed in the directory, we ignore the earliest years. The yearsort array
110 is big enough to accomodate the most ambitious use of sarg but this safety is added to prevent
111 a crash should the directory be polluted by other entries.
113 if (year
>yearsort
[0]) {
114 for (i
=1 ; i
<nyears
&& year
>yearsort
[i
] ; i
++)
115 yearsort
[i
-1]=yearsort
[i
];
119 for (i
=nyears
; i
>0 && year
<yearsort
[i
-1] ; i
--) {
120 yearsort
[i
]=yearsort
[i
-1];
126 (void)closedir( dirp
);
128 order
=(strcmp(IndexSortOrder
,"A") == 0) ? 1 : -1;
130 if((fp_ou
=fopen(yearindex
,"w"))==NULL
) {
131 fprintf(stderr
, "SARG: (index) %s: %s - %s\n",text
[45],yearindex
,strerror(errno
));
134 write_html_header(fp_ou
, ".");
135 fprintf(fp_ou
,"<tr><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th></tr>\n",text
[130],text
[132]);
136 for (y
=0 ; y
<nyears
; y
++) {
140 year
=yearsort
[nyears
-1-y
];
141 sprintf(yearnum
,"%04d",year
);
142 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
));
143 sprintf(yeardir
,"%s%s",outdir
,yearnum
);
146 dirp2
= opendir(yeardir
);
147 while ((direntp2
= readdir( dirp2
)) != NULL
) {
148 if(!isdigit(direntp2
->d_name
[0]) || !isdigit(direntp2
->d_name
[1])) continue;
150 if (sscanf(direntp2
->d_name
,"%d%n",&m1
,&i
)!=1 || m1
<=0 || m1
>12 || i
<0) continue;
151 if (direntp2
->d_name
[i
]=='-') {
152 if (sscanf(direntp2
->d_name
+i
+1,"%d",&m2
)!=1 || m2
<m1
|| m2
>12) continue;
153 } else if (direntp2
->d_name
[i
]!='\0') {
158 if (nmonths
>=sizeof(monthsort
)/sizeof(monthsort
[0])) {
159 fprintf(stderr
,"SARG: Too many month directories in %s\nSupernumerary entries are ignored\n",yeardir
);
163 for (i
=nmonths
; i
>0 && month
<monthsort
[i
-1] ; i
--) {
164 monthsort
[i
]=monthsort
[i
-1];
169 (void)closedir(dirp2
);
170 sprintf(monthindex
,"%s/index.html",yeardir
);
171 if((fp_ou2
=fopen(monthindex
,"w"))==NULL
) {
172 fprintf(stderr
, "SARG: (index) %s: %s - %s\n",text
[45],monthindex
,strerror(errno
));
175 write_html_header(fp_ou2
,"..");
176 fprintf(fp_ou2
,"<tr><th class=\"header_l\">%s/%s</th></tr>\n",text
[130],text
[131]);
177 for (m
=0 ; m
<nmonths
; m
++) {
181 month
=monthsort
[nmonths
-1-m
];
183 if(month
% 16 != 0) {
185 sprintf(monthnum
,"%02d-%02d",m1
,m2
);
186 sprintf(monthname1
,"%02d",m1
);
187 sprintf(monthname2
,"%02d",m2
);
188 name_month(monthname1
,sizeof(monthname1
));
189 name_month(monthname2
,sizeof(monthname2
));
190 sprintf(nmonth
,"%s-%s",monthname1
,monthname2
);
192 sprintf(nmonth
,"%02d",m1
);
193 sprintf(monthnum
,"%02d",m1
);
194 name_month(nmonth
,sizeof(nmonth
));
196 fprintf(fp_ou2
,"<tr><td class=\"data2\"><a href=\"%s/index.html\">%s %s</a></td></tr>\n",monthnum
,yearnum
,nmonth
);
198 sprintf(monthdir
,"%s/%s",yeardir
,monthnum
);
201 dirp3
= opendir(monthdir
);
202 while ((direntp3
= readdir( dirp3
)) != NULL
) {
203 if(!isdigit(direntp3
->d_name
[0]) && !isdigit(direntp3
->d_name
[1])) continue;
205 if (sscanf(direntp3
->d_name
,"%d%n",&d1
,&i
)!=1 || d1
<=0 || d1
>31 || i
<0) continue;
206 if (direntp3
->d_name
[i
]=='-') {
207 if (sscanf(direntp3
->d_name
+i
+1,"%d",&d2
)!=1 || d2
<d1
|| d2
>31) continue;
208 } else if (direntp3
->d_name
[i
]!='\0') {
213 if (ndays
>=sizeof(daysort
)/sizeof(daysort
[0])) {
214 fprintf(stderr
,"SARG: Too many day directories in %s\nSupernumerary entries are ignored\n",monthdir
);
218 for (i
=ndays
; i
>0 && day
<daysort
[i
-1] ; i
--) {
219 daysort
[i
]=daysort
[i
-1];
224 (void)closedir(dirp3
);
225 sprintf(dayindex
,"%s/index.html",monthdir
);
226 if((fp_ou3
=fopen(dayindex
,"w"))==NULL
) {
227 fprintf(stderr
, "SARG: (index) %s: %s - %s\n",text
[45],dayindex
,strerror(errno
));
230 write_html_header(fp_ou3
,"../..");
231 fprintf(fp_ou3
,"<tr><th class=\"header_l\">%s/%s/%s</th></tr>\n",text
[130],text
[131],text
[127]);
232 for (d
=0 ; d
<ndays
; d
++) {
236 day
=daysort
[ndays
-1-d
];
240 sprintf(daynum
,"%02d-%02d",d1
,d2
);
242 sprintf(daynum
,"%02d",d1
);
244 fprintf(fp_ou3
,"<tr><td class=\"data2\"><a href=\"%s/index.html\">%s %s %s</a></td></tr>\n",daynum
,yearnum
,nmonth
,daynum
);
246 write_html_trailer(fp_ou3
);
249 write_html_trailer(fp_ou2
);
253 write_html_trailer(fp_ou
);
257 static void make_file_index(void)
259 #define MAX_CREATION_DATE 15
260 #define MAX_DIR_NAME 30
263 struct dirent
*direntp
;
271 char day
[6], mon
[8], year
[40], hour
[10];
272 int iyear
, imonth
, iday
, ihour
, iminute
, isecond
, idst
;
278 struct getwordstruct gwarea
;
282 char creationdate
[MAX_CREATION_DATE
];
283 char dirname
[MAX_DIR_NAME
];
285 } **sortlist
, *item
, **tempsort
;
287 sprintf(wdir
,"%sindex.html",outdir
);
289 order
=(strcmp(IndexSortOrder
,"A") == 0) ? 1 : -1;
291 dirp
= opendir(outdir
);
296 while ((direntp
= readdir( dirp
)) != NULL
) {
297 if (strchr(direntp
->d_name
,'-') == 0) continue;
298 if (strlen(direntp
->d_name
)>MAX_DIR_NAME
) continue;
299 item
=malloc(sizeof(*item
));
301 fprintf(stderr
,"SARG: not enough memory to sort the index\n");
304 if(strcmp(df
,"u") == 0) {
305 strncpy(item
->sortname
,direntp
->d_name
,4);
306 strncpy(month
,direntp
->d_name
+4,3);
308 strncpy(item
->sortname
,direntp
->d_name
+5,4);
309 strncpy(month
,direntp
->d_name
+2,3);
311 item
->sortname
[4]='\0';
314 strcat(item
->sortname
,month
);
315 if(strcmp(df
,"u") == 0) strncat(item
->sortname
,direntp
->d_name
+7,2);
316 else strncat(item
->sortname
,direntp
->d_name
,2);
317 obtdate(outdir
,direntp
->d_name
,data
);
318 if (sscanf(data
,"%d-%d-%d %d:%d:%d %d",&iyear
,&imonth
,&iday
,&ihour
,&iminute
,&isecond
,&idst
)==7) {
319 formatdate(data
,sizeof(data
),iyear
,imonth
,iday
,ihour
,iminute
,isecond
,idst
);
320 snprintf(item
->creationdate
,sizeof(item
->creationdate
),"%04d%02d%02d%02d%02d%02d",iyear
,imonth
,iday
,ihour
,iminute
,isecond
);
323 Old code to parse a date stored by sarg before 2.2.6.1 in the sarg-date file of each report directory.
325 getword_start(&gwarea
,data
);
326 if (getword_skip(16,&gwarea
,' ')<0) {
327 printf("SARG: Maybe you have a broken week day in your %s%s/sarg-date file.\n",outdir
,direntp
->d_name
);
330 if (getword_multisep(mon
,sizeof(mon
),&gwarea
,' ')<0) {
331 printf("SARG: Maybe you have a broken month in your %s%s/sarg-date file.\n",outdir
,direntp
->d_name
);
334 if (getword_multisep(day
,sizeof(day
),&gwarea
,' ')<0) {
335 printf("SARG: Maybe you have a broken day in your %s%s/sarg-date file.\n",outdir
,direntp
->d_name
);
338 if (getword_multisep(hour
,sizeof(hour
),&gwarea
,' ')<0) {
339 printf("SARG: Maybe you have a broken time in your %s%s/sarg-date file.\n",outdir
,direntp
->d_name
);
343 if (getword_multisep(year
,sizeof(year
),&gwarea
,' ')<0) {
344 printf("SARG: Maybe you have a broken year in your %s%s/sarg-date file.\n",outdir
,direntp
->d_name
);
347 } while (year
[0] && !isdigit(year
[0])); //skip time zone information with spaces until the year is found
348 if (sscanf(hour
,"%d:%d:%d",&ihour
,&iminute
,&isecond
)!=3) {
349 printf("SARG: Maybe you have a broken time in your %s%s/sarg-date file.\n",outdir
,direntp
->d_name
);
352 buildymd(day
,mon
,year
,ftime
);
353 snprintf(item
->creationdate
,sizeof(item
->creationdate
),"%s%02d%02d%02d",ftime
, ihour
, iminute
, isecond
);
355 strcpy(item
->dirname
,direntp
->d_name
);
356 strncpy(item
->date
,data
,sizeof(item
->date
));
357 if (nsort
+1>nallocated
) {
359 tempsort
=realloc(sortlist
,nallocated
*sizeof(*item
));
361 fprintf(stderr
,"SARG: not enough memory to sort the index\n");
366 for (i
=nsort
; i
>0 ; i
--) {
367 cmp
=strcmp(item
->sortname
,sortlist
[i
-1]->sortname
);
368 if (cmp
==0) cmp
=strcmp(item
->creationdate
,sortlist
[i
-1]->creationdate
);
372 sortlist
[i
]=sortlist
[i
-1];
378 (void)closedir( dirp
);
380 if((fp_ou
=fopen(wdir
,"w"))==NULL
) {
381 fprintf(stderr
, "SARG: (index) %s: %s\n",text
[45],wdir
);
384 write_html_header(fp_ou
,".");
385 fprintf(fp_ou
,"<tr><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th></tr>\n",text
[101],text
[102],text
[103],text
[93],text
[96]);
386 for (i
=0 ; i
<nsort
; i
++) {
390 item
=sortlist
[nsort
-i
-1];
391 obtuser(outdir
,item
->dirname
,tuser
);
392 obttotal(outdir
,item
->dirname
,tbytes
,tuser
,media
);
393 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
);
395 write_html_trailer(fp_ou
);
399 for (i
=0 ; i
<nsort
; i
++)
405 static void file_index_to_date_index(const char *entry
)
412 char olddir
[MAXLEN
], newdir
[MAXLEN
];
414 if(strlen(entry
) < 19) return;
418 memset(m1
,0,sizeof(m1
));
419 memset(m2
,0,sizeof(m2
));
423 if(strcmp(df
,"u") == 0) {
424 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
425 y1
=y1
*10+(entry
[i
++]-'0');
427 for (j
=0 ; j
<sizeof(m1
)-1 && entry
[i
] && isalpha(entry
[i
]) ; j
++)
431 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
432 d1
=d1
*10+(entry
[i
++]-'0');
435 if (entry
[i
++]!='-') return;
437 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
438 y2
=y2
*10+(entry
[i
++]-'0');
440 for (j
=0 ; j
<sizeof(m2
)-1 && entry
[i
] && isalpha(entry
[i
]) ; j
++)
444 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
445 d2
=d2
*10+(entry
[i
++]-'0');
447 } else if(strcmp(df
,"e") == 0) {
448 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
449 d1
=d1
*10+(entry
[i
++]-'0');
451 for (j
=0 ; j
<sizeof(m1
)-1 && entry
[i
] && isalpha(entry
[i
]) ; j
++)
455 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
456 y1
=y1
*10+(entry
[i
++]-'0');
459 if (entry
[i
++]!='-') return;
461 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
462 d2
=d2
*10+(entry
[i
++]-'0');
464 for (j
=0 ; j
<sizeof(m2
)-1 && entry
[i
] && isalpha(entry
[i
]) ; j
++)
468 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
469 y2
=y2
*10+(entry
[i
++]-'0');
476 ndirlen
=sprintf(newdir
,"%s%04d",outdir
,y1
);
477 if(access(newdir
, R_OK
) != 0) mkdir(newdir
,0755);
478 if(strcmp(m1
,m2
) != 0) ndirlen
+=sprintf(newdir
+ndirlen
,"/%s-%s",m1
,m2
);
479 else ndirlen
+=sprintf(newdir
+ndirlen
,"/%s",m1
);
480 if(access(newdir
, R_OK
) != 0) mkdir(newdir
,0755);
482 if(d1
!=d2
) ndirlen
+=sprintf(newdir
+ndirlen
,"/%02d-%02d",d1
,d2
);
483 else ndirlen
+=sprintf(newdir
+ndirlen
,"/%02d",d1
);
485 sprintf(olddir
,"%s%s",outdir
,entry
);
486 if (rename(olddir
,newdir
)) {
487 fprintf(stderr
, "SARG: (index) rename error from \"%s\" to \"%s\" - %s\n",olddir
,newdir
,strerror(errno
));
491 strcpy(newdir
+monthlen
,"/images");
492 if(access(newdir
, R_OK
) != 0) {
494 char linkdir
[MAXLEN
];
496 sprintf(linkdir
,"%simages",outdir
);
497 if (symlink(linkdir
,newdir
)) {
498 fprintf(stderr
, "SARG: failed to create link \"%s\" to \"%s\" - %s\n",linkdir
,newdir
,strerror(errno
));
505 sprintf(cmd
,"ln -s \"%simages\" \"%s/images\"",outdir
,newdir
);
507 if (!WIFEXITED(cstatus
) || WEXITSTATUS(cstatus
)) {
508 fprintf(stderr
, "SARG: command return status %d\n",WEXITSTATUS(cstatus
));
509 fprintf(stderr
, "SARG: command: %s\n",cmd
);
516 static void date_index_to_file_index(const char *entry
)
525 char newdir
[MAXLEN
], olddir
[MAXLEN
];
527 struct dirent
*direntp2
;
528 struct dirent
*direntp3
;
530 if(strlen(entry
) != 4) return;
533 if (sscanf(entry
,"%d%n",&y1
,&next
)!=1 || next
<0 || entry
[next
]) return;
535 val1len
=sprintf(val1
,"%s%s",outdir
,entry
);
536 dirp2
= opendir(val1
);
538 while ((direntp2
= readdir( dirp2
)) != NULL
) {
539 if(!isdigit(direntp2
->d_name
[0]) || !isdigit(direntp2
->d_name
[1])) continue;
541 str
=direntp2
->d_name
;
542 for (j
=0 ; j
<sizeof(m1
) && str
[i
] && isdigit(str
[i
]) ; j
++)
544 if (j
>=sizeof(m1
)) continue;
549 for (j
=0 ; j
<sizeof(m2
) && str
[i
] && isdigit(str
[i
]) ; j
++)
551 if (j
>=sizeof(m2
)) continue;
554 } else if (!str
[i
]) {
560 sprintf(val1
+val1len
,"/%s",direntp2
->d_name
);
561 dirp3
= opendir(val1
);
562 if (!dirp3
) continue;
563 while ((direntp3
= readdir( dirp3
)) != NULL
) {
564 if(!isdigit(direntp3
->d_name
[0]) || !isdigit(direntp3
->d_name
[1])) continue;
566 str
=direntp3
->d_name
;
568 for (j
=0 ; str
[i
] && isdigit(str
[i
]) ; j
++)
569 d1
=d1
*10+(str
[i
++]-'0');
574 for (j
=0 ; str
[i
] && isdigit(str
[i
]) ; j
++)
575 d2
=d2
*10+(str
[i
++]-'0');
577 } else if (!str
[i
]) {
583 if(strcmp(df
,"u") == 0) sprintf(newdir
,"%s%04d%s%02d-%04d%s%02d",outdir
,y1
,m1
,d1
,y1
,m2
,d2
);
584 else if(strcmp(df
,"e") == 0) sprintf(newdir
,"%s%02d%s%04d-%02d%s%04d",outdir
,d1
,m1
,y1
,d2
,m2
,y1
);
586 sprintf(olddir
,"%s%04d/%s/%s",outdir
,y1
,direntp2
->d_name
,direntp3
->d_name
);
587 if(rename(olddir
,newdir
)) {
588 fprintf(stderr
, "SARG: (index) rename error from \"%s\" to \"%s\" - %s\n",olddir
,newdir
,strerror(errno
));
592 (void)closedir( dirp3
);
594 (void)closedir( dirp2
);
597 \bug The links to the images in the reports are broken after moving the directories
598 as the the HTML files are not at the right level for the images any more.