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
];
98 char hm
[15], hmf
[15], hmr
[15];
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
];
142 long int max_elapsed
=0;
143 long long int iyear
, imonth
, iday
;
148 unsigned long recs1
=0UL;
149 unsigned long recs2
=0UL;
150 int OutputNonZero
= REPORT_EVERY_X_LINES
;
151 bool download_flag
=false;
152 char *download_url
=NULL
;
153 struct getwordstruct gwarea
;
157 struct userinfostruct
*uinfo
;
158 struct userfilestruct
*first_user_file
, *ufile
, *ufile1
, *prev_ufile
;
160 static int convert
=0;
161 static int output_css
=0;
163 static struct option long_options
[]=
165 {"convert",no_argument
,&convert
,1},
166 {"css",no_argument
,&output_css
,1},
167 {"split",no_argument
,&split
,1},
172 setlocale(LC_TIME
,"");
175 #if defined(ENABLE_NLS) && defined(HAVE_LOCALE_H)
176 if (!setlocale (LC_ALL
, "")) {
177 fprintf(stderr
,"SARG: Cannot set the locale LC_ALL to the environment variable\n");
180 if (!bindtextdomain (PACKAGE_NAME
, LOCALEDIR
)) {
181 fprintf(stderr
,"SARG: Cannot bind to text domain %s in directory %s (%s)\n",PACKAGE_NAME
,LOCALEDIR
,strerror(errno
));
184 if (!textdomain (PACKAGE_NAME
)) {
185 fprintf(stderr
,"SARG: Cannot set gettext domain for %s PACKAGE_NAME (%s)\n",PACKAGE_NAME
,strerror(errno
));
195 UserAgentLog
[0]='\0';
196 ExcludeHosts
[0]='\0';
197 ExcludeUsers
[0]='\0';
204 ExternalCSSFile
[0]='\0';
205 RedirectorLogFormat
[0]='\0';
207 for (ilf
=0 ; ilf
<ILF_Last
; ilf
++) ilf_count
[ilf
]=0;
209 sprintf(ExcludeCodes
,"%s/exclude_codes",SYSCONFDIR
);
210 strcpy(GraphDaysBytesBarColor
,"orange");
211 strcpy(BgColor
,"#ffffff");
212 strcpy(TxColor
,"#000000");
213 strcpy(TxBgColor
,"lavender");
214 strcpy(TiColor
,"darkblue");
217 strcpy(LogoTextColor
,"#000000");
218 strcpy(HeaderColor
,"darkblue");
219 strcpy(HeaderBgColor
,"#dddddd");
220 strcpy(LogoTextColor
,"#006699");
221 strcpy(FontSize
,"9px");
222 strcpy(TempDir
,"/tmp");
223 strcpy(OutputDir
,"/var/www/html/squid-reports");
225 strcpy(DateFormat
,"u");
226 OverwriteReport
=false;
227 RemoveTempFiles
=true;
228 strcpy(ReplaceIndex
,"index.html");
230 RecordsWithoutUser
=RECORDWITHOUTUSER_IP
;
232 strcpy(MailUtility
,"mailx");
236 strcpy(TopuserSortField
,"BYTES");
237 strcpy(UserSortField
,"BYTES");
238 strcpy(TopuserSortOrder
,"reverse");
239 strcpy(UserSortOrder
,"reverse");
240 strcpy(TopsitesSortField
,"CONNECT");
241 strcpy(TopsitesSortType
,"D");
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 strcpy(RealtimeTypes
,"GET,PUT,CONNECT");
281 RealtimeUnauthRec
=REALTIME_UNAUTH_REC_SHOW
;
282 RedirectorFilterOutDate
=true;
283 DansguardianFilterOutDate
=true;
284 DataFileUrl
=DATAFILEURL_IP
;
285 strcpy(MaxElapsed
,"28800000");
286 BytesInSitesUsersReport
=0;
287 UserAuthentication
=0;
288 strcpy(LDAPHost
,"127.0.0.1");
290 LDAPProtocolVersion
=3;
293 LDAPBaseSearch
[0]='\0';
294 strcpy(LDAPFilterSearch
, "uid=%s");
295 strcpy(LDAPTargetAttr
, "cn");
317 UserInvalidChar
[0]='\0';
319 SquidGuardConf
[0]='\0';
320 DansGuardianConf
[0]='\0';
327 dansguardian_count
=0;
330 DeniedReportLimit
=10;
331 AuthfailReportLimit
=10;
332 DansGuardianReportLimit
=10;
333 SquidGuardReportLimit
=10;
334 DownloadReportLimit
=50;
343 realtime_access_log_lines
=1000;
351 bzero(IncludeUsers
, sizeof(IncludeUsers
));
352 bzero(ExcludeString
, sizeof(ExcludeString
));
353 first_user_file
=NULL
;
354 memset(&period
,0,sizeof(period
));
357 for(x
=0; x
<MAXLOGS
; x
++)
358 AccessLog
[x
][0]='\0';
359 AccessLogFromCmdLine
=0;
360 RedirectorLogFromCmdLine
=0;
362 strcpy(Title
,_("Squid User Access Report"));
364 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 strcpy(uagent
,optarg
);
376 strcpy(hexclude
,optarg
);
379 strncpy(date
,optarg
,sizeof(date
)-1);
380 date
[sizeof(date
)-1]='\0';
381 date_from(date
, &dfrom
, &duntil
);
384 strcpy(email
,optarg
);
387 strcpy(ConfigFile
,optarg
);
399 if (NAccessLog
>=MAXLOGS
) {
400 debuga(_("Too many log files passed on command line with option -l.\n"));
403 if (strlen(optarg
)>=MAX_LOG_FILELEN
) {
404 debuga(_("Log file name too long passed on command line with option -l: %s\n"),optarg
);
407 strcpy(AccessLog
[NAccessLog
],optarg
);
409 AccessLogFromCmdLine
++;
412 if (NRedirectorLogs
>MAX_REDIRECTOR_LOGS
) {
413 debuga(_("Too many redirector logs passed on command line with option -L.\n"));
416 if (strlen(optarg
)>=MAX_REDIRECTOR_FILELEN
) {
417 debuga(_("Redirector log file name too long passed on command line with opton -L: %s\n"),optarg
);
420 strcpy(RedirectorLogs
[NRedirectorLogs
],optarg
);
422 RedirectorLogFromCmdLine
++;
431 strcpy(outdir
,optarg
);
446 if(strstr(optarg
,"-") == 0) {
450 getword_start(&gwarea
,optarg
);
451 if (getword(hm
,sizeof(hm
),&gwarea
,'-')<0 || getword(hmf
,sizeof(hmf
),&gwarea
,'\0')<0) {
452 debuga(_("The time range passed on the command line with option -t is invalid\n"));
456 if(sscanf(hm
,"%d:%d",&h
,&m
)!=2) {
457 debuga(_("Time period must be MM or MM:SS. Exit\n"));
460 sprintf(hm
,"%02d%02d",h
,m
);
461 if(sscanf(hmf
,"%d:%d",&h
,&m
)!=2) {
462 debuga(_("Time period must be MM or MM:SS. Exit\n"));
465 sprintf(hmf
,"%02d%02d",h
,m
);
487 debuga(_("Option -%c require an argument\n"),optopt);
504 for (iarq
=optind
; iarq
<argc
; iarq
++) {
505 if (NAccessLog
>=MAXLOGS
) {
506 debuga(_("Too many log files passed on command line.\n"));
509 if (strlen(argv
[iarq
])>=MAX_LOG_FILELEN
) {
510 debuga(_("Log file name too long passed on command line: %s\n"),argv
[iarq
]);
513 strcpy(AccessLog
[NAccessLog
],argv
[iarq
]);
515 AccessLogFromCmdLine
++;
519 if(debug
) debuga(_("Init\n"));
521 if(ConfigFile
[0] == '\0') snprintf(ConfigFile
,sizeof(ConfigFile
),"%s/sarg.conf",SYSCONFDIR
);
522 if(access(ConfigFile
, R_OK
) != 0) {
523 debuga(_("Cannot open config file: %s - %s\n"),ConfigFile
,strerror(errno
));
527 if(access(ConfigFile
, R_OK
) == 0)
530 if(userip
) UserIp
=true;
532 if(dns
) Ip2Name
=true;
539 if(IndexTree
== INDEX_TREE_FILE
)
540 strcpy(ImageFile
,"../images");
542 strcpy(ImageFile
,"../../../images");
545 if(DataFile
[0] != '\0')
548 if(NAccessLog
== 0) {
549 strcpy(AccessLog
[0],"/var/log/squid/access.log");
558 for (iarq
=0 ; iarq
<NAccessLog
; iarq
++)
559 splitlog(AccessLog
[iarq
], df
, dfrom
, duntil
, convert
);
563 for (iarq
=0 ; iarq
<NAccessLog
; iarq
++)
564 convlog(AccessLog
[iarq
], df
, dfrom
, duntil
);
568 load_excludecodes(ExcludeCodes
);
570 if(access(PasswdFile
, R_OK
) == 0) {
571 getusers(PasswdFile
,debug
);
575 if(hexclude
[0] == '\0')
576 strcpy(hexclude
,ExcludeHosts
);
577 if(hexclude
[0] != '\0') {
578 gethexclude(hexclude
,debug
);
582 if(ReportType
== 0) {
583 ReportType
=REPORT_TYPE_TOPUSERS
| REPORT_TYPE_TOPSITES
| REPORT_TYPE_USERS_SITES
|
584 REPORT_TYPE_SITES_USERS
| REPORT_TYPE_DATE_TIME
| REPORT_TYPE_DENIED
|
585 REPORT_TYPE_AUTH_FAILURES
| REPORT_TYPE_SITE_USER_TIME_DATE
| REPORT_TYPE_DOWNLOADS
;
588 if(access(ExcludeUsers
, R_OK
) == 0) {
589 getuexclude(ExcludeUsers
,debug
);
598 if(strcmp(ExcludeUsers
,"indexonly") == 0) indexonly
++;
599 if(Index
== INDEX_ONLY
) indexonly
++;
601 if(MaxElapsed
[0] != '\0') max_elapsed
=atol(MaxElapsed
);
603 if(outdir
[0] == '\0') strcpy(outdir
,OutputDir
);
606 if(uagent
[0] == '\0') strcpy(uagent
,UserAgentLog
);
608 if(tmp
[0] == '\0') strcpy(tmp
,TempDir
);
609 else strcpy(TempDir
,tmp
);
611 For historical reasons, the temporary directory is the subdirectory "sarg" of the path
612 provided by the user.
616 if(df
[0] == '\0') strcpy(df
,DateFormat
);
617 else strcpy(DateFormat
,df
);
621 strcpy(DateFormat
,"u");
624 IndexTree
=INDEX_TREE_FILE
;
626 if(email
[0] == '\0' && OutputEmail
[0] != '\0') strcpy(email
,OutputEmail
);
628 if(email
[0] != '\0') {
634 if(access(tmp
, R_OK
) == 0) {
638 snprintf(denied_unsort
,sizeof(denied_unsort
),"%s/denied.log.unsort",tmp
);
639 snprintf(denied_sort
,sizeof(denied_sort
),"%s/denied.log",tmp
);
640 snprintf(authfail_unsort
,sizeof(authfail_unsort
),"%s/authfail.log.unsort",tmp
);
643 debuga(_("Parameters:\n"));
644 debuga(_(" Hostname or IP address (-a) = %s\n"),addr
);
645 debuga(_(" Useragent log (-b) = %s\n"),uagent
);
646 debuga(_(" Exclude file (-c) = %s\n"),hexclude
);
647 debuga(_(" Date from-until (-d) = %s\n"),date
);
648 debuga(_(" Email address to send reports (-e) = %s\n"),email
);
649 debuga(_(" Config file (-f) = %s\n"),ConfigFile
);
650 if(strcmp(df
,"e") == 0)
651 debuga(_(" Date format (-g) = Europe (dd/mm/yyyy)\n"));
652 if(strcmp(df
,"u") == 0)
653 debuga(_(" Date format (-g) = USA (mm/dd/yyyy)\n"));
654 if(strcmp(df
,"w") == 0)
655 debuga(_(" Date format (-g) = Sites & Users (yyyy/ww)\n"));
656 debuga(_(" IP report (-i) = %s\n"),(iprel
) ? _("Yes") : _("No"));
657 for (iarq
=0 ; iarq
<NAccessLog
; iarq
++)
658 debuga(_(" Input log (-l) = %s\n"),AccessLog
[iarq
]);
659 for (iarq
=0 ; iarq
<NRedirectorLogs
; iarq
++)
660 debuga(_(" Redirector log (-L) = %s\n"),RedirectorLogs
[iarq
]);
661 debuga(_(" Resolve IP Address (-n) = %s\n"),(Ip2Name
) ? _("Yes") : _("No"));
662 debuga(_(" Output dir (-o) = %s\n"),outdir
);
663 debuga(_("Use Ip Address instead of userid (-p) = %s\n"),(UserIp
) ? _("Yes") : _("No"));
664 debuga(_(" Accessed site (-s) = %s\n"),site
);
665 debuga(_(" Time (-t) = %s\n"),hm
);
666 debuga(_(" User (-u) = %s\n"),us
);
667 debuga(_(" Temporary dir (-w) = %s\n"),tmp
);
668 debuga(_(" Debug messages (-x) = %s\n"),(debug
) ? _("Yes") : _("No"));
669 debuga(_(" Process messages (-z) = %s\n"),(debugz
) ? _("Yes") : _("No"));
674 printf(_("Parameters:\n"));
675 printf(_(" Hostname or IP address (-a) = %s\n"),addr
);
676 printf(_(" Useragent log (-b) = %s\n"),uagent
);
677 printf(_(" Exclude file (-c) = %s\n"),hexclude
);
678 printf(_(" Date from-until (-d) = %s\n"),date
);
679 printf(_(" Email address to send reports (-e) = %s\n"),email
);
680 printf(_(" Config file (-f) = %s\n"),ConfigFile
);
681 if(strcmp(df
,"e") == 0)
682 printf(_(" Date format (-g) = Europe (dd/mm/yyyy)\n"));
683 if(strcmp(df
,"u") == 0)
684 printf(_(" Date format (-g) = USA (mm/dd/yyyy)\n"));
685 if(strcmp(df
,"w") == 0)
686 printf(_(" Date format (-g) = Sites & Users (yyyy/ww)\n"));
687 printf(_(" IP report (-i) = %s\n"),(iprel
) ? _("Yes") : _("No"));
688 for (iarq
=0 ; iarq
<NAccessLog
; iarq
++)
689 printf(_(" Input log (-l) = %s\n"),AccessLog
[iarq
]);
690 for (iarq
=0 ; iarq
<NRedirectorLogs
; iarq
++)
691 printf(_(" Redirector log (-L) = %s\n"),RedirectorLogs
[iarq
]);
692 printf(_(" Resolve IP Address (-n) = %s\n"),(Ip2Name
) ? _("Yes") : _("No"));
693 printf(_(" Output dir (-o) = %s\n"),outdir
);
694 printf(_("Use Ip Address instead of userid (-p) = %s\n"),(UserIp
) ? _("Yes") : _("No"));
695 printf(_(" Accessed site (-s) = %s\n"),site
);
696 printf(_(" Time (-t) = %s\n"),hm
);
697 printf(_(" User (-u) = %s\n"),us
);
698 printf(_(" Temporary dir (-w) = %s\n"),tmp
);
699 printf(_(" Debug messages (-x) = %s\n"),(debug
) ? _("Yes") : _("No"));
700 printf(_(" Process messages (-z) = %s\n"),(debugz
) ? _("Yes") : _("No"));
701 printf(_("sarg version: %s\n"),VERSION
);
705 debuga(_("sarg version: %s\n"),VERSION
);
707 maxopenfiles
=MAX_OPEN_USER_FILES
;
709 if (Ulimit
[0] != '\0') {
714 #if defined(RLIMIT_NOFILE)
715 getrlimit (RLIMIT_NOFILE
, &rl
);
716 #elif defined(RLIMIT_OFILE)
717 getrlimit (RLIMIT_OFILE
, &rl
);
719 #warning "No rlimit resource for the number of open files"
724 rl
.rlim_cur
= atol(Ulimit
);
725 rl
.rlim_max
= atol(Ulimit
);
726 #if defined(RLIMIT_NOFILE)
727 rc
=setrlimit (RLIMIT_NOFILE
, &rl
);
728 #elif defined(RLIMIT_OFILE)
729 rc
=setrlimit (RLIMIT_OFILE
, &rl
);
731 #warning "No rlimit resource for the number of open files"
734 debuga(_("setrlimit error - %s\n"),strerror(errno
));
738 debuga("Maximum file descriptor: cur=%ld max=%ld, changed to cur="RLIM_STRING
" max="RLIM_STRING
,l1
,l2
,rl
.rlim_cur
,rl
.rlim_max
);
742 init_usertab(UserTabFile
);
744 if ((line
=longline_create())==NULL
) {
745 debuga(_("Not enough memory to read a log file\n"));
749 snprintf(sz_Download_Unsort
,sizeof(sz_Download_Unsort
),"%s/download.unsort", tmp
);
751 if(DataFile
[0]=='\0') {
752 if((ReportType
& REPORT_TYPE_DENIED
) != 0) {
753 if((fp_denied
=MY_FOPEN(denied_unsort
,"w"))==NULL
) {
754 debuga(_("(log) Cannot open file: %s - %s\n"),denied_unsort
,strerror(errno
));
759 if((ReportType
& REPORT_TYPE_DENIED
) != 0 || (ReportType
& REPORT_TYPE_AUTH_FAILURES
) != 0) {
760 if((fp_authfail
=MY_FOPEN(authfail_unsort
,"w"))==NULL
) {
761 debuga(_("(log) Cannot open file: %s - %s\n"),authfail_unsort
,strerror(errno
));
767 for (iarq
=0 ; iarq
<NAccessLog
; iarq
++) {
768 strcpy(arq
,AccessLog
[iarq
]);
772 if(strcmp(arq
,"-")==0) {
774 debuga(_("Reading access log file: from stdin\n"));
779 if (stat(arq
,&logstat
)!=0) {
780 debuga(_("Cannot get the modification time of input log file %s (%s). Processing it anyway\n"),arq
,strerror(errno
));
782 struct tm
*logtime
=localtime(&logstat
.st_mtime
);
783 if ((logtime
->tm_year
+1900)*10000+(logtime
->tm_mon
+1)*100+logtime
->tm_mday
<dfrom
) {
784 debuga(_("Ignoring old log file %s\n"),arq
);
789 fp_in
=decomp(arq
,&from_pipe
);
791 debuga(_("(log) Cannot open log file: %s - %s\n"),arq
,strerror(errno
));
794 if(debug
) debuga(_("Reading access log file: %s\n"),arq
);
799 // pre-read the file only if we have to show stats
800 if(ShowReadStatistics
&& !from_stdin
&& !from_pipe
) {
808 while ((nread
=fread(tmp4
,1,sizeof(tmp4
),fp_in
))>0) {
809 for (i
=0 ; i
<nread
; i
++)
811 if (tmp4
[i
]!='\n' && tmp4
[i
]!='\r') {
815 if (tmp4
[i
]=='\n' || tmp4
[i
]=='\r') {
822 printf(_("SARG: Records in file: %lu, reading: %3.2f%%"),recs1
,(float) 0);
827 longline_reset(line
);
829 while ((linebuf
=longline_read(fp_in
,line
))!=NULL
) {
830 blen
=strlen(linebuf
);
832 if (ilf
==ILF_Unknown
) {
833 if(strncmp(linebuf
,"#Software: Mic",14) == 0) {
834 fixendofline(linebuf
);
836 debuga(_("Log is from Microsoft ISA: %s\n"),linebuf
);
842 if(strncmp(linebuf
,"*** SARG Log ***",16) == 0) {
843 if (getperiod_fromsarglog(arqtt
,&period
)<0) {
844 debuga(_("The name of the file is invalid: %s\n"),arq
);
853 if(!fp_log
&& strcmp(ParsedOutputLog
, "no") != 0 && ilf
!=ILF_Sarg
) {
854 if(access(ParsedOutputLog
,R_OK
) != 0) {
855 my_mkdir(ParsedOutputLog
);
857 sprintf(arq_log
,"%s/sarg_temp.log",ParsedOutputLog
);
858 if((fp_log
=MY_FOPEN(arq_log
,"w"))==NULL
) {
859 debuga(_("(log) Cannot open log file: %s - %s\n"),arq_log
,strerror(errno
));
862 fputs("*** SARG Log ***\n",fp_log
);
866 if( ShowReadStatistics
&& !from_stdin
&& --OutputNonZero
<=0) {
867 double perc
= recs2
* 100. / recs1
;
868 printf(_("SARG: Records in file: %lu, reading: %3.2lf%%"),recs1
,perc
);
871 OutputNonZero
= REPORT_EVERY_X_LINES
;
873 if(blen
< 58) continue;
874 if(strstr(linebuf
,"HTTP/0.0") != 0) continue;
875 if(strstr(linebuf
,"logfile turned over") != 0) continue;
876 if(linebuf
[0] == ' ') continue;
879 if(ExcludeString
[0] != '\0') {
881 getword_start(&gwarea
,ExcludeString
);
882 while(strchr(gwarea
.current
,':') != 0) {
883 if (getword_multisep(val1
,sizeof(val1
),&gwarea
,':')<0) {
884 debuga(_("Maybe you have a broken record or garbage in your exclusion string\n"));
887 if((str
=(char *) strstr(linebuf
,val1
)) != (char *) NULL
) {
892 if(!exstring
&& (str
=(char *) strstr(linebuf
,gwarea
.current
)) != (char *) NULL
)
894 if(exstring
) continue;
899 printf("BUF=%s\n",linebuf
);
902 if (ilf
==ILF_Squid
|| ilf
==ILF_Common
|| ilf
==ILF_Unknown
) {
903 getword_start(&gwarea
,linebuf
);
904 if (getword(data
,sizeof(data
),&gwarea
,' ')<0) {
905 debuga(_("Maybe you have a broken time in your access.log file\n"));
908 if((str
=(char *) strchr(data
, '.')) != (char *) NULL
&& (str
=(char *) strchr(str
+1, '.')) != (char *) NULL
) {
912 if (getword(user
,sizeof(user
),&gwarea
,' ')<0 || getword_skip(255,&gwarea
,' ')<0) {
913 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
917 if (getword_skip(255,&gwarea
,' ')<0 || getword(user
,sizeof(user
),&gwarea
,' ')<0) {
918 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
922 if (getword(data
,sizeof(data
),&gwarea
,']')<0 || getword_skip(MAXLEN
,&gwarea
,'"')<0 ||
923 getword(fun
,sizeof(fun
),&gwarea
,' ')<0) {
924 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
927 if (getword_ptr(linebuf
,&url
,&gwarea
,' ')<0) {
928 debuga(_("Maybe you have a broken url in your %s file\n"),arq
);
931 if (getword_skip(MAXLEN
,&gwarea
,' ')<0) {
932 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
935 if (getword(code2
,sizeof(code2
),&gwarea
,' ')<0) {
936 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
939 if (getword(tam
,sizeof(tam
),&gwarea
,' ')<0) {
940 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
943 if((str
=(char *) strchr(gwarea
.current
, ' ')) != (char *) NULL
) {
944 if (getword(code
,sizeof(code
),&gwarea
,' ')<0) {
945 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
949 if (getword(code
,sizeof(code
),&gwarea
,'\0')<0) {
950 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
955 if ((str
= strchr(code
, ':')) != NULL
)
958 if(strcmp(tam
,"\0") == 0)
964 getword_start(&gwarea
,data
+1);
965 if (getword_multisep(data
,sizeof(data
),&gwarea
,':')<0){
966 debuga(_("Maybe you have a broken date in your %s file\n"),arq
);
969 if (getword_multisep(hora
,sizeof(hora
),&gwarea
,' ')<0){
970 debuga(_("Maybe you have a broken date in your %s file\n"),arq
);
973 getword_start(&gwarea
,data
);
974 if (getword_atoll(&iday
,&gwarea
,'/')<0){
975 debuga(_("Maybe you have a broken date in your %s file\n"),arq
);
978 if (getword(mes
,sizeof(mes
),&gwarea
,'/')<0){
979 debuga(_("Maybe you have a broken date in your %s file\n"),arq
);
982 if (getword_atoll(&iyear
,&gwarea
,'/')<0){
983 debuga(_("Maybe you have a broken date in your %s file\n"),arq
);
987 imonth
=month2num(mes
)+1;
988 idata
=builddia(iday
,imonth
,iyear
);
989 computedate(iyear
,imonth
,iday
,&tt
);
993 if(ilf
==ILF_Unknown
|| ilf
==ILF_Squid
) {
994 if (getword(elap
,sizeof(elap
),&gwarea
,' ')<0) {
995 debuga(_("Maybe you have a broken elapsed time in your %s file\n"),arq
);
998 while(strcmp(elap
,"") == 0 && gwarea
.current
[0] != '\0')
999 if (getword(elap
,sizeof(elap
),&gwarea
,' ')<0) {
1000 debuga(_("Maybe you have a broken elapsed time in your %s file\n"),arq
);
1003 if(strlen(elap
) < 1) continue;
1004 if (getword(ip
,sizeof(ip
),&gwarea
,' ')<0){
1005 debuga(_("Maybe you have a broken client IP address in your %s file\n"),arq
);
1008 if (getword(code
,sizeof(code
),&gwarea
,' ')<0){
1009 debuga(_("Maybe you have a broken result code in your %s file\n"),arq
);
1012 if (getword(tam
,sizeof(tam
),&gwarea
,' ')<0){
1013 debuga(_("Maybe you have a broken amount of data in your %s file\n"),arq
);
1016 if (getword(fun
,sizeof(fun
),&gwarea
,' ')<0){
1017 debuga(_("Maybe you have a broken request method in your %s file\n"),arq
);
1020 if (getword_ptr(linebuf
,&url
,&gwarea
,' ')<0){
1021 debuga(_("Maybe you have a broken url in your %s file\n"),arq
);
1024 if (getword(user
,sizeof(user
),&gwarea
,' ')<0){
1025 debuga(_("Maybe you have a broken user ID in your %s file\n"),arq
);
1034 debuga(_("Cannot convert the timestamp from the squid log file\n"));
1038 strftime(tbuf2
, sizeof(tbuf2
), "%H%M", t
);
1040 idata
=(t
->tm_year
+1900)*10000+(t
->tm_mon
+1)*100+t
->tm_mday
;
1043 if (ilf
==ILF_Sarg
) {
1044 getword_start(&gwarea
,linebuf
);
1045 if (getword(data
,sizeof(data
),&gwarea
,'\t')<0){
1046 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1049 if (getword(hora
,sizeof(hora
),&gwarea
,'\t')<0) {
1050 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1053 if (getword(user
,sizeof(user
),&gwarea
,'\t')<0) {
1054 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1057 if (getword(ip
,sizeof(ip
),&gwarea
,'\t')<0) {
1058 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1061 if (getword_ptr(linebuf
,&url
,&gwarea
,'\t')<0){
1062 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1065 if (getword(tam
,sizeof(tam
),&gwarea
,'\t')<0){
1066 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1069 if (getword(code
,sizeof(code
),&gwarea
,'\t')<0){
1070 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1073 if (getword(elap
,sizeof(elap
),&gwarea
,'\t')<0){
1074 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1077 if (getword(smartfilter
,sizeof(smartfilter
),&gwarea
,'\0')<0){
1078 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1081 getword_start(&gwarea
,data
);
1082 if (getword_atoll(&iday
,&gwarea
,'/')<0 || iday
<1 || iday
>31){
1083 debuga(_("Maybe you have a broken date in your %s file\n"),arq
);
1086 if (getword_atoll(&imonth
,&gwarea
,'/')<0 || imonth
<1 || imonth
>12){
1087 debuga(_("Maybe you have a broken date in your %s file\n"),arq
);
1090 if (getword_atoll(&iyear
,&gwarea
,'\0')<0){
1091 debuga(_("Maybe you have a broken date in your %s file\n"),arq
);
1094 idata
=builddia(iday
,imonth
,iyear
);
1095 computedate(iyear
,imonth
,iday
,&tt
);
1099 if (linebuf
[0] == '#') {
1100 int ncols
,cols
[ISACOL_Last
];
1102 fixendofline(linebuf
);
1103 getword_start(&gwarea
,linebuf
);
1104 // remove the #Fields: column at the beginning of the line
1105 if (getword_skip(1000,&gwarea
,' ')<0){
1106 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1109 for (ncols
=0 ; ncols
<ISACOL_Last
; ncols
++) cols
[ncols
]=-1;
1111 while(gwarea
.current
[0] != '\0') {
1112 if (getword(val1
,sizeof(val1
),&gwarea
,'\t')<0){
1113 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1116 if(strcmp(val1
,"c-ip") == 0) cols
[ISACOL_Ip
]=ncols
;
1117 if(strcmp(val1
,"cs-username") == 0) cols
[ISACOL_UserName
]=ncols
;
1118 if(strcmp(val1
,"date") == 0) cols
[ISACOL_Date
]=ncols
;
1119 if(strcmp(val1
,"time") == 0) cols
[ISACOL_Time
]=ncols
;
1120 if(strcmp(val1
,"time-taken") == 0) cols
[ISACOL_TimeTaken
]=ncols
;
1121 if(strcmp(val1
,"sc-bytes") == 0) cols
[ISACOL_Bytes
]=ncols
;
1122 if(strcmp(val1
,"cs-uri") == 0) cols
[ISACOL_Uri
]=ncols
;
1123 if(strcmp(val1
,"sc-status") == 0) cols
[ISACOL_Status
]=ncols
;
1126 if (cols
[ISACOL_Ip
]>=0) {
1128 for (ncols
=0 ; ncols
<ISACOL_Last
; ncols
++)
1129 isa_cols
[ncols
]=cols
[ncols
];
1133 if (!isa_ncols
) continue;
1134 getword_start(&gwarea
,linebuf
);
1135 for (x
=0 ; x
<isa_ncols
; x
++) {
1136 if (getword_ptr(linebuf
,&str
,&gwarea
,'\t')<0) {
1137 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),arq
);
1140 if (x
==isa_cols
[ISACOL_Ip
]) {
1141 if (strlen(str
)>=sizeof(ip
)) {
1142 debuga(_("Maybe you have a broken IP in your %s file\n"),arq
);
1146 } else if (x
==isa_cols
[ISACOL_UserName
]) {
1147 if (strlen(str
)>=sizeof(user
)) {
1148 debuga(_("Maybe you have a broken user ID in your %s file\n"),arq
);
1152 } else if (x
==isa_cols
[ISACOL_Date
]) {
1153 if (strlen(str
)>=sizeof(data
)) {
1154 debuga(_("Maybe you have a broken date in your %s file\n"),arq
);
1158 } else if (x
==isa_cols
[ISACOL_Time
]) {
1159 if (strlen(str
)>=sizeof(hora
)) {
1160 debuga(_("Maybe you have a broken time in your %s file\n"),arq
);
1164 } else if (x
==isa_cols
[ISACOL_TimeTaken
]) {
1165 if (strlen(str
)>=sizeof(elap
)) {
1166 debuga(_("Maybe you have a broken download duration in your %s file\n"),arq
);
1170 } else if (x
==isa_cols
[ISACOL_Bytes
]) {
1171 if (strlen(str
)>=sizeof(tam
)) {
1172 debuga(_("Maybe you have a broken download size in your %s file\n"),arq
);
1176 } else if (x
==isa_cols
[ISACOL_Uri
]) {
1178 } else if (x
==isa_cols
[ISACOL_Status
]) {
1179 if (strlen(str
)>=sizeof(code
)) {
1180 debuga(_("Maybe you have a broken access code in your %s file\n"),arq
);
1187 if(strcmp(code
,"401") == 0 || strcmp(code
,"403") == 0 || strcmp(code
,"407") == 0) {
1188 sprintf(val1
,"DENIED/%s",code
);
1191 getword_start(&gwarea
,data
);
1192 if (getword_atoll(&iyear
,&gwarea
,'-')<0){
1193 debuga(_("Maybe you have a broken year in your %s file\n"),arq
);
1196 if (getword_atoll(&imonth
,&gwarea
,'-')<0){
1197 debuga(_("Maybe you have a broken month in your %s file\n"),arq
);
1200 if (getword_atoll(&iday
,&gwarea
,'\0')<0){
1201 debuga(_("Maybe you have a broken day in your %s file\n"),arq
);
1205 idata
=builddia(iday
,imonth
,iyear
);
1206 computedate(iyear
,imonth
,iday
,&tt
);
1210 debuga(_("Unknown input log file format\n"));
1214 strftime(dia
, sizeof(dia
), "%d/%m/%Y", t
);
1215 snprintf(hora
,sizeof(hora
),"%02d:%02d:%02d",t
->tm_hour
,t
->tm_min
,t
->tm_sec
);
1218 printf("DATE=%s IDATA=%d DFROM=%d DUNTIL=%d\n",date
,idata
,dfrom
,duntil
);
1220 if(date
[0] != '\0'){
1221 if(idata
< dfrom
|| idata
> duntil
) continue;
1224 // Record only hours usage which is required
1226 if( bsearch( &( t
-> tm_wday
), weekdays
.list
, weekdays
.len
,
1227 sizeof( int ), compar
) == NULL
)
1230 if( bsearch( &( t
-> tm_hour
), hours
.list
, hours
.len
,
1231 sizeof( int ), compar
) == NULL
)
1236 if(strlen(user
) > MAX_USER_LEN
) {
1237 if (debugm
) printf(_("User ID too long: %s\n"),user
);
1243 if(IncludeUsers
[0] != '\0') {
1244 sprintf(val1
,":%s:",user
);
1245 if((str
=(char *) strstr(IncludeUsers
,val1
)) == (char *) NULL
)
1250 if (debugm
) printf(_("Excluded code: %s\n"),code
);
1255 if(testvaliduserchar(user
))
1259 if((str
= strstr(user
,"%20")) != NULL
) {
1261 This is a patch introduced to solve bug #1624251 reported at sourceforge but
1262 the side effect is to truncate the name at the first space and merge the reports
1263 of people whose name is identical up to the first space.
1265 The old code used to truncate the user name at the first % if a %20 was
1266 found anywhere in the string. That means the string could be truncated
1267 at the wrong place if another % occured before the %20. This new code should
1268 avoid that problem and only truncate at the space. There is no bug
1269 report indicating that anybody noticed this.
1275 Code prior to 2.2.7 used to replace any %xx by a dot as long as a %5c was
1276 found in the user name.
1278 while((str
= strstr(user
,"%5c")) != NULL
) {
1280 for (x
=3 ; str
[x
] ; x
++) str
[x
-2]=str
[x
];
1288 The full URL is not saved in sarg log. There is no point in testing the URL to detect
1291 download_flag
=is_download_suffix(url
);
1292 if (download_flag
) {
1297 download_flag
=false;
1299 // remove any protocol:// at the beginning of the URL
1300 if ((str
= strchr(url
,'/')) != NULL
&& str
[1] == '/') {
1304 for (i
=0 ; str
[i
] ; i
++)
1310 url_hostname(url
,hostname
,sizeof(hostname
));
1314 if(url
[0] == '\0') continue;
1316 if(addr
[0] != '\0'){
1317 if(strcmp(addr
,ip
)!=0) continue;
1320 if(!vhexclude(url
)) {
1321 if (debugm
) printf(_("Excluded site: %s\n"),url
);
1330 getword_start(&gwarea
,hora
);
1332 if (getword_multisep(warea
,sizeof(warea
),&gwarea
,':')<0){
1333 debuga(_("Maybe you have a broken time in your %s file\n"),arq
);
1336 strncat(hmr
,warea
,2);
1339 strncat(hmr
,gwarea
.current
,2);
1341 if(atoi(hmr
) < atoi(hm
) || atoi(hmr
) > atoi(hmf
)) continue;
1344 if(site
[0] != '\0'){
1345 if(strstr(url
,site
)==0) continue;
1353 if(strcmp(user
,"-") == 0 || strcmp(user
," ") == 0 || strcmp(user
,"") == 0) {
1354 if(RecordsWithoutUser
== RECORDWITHOUTUSER_IP
) {
1358 if(RecordsWithoutUser
== RECORDWITHOUTUSER_IGNORE
)
1360 if(RecordsWithoutUser
== RECORDWITHOUTUSER_EVERYBODY
)
1361 strcpy(user
,"everybody");
1364 if(NtlmUserFormat
== NTLMUSERFORMAT_USER
) {
1365 if((str
= strchr(user
,'_')) != 0) {
1366 strcpy(warea
,str
+1);
1369 if((str
= strchr(user
,'+')) != 0) {
1370 strcpy(warea
,str
+1);
1378 if(strcmp(user
,us
)!=0) continue;
1382 sprintf(wuser
,":%s:",user
);
1383 if(strstr(userfile
, wuser
) == 0)
1388 if(!vuexclude(user
)) {
1389 if (debugm
) printf(_("Excluded user: %s\n"),user
);
1395 if(strcmp(user
,"-") ==0 || strcmp(user
," ") ==0 || strcmp(user
,"") ==0 || strcmp(user
,":") ==0)
1399 if(atol(elap
)>max_elapsed
) {
1405 if((str
=(char *) strstr(linebuf
, "[SmartFilter:")) != (char *) NULL
) {
1407 sprintf(smartfilter
,"\"%s\"",str
+1);
1408 } else sprintf(smartfilter
,"\"\"");
1412 for (ufile
=first_user_file
; ufile
&& strcmp(user
,ufile
->user
->id
)!=0 ; ufile
=ufile
->next
) {
1414 if (ufile
->file
) nopen
++;
1417 ufile
=malloc(sizeof(*ufile
));
1419 debuga(_("Not enough memory to store the user %s\n"),user
);
1422 memset(ufile
,0,sizeof(*ufile
));
1423 ufile
->next
=first_user_file
;
1424 first_user_file
=ufile
;
1425 uinfo
=userinfo_create(user
);
1427 uinfo
->id_is_ip
=id_is_ip
;
1430 prev_ufile
->next
=ufile
->next
;
1431 ufile
->next
=first_user_file
;
1432 first_user_file
=ufile
;
1436 if (ufile
->file
==NULL
) {
1437 if (nopen
>=maxopenfiles
) {
1439 for (ufile1
=first_user_file
; ufile1
; ufile1
=ufile1
->next
) {
1440 if (ufile1
->file
!=NULL
) {
1441 if (x
>=maxopenfiles
) {
1442 if (fclose(ufile1
->file
)==EOF
) {
1443 debuga(_("Failed to close the log file of user %s - %s\n"),ufile1
->user
->id
,strerror(errno
));
1452 if (snprintf (tmp3
, sizeof(tmp3
), "%s/%s.unsort", tmp
, ufile
->user
->filename
)>=sizeof(tmp3
)) {
1453 debuga(_("Temporary user file name too long: %s/%s.unsort\n"), tmp
, ufile
->user
->filename
);
1456 if ((ufile
->file
= MY_FOPEN (tmp3
, "a")) == NULL
) {
1457 debuga(_("(log) Cannot open temporary file: %s - %s\n"), tmp3
, strerror(errno
));
1462 /*if ( strcmp ( user , sz_Last_User ) != 0 ) {
1463 if ( fp_Write_User )
1464 fclose( fp_Write_User ) ;
1465 sprintf (tmp3, "%s/%s.unsort", tmp, user);
1467 if ((fp_Write_User = MY_FOPEN (tmp3, "a")) == NULL) {
1468 fprintf (stderr, "%s: (log) %s: %s - %s\n", argv[0], _("Cannot open temporary file"), tmp3, strerror(errno));
1471 strcpy( sz_Last_User , user ) ;
1473 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) {
1474 debuga(_("Write error in the log file of user %s\n"),user
);
1478 if(fp_log
&& ilf
!=ILF_Sarg
)
1479 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
);
1483 if(!dataonly
&& download_flag
&& download_url
&& strstr(code
,"DENIED") == 0) {
1486 if ( ! fp_Download_Unsort
) {
1487 if ((fp_Download_Unsort
= MY_FOPEN ( sz_Download_Unsort
, "a")) == NULL
) {
1488 debuga(_("(log) Cannot open temporary file: %s - %s\n"),sz_Download_Unsort
, strerror(errno
));
1492 fprintf(fp_Download_Unsort
,"%s\t%s\t%s\t%s\t%s\n",dia
,hora
,user
,ip
,download_url
);
1495 if((ReportType
& REPORT_TYPE_DENIED
) != 0 || (ReportType
& REPORT_TYPE_AUTH_FAILURES
) != 0) {
1496 if(fp_denied
&& strstr(code
,"DENIED/403") != 0) {
1497 fprintf(fp_denied
, "%s\t%s\t%s\t%s\t%s\n",dia
,hora
,user
,ip
,urly
);
1500 if(fp_authfail
&& (strstr(code
,"DENIED/401") != 0 || strstr(code
,"DENIED/407") != 0)) {
1501 fprintf(fp_authfail
, "%s\t%s\t%s\t%s\t%s\n",dia
,hora
,user
,ip
,urly
);
1506 if (ilf
!=ILF_Sarg
) {
1507 if(!totper
|| idata
<mindate
){
1509 memcpy(&period
.start
,t
,sizeof(*t
));
1510 strcpy(start_hour
,tbuf2
);
1512 if (!totper
|| idata
>maxdate
) {
1514 memcpy(&period
.end
,t
,sizeof(*t
));
1520 printf("IP=\t%s\n",ip
);
1521 printf("USER=\t%s\n",user
);
1522 printf("ELAP=\t%s\n",elap
);
1523 printf("DATE=\t%s\n",dia
);
1524 printf("TIME=\t%s\n",hora
);
1525 printf("FUNC=\t%s\n",fun
);
1526 printf("URL=\t%s\n",url
);
1527 printf("CODE=\t%s\n",code
);
1528 printf("LEN=\t%s\n",tam
);
1536 if( ShowReadStatistics
)
1537 printf(_("SARG: Records in file: %lu, reading: %3.2f%%\n"),recs1
, (float) 100 );
1542 debuga(_(" Records read: %ld, written: %ld, excluded: %ld\n"),totregsl
,totregsg
,totregsx
);
1544 longline_destroy(&line
);
1545 if ( fp_Download_Unsort
)
1546 fclose (fp_Download_Unsort
);
1548 for (ufile
=first_user_file
; ufile
; ufile
=ufile1
) {
1550 if (ufile
->file
!=NULL
) fclose(ufile
->file
);
1555 free_excludecodes();
1561 for (ilf
=0 ; ilf
<ILF_Last
; ilf
++) totalcount
+=ilf_count
[ilf
];
1563 if(ilf_count
[ILF_Common
]>0 && ilf_count
[ILF_Squid
]>0)
1564 debuga(_("Log with mixed records format (squid and common log)\n"));
1566 if(ilf_count
[ILF_Common
]>0 && ilf_count
[ILF_Squid
]==0)
1567 debuga(_("Common log format\n"));
1569 if(ilf_count
[ILF_Common
]==0 && ilf_count
[ILF_Squid
]>0)
1570 debuga(_("Squid log format\n"));
1572 if(ilf_count
[ILF_Sarg
]>0)
1573 debuga(_("Sarg log format\n"));
1575 if(totalcount
==0 && totregsg
)
1576 debuga(_("Log with invalid format\n"));
1580 debuga(_("No records found\n"));
1582 if(fp_denied
) fclose(fp_denied
);
1583 if(fp_authfail
) fclose(fp_authfail
);
1585 if(userfile
) free(userfile
);
1590 if (date
[0]!='\0') {
1591 char date0
[30], date1
[30];
1593 strftime(date0
,sizeof(date0
),"%d/%m/%Y",&period
.start
);
1594 strftime(date1
,sizeof(date1
),"%d/%m/%Y",&period
.end
);
1595 debuga(_("Period covered by log files: %s-%s\n"),date0
,date1
);
1596 getperiod_fromrange(&period
,dfrom
,duntil
);
1598 if (getperiod_buildtext(&period
)<0) {
1599 debuga(_("Failed to build the string representation of the date range\n"));
1604 debugaz("data",dia
);
1605 debugaz("period",period
.text
);
1609 debuga(_("Period: %s\n"),period
.text
);
1615 fclose(fp_authfail
);
1617 if(fp_log
!= NULL
) {
1619 strcpy(end_hour
,tbuf2
);
1620 strftime(val2
,sizeof(val2
),"%d%m%Y",&period
.start
);
1621 strftime(val1
,sizeof(val1
),"%d%m%Y",&period
.end
);
1622 sprintf(val4
,"%s/sarg-%s_%s-%s_%s.log",ParsedOutputLog
,val2
,start_hour
,val1
,end_hour
);
1623 if (rename(arq_log
,val4
)) {
1624 debuga(_("failed to rename %s to %s - %s\n"),arq_log
,val4
,strerror(errno
));
1626 strcpy(arq_log
,val4
);
1628 if(strcmp(ParsedOutputLogCompress
,"nocompress") != 0 && ParsedOutputLogCompress
[0] != '\0') {
1630 No double quotes around ParsedOutputLogCompress because it may contain command line options. If double quotes are
1631 necessary around the command name, put them in the configuration file.
1633 sprintf(val1
,"%s \"%s\"",ParsedOutputLogCompress
,arq_log
);
1634 cstatus
=system(val1
);
1635 if (!WIFEXITED(cstatus
) || WEXITSTATUS(cstatus
)) {
1636 debuga(_("command return status %d\n"),WEXITSTATUS(cstatus
));
1637 debuga(_("command: %s\n"),val1
);
1643 debuga(_("Sarg parsed log saved as %s\n"),arq_log
);
1646 if(DataFile
[0] == '\0' && (ReportType
& REPORT_TYPE_DENIED
) != 0) {
1647 sprintf(csort
,"sort -T \"%s\" -k 3,3 -k 5,5 -o \"%s\" \"%s\"",tmp
,denied_sort
,denied_unsort
);
1648 cstatus
=system(csort
);
1649 if (!WIFEXITED(cstatus
) || WEXITSTATUS(cstatus
)) {
1650 debuga(_("sort command return status %d\n"),WEXITSTATUS(cstatus
));
1651 debuga(_("sort command: %s\n"),csort
);
1654 unlink(denied_unsort
);
1657 sort_users_log(tmp
, debug
);
1659 if(DataFile
[0] != '\0')
1664 if((ReportType
& REPORT_TYPE_DENIED
) != 0)
1665 unlink(denied_sort
);
1667 if(strcmp(tmp
,"/tmp") != 0) {
1684 static void getusers(const char *pwdfile
, int debug
)
1693 debuga(_("Loading password file from %s\n"),pwdfile
);
1695 if ((fp_usr
= fopen(pwdfile
, "r")) == NULL
) {
1696 debuga(_("(getusers) Cannot open file %s - %s\n"),pwdfile
,strerror(errno
));
1700 if (fseek(fp_usr
, 0, SEEK_END
)==-1) {
1701 debuga(_("Failed to move till the end of the users file %s: %s\n"),pwdfile
,strerror(errno
));
1704 nreg
= ftell(fp_usr
);
1706 debuga(_("Cannot get the size of file %s\n"),pwdfile
);
1710 if (fseek(fp_usr
, 0, SEEK_SET
)==-1) {
1711 debuga(_("Failed to rewind the users file %s: %s\n"),pwdfile
,strerror(errno
));
1715 if((userfile
=(char *) malloc(nreg
))==NULL
){
1716 debuga(_("malloc error (%ld)\n"),nreg
);
1720 bzero(userfile
,nreg
);
1721 strcpy(userfile
,":");
1723 while(fgets(buf
,sizeof(buf
),fp_usr
)!=NULL
) {
1724 str
=strchr(buf
,':');
1726 debuga(_("You have an invalid user in your %s file\n"),pwdfile
);
1730 strcat(userfile
,buf
);