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"
34 #define REPORT_EVERY_X_LINES 5000
35 #define MAX_OPEN_USER_FILES 10
39 struct userfilestruct
*next
;
40 struct userinfostruct
*user
;
44 /*@null@*/static char *userfile
=NULL
;
46 numlist weekdays
= { { 0, 1, 2, 3, 4, 5, 6 }, 7 };
47 numlist hours
= { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
48 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }, 24 };
50 static void getusers(const char *pwdfile
, int debug
);
52 int main(int argc
,char *argv
[])
63 ISACOL_Last
//last entry of the list !
71 ILF_Last
//last entry of the list !
74 FILE *fp_in
= NULL
, *fp_denied
=NULL
, *fp_authfail
=NULL
, *fp_log
=NULL
;
76 char sz_Download_Unsort
[ 20000 ] ;
77 FILE * fp_Download_Unsort
= NULL
;
89 char smartfilter
[MAXLEN
];
101 char hexclude
[MAXLEN
];
108 char denied_unsort
[MAXLEN
];
109 char denied_sort
[MAXLEN
];
110 char authfail_unsort
[MAXLEN
];
111 char start_hour
[128];
117 char user
[MAX_USER_LEN
];
118 enum InputLogFormat ilf
;
119 int ilf_count
[ILF_Last
];
131 int isa_ncols
=0,isa_cols
[ISACOL_Last
];
143 long int max_elapsed
=0;
144 long long int iyear
, imonth
, iday
;
149 unsigned long recs1
=0UL;
150 unsigned long recs2
=0UL;
151 int OutputNonZero
= REPORT_EVERY_X_LINES
;
152 bool download_flag
=false;
153 char *download_url
=NULL
;
154 struct getwordstruct gwarea
;
158 struct userinfostruct
*uinfo
;
159 struct userfilestruct
*first_user_file
, *ufile
, *ufile1
, *prev_ufile
;
161 static int convert
=0;
162 static int output_css
=0;
164 static struct option long_options
[]=
166 {"convert",no_argument
,&convert
,1},
167 {"css",no_argument
,&output_css
,1},
168 {"lastlog",required_argument
,NULL
,2},
169 {"keeplogs",no_argument
,NULL
,3},
170 {"split",no_argument
,&split
,1},
175 setlocale(LC_TIME
,"");
178 #if defined(ENABLE_NLS) && defined(HAVE_LOCALE_H)
179 if (!setlocale (LC_ALL
, "")) {
180 fprintf(stderr
,"SARG: Cannot set the locale LC_ALL to the environment variable\n");
183 if (!bindtextdomain (PACKAGE_NAME
, LOCALEDIR
)) {
184 fprintf(stderr
,"SARG: Cannot bind to text domain %s in directory %s (%s)\n",PACKAGE_NAME
,LOCALEDIR
,strerror(errno
));
187 if (!textdomain (PACKAGE_NAME
)) {
188 fprintf(stderr
,"SARG: Cannot set gettext domain for %s PACKAGE_NAME (%s)\n",PACKAGE_NAME
,strerror(errno
));
198 UserAgentLog
[0]='\0';
199 ExcludeHosts
[0]='\0';
200 ExcludeUsers
[0]='\0';
207 ExternalCSSFile
[0]='\0';
208 RedirectorLogFormat
[0]='\0';
210 for (ilf
=0 ; ilf
<ILF_Last
; ilf
++) ilf_count
[ilf
]=0;
212 sprintf(ExcludeCodes
,"%s/exclude_codes",SYSCONFDIR
);
213 strcpy(GraphDaysBytesBarColor
,"orange");
214 strcpy(BgColor
,"#ffffff");
215 strcpy(TxColor
,"#000000");
216 strcpy(TxBgColor
,"lavender");
217 strcpy(TiColor
,"darkblue");
220 strcpy(LogoTextColor
,"#000000");
221 strcpy(HeaderColor
,"darkblue");
222 strcpy(HeaderBgColor
,"#dddddd");
223 strcpy(LogoTextColor
,"#006699");
224 strcpy(FontSize
,"9px");
225 strcpy(TempDir
,"/tmp");
226 strcpy(OutputDir
,"/var/www/html/squid-reports");
228 strcpy(DateFormat
,"u");
229 OverwriteReport
=false;
230 RemoveTempFiles
=true;
231 strcpy(ReplaceIndex
,"index.html");
233 RecordsWithoutUser
=RECORDWITHOUTUSER_IP
;
235 strcpy(MailUtility
,"mailx");
239 TopuserSort
=TOPUSER_SORT_BYTES
| TOPUSER_SORT_REVERSE
;
240 UserSort
=USER_SORT_BYTES
| USER_SORT_REVERSE
;
241 TopsitesSort
=TOPSITE_SORT_CONNECT
| TOPSITE_SORT_REVERSE
;
243 strcpy(FontFace
,"Verdana,Tahoma,Arial");
244 datetimeby
=DATETIME_BYTE
;
245 strcpy(CharSet
,"ISO-8859-1");
247 strcpy(PrivacyString
,"***.***.***.***");
248 strcpy(PrivacyStringColor
,"blue");
250 TopUserFields
=TOPUSERFIELDS_NUM
| TOPUSERFIELDS_DATE_TIME
| TOPUSERFIELDS_USERID
| TOPUSERFIELDS_CONNECT
|
251 TOPUSERFIELDS_BYTES
| TOPUSERFIELDS_SETYB
| TOPUSERFIELDS_IN_CACHE_OUT
|
252 TOPUSERFIELDS_USED_TIME
| TOPUSERFIELDS_MILISEC
| TOPUSERFIELDS_PTIME
|
253 TOPUSERFIELDS_TOTAL
| TOPUSERFIELDS_AVERAGE
;
254 UserReportFields
=USERREPORTFIELDS_CONNECT
| USERREPORTFIELDS_BYTES
| USERREPORTFIELDS_SETYB
|
255 USERREPORTFIELDS_IN_CACHE_OUT
| USERREPORTFIELDS_USED_TIME
| USERREPORTFIELDS_MILISEC
|
256 USERREPORTFIELDS_PTIME
| USERREPORTFIELDS_TOTAL
| USERREPORTFIELDS_AVERAGE
;
257 strcpy(DataFileDelimiter
,";");
258 DataFileFields
=DATA_FIELD_USER
| DATA_FIELD_DATE
| DATA_FIELD_TIME
| DATA_FIELD_URL
| DATA_FIELD_CONNECT
|
259 DATA_FIELD_BYTES
| DATA_FIELD_IN_CACHE
| DATA_FIELD_OUT_CACHE
| DATA_FIELD_ELAPSED
;
260 ShowReadStatistics
=true;
261 strcpy(IndexSortOrder
,"D");
264 strcpy(ParsedOutputLog
,"no");
265 strcpy(ParsedOutputLogCompress
,"/bin/gzip -f");
266 DisplayedValues
=DISPLAY_ABBREV
;
267 strcpy(HeaderFontSize
,"9px");
268 strcpy(TitleFontSize
,"11px");
269 strcpy(AuthUserTemplateFile
,"sarg_htaccess");
270 set_download_suffix("7z,ace,arj,avi,bat,bin,bz2,bzip,cab,com,cpio,dll,doc,dot,exe,gz,iso,lha,lzh,mdb,mov,mp3,mpeg,mpg,mso,nrg,ogg,ppt,rar,rtf,shs,src,sys,tar,tgz,vcd,vob,wma,wmv,zip");
273 strcpy(GraphFont
,FONTDIR
"/DejaVuSans.ttf");
277 strcpy(Ulimit
,"20000");
278 NtlmUserFormat
=NTLMUSERFORMAT_DOMAINUSER
;
279 IndexTree
=INDEX_TREE_FILE
;
280 IndexFields
=INDEXFIELDS_DIRSIZE
;
281 strcpy(RealtimeTypes
,"GET,PUT,CONNECT");
282 RealtimeUnauthRec
=REALTIME_UNAUTH_REC_SHOW
;
283 RedirectorFilterOutDate
=true;
284 DansguardianFilterOutDate
=true;
285 DataFileUrl
=DATAFILEURL_IP
;
286 strcpy(MaxElapsed
,"28800000");
287 BytesInSitesUsersReport
=0;
288 UserAuthentication
=0;
289 strcpy(LDAPHost
,"127.0.0.1");
291 LDAPProtocolVersion
=3;
294 LDAPBaseSearch
[0]='\0';
295 strcpy(LDAPFilterSearch
, "(uid=%s)");
296 strcpy(LDAPTargetAttr
, "cn");
319 UserInvalidChar
[0]='\0';
321 SquidGuardConf
[0]='\0';
322 DansGuardianConf
[0]='\0';
330 dansguardian_count
=0;
333 DeniedReportLimit
=10;
334 AuthfailReportLimit
=10;
335 DansGuardianReportLimit
=10;
336 SquidGuardReportLimit
=10;
337 DownloadReportLimit
=50;
346 realtime_access_log_lines
=1000;
354 bzero(IncludeUsers
, sizeof(IncludeUsers
));
355 bzero(ExcludeString
, sizeof(ExcludeString
));
356 first_user_file
=NULL
;
357 memset(&period
,0,sizeof(period
));
360 for(x
=0; x
<MAXLOGS
; x
++)
361 AccessLog
[x
][0]='\0';
362 AccessLogFromCmdLine
=0;
363 RedirectorLogFromCmdLine
=0;
365 strcpy(Title
,_("Squid User Access Report"));
367 while((ch
= getopt_long_only(argc
, argv
, "a:b:c:d:e:f:g:u:l:L:o:s:t:w:hijmnprvxyz",long_options
,&option_index
)) != -1){
373 lastlog
=atoi(optarg
);
382 strcpy(uagent
,optarg
);
385 strcpy(hexclude
,optarg
);
388 strncpy(date
,optarg
,sizeof(date
)-1);
389 date
[sizeof(date
)-1]='\0';
390 date_from(date
, &dfrom
, &duntil
);
393 strcpy(email
,optarg
);
396 strcpy(ConfigFile
,optarg
);
408 if (NAccessLog
>=MAXLOGS
) {
409 debuga(_("Too many log files passed on command line with option -l.\n"));
412 if (strlen(optarg
)>=MAX_LOG_FILELEN
) {
413 debuga(_("Log file name too long passed on command line with option -l: %s\n"),optarg
);
416 strcpy(AccessLog
[NAccessLog
],optarg
);
418 AccessLogFromCmdLine
++;
421 if (NRedirectorLogs
>MAX_REDIRECTOR_LOGS
) {
422 debuga(_("Too many redirector logs passed on command line with option -L.\n"));
425 if (strlen(optarg
)>=MAX_REDIRECTOR_FILELEN
) {
426 debuga(_("Redirector log file name too long passed on command line with opton -L: %s\n"),optarg
);
429 strcpy(RedirectorLogs
[NRedirectorLogs
],optarg
);
431 RedirectorLogFromCmdLine
++;
440 strcpy(outdir
,optarg
);
455 if(strstr(optarg
,"-") == 0) {
456 if(sscanf(optarg
,"%d:%d",&h1
,&m1
)!=2) {
457 debuga(_("Time period passed on the command line with option -t must be MM:SS\n"));
462 snprintf(hm_str
,sizeof(hm_str
),"%02d:%02d",h1
,m1
);
464 if(sscanf(optarg
,"%d:%d-%d:%d",&h1
,&m1
,&h2
,&m2
)!=4) {
465 debuga(_("Time range passed on the command line with option -t must be MM:SS-MM:SS\n"));
470 snprintf(hm_str
,sizeof(hm_str
),"%02d:%02d-%02d:%02d",h1
,m1
,h2
,m2
);
493 debuga(_("Option -%c require an argument\n"),optopt);
510 for (iarq
=optind
; iarq
<argc
; iarq
++) {
511 if (NAccessLog
>=MAXLOGS
) {
512 debuga(_("Too many log files passed on command line.\n"));
515 if (strlen(argv
[iarq
])>=MAX_LOG_FILELEN
) {
516 debuga(_("Log file name too long passed on command line: %s\n"),argv
[iarq
]);
519 strcpy(AccessLog
[NAccessLog
],argv
[iarq
]);
521 AccessLogFromCmdLine
++;
525 if(debug
) debuga(_("Init\n"));
527 if(ConfigFile
[0] == '\0') snprintf(ConfigFile
,sizeof(ConfigFile
),"%s/sarg.conf",SYSCONFDIR
);
528 if(access(ConfigFile
, R_OK
) != 0) {
529 debuga(_("Cannot open config file: %s - %s\n"),ConfigFile
,strerror(errno
));
533 if(access(ConfigFile
, R_OK
) == 0)
536 if(userip
) UserIp
=true;
538 if(dns
) Ip2Name
=true;
540 if (lastlog
>=0) LastLog
=lastlog
;
547 if(IndexTree
== INDEX_TREE_FILE
)
548 strcpy(ImageFile
,"../images");
550 strcpy(ImageFile
,"../../../images");
553 if(DataFile
[0] != '\0')
556 if(NAccessLog
== 0) {
557 strcpy(AccessLog
[0],"/var/log/squid/access.log");
566 for (iarq
=0 ; iarq
<NAccessLog
; iarq
++)
567 splitlog(AccessLog
[iarq
], df
, dfrom
, duntil
, convert
);
571 for (iarq
=0 ; iarq
<NAccessLog
; iarq
++)
572 convlog(AccessLog
[iarq
], df
, dfrom
, duntil
);
576 load_excludecodes(ExcludeCodes
);
578 if(access(PasswdFile
, R_OK
) == 0) {
579 getusers(PasswdFile
,debug
);
583 if(hexclude
[0] == '\0')
584 strcpy(hexclude
,ExcludeHosts
);
585 if(hexclude
[0] != '\0') {
586 gethexclude(hexclude
,debug
);
590 if(ReportType
== 0) {
591 ReportType
=REPORT_TYPE_TOPUSERS
| REPORT_TYPE_TOPSITES
| REPORT_TYPE_USERS_SITES
|
592 REPORT_TYPE_SITES_USERS
| REPORT_TYPE_DATE_TIME
| REPORT_TYPE_DENIED
|
593 REPORT_TYPE_AUTH_FAILURES
| REPORT_TYPE_SITE_USER_TIME_DATE
| REPORT_TYPE_DOWNLOADS
;
596 if(access(ExcludeUsers
, R_OK
) == 0) {
597 getuexclude(ExcludeUsers
,debug
);
606 if(strcmp(ExcludeUsers
,"indexonly") == 0) indexonly
++;
607 if(Index
== INDEX_ONLY
) indexonly
++;
609 if(MaxElapsed
[0] != '\0') max_elapsed
=atol(MaxElapsed
);
611 if(outdir
[0] == '\0') strcpy(outdir
,OutputDir
);
614 if(uagent
[0] == '\0') strcpy(uagent
,UserAgentLog
);
616 if(tmp
[0] == '\0') strcpy(tmp
,TempDir
);
617 else strcpy(TempDir
,tmp
);
619 For historical reasons, the temporary directory is the subdirectory "sarg" of the path
620 provided by the user.
624 if (tmp
[0]!='\0' && strncmp(outdir
,tmp
,strlen(tmp
))==0) {
625 debuga(_("The output directory \"%s\" must be outside of the temporary directory \"%s\"\n"),outdir
,tmp
);
629 if(df
[0] == '\0') strcpy(df
,DateFormat
);
630 else strcpy(DateFormat
,df
);
634 strcpy(DateFormat
,"u");
637 IndexTree
=INDEX_TREE_FILE
;
639 if(email
[0] == '\0' && OutputEmail
[0] != '\0') strcpy(email
,OutputEmail
);
641 if(email
[0] != '\0') {
647 if(access(tmp
, R_OK
) == 0) {
651 snprintf(denied_unsort
,sizeof(denied_unsort
),"%s/denied.log.unsort",tmp
);
652 snprintf(denied_sort
,sizeof(denied_sort
),"%s/denied.log",tmp
);
653 snprintf(authfail_unsort
,sizeof(authfail_unsort
),"%s/authfail.log.unsort",tmp
);
656 debuga(_("Parameters:\n"));
657 debuga(_(" Hostname or IP address (-a) = %s\n"),addr
);
658 debuga(_(" Useragent log (-b) = %s\n"),uagent
);
659 debuga(_(" Exclude file (-c) = %s\n"),hexclude
);
660 debuga(_(" Date from-until (-d) = %s\n"),date
);
661 debuga(_(" Email address to send reports (-e) = %s\n"),email
);
662 debuga(_(" Config file (-f) = %s\n"),ConfigFile
);
663 if(strcmp(df
,"e") == 0)
664 debuga(_(" Date format (-g) = Europe (dd/mm/yyyy)\n"));
665 if(strcmp(df
,"u") == 0)
666 debuga(_(" Date format (-g) = USA (mm/dd/yyyy)\n"));
667 if(strcmp(df
,"w") == 0)
668 debuga(_(" Date format (-g) = Sites & Users (yyyy/ww)\n"));
669 debuga(_(" IP report (-i) = %s\n"),(iprel
) ? _("Yes") : _("No"));
670 for (iarq
=0 ; iarq
<NAccessLog
; iarq
++)
671 debuga(_(" Input log (-l) = %s\n"),AccessLog
[iarq
]);
672 for (iarq
=0 ; iarq
<NRedirectorLogs
; iarq
++)
673 debuga(_(" Redirector log (-L) = %s\n"),RedirectorLogs
[iarq
]);
674 debuga(_(" Resolve IP Address (-n) = %s\n"),(Ip2Name
) ? _("Yes") : _("No"));
675 debuga(_(" Output dir (-o) = %s\n"),outdir
);
676 debuga(_("Use Ip Address instead of userid (-p) = %s\n"),(UserIp
) ? _("Yes") : _("No"));
677 debuga(_(" Accessed site (-s) = %s\n"),site
);
678 debuga(_(" Time (-t) = %s\n"),hm_str
);
679 debuga(_(" User (-u) = %s\n"),us
);
680 debuga(_(" Temporary dir (-w) = %s\n"),tmp
);
681 debuga(_(" Debug messages (-x) = %s\n"),(debug
) ? _("Yes") : _("No"));
682 debuga(_(" Process messages (-z) = %s\n"),(debugz
) ? _("Yes") : _("No"));
683 debuga(_(" Previous reports to keep (--lastlog) = %d\n"),LastLog
);
688 printf(_("Parameters:\n"));
689 printf(_(" Hostname or IP address (-a) = %s\n"),addr
);
690 printf(_(" Useragent log (-b) = %s\n"),uagent
);
691 printf(_(" Exclude file (-c) = %s\n"),hexclude
);
692 printf(_(" Date from-until (-d) = %s\n"),date
);
693 printf(_(" Email address to send reports (-e) = %s\n"),email
);
694 printf(_(" Config file (-f) = %s\n"),ConfigFile
);
695 if(strcmp(df
,"e") == 0)
696 printf(_(" Date format (-g) = Europe (dd/mm/yyyy)\n"));
697 if(strcmp(df
,"u") == 0)
698 printf(_(" Date format (-g) = USA (mm/dd/yyyy)\n"));
699 if(strcmp(df
,"w") == 0)
700 printf(_(" Date format (-g) = Sites & Users (yyyy/ww)\n"));
701 printf(_(" IP report (-i) = %s\n"),(iprel
) ? _("Yes") : _("No"));
702 for (iarq
=0 ; iarq
<NAccessLog
; iarq
++)
703 printf(_(" Input log (-l) = %s\n"),AccessLog
[iarq
]);
704 for (iarq
=0 ; iarq
<NRedirectorLogs
; iarq
++)
705 printf(_(" Redirector log (-L) = %s\n"),RedirectorLogs
[iarq
]);
706 printf(_(" Resolve IP Address (-n) = %s\n"),(Ip2Name
) ? _("Yes") : _("No"));
707 printf(_(" Output dir (-o) = %s\n"),outdir
);
708 printf(_("Use Ip Address instead of userid (-p) = %s\n"),(UserIp
) ? _("Yes") : _("No"));
709 printf(_(" Accessed site (-s) = %s\n"),site
);
710 printf(_(" Time (-t) = %s\n"),hm_str
);
711 printf(_(" User (-u) = %s\n"),us
);
712 printf(_(" Temporary dir (-w) = %s\n"),tmp
);
713 printf(_(" Debug messages (-x) = %s\n"),(debug
) ? _("Yes") : _("No"));
714 printf(_(" Process messages (-z) = %s\n"),(debugz
) ? _("Yes") : _("No"));
715 printf(_(" Previous reports to keep (--lastlog) = %d\n"),LastLog
);
716 printf(_("sarg version: %s\n"),VERSION
);
720 debuga(_("sarg version: %s\n"),VERSION
);
722 #ifdef ENABLE_DOUBLE_CHECK_DATA
723 debuga(_("Sarg compiled to report warnings if the output is inconsistent\n"));
726 maxopenfiles
=MAX_OPEN_USER_FILES
;
728 if (Ulimit
[0] != '\0') {
733 #if defined(RLIMIT_NOFILE)
734 getrlimit (RLIMIT_NOFILE
, &rl
);
735 #elif defined(RLIMIT_OFILE)
736 getrlimit (RLIMIT_OFILE
, &rl
);
738 #warning "No rlimit resource for the number of open files"
743 rl
.rlim_cur
= atol(Ulimit
);
744 rl
.rlim_max
= atol(Ulimit
);
745 #if defined(RLIMIT_NOFILE)
746 rc
=setrlimit (RLIMIT_NOFILE
, &rl
);
747 #elif defined(RLIMIT_OFILE)
748 rc
=setrlimit (RLIMIT_OFILE
, &rl
);
750 #warning "No rlimit resource for the number of open files"
753 debuga(_("setrlimit error - %s\n"),strerror(errno
));
757 debuga("Maximum file descriptor: cur=%ld max=%ld, changed to cur="RLIM_STRING
" max="RLIM_STRING
,l1
,l2
,rl
.rlim_cur
,rl
.rlim_max
);
761 init_usertab(UserTabFile
);
763 if ((line
=longline_create())==NULL
) {
764 debuga(_("Not enough memory to read a log file\n"));
768 snprintf(sz_Download_Unsort
,sizeof(sz_Download_Unsort
),"%s/download.unsort", tmp
);
770 if(DataFile
[0]=='\0') {
771 if((ReportType
& REPORT_TYPE_DENIED
) != 0) {
772 if((fp_denied
=MY_FOPEN(denied_unsort
,"w"))==NULL
) {
773 debuga(_("(log) Cannot open file: %s - %s\n"),denied_unsort
,strerror(errno
));
778 if((ReportType
& REPORT_TYPE_DENIED
) != 0 || (ReportType
& REPORT_TYPE_AUTH_FAILURES
) != 0) {
779 if((fp_authfail
=MY_FOPEN(authfail_unsort
,"w"))==NULL
) {
780 debuga(_("(log) Cannot open file: %s - %s\n"),authfail_unsort
,strerror(errno
));
786 for (iarq
=0 ; iarq
<NAccessLog
; iarq
++) {
787 strcpy(arq
,AccessLog
[iarq
]);
791 if(strcmp(arq
,"-")==0) {
793 debuga(_("Reading access log file: from stdin\n"));
798 if (stat(arq
,&logstat
)!=0) {
799 debuga(_("Cannot get the modification time of input log file %s (%s). Processing it anyway\n"),arq
,strerror(errno
));
801 struct tm
*logtime
=localtime(&logstat
.st_mtime
);
802 if ((logtime
->tm_year
+1900)*10000+(logtime
->tm_mon
+1)*100+logtime
->tm_mday
<dfrom
) {
803 debuga(_("Ignoring old log file %s\n"),arq
);
808 fp_in
=decomp(arq
,&from_pipe
);
810 debuga(_("(log) Cannot open log file: %s - %s\n"),arq
,strerror(errno
));
813 if(debug
) debuga(_("Reading access log file: %s\n"),arq
);
818 // pre-read the file only if we have to show stats
819 if(ShowReadStatistics
&& !from_stdin
&& !from_pipe
) {
827 while ((nread
=fread(tmp4
,1,sizeof(tmp4
),fp_in
))>0) {
828 for (i
=0 ; i
<nread
; i
++)
830 if (tmp4
[i
]!='\n' && tmp4
[i
]!='\r') {
834 if (tmp4
[i
]=='\n' || tmp4
[i
]=='\r') {
841 printf(_("SARG: Records in file: %lu, reading: %3.2f%%"),recs1
,(float) 0);
846 longline_reset(line
);
848 while ((linebuf
=longline_read(fp_in
,line
))!=NULL
) {
849 blen
=strlen(linebuf
);
851 if (ilf
==ILF_Unknown
) {
852 if(strncmp(linebuf
,"#Software: Mic",14) == 0) {
853 fixendofline(linebuf
);
855 debuga(_("Log is from Microsoft ISA: %s\n"),linebuf
);
861 if(strncmp(linebuf
,"*** SARG Log ***",16) == 0) {
862 if (getperiod_fromsarglog(arqtt
,&period
)<0) {
863 debuga(_("The name of the file is invalid: %s\n"),arq
);
872 if(!fp_log
&& strcmp(ParsedOutputLog
, "no") != 0 && ilf
!=ILF_Sarg
) {
873 if(access(ParsedOutputLog
,R_OK
) != 0) {
874 my_mkdir(ParsedOutputLog
);
876 sprintf(arq_log
,"%s/sarg_temp.log",ParsedOutputLog
);
877 if((fp_log
=MY_FOPEN(arq_log
,"w"))==NULL
) {
878 debuga(_("(log) Cannot open log file: %s - %s\n"),arq_log
,strerror(errno
));
881 fputs("*** SARG Log ***\n",fp_log
);
885 if( ShowReadStatistics
&& !from_stdin
&& !from_pipe
&& --OutputNonZero
<=0) {
886 double perc
= recs2
* 100. / recs1
;
887 printf(_("SARG: Records in file: %lu, reading: %3.2lf%%"),recs2
,perc
);
890 OutputNonZero
= REPORT_EVERY_X_LINES
;
892 if(blen
< 58) continue;
893 if(strstr(linebuf
,"HTTP/0.0") != 0) continue;
894 if(strstr(linebuf
,"logfile turned over") != 0) continue;
895 if(linebuf
[0] == ' ') continue;
898 if(ExcludeString
[0] != '\0') {
900 getword_start(&gwarea
,ExcludeString
);
901 while(strchr(gwarea
.current
,':') != 0) {
902 if (getword_multisep(val1
,sizeof(val1
),&gwarea
,':')<0) {
903 debuga(_("Maybe you have a broken record or garbage in your exclusion string\n"));
906 if((str
=(char *) strstr(linebuf
,val1
)) != (char *) NULL
) {
911 if(!exstring
&& (str
=(char *) strstr(linebuf
,gwarea
.current
)) != (char *) NULL
)
913 if(exstring
) continue;
918 printf("BUF=%s\n",linebuf
);
921 if (ilf
==ILF_Squid
|| ilf
==ILF_Common
|| ilf
==ILF_Unknown
) {
922 getword_start(&gwarea
,linebuf
);
923 if (getword(data
,sizeof(data
),&gwarea
,' ')<0) {
924 debuga(_("Maybe you have a broken time in your access.log file\n"));
927 if((str
=(char *) strchr(data
, '.')) != (char *) NULL
&& (str
=(char *) strchr(str
+1, '.')) != (char *) NULL
) {
931 if (getword(user
,sizeof(user
),&gwarea
,' ')<0 || getword_skip(255,&gwarea
,' ')<0) {
932 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
936 if (getword_skip(255,&gwarea
,' ')<0 || getword(user
,sizeof(user
),&gwarea
,' ')<0) {
937 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
941 if (getword(data
,sizeof(data
),&gwarea
,']')<0 || getword_skip(MAXLEN
,&gwarea
,'"')<0 ||
942 getword(fun
,sizeof(fun
),&gwarea
,' ')<0) {
943 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
946 if (getword_ptr(linebuf
,&url
,&gwarea
,' ')<0) {
947 debuga(_("Maybe you have a broken url in your %s file\n"),arq
);
950 if (getword_skip(MAXLEN
,&gwarea
,' ')<0) {
951 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
954 if (getword(code2
,sizeof(code2
),&gwarea
,' ')<0) {
955 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
958 if (getword(tam
,sizeof(tam
),&gwarea
,' ')<0) {
959 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
962 if((str
=(char *) strchr(gwarea
.current
, ' ')) != (char *) NULL
) {
963 if (getword(code
,sizeof(code
),&gwarea
,' ')<0) {
964 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
968 if (getword(code
,sizeof(code
),&gwarea
,'\0')<0) {
969 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
974 if ((str
= strchr(code
, ':')) != NULL
)
977 if(strcmp(tam
,"\0") == 0)
983 getword_start(&gwarea
,data
+1);
984 if (getword_multisep(data
,sizeof(data
),&gwarea
,':')<0){
985 debuga(_("Maybe you have a broken date in your %s file\n"),arq
);
988 if (getword_multisep(hora
,sizeof(hora
),&gwarea
,' ')<0){
989 debuga(_("Maybe you have a broken date in your %s file\n"),arq
);
992 getword_start(&gwarea
,data
);
993 if (getword_atoll(&iday
,&gwarea
,'/')<0){
994 debuga(_("Maybe you have a broken date in your %s file\n"),arq
);
997 if (getword(mes
,sizeof(mes
),&gwarea
,'/')<0){
998 debuga(_("Maybe you have a broken date in your %s file\n"),arq
);
1001 if (getword_atoll(&iyear
,&gwarea
,'/')<0){
1002 debuga(_("Maybe you have a broken date in your %s file\n"),arq
);
1006 imonth
=month2num(mes
)+1;
1007 idata
=builddia(iday
,imonth
,iyear
);
1008 computedate(iyear
,imonth
,iday
,&tt
);
1012 if(ilf
==ILF_Unknown
|| ilf
==ILF_Squid
) {
1013 if (getword(elap
,sizeof(elap
),&gwarea
,' ')<0) {
1014 debuga(_("Maybe you have a broken elapsed time in your %s file\n"),arq
);
1017 while(strcmp(elap
,"") == 0 && gwarea
.current
[0] != '\0')
1018 if (getword(elap
,sizeof(elap
),&gwarea
,' ')<0) {
1019 debuga(_("Maybe you have a broken elapsed time in your %s file\n"),arq
);
1022 if(strlen(elap
) < 1) continue;
1023 if (getword(ip
,sizeof(ip
),&gwarea
,' ')<0){
1024 debuga(_("Maybe you have a broken client IP address in your %s file\n"),arq
);
1027 if (getword(code
,sizeof(code
),&gwarea
,' ')<0){
1028 debuga(_("Maybe you have a broken result code in your %s file\n"),arq
);
1031 if (getword(tam
,sizeof(tam
),&gwarea
,' ')<0){
1032 debuga(_("Maybe you have a broken amount of data in your %s file\n"),arq
);
1035 if (getword(fun
,sizeof(fun
),&gwarea
,' ')<0){
1036 debuga(_("Maybe you have a broken request method in your %s file\n"),arq
);
1039 if (getword_ptr(linebuf
,&url
,&gwarea
,' ')<0){
1040 debuga(_("Maybe you have a broken url in your %s file\n"),arq
);
1043 if (getword(user
,sizeof(user
),&gwarea
,' ')<0){
1044 debuga(_("Maybe you have a broken user ID in your %s file\n"),arq
);
1053 debuga(_("Cannot convert the timestamp from the squid log file\n"));
1057 strftime(tbuf2
, sizeof(tbuf2
), "%H%M", t
);
1059 idata
=(t
->tm_year
+1900)*10000+(t
->tm_mon
+1)*100+t
->tm_mday
;
1062 if (ilf
==ILF_Sarg
) {
1063 getword_start(&gwarea
,linebuf
);
1064 if (getword(data
,sizeof(data
),&gwarea
,'\t')<0){
1065 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1068 if (getword(hora
,sizeof(hora
),&gwarea
,'\t')<0) {
1069 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1072 if (getword(user
,sizeof(user
),&gwarea
,'\t')<0) {
1073 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1076 if (getword(ip
,sizeof(ip
),&gwarea
,'\t')<0) {
1077 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1080 if (getword_ptr(linebuf
,&url
,&gwarea
,'\t')<0){
1081 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1084 if (getword(tam
,sizeof(tam
),&gwarea
,'\t')<0){
1085 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1088 if (getword(code
,sizeof(code
),&gwarea
,'\t')<0){
1089 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1092 if (getword(elap
,sizeof(elap
),&gwarea
,'\t')<0){
1093 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1096 if (getword(smartfilter
,sizeof(smartfilter
),&gwarea
,'\0')<0){
1097 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1100 getword_start(&gwarea
,data
);
1101 if (getword_atoll(&iday
,&gwarea
,'/')<0 || iday
<1 || iday
>31){
1102 debuga(_("Maybe you have a broken date in your %s file\n"),arq
);
1105 if (getword_atoll(&imonth
,&gwarea
,'/')<0 || imonth
<1 || imonth
>12){
1106 debuga(_("Maybe you have a broken date in your %s file\n"),arq
);
1109 if (getword_atoll(&iyear
,&gwarea
,'\0')<0){
1110 debuga(_("Maybe you have a broken date in your %s file\n"),arq
);
1113 idata
=builddia(iday
,imonth
,iyear
);
1114 computedate(iyear
,imonth
,iday
,&tt
);
1118 if (linebuf
[0] == '#') {
1119 int ncols
,cols
[ISACOL_Last
];
1121 fixendofline(linebuf
);
1122 getword_start(&gwarea
,linebuf
);
1123 // remove the #Fields: column at the beginning of the line
1124 if (getword_skip(1000,&gwarea
,' ')<0){
1125 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1128 for (ncols
=0 ; ncols
<ISACOL_Last
; ncols
++) cols
[ncols
]=-1;
1130 while(gwarea
.current
[0] != '\0') {
1131 if (getword(val1
,sizeof(val1
),&gwarea
,'\t')<0){
1132 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1135 if(strcmp(val1
,"c-ip") == 0) cols
[ISACOL_Ip
]=ncols
;
1136 if(strcmp(val1
,"cs-username") == 0) cols
[ISACOL_UserName
]=ncols
;
1137 if(strcmp(val1
,"date") == 0) cols
[ISACOL_Date
]=ncols
;
1138 if(strcmp(val1
,"time") == 0) cols
[ISACOL_Time
]=ncols
;
1139 if(strcmp(val1
,"time-taken") == 0) cols
[ISACOL_TimeTaken
]=ncols
;
1140 if(strcmp(val1
,"sc-bytes") == 0) cols
[ISACOL_Bytes
]=ncols
;
1141 if(strcmp(val1
,"cs-uri") == 0) cols
[ISACOL_Uri
]=ncols
;
1142 if(strcmp(val1
,"sc-status") == 0) cols
[ISACOL_Status
]=ncols
;
1145 if (cols
[ISACOL_Ip
]>=0) {
1147 for (ncols
=0 ; ncols
<ISACOL_Last
; ncols
++)
1148 isa_cols
[ncols
]=cols
[ncols
];
1152 if (!isa_ncols
) continue;
1153 getword_start(&gwarea
,linebuf
);
1154 for (x
=0 ; x
<isa_ncols
; x
++) {
1155 if (getword_ptr(linebuf
,&str
,&gwarea
,'\t')<0) {
1156 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1159 if (x
==isa_cols
[ISACOL_Ip
]) {
1160 if (strlen(str
)>=sizeof(ip
)) {
1161 debuga(_("Maybe you have a broken IP in your %s file\n"),arq
);
1165 } else if (x
==isa_cols
[ISACOL_UserName
]) {
1166 if (strlen(str
)>=sizeof(user
)) {
1167 debuga(_("Maybe you have a broken user ID in your %s file\n"),arq
);
1171 } else if (x
==isa_cols
[ISACOL_Date
]) {
1172 if (strlen(str
)>=sizeof(data
)) {
1173 debuga(_("Maybe you have a broken date in your %s file\n"),arq
);
1177 } else if (x
==isa_cols
[ISACOL_Time
]) {
1178 if (strlen(str
)>=sizeof(hora
)) {
1179 debuga(_("Maybe you have a broken time in your %s file\n"),arq
);
1183 } else if (x
==isa_cols
[ISACOL_TimeTaken
]) {
1184 if (strlen(str
)>=sizeof(elap
)) {
1185 debuga(_("Maybe you have a broken download duration in your %s file\n"),arq
);
1189 } else if (x
==isa_cols
[ISACOL_Bytes
]) {
1190 if (strlen(str
)>=sizeof(tam
)) {
1191 debuga(_("Maybe you have a broken download size in your %s file\n"),arq
);
1195 } else if (x
==isa_cols
[ISACOL_Uri
]) {
1197 } else if (x
==isa_cols
[ISACOL_Status
]) {
1198 if (strlen(str
)>=sizeof(code
)) {
1199 debuga(_("Maybe you have a broken access code in your %s file\n"),arq
);
1206 if(strcmp(code
,"401") == 0 || strcmp(code
,"403") == 0 || strcmp(code
,"407") == 0) {
1207 sprintf(val1
,"DENIED/%s",code
);
1210 getword_start(&gwarea
,data
);
1211 if (getword_atoll(&iyear
,&gwarea
,'-')<0){
1212 debuga(_("Maybe you have a broken year in your %s file\n"),arq
);
1215 if (getword_atoll(&imonth
,&gwarea
,'-')<0){
1216 debuga(_("Maybe you have a broken month in your %s file\n"),arq
);
1219 if (getword_atoll(&iday
,&gwarea
,'\0')<0){
1220 debuga(_("Maybe you have a broken day in your %s file\n"),arq
);
1224 idata
=builddia(iday
,imonth
,iyear
);
1225 computedate(iyear
,imonth
,iday
,&tt
);
1229 debuga(_("Unknown input log file format\n"));
1233 strftime(dia
, sizeof(dia
), "%d/%m/%Y", t
);
1234 snprintf(hora
,sizeof(hora
),"%02d:%02d:%02d",t
->tm_hour
,t
->tm_min
,t
->tm_sec
);
1237 printf("DATE=%s IDATA=%d DFROM=%d DUNTIL=%d\n",date
,idata
,dfrom
,duntil
);
1239 if(date
[0] != '\0'){
1240 if(idata
< dfrom
|| idata
> duntil
) continue;
1243 // Record only hours usage which is required
1245 if( bsearch( &( t
-> tm_wday
), weekdays
.list
, weekdays
.len
,
1246 sizeof( int ), compar
) == NULL
)
1249 if( bsearch( &( t
-> tm_hour
), hours
.list
, hours
.len
,
1250 sizeof( int ), compar
) == NULL
)
1255 if(strlen(user
) > MAX_USER_LEN
) {
1256 if (debugm
) printf(_("User ID too long: %s\n"),user
);
1262 if(IncludeUsers
[0] != '\0') {
1263 sprintf(val1
,":%s:",user
);
1264 if((str
=(char *) strstr(IncludeUsers
,val1
)) == (char *) NULL
)
1269 if (debugm
) printf(_("Excluded code: %s\n"),code
);
1274 if(testvaliduserchar(user
))
1278 if((str
= strstr(user
,"%20")) != NULL
) {
1280 This is a patch introduced to solve bug #1624251 reported at sourceforge but
1281 the side effect is to truncate the name at the first space and merge the reports
1282 of people whose name is identical up to the first space.
1284 The old code used to truncate the user name at the first % if a %20 was
1285 found anywhere in the string. That means the string could be truncated
1286 at the wrong place if another % occured before the %20. This new code should
1287 avoid that problem and only truncate at the space. There is no bug
1288 report indicating that anybody noticed this.
1294 Code prior to 2.2.7 used to replace any %xx by a dot as long as a %5c was
1295 found in the user name.
1297 while((str
= strstr(user
,"%5c")) != NULL
) {
1299 for (x
=3 ; str
[x
] ; x
++) str
[x
-2]=str
[x
];
1307 The full URL is not saved in sarg log. There is no point in testing the URL to detect
1310 download_flag
=is_download_suffix(url
);
1311 if (download_flag
) {
1316 download_flag
=false;
1318 // remove any protocol:// at the beginning of the URL
1319 if ((str
= strchr(url
,'/')) != NULL
&& str
[1] == '/') {
1323 for (i
=0 ; str
[i
] ; i
++)
1329 url_hostname(url
,hostname
,sizeof(hostname
));
1333 if(url
[0] == '\0') continue;
1335 if(addr
[0] != '\0'){
1336 if(strcmp(addr
,ip
)!=0) continue;
1339 if(!vhexclude(url
)) {
1340 if (debugm
) printf(_("Excluded site: %s\n"),url
);
1346 if(hm
>= 0 && hmf
>= 0) {
1347 hmr
=t
->tm_hour
*100+t
->tm_min
;
1348 if(hmr
< hm
|| hmr
> hmf
) continue;
1351 if(site
[0] != '\0'){
1352 if(strstr(url
,site
)==0) continue;
1360 if(strcmp(user
,"-") == 0 || strcmp(user
," ") == 0 || strcmp(user
,"") == 0) {
1361 if(RecordsWithoutUser
== RECORDWITHOUTUSER_IP
) {
1365 if(RecordsWithoutUser
== RECORDWITHOUTUSER_IGNORE
)
1367 if(RecordsWithoutUser
== RECORDWITHOUTUSER_EVERYBODY
)
1368 strcpy(user
,"everybody");
1371 if(NtlmUserFormat
== NTLMUSERFORMAT_USER
) {
1372 if((str
= strchr(user
,'_')) != 0) {
1373 strcpy(warea
,str
+1);
1376 if((str
= strchr(user
,'+')) != 0) {
1377 strcpy(warea
,str
+1);
1385 if(strcmp(user
,us
)!=0) continue;
1389 sprintf(wuser
,":%s:",user
);
1390 if(strstr(userfile
, wuser
) == 0)
1395 if(!vuexclude(user
)) {
1396 if (debugm
) printf(_("Excluded user: %s\n"),user
);
1402 if(strcmp(user
,"-") ==0 || strcmp(user
," ") ==0 || strcmp(user
,"") ==0 || strcmp(user
,":") ==0)
1406 if(atol(elap
)>max_elapsed
) {
1412 if((str
=(char *) strstr(linebuf
, "[SmartFilter:")) != (char *) NULL
) {
1414 sprintf(smartfilter
,"\"%s\"",str
+1);
1415 } else sprintf(smartfilter
,"\"\"");
1419 for (ufile
=first_user_file
; ufile
&& strcmp(user
,ufile
->user
->id
)!=0 ; ufile
=ufile
->next
) {
1421 if (ufile
->file
) nopen
++;
1424 ufile
=malloc(sizeof(*ufile
));
1426 debuga(_("Not enough memory to store the user %s\n"),user
);
1429 memset(ufile
,0,sizeof(*ufile
));
1430 ufile
->next
=first_user_file
;
1431 first_user_file
=ufile
;
1432 uinfo
=userinfo_create(user
);
1434 uinfo
->id_is_ip
=id_is_ip
;
1437 prev_ufile
->next
=ufile
->next
;
1438 ufile
->next
=first_user_file
;
1439 first_user_file
=ufile
;
1443 if (ufile
->file
==NULL
) {
1444 if (nopen
>=maxopenfiles
) {
1446 for (ufile1
=first_user_file
; ufile1
; ufile1
=ufile1
->next
) {
1447 if (ufile1
->file
!=NULL
) {
1448 if (x
>=maxopenfiles
) {
1449 if (fclose(ufile1
->file
)==EOF
) {
1450 debuga(_("Failed to close the log file of user %s - %s\n"),ufile1
->user
->id
,strerror(errno
));
1459 if (snprintf (tmp3
, sizeof(tmp3
), "%s/%s.unsort", tmp
, ufile
->user
->filename
)>=sizeof(tmp3
)) {
1460 debuga(_("Temporary user file name too long: %s/%s.unsort\n"), tmp
, ufile
->user
->filename
);
1463 if ((ufile
->file
= MY_FOPEN (tmp3
, "a")) == NULL
) {
1464 debuga(_("(log) Cannot open temporary file: %s - %s\n"), tmp3
, strerror(errno
));
1469 /*if ( strcmp ( user , sz_Last_User ) != 0 ) {
1470 if ( fp_Write_User )
1471 fclose( fp_Write_User ) ;
1472 sprintf (tmp3, "%s/%s.unsort", tmp, user);
1474 if ((fp_Write_User = MY_FOPEN (tmp3, "a")) == NULL) {
1475 fprintf (stderr, "%s: (log) %s: %s - %s\n", argv[0], _("Cannot open temporary file"), tmp3, strerror(errno));
1478 strcpy( sz_Last_User , user ) ;
1480 if (fprintf(ufile
->file
, "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",dia
,hora
,ip
,url
,tam
,code
,elap
,smartfilter
)<=0) {
1481 debuga(_("Write error in the log file of user %s\n"),user
);
1485 if(fp_log
&& ilf
!=ILF_Sarg
)
1486 fprintf(fp_log
, "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",dia
,hora
,user
,ip
,url
,tam
,code
,elap
,smartfilter
);
1490 if(!dataonly
&& download_flag
&& download_url
&& strstr(code
,"DENIED") == 0) {
1493 if ( ! fp_Download_Unsort
) {
1494 if ((fp_Download_Unsort
= MY_FOPEN ( sz_Download_Unsort
, "a")) == NULL
) {
1495 debuga(_("(log) Cannot open temporary file: %s - %s\n"),sz_Download_Unsort
, strerror(errno
));
1499 fprintf(fp_Download_Unsort
,"%s\t%s\t%s\t%s\t%s\n",dia
,hora
,user
,ip
,download_url
);
1502 if((ReportType
& REPORT_TYPE_DENIED
) != 0 || (ReportType
& REPORT_TYPE_AUTH_FAILURES
) != 0) {
1503 if(fp_denied
&& strstr(code
,"DENIED/403") != 0) {
1504 fprintf(fp_denied
, "%s\t%s\t%s\t%s\t%s\n",dia
,hora
,user
,ip
,urly
);
1507 if(fp_authfail
&& (strstr(code
,"DENIED/401") != 0 || strstr(code
,"DENIED/407") != 0)) {
1508 fprintf(fp_authfail
, "%s\t%s\t%s\t%s\t%s\n",dia
,hora
,user
,ip
,urly
);
1513 if (ilf
!=ILF_Sarg
) {
1514 if(!totper
|| idata
<mindate
){
1516 memcpy(&period
.start
,t
,sizeof(*t
));
1517 strcpy(start_hour
,tbuf2
);
1519 if (!totper
|| idata
>maxdate
) {
1521 memcpy(&period
.end
,t
,sizeof(*t
));
1527 printf("IP=\t%s\n",ip
);
1528 printf("USER=\t%s\n",user
);
1529 printf("ELAP=\t%s\n",elap
);
1530 printf("DATE=\t%s\n",dia
);
1531 printf("TIME=\t%s\n",hora
);
1532 printf("FUNC=\t%s\n",fun
);
1533 printf("URL=\t%s\n",url
);
1534 printf("CODE=\t%s\n",code
);
1535 printf("LEN=\t%s\n",tam
);
1543 if( ShowReadStatistics
)
1544 printf(_("SARG: Records in file: %lu, reading: %3.2f%%\n"),recs1
, (float) 100 );
1550 debuga(_(" Records read: %ld, written: %ld, excluded: %ld\n"),totregsl
,totregsg
,totregsx
);
1552 longline_destroy(&line
);
1553 if ( fp_Download_Unsort
)
1554 fclose (fp_Download_Unsort
);
1556 for (ufile
=first_user_file
; ufile
; ufile
=ufile1
) {
1558 if (ufile
->file
!=NULL
) fclose(ufile
->file
);
1563 free_excludecodes();
1569 for (ilf
=0 ; ilf
<ILF_Last
; ilf
++) totalcount
+=ilf_count
[ilf
];
1571 if(ilf_count
[ILF_Common
]>0 && ilf_count
[ILF_Squid
]>0)
1572 debuga(_("Log with mixed records format (squid and common log)\n"));
1574 if(ilf_count
[ILF_Common
]>0 && ilf_count
[ILF_Squid
]==0)
1575 debuga(_("Common log format\n"));
1577 if(ilf_count
[ILF_Common
]==0 && ilf_count
[ILF_Squid
]>0)
1578 debuga(_("Squid log format\n"));
1580 if(ilf_count
[ILF_Sarg
]>0)
1581 debuga(_("Sarg log format\n"));
1583 if(totalcount
==0 && totregsg
)
1584 debuga(_("Log with invalid format\n"));
1588 debuga(_("No records found\n"));
1590 if(fp_denied
) fclose(fp_denied
);
1591 if(fp_authfail
) fclose(fp_authfail
);
1593 if(userfile
) free(userfile
);
1598 if (date
[0]!='\0') {
1599 char date0
[30], date1
[30];
1601 strftime(date0
,sizeof(date0
),"%d/%m/%Y",&period
.start
);
1602 strftime(date1
,sizeof(date1
),"%d/%m/%Y",&period
.end
);
1603 debuga(_("Period covered by log files: %s-%s\n"),date0
,date1
);
1604 getperiod_fromrange(&period
,dfrom
,duntil
);
1606 if (getperiod_buildtext(&period
)<0) {
1607 debuga(_("Failed to build the string representation of the date range\n"));
1612 debugaz("data",dia
);
1613 debugaz("period",period
.text
);
1617 debuga(_("Period: %s\n"),period
.text
);
1623 fclose(fp_authfail
);
1625 if(fp_log
!= NULL
) {
1627 strcpy(end_hour
,tbuf2
);
1628 strftime(val2
,sizeof(val2
),"%d%m%Y",&period
.start
);
1629 strftime(val1
,sizeof(val1
),"%d%m%Y",&period
.end
);
1630 sprintf(val4
,"%s/sarg-%s_%s-%s_%s.log",ParsedOutputLog
,val2
,start_hour
,val1
,end_hour
);
1631 if (rename(arq_log
,val4
)) {
1632 debuga(_("failed to rename %s to %s - %s\n"),arq_log
,val4
,strerror(errno
));
1634 strcpy(arq_log
,val4
);
1636 if(strcmp(ParsedOutputLogCompress
,"nocompress") != 0 && ParsedOutputLogCompress
[0] != '\0') {
1638 No double quotes around ParsedOutputLogCompress because it may contain command line options. If double quotes are
1639 necessary around the command name, put them in the configuration file.
1641 sprintf(val1
,"%s \"%s\"",ParsedOutputLogCompress
,arq_log
);
1642 cstatus
=system(val1
);
1643 if (!WIFEXITED(cstatus
) || WEXITSTATUS(cstatus
)) {
1644 debuga(_("command return status %d\n"),WEXITSTATUS(cstatus
));
1645 debuga(_("command: %s\n"),val1
);
1651 debuga(_("Sarg parsed log saved as %s\n"),arq_log
);
1654 if(DataFile
[0] == '\0' && (ReportType
& REPORT_TYPE_DENIED
) != 0) {
1655 sprintf(csort
,"sort -T \"%s\" -k 3,3 -k 5,5 -o \"%s\" \"%s\"",tmp
,denied_sort
,denied_unsort
);
1656 cstatus
=system(csort
);
1657 if (!WIFEXITED(cstatus
) || WEXITSTATUS(cstatus
)) {
1658 debuga(_("sort command return status %d\n"),WEXITSTATUS(cstatus
));
1659 debuga(_("sort command: %s\n"),csort
);
1662 unlink(denied_unsort
);
1665 sort_users_log(tmp
, debug
);
1667 if(DataFile
[0] != '\0')
1672 if((ReportType
& REPORT_TYPE_DENIED
) != 0)
1673 unlink(denied_sort
);
1675 if(strcmp(tmp
,"/tmp") != 0) {
1691 static void getusers(const char *pwdfile
, int debug
)
1699 debuga(_("Loading password file from %s\n"),pwdfile
);
1701 if ((fp_usr
= fopen(pwdfile
, "r")) == NULL
) {
1702 debuga(_("(getusers) Cannot open file %s - %s\n"),pwdfile
,strerror(errno
));
1706 if (fseek(fp_usr
, 0, SEEK_END
)==-1) {
1707 debuga(_("Failed to move till the end of the users file %s: %s\n"),pwdfile
,strerror(errno
));
1710 nreg
= ftell(fp_usr
);
1712 debuga(_("Cannot get the size of file %s\n"),pwdfile
);
1716 if (fseek(fp_usr
, 0, SEEK_SET
)==-1) {
1717 debuga(_("Failed to rewind the users file %s: %s\n"),pwdfile
,strerror(errno
));
1721 if((userfile
=(char *) malloc(nreg
))==NULL
){
1722 debuga(_("malloc error (%ld)\n"),nreg
);
1726 bzero(userfile
,nreg
);
1727 strcpy(userfile
,":");
1729 while(fgets(buf
,sizeof(buf
),fp_usr
)!=NULL
) {
1730 str
=strchr(buf
,':');
1732 debuga(_("You have an invalid user in your %s file\n"),pwdfile
);
1736 strcat(userfile
,buf
);