]>
git.ipfire.org Git - thirdparty/sarg.git/blob - index.c
ffd57c595a2d7a68d160bd805cf13c7e52954ce5
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] != '\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
);
61 if(strcmp(IndexTree
,"date") == 0) {
68 static void make_date_index(void)
70 FILE *fp_ou
, *fp_ou2
, *fp_ou3
;
71 DIR *dirp
, *dirp2
, *dirp3
;
72 struct dirent
*direntp
;
73 struct dirent
*direntp2
;
74 struct dirent
*direntp3
;
76 char yearindex
[MAXLEN
];
79 char monthindex
[MAXLEN
];
80 char monthdir
[MAXLEN
];
81 char monthname1
[9], monthname2
[9];
84 char dayindex
[MAXLEN
];
98 sprintf(yearindex
,"%sindex.html",outdir
);
99 strcpy(hbc1
,"class=\"header\"");
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 %s>%s</th><th %s>%s</th></tr>\n",hbc1
,text
[130],hbc1
,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 %s>%s/%s</th></tr>\n",hbc1
,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 %s>%s/%s/%s</th></tr>\n",hbc1
,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
);
288 strcpy(hbc1
,"class=\"header\"");
290 order
=(strcmp(IndexSortOrder
,"A") == 0) ? 1 : -1;
292 dirp
= opendir(outdir
);
297 while ((direntp
= readdir( dirp
)) != NULL
) {
298 if (strchr(direntp
->d_name
,'-') == 0) continue;
299 if (strlen(direntp
->d_name
)>MAX_DIR_NAME
) continue;
300 item
=malloc(sizeof(*item
));
302 fprintf(stderr
,"SARG: not enough memory to sort the index\n");
305 if(strcmp(df
,"u") == 0) {
306 strncpy(item
->sortname
,direntp
->d_name
,4);
307 strncpy(month
,direntp
->d_name
+4,3);
309 strncpy(item
->sortname
,direntp
->d_name
+5,4);
310 strncpy(month
,direntp
->d_name
+2,3);
312 item
->sortname
[4]='\0';
315 strcat(item
->sortname
,month
);
316 if(strcmp(df
,"u") == 0) strncat(item
->sortname
,direntp
->d_name
+7,2);
317 else strncat(item
->sortname
,direntp
->d_name
,2);
318 obtdate(outdir
,direntp
->d_name
,data
);
319 if (sscanf(data
,"%d-%d-%d %d:%d:%d %d",&iyear
,&imonth
,&iday
,&ihour
,&iminute
,&isecond
,&idst
)==7) {
320 formatdate(data
,sizeof(data
),iyear
,imonth
,iday
,ihour
,iminute
,isecond
,idst
);
321 snprintf(item
->creationdate
,sizeof(item
->creationdate
),"%04d%02d%02d%02d%02d%02d",iyear
,imonth
,iday
,ihour
,iminute
,isecond
);
324 Old code to parse a date stored by sarg before 2.2.6.1 in the sarg-date file of each report directory.
326 getword_start(&gwarea
,data
);
327 if (getword_skip(16,&gwarea
,' ')<0) {
328 printf("SARG: Maybe you have a broken week day in your %s%s/sarg-date file.\n",outdir
,direntp
->d_name
);
331 if (getword_multisep(mon
,sizeof(mon
),&gwarea
,' ')<0) {
332 printf("SARG: Maybe you have a broken month in your %s%s/sarg-date file.\n",outdir
,direntp
->d_name
);
335 if (getword_multisep(day
,sizeof(day
),&gwarea
,' ')<0) {
336 printf("SARG: Maybe you have a broken day in your %s%s/sarg-date file.\n",outdir
,direntp
->d_name
);
339 if (getword_multisep(hour
,sizeof(hour
),&gwarea
,' ')<0) {
340 printf("SARG: Maybe you have a broken time in your %s%s/sarg-date file.\n",outdir
,direntp
->d_name
);
344 if (getword_multisep(year
,sizeof(year
),&gwarea
,' ')<0) {
345 printf("SARG: Maybe you have a broken year in your %s%s/sarg-date file.\n",outdir
,direntp
->d_name
);
348 } while (year
[0] && !isdigit(year
[0])); //skip time zone information with spaces until the year is found
349 if (sscanf(hour
,"%d:%d:%d",&ihour
,&iminute
,&isecond
)!=3) {
350 printf("SARG: Maybe you have a broken time in your %s%s/sarg-date file.\n",outdir
,direntp
->d_name
);
353 buildymd(day
,mon
,year
,ftime
);
354 snprintf(item
->creationdate
,sizeof(item
->creationdate
),"%s%02d%02d%02d",ftime
, ihour
, iminute
, isecond
);
356 strcpy(item
->dirname
,direntp
->d_name
);
357 strncpy(item
->date
,data
,sizeof(item
->date
));
358 if (nsort
+1>nallocated
) {
360 tempsort
=realloc(sortlist
,nallocated
*sizeof(*item
));
362 fprintf(stderr
,"SARG: not enough memory to sort the index\n");
367 for (i
=nsort
; i
>0 ; i
--) {
368 cmp
=strcmp(item
->sortname
,sortlist
[i
-1]->sortname
);
369 if (cmp
==0) cmp
=strcmp(item
->creationdate
,sortlist
[i
-1]->creationdate
);
373 sortlist
[i
]=sortlist
[i
-1];
379 (void)closedir( dirp
);
381 if((fp_ou
=fopen(wdir
,"w"))==NULL
) {
382 fprintf(stderr
, "SARG: (index) %s: %s\n",text
[45],wdir
);
385 write_html_header(fp_ou
,".");
386 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]);
387 for (i
=0 ; i
<nsort
; i
++) {
391 item
=sortlist
[nsort
-i
-1];
392 obtuser(outdir
,item
->dirname
,tuser
);
393 obttotal(outdir
,item
->dirname
,tbytes
,tuser
,media
);
394 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
);
396 write_html_trailer(fp_ou
);
400 for (i
=0 ; i
<nsort
; i
++)
406 static void file_index_to_date_index(const char *entry
)
413 char olddir
[MAXLEN
], newdir
[MAXLEN
];
415 if(strlen(entry
) < 19) return;
419 memset(m1
,0,sizeof(m1
));
420 memset(m2
,0,sizeof(m2
));
424 if(strcmp(df
,"u") == 0) {
425 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
426 y1
=y1
*10+(entry
[i
++]-'0');
428 for (j
=0 ; j
<sizeof(m1
)-1 && entry
[i
] && isalpha(entry
[i
]) ; j
++)
432 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
433 d1
=d1
*10+(entry
[i
++]-'0');
436 if (entry
[i
++]!='-') return;
438 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
439 y2
=y2
*10+(entry
[i
++]-'0');
441 for (j
=0 ; j
<sizeof(m2
)-1 && entry
[i
] && isalpha(entry
[i
]) ; j
++)
445 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
446 d2
=d2
*10+(entry
[i
++]-'0');
448 } else if(strcmp(df
,"e") == 0) {
449 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
450 d1
=d1
*10+(entry
[i
++]-'0');
452 for (j
=0 ; j
<sizeof(m1
)-1 && entry
[i
] && isalpha(entry
[i
]) ; j
++)
456 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
457 y1
=y1
*10+(entry
[i
++]-'0');
460 if (entry
[i
++]!='-') return;
462 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
463 d2
=d2
*10+(entry
[i
++]-'0');
465 for (j
=0 ; j
<sizeof(m2
)-1 && entry
[i
] && isalpha(entry
[i
]) ; j
++)
469 for (j
=0 ; entry
[i
] && isdigit(entry
[i
]) ; j
++)
470 y2
=y2
*10+(entry
[i
++]-'0');
477 ndirlen
=sprintf(newdir
,"%s%04d",outdir
,y1
);
478 if(access(newdir
, R_OK
) != 0) mkdir(newdir
,0755);
479 if(strcmp(m1
,m2
) != 0) ndirlen
+=sprintf(newdir
+ndirlen
,"/%s-%s",m1
,m2
);
480 else ndirlen
+=sprintf(newdir
+ndirlen
,"/%s",m1
);
481 if(access(newdir
, R_OK
) != 0) mkdir(newdir
,0755);
483 if(d1
!=d2
) ndirlen
+=sprintf(newdir
+ndirlen
,"/%02d-%02d",d1
,d2
);
484 else ndirlen
+=sprintf(newdir
+ndirlen
,"/%02d",d1
);
486 sprintf(olddir
,"%s%s",outdir
,entry
);
487 if (rename(olddir
,newdir
)) {
488 fprintf(stderr
, "SARG: (index) rename error from \"%s\" to \"%s\" - %s\n",olddir
,newdir
,strerror(errno
));
492 strcpy(newdir
+monthlen
,"/images");
493 if(access(newdir
, R_OK
) != 0) {
495 char linkdir
[MAXLEN
];
497 sprintf(linkdir
,"%simages",outdir
);
498 if (symlink(linkdir
,newdir
)) {
499 fprintf(stderr
, "SARG: failed to create link \"%s\" to \"%s\" - %s\n",linkdir
,newdir
,strerror(errno
));
506 sprintf(cmd
,"ln -s \"%simages\" \"%s/images\"",outdir
,newdir
);
508 if (!WIFEXITED(cstatus
) || WEXITSTATUS(cstatus
)) {
509 fprintf(stderr
, "SARG: command return status %d\n",WEXITSTATUS(cstatus
));
510 fprintf(stderr
, "SARG: command: %s\n",cmd
);
517 static void date_index_to_file_index(const char *entry
)
526 char newdir
[MAXLEN
], olddir
[MAXLEN
];
528 struct dirent
*direntp2
;
529 struct dirent
*direntp3
;
531 if(strlen(entry
) != 4) return;
534 if (sscanf(entry
,"%d%n",&y1
,&next
)!=1 || next
<0 || entry
[next
]) return;
536 val1len
=sprintf(val1
,"%s%s",outdir
,entry
);
537 dirp2
= opendir(val1
);
539 while ((direntp2
= readdir( dirp2
)) != NULL
) {
540 if(!isdigit(direntp2
->d_name
[0]) || !isdigit(direntp2
->d_name
[1])) continue;
542 str
=direntp2
->d_name
;
543 for (j
=0 ; j
<sizeof(m1
) && str
[i
] && isdigit(str
[i
]) ; j
++)
545 if (j
>=sizeof(m1
)) continue;
550 for (j
=0 ; j
<sizeof(m2
) && str
[i
] && isdigit(str
[i
]) ; j
++)
552 if (j
>=sizeof(m2
)) continue;
555 } else if (!str
[i
]) {
561 sprintf(val1
+val1len
,"/%s",direntp2
->d_name
);
562 dirp3
= opendir(val1
);
563 if (!dirp3
) continue;
564 while ((direntp3
= readdir( dirp3
)) != NULL
) {
565 if(!isdigit(direntp3
->d_name
[0]) || !isdigit(direntp3
->d_name
[1])) continue;
567 str
=direntp3
->d_name
;
569 for (j
=0 ; str
[i
] && isdigit(str
[i
]) ; j
++)
570 d1
=d1
*10+(str
[i
++]-'0');
575 for (j
=0 ; str
[i
] && isdigit(str
[i
]) ; j
++)
576 d2
=d2
*10+(str
[i
++]-'0');
578 } else if (!str
[i
]) {
584 if(strcmp(df
,"u") == 0) sprintf(newdir
,"%s%04d%s%02d-%04d%s%02d",outdir
,y1
,m1
,d1
,y1
,m2
,d2
);
585 else if(strcmp(df
,"e") == 0) sprintf(newdir
,"%s%02d%s%04d-%02d%s%04d",outdir
,d1
,m1
,y1
,d2
,m2
,y1
);
587 sprintf(olddir
,"%s%04d/%s/%s",outdir
,y1
,direntp2
->d_name
,direntp3
->d_name
);
588 if(rename(olddir
,newdir
)) {
589 fprintf(stderr
, "SARG: (index) rename error from \"%s\" to \"%s\" - %s\n",olddir
,newdir
,strerror(errno
));
593 (void)closedir( dirp3
);
595 (void)closedir( dirp2
);
598 \bug The links to the images in the reports are broken after moving the directories
599 as the the HTML files are not at the right level for the images any more.