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 FILE *fp_tt
=NULL
;
32 static void maketmp(const char *user
, const char *dirname
, int debug
, int indexonly
);
33 static void maketmp_hour(const char *user
, const char *dirname
, int indexonly
);
34 static void gravatmp_hora(const char *dirname
, const char *user
, const char *data
, const char *hora
, long long int elap
, long long int accbytes
, int indexonly
);
35 static void gravatmpf(const char *oldaccuser
, const char *dirname
, const char *oldurl
, long long int nacc
, long long int nbytes
, const char *oldmsg
, long long int nelap
, int indexonly
, long long int incache
, long long int oucache
);
36 static void gravaporuser(const char *user
, const char *dirname
, const char *url
, const char *ip
, const char *data
, const char *hora
, long long int tam
, long long int elap
, int indexonly
);
37 static void gravager(FILE *fp_gen
, const char *user
, long long int nacc
, const char *url
, long long int nbytes
, const char *ip
, const char *hora
, const char *dia
, long long int nelap
, long long int incache
, long long int oucache
);
38 static void grava_SmartFilter(const char *dirname
, const char *user
, const char *ip
, const char *data
, const char *hora
, const char *url
, const char *smart
);
47 char accdia
[11], acchora
[9], accuser
[MAXLEN
], accip
[MAXLEN
], *accurl
;
48 char oldaccdia
[11], oldacchora
[9], oldaccip
[MAXLEN
];
49 char wdirname
[MAXLEN
], oldaccuser
[MAXLEN
];
51 char olduser
[MAXLEN
], oldmsg
[50], acccode
[MAXLEN
/2 - 1], oldacccode
[MAXLEN
/2 - 1], user
[MAXLEN
];
52 char ipantes
[MAXLEN
], nameantes
[MAXLEN
];
53 char accsmart
[MAXLEN
];
54 char crc2
[MAXLEN
/2 -1];
55 char siteind
[MAX_TRUNCATED_URL
];
58 char oldaccdiatt
[11],oldacchoratt
[9];
59 long long int nbytes
=0;
60 long long int nelap
=0;
62 long long int rtotal
=0;
63 long long int incache
=0;
64 long long int oucache
=0;
65 long long int accbytes
, accelap
;
68 struct dirent
*direntp
;
69 const char logext
[]=".log";
75 struct getwordstruct gwarea
;
76 struct longlinestruct line
;
82 sprintf(dirname
, "%s%s", outdir
, period
);
83 vrfydir(period
, addr
, site
, us
, email
);
86 debugaz("dirname",dirname
);
89 gperiod(dirname
,period
);
91 if(UserAgentLog
[0] != '\0' && email
[0] == '\0') useragent();
93 sprintf(wdirname
,"%s/sarg-general",dirname
);
94 if((fp_gen
=MY_FOPEN(wdirname
,"w"))==NULL
){
95 fprintf(stderr
, "SARG: (report) %s: %s\n",text
[45],wdirname
);
100 strncat(tmp
,"/sarg",5);
104 while ((direntp
= readdir( dirp
)) != NULL
) {
105 dlen
=strlen(direntp
->d_name
)-(sizeof(logext
)-1);
106 if (dlen
<0) continue;
107 if((strcmp(direntp
->d_name
+dlen
,logext
) != 0) ||
108 (strncmp(direntp
->d_name
,"download.log",12) == 0) ||
109 (strncmp(direntp
->d_name
,"denied.log",10) == 0) ||
110 (strncmp(direntp
->d_name
,"authfail.log.unsort",19) == 0))
112 if (snprintf(tmp3
,sizeof(tmp3
),"%s/%s",tmp
,direntp
->d_name
)>=sizeof(tmp3
)) {
113 fprintf(stderr
, "SARG: (report) directory entry too long: %s/%s\n",tmp
,direntp
->d_name
);
116 if((fp_in
=MY_FOPEN(tmp3
,"r"))==NULL
){
117 fprintf(stderr
, "SARG: (report) %s: %s\n",text
[45],tmp
);
122 if (dlen
>=sizeof(user
)) continue;
123 strncpy(user
,direntp
->d_name
,dlen
);
129 strcpy(wdirname
,dirname
);
130 maketmp(user
,tmp
,debug
,indexonly
);
131 maketmp_hour(user
,tmp
,indexonly
);
135 ip2name(u2
,sizeof(u2
));
136 user_find(name
,sizeof(name
), u2
);
138 if(dotinuser
&& strchr(name
,'_')) {
139 subs(name
,sizeof(name
),"_",".");
145 memset(oldaccdiatt
,0,sizeof(oldaccdiatt
));
146 memset(oldacchoratt
,0,sizeof(oldacchoratt
));
148 if (longline_prepare(&line
)<0) {
149 debuga(_("Not enough memory to read the downloaded files"));
153 while((buf
=longline_read(fp_in
,&line
))!=NULL
) {
154 getword_start(&gwarea
,buf
);
155 if (getword(accdia
,sizeof(accdia
),&gwarea
,'\t')<0 || getword(acchora
,sizeof(acchora
),&gwarea
,'\t')<0 ||
156 getword(accuser
,sizeof(accuser
),&gwarea
,'\t')<0 || getword(accip
,sizeof(accip
),&gwarea
,'\t')<0 ||
157 getword_ptr(buf
,&accurl
,&gwarea
,'\t')<0 || getword_atoll(&accbytes
,&gwarea
,'\t')<0 ||
158 getword(acccode
,sizeof(acccode
),&gwarea
,'\t')<0) {
159 debuga(_("Maybe you have a broken record or garbage in your %s file (%d)"),tmp3
,__LINE__
);
162 if(strncmp(acccode
,"TCP_DENIED/407",14) == 0) continue;
163 if (getword_atoll(&accelap
,&gwarea
,'\t')<0 || getword_skip(20000,&gwarea
,'\t')<0) {
164 printf("SARG: Maybe you have a broken elapsed time in your %s file (%d).\n",tmp3
,__LINE__
);
167 if (getword(accsmart
,sizeof(accsmart
),&gwarea
,'"')<0) {
168 printf("SARG: Maybe you have a broken smart info in your %s file (%d).\n",tmp3
,__LINE__
);
172 if(accsmart
[0] != '\0') {
174 strcpy(wdirname
,dirname
);
175 grava_SmartFilter(wdirname
,accuser
,accip
,accdia
,acchora
,accurl
,accsmart
);
179 if(strcmp(accip
,ipantes
) != 0) {
180 strcpy(ipantes
,accip
);
181 ip2name(accip
,sizeof(accip
));
182 strcpy(nameantes
,accip
);
183 } else strcpy(accip
,nameantes
);
186 strcpy(wdirname
,dirname
);
187 gravatmp_hora(wdirname
,accuser
,accdia
,acchora
,accelap
,accbytes
,indexonly
);
190 strcpy(wdirname
,dirname
);
191 gravaporuser(accuser
,wdirname
,accurl
,accip
,accdia
,acchora
,accbytes
,accelap
,indexonly
);
195 url_len
=strlen(accurl
);
196 if (!oldurl
|| url_len
>=ourl_size
) {
198 oldurl
=realloc(oldurl
,ourl_size
);
200 debuga(_("Not enough memory to store the url"));
204 strcpy(oldurl
,accurl
);
205 strcpy(oldacccode
,acccode
);
206 strcpy(oldaccuser
,accuser
);
207 strcpy(oldaccip
,accip
);
208 strcpy(oldaccdia
,accdia
);
209 strcpy(oldacchora
,acchora
);
212 same_url
=(strcmp(oldurl
,accurl
) == 0);
214 if(site
[0] != '\0') {
215 if(strcmp(oldaccuser
,accuser
) != 0){
217 if(strstr(oldacccode
,"DENIED") != 0)
218 sprintf(oldmsg
,"%s",text
[46]);
219 gravatmp(oldaccuser
,oldurl
,nacc
,nbytes
,oldmsg
,nelap
,indexonly
,incache
,oucache
);
220 gravager(fp_gen
,oldaccuser
,nacc
,oldurl
,nbytes
,oldaccip
,oldacchora
,oldaccdia
,nelap
,incache
,oucache
);
228 if(!same_url
|| strcmp(oldaccuser
,accuser
) != 0){
229 if(strstr(oldacccode
,"DENIED") != 0)
230 strcpy(oldmsg
,text
[46]);
233 gravatmp(oldaccuser
,oldurl
,nacc
,nbytes
,oldmsg
,nelap
,indexonly
,incache
,oucache
);
234 gravager(fp_gen
,oldaccuser
,nacc
,oldurl
,nbytes
,oldaccip
,oldacchora
,oldaccdia
,nelap
,incache
,oucache
);
240 if(strcmp(oldaccuser
,accuser
) != 0)
248 if ((ReportType
& REPORT_TYPE_SITE_USER_TIME_DATE
) != 0 &&
249 (!oldurltt
|| strcmp(oldurltt
,accurl
) || strcmp(oldaccdiatt
,accdia
) || strcmp(oldacchoratt
,acchora
))) {
253 url_to_file(accurl
,siteind
,sizeof(siteind
));
254 snprintf(arqtt
,sizeof(arqtt
),"%s/%s",dirname
,accuser
);
255 if(access(arqtt
, R_OK
) != 0)
257 snprintf(arqtt
,sizeof(arqtt
),"%s/%s/tt%s-%s.html",dirname
,accuser
,accuser
,siteind
);
258 if ((fp_tt
= fopen(arqtt
, "w")) == 0) {
259 fprintf(stderr
, "SARG: (report) %s: %s\n",text
[45],arqtt
);
266 sprintf(httplink,"<font size=%s color=%s><href=http://%s>%s", \
267 FontSize,PrivacyStringColor,PrivacyString,PrivacyString);
269 sprintf(httplink,"<font size=%s><a href=\"http://%s\">%s</a>",FontSize,accurl,accurl);
272 write_html_header(fp_tt
,(IndexTree
== INDEX_TREE_DATE
) ? 4 : 2,_("Site access report"));
273 fprintf(fp_tt
,"<tr><td class=\"header_l\">%s: %s</td></tr>\n",text
[89],period
);
274 fprintf(fp_tt
,"<tr><td class=\"header_l\">%s: %s</td></tr>\n",text
[90],name
);
275 fprintf(fp_tt
,"<tr><td class=\"header_l\">%s: %s, %s</td></tr>\n",text
[104],UserSortField
,UserSortOrder
);
276 fprintf(fp_tt
,"<tr><th class=\"header_c\">%s</th></tr>\n",text
[32]);
277 close_html_header(fp_tt
);
279 fputs("<div class=\"report\"><table cellpadding=\"0\" cellspacing=\"2\">\n",fp_tt
);
280 fputs("<tr><td></td><td></td></tr>",fp_tt
);
282 strncpy(tmp4
,text
[110],4);
283 fprintf(fp_tt
,"<tr><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th></tr>\n",text
[91],tmp4
,text
[110]+5);
286 fputs("<tr><td class=\"data\">",fp_tt
);
287 output_html_string(fp_tt
,accurl
,100);
288 fprintf(fp_tt
,"</td><td class=\"data\">%s</td><td class=\"data\">%s</td></tr>\n",accdia
,acchora
);
290 url_len
=strlen(accurl
);
291 if (!oldurltt
|| url_len
>=ourltt_size
) {
292 ourltt_size
=url_len
+1;
293 oldurltt
=realloc(oldurltt
,ourltt_size
);
295 debuga(_("Not enough memory to store the url"));
299 strcpy(oldurltt
,accurl
);
300 strcpy(oldaccdiatt
,accdia
);
301 strcpy(oldacchoratt
,acchora
);
304 strcpy(crc2
,acccode
);
305 str
=strchr(crc2
,'/');
307 if(strstr(crc2
,"MISS") != 0)
309 else incache
+=accbytes
;
311 if(strcmp(accuser
,oldaccuser
) != 0) {
312 strcpy(wdirname
,dirname
);
313 day_totalize(tmp
,oldaccuser
,indexonly
);
314 strcpy(oldaccuser
,accuser
);
317 strcpy(oldacccode
,acccode
);
318 strcpy(oldaccip
,accip
);
320 url_len
=strlen(accurl
);
321 if (url_len
>=ourl_size
) {
323 oldurl
=realloc(oldurl
,ourl_size
);
325 debuga(_("Not enough memory to store the url"));
329 strcpy(oldurl
,accurl
);
331 strcpy(oldaccdia
,accdia
);
332 strcpy(oldacchora
,acchora
);
336 longline_free(&line
);
337 if (oldurltt
) free(oldurltt
);
339 bzero(user
,sizeof(user
));
344 if(strstr(oldacccode
,"DENIED") != 0)
345 strcpy(oldmsg
,text
[46]);
348 strcpy(wdirname
,dirname
);
349 if(oldaccuser
[0] == '\0')
350 strcpy(oldaccuser
,accuser
);
351 gravatmpf(oldaccuser
,wdirname
,oldurl
,nacc
,nbytes
,oldmsg
,nelap
,indexonly
,incache
,oucache
);
352 strcpy(wdirname
,dirname
);
353 gravager(fp_gen
,oldaccuser
,nacc
,oldurl
,nbytes
,oldaccip
,oldacchora
,oldaccdia
,nelap
,incache
,oucache
);
357 day_totalize(tmp
,oldaccuser
,indexonly
);
361 strcpy(wdirname
,dirname
);
362 totalger(wdirname
, debug
, outdir
);
364 if(email
[0] == '\0') {
365 if((ReportType
& REPORT_TYPE_DOWNLOADS
) != 0) download_report();
367 if(DansGuardianConf
[0] != '\0') {
368 strcpy(wdirname
,dirname
);
372 strcpy(wdirname
,dirname
);
375 strcpy(wdirname
,dirname
);
378 if((ReportType
& REPORT_TYPE_TOPSITES
) != 0) topsites();
380 if((ReportType
& REPORT_TYPE_SITES_USERS
) != 0) siteuser();
383 strcpy(wdirname
,dirname
);
386 if(smartfilter
) smartfilter_report();
388 if(DansGuardianConf
[0] != '\0') dansguardian_report();
392 if((ReportType
& REPORT_TYPE_USERS_SITES
) != 0) htmlrel();
396 if(SuccessfulMsg
) fprintf(stderr
, "SARG: %s %s\n",text
[47],dirname
);
398 strcpy(wdirname
,dirname
);
399 geramail(wdirname
, debug
, outdir
, userip
, email
, TempDir
);
401 if((strcmp(email
,"stdout") != 0) && SuccessfulMsg
)
402 fprintf(stderr
, "SARG: %s %s\n",text
[48],email
);
406 strcpy(wdirname
,dirname
);
407 index_only(wdirname
, debug
);
411 2009-10-13(Frederic) This piece of code is never called so it is commented out for good.
412 if(strlen(email) < 0)
419 static void maketmp(const char *user
, const char *dirname
, int debug
, int indexonly
)
424 char wdirname
[MAXLEN
];
426 if(indexonly
) return;
427 if((ReportType
& REPORT_TYPE_USERS_SITES
) == 0) return;
429 strcpy(wdirname
,tmp
);
430 strcat(wdirname
,"/");
431 strcat(wdirname
,user
);
434 debuga("%s: %s",text
[49],wdirname
);
437 strcat(wdirname
,".utmp");
438 if((fp_ou
=fopen(wdirname
,"w"))==NULL
){
439 fprintf(stderr
, "SARG: (report) %s: %s\n",text
[45],wdirname
);
448 static void maketmp_hour(const char *user
, const char *dirname
, int indexonly
)
453 char wdirname
[MAXLEN
];
455 if(indexonly
) return;
456 if((ReportType
& REPORT_TYPE_USERS_SITES
) == 0) return;
458 strcpy(wdirname
,tmp
);
459 strcat(wdirname
,"/");
460 strcat(wdirname
,user
);
462 strcat(wdirname
,".htmp");
463 if((fp_ou
=fopen(wdirname
,"w"))==NULL
){
464 fprintf(stderr
, "SARG: (report-1) %s: %s - %s\n",text
[45],wdirname
,strerror(errno
));
473 void gravatmp(const char *oldaccuser
, const char *oldurl
, long long int nacc
, long long int nbytes
, const char *oldmsg
, long long int nelap
, int indexonly
, long long int incache
, long long int oucache
)
477 char wdirname
[MAXLEN
];
479 if(indexonly
) return;
480 if((ReportType
& REPORT_TYPE_USERS_SITES
) == 0) return;
482 if (snprintf(wdirname
,sizeof(wdirname
),"%s/%s.utmp",tmp
,oldaccuser
)>=sizeof(wdirname
)) {
483 debuga(_("Path too long %s/%s.utmp"),tmp
,oldaccuser
);
487 if((fp_ou
=MY_FOPEN(wdirname
,"a"))==NULL
){
488 fprintf(stderr
, "SARG: (report) %s: %s\n",text
[45],wdirname
);
492 fprintf(fp_ou
,"%lld\t%lld\t%s\t%s\t%lld\t%lld\t%lld\n",nacc
,nbytes
,oldurl
,oldmsg
,nelap
,incache
,oucache
);
498 fputs("</table>\n</div>\n",fp_tt
);
499 fputs("</body>\n</html>\n",fp_tt
);
509 static void gravatmp_hora(const char *dirname
, const char *user
, const char *data
, const char *hora
, long long int elap
, long long int bytes
, int indexonly
)
513 char wdirname
[MAXLEN
];
515 if(indexonly
|| ((ReportType
& REPORT_TYPE_USERS_SITES
) == 0)) return;
517 if (snprintf(wdirname
,sizeof(wdirname
),"%s/%s.htmp",tmp
,user
)>=sizeof(wdirname
)) {
518 fprintf(stderr
,"SARG: Path too long %s/%s.htmp\n",tmp
,user
);
522 if((fp_ou
=MY_FOPEN(wdirname
,"a"))==NULL
){
523 fprintf(stderr
, "SARG: (report-2) %s: %s - %s\n",text
[45],wdirname
,strerror(errno
));
527 if(strcmp(datetimeby
,"bytes") == 0) fprintf(fp_ou
,"%s\t%s\t%lld\n",data
,hora
,bytes
);
528 else fprintf(fp_ou
,"%s\t%s\t%lld\n",data
,hora
,elap
);
536 static void gravaporuser(const char *user
, const char *dirname
, const char *url
, const char *ip
, const char *data
, const char *hora
, long long int tam
, long long int elap
, int indexonly
)
540 char wdirname
[MAXLEN
];
542 if(indexonly
|| ((ReportType
& REPORT_TYPE_USERS_SITES
) == 0)) return;
544 if (snprintf(wdirname
,sizeof(wdirname
),"%s/%s.ip",tmp
,user
)>=sizeof(wdirname
)) {
545 fprintf(stderr
,"SARG: Path too long %s/%s.ip\n",tmp
,user
);
549 if((fp_ou
=MY_FOPEN(wdirname
,"a"))==NULL
){
550 fprintf(stderr
, "SARG: (report) %s: %s\n",text
[45],wdirname
);
554 fprintf(fp_ou
,"%s\t%s\t%s\t%s\t%lld\t%lld\n",ip
,url
,data
,hora
,tam
,elap
);
563 static void gravatmpf(const char *oldaccuser
, const char *dirname
, const char *oldurl
, long long int nacc
, long long int nbytes
, const char *oldmsg
, long long int nelap
, int indexonly
, long long int incache
, long long int oucache
)
567 char wdirname
[MAXLEN
];
569 if(indexonly
|| ((ReportType
& REPORT_TYPE_USERS_SITES
) == 0)) return;
571 if (snprintf(wdirname
,sizeof(wdirname
),"%s/%s.utmp",tmp
,oldaccuser
)>=sizeof(wdirname
)) {
572 fprintf(stderr
,"SARG: Path too long %s/%s.utmp\n",tmp
,oldaccuser
);
576 if((fp_ou
=MY_FOPEN(wdirname
,"a"))==NULL
){
577 fprintf(stderr
, "SARG: (report) %s: %s\n",text
[45],wdirname
);
581 fprintf(fp_ou
,"%lld\t%lld\t%s\t%s\t%lld\t%lld\t%lld\n",nacc
,nbytes
,oldurl
,oldmsg
,nelap
,incache
,oucache
);
588 fputs("</table>\n",fp_tt
);
589 fputs("</body>\n</html>\n",fp_tt
);
599 static void gravager(FILE *fp_gen
, const char *user
, long long int nacc
, const char *url
, long long int nbytes
, const char *ip
, const char *hora
, const char *dia
, long long int nelap
, long long int incache
, long long int oucache
)
601 fprintf(fp_gen
,"%s\t%lld\t%lld\t%s\t%s\t%s\t%s\t%lld\t%lld\t%lld\n",user
,nacc
,nbytes
,url
,ip
,hora
,dia
,nelap
,incache
,oucache
);
605 static void grava_SmartFilter(const char *dirname
, const char *user
, const char *ip
, const char *data
, const char *hora
, const char *url
, const char *smart
)
609 char wdirname
[MAXLEN
];
611 sprintf(wdirname
,"%s/smartfilter.unsort",dirname
);
613 if((fp_ou
=MY_FOPEN(wdirname
,"a"))==NULL
){
614 fprintf(stderr
, "SARG: (report) %s: %s\n",text
[45],wdirname
);
618 fprintf(fp_ou
,"%s\t%s\t%s\t%s\t%s\t%s\n",user
,data
,hora
,ip
,url
,smart
);
619 fputs("</body>\n</html>\n",fp_tt
);