]> git.ipfire.org Git - thirdparty/sarg.git/blob - log.c
Merge branch 'v2.3' of ssh://git.code.sf.net/p/sarg/code into v2.3
[thirdparty/sarg.git] / log.c
1 /*
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
3 * 1998, 2013
4 *
5 * SARG donations:
6 * please look at http://sarg.sourceforge.net/donations.php
7 * Support:
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
9 * ---------------------------------------------------------------------
10 *
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.
15 *
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.
20 *
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.
24 *
25 */
26
27 #include "include/conf.h"
28 #include "include/defs.h"
29
30 #ifdef HAVE_GETOPT_H
31 #include <getopt.h>
32 #endif
33
34 #define REPORT_EVERY_X_LINES 5000
35 #define MAX_OPEN_USER_FILES 10
36
37 struct userfilestruct
38 {
39 struct userfilestruct *next;
40 struct userinfostruct *user;
41 FILE *file;
42 };
43
44 /*@null@*/static char *userfile=NULL;
45
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, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }, 24 };
48
49 //! Selected locale set through the environment variable.
50 char *CurrentLocale=NULL;
51
52 static void getusers(const char *pwdfile, int debug);
53
54 int main(int argc,char *argv[])
55 {
56 enum isa_col_id {
57 ISACOL_Ip,
58 ISACOL_UserName,
59 ISACOL_Date,
60 ISACOL_Time,
61 ISACOL_TimeTaken,
62 ISACOL_Bytes,
63 ISACOL_Uri,
64 ISACOL_Status,
65 ISACOL_Last //last entry of the list !
66 };
67 enum InputLogFormat {
68 ILF_Unknown,
69 ILF_Squid,
70 ILF_Common,
71 ILF_Sarg,
72 ILF_Isa,
73 ILF_Last //last entry of the list !
74 };
75
76 FILE *fp_in = NULL, *fp_denied=NULL, *fp_authfail=NULL, *fp_log=NULL;
77
78 char sz_Download_Unsort[ 20000 ] ;
79 FILE * fp_Download_Unsort = NULL ;
80
81 extern int optind;
82 extern int optopt;
83 extern char *optarg;
84
85 char data[255];
86 char elap[255];
87 char ip[MAXLEN];
88 char tam[255];
89 char fun[MAXLEN];
90 char wuser[MAXLEN];
91 char smartfilter[MAXLEN];
92 char dia[128];
93 char mes[30];
94 char hora[30];
95 char date[255];
96 char arq[255];
97 char arq_log[255];
98 int hm, hmf, hmr;
99 char hm_str[15];
100 char uagent[MAXLEN];
101 char hexclude[MAXLEN];
102 char csort[MAXLEN];
103 int cstatus;
104 char tbuf2[128];
105 char *str;
106 char tmp3[MAXLEN];
107 char denied_unsort[MAXLEN];
108 char denied_sort[MAXLEN];
109 char authfail_unsort[MAXLEN];
110 char start_hour[128];
111 char *linebuf;
112 const char *url;
113 char *full_url;
114 char user[MAX_USER_LEN];
115 char splitprefix[MAXLEN];
116 enum InputLogFormat ilf;
117 int ilf_count[ILF_Last];
118 int ch;
119 int x;
120 int errflg=0;
121 int puser=0;
122 bool fhost=false;
123 bool dns=false;
124 bool fuser=false;
125 int idata=0;
126 int mindate=0;
127 int maxdate=0;
128 int iarq=0;
129 int isa_ncols=0,isa_cols[ISACOL_Last];
130 int lastlog=-1;
131 long long int nbytes;
132 long int elap_time;
133 bool from_stdin;
134 bool from_pipe;
135 int blen;
136 int maxopenfiles;
137 int nopen;
138 bool id_is_ip;
139 long totregsl=0;
140 long totregsg=0;
141 long totregsx=0;
142 bool totper=false;
143 long int max_elapsed=0;
144 long long int iyear, imonth, iday;
145 bool realt;
146 bool userip;
147 struct tm tt;
148 struct tm *t;
149 unsigned long recs1=0UL;
150 unsigned long recs2=0UL;
151 unsigned long int lines_read=0UL;
152 unsigned long int records_kept=0UL;
153 unsigned long int nusers=0UL;
154 int OutputNonZero = REPORT_EVERY_X_LINES ;
155 bool download_flag=false;
156 char download_url[MAXLEN];
157 struct getwordstruct gwarea;
158 longline line;
159 time_t tnum;
160 time_t start_time;
161 time_t end_time;
162 time_t read_start_time;
163 time_t read_end_time;
164 time_t process_start_time;
165 time_t process_end_time;
166 double read_elapsed;
167 double process_elapsed;
168 struct stat logstat;
169 struct userinfostruct *uinfo;
170 struct userfilestruct *first_user_file, *ufile, *ufile1, *prev_ufile;
171 static int split=0;
172 static int convert=0;
173 static int output_css=0;
174 static int show_statis=0;
175 int option_index;
176 static struct option long_options[]=
177 {
178 {"convert",no_argument,&convert,1},
179 {"css",no_argument,&output_css,1},
180 {"help",no_argument,NULL,'h'},
181 {"lastlog",required_argument,NULL,2},
182 {"keeplogs",no_argument,NULL,3},
183 {"split",no_argument,&split,1},
184 {"splitprefix",required_argument,NULL,'P'},
185 {"statistics",no_argument,&show_statis,1},
186 {0,0,0,0}
187 };
188
189 start_time=time(NULL);
190
191 #ifdef HAVE_LOCALE_H
192 setlocale(LC_TIME,"");
193 #endif
194
195 #if defined(ENABLE_NLS) && defined(HAVE_LOCALE_H)
196 CurrentLocale=setlocale (LC_ALL, "");
197 if (!CurrentLocale) {
198 fprintf(stderr,"SARG: Cannot set the locale LC_ALL to the environment variable\n");
199 exit(EXIT_FAILURE);
200 }
201 if (!bindtextdomain (PACKAGE_NAME, LOCALEDIR)) {
202 fprintf(stderr,"SARG: Cannot bind to text domain %s in directory %s (%s)\n",PACKAGE_NAME,LOCALEDIR,strerror(errno));
203 exit(EXIT_FAILURE);
204 }
205 if (!textdomain (PACKAGE_NAME)) {
206 fprintf(stderr,"SARG: Cannot set gettext domain for %s PACKAGE_NAME (%s)\n",PACKAGE_NAME,strerror(errno));
207 exit(EXIT_FAILURE);
208 }
209 #endif //ENABLE_NLS
210
211 BgImage[0]='\0';
212 LogoImage[0]='\0';
213 LogoText[0]='\0';
214 PasswdFile[0]='\0';
215 OutputEmail[0]='\0';
216 UserAgentLog[0]='\0';
217 ExcludeHosts[0]='\0';
218 ExcludeUsers[0]='\0';
219 ConfigFile[0]='\0';
220 code[0]='\0';
221 LastLog=0;
222 ReportType=0UL;
223 UserTabFile[0]='\0';
224 BlockIt[0]='\0';
225 ExternalCSSFile[0]='\0';
226 RedirectorLogFormat[0]='\0';
227 NRedirectorLogs=0;
228 for (ilf=0 ; ilf<ILF_Last ; ilf++) ilf_count[ilf]=0;
229
230 snprintf(ExcludeCodes,sizeof(ExcludeCodes),"%s/exclude_codes",SYSCONFDIR);
231 strcpy(GraphDaysBytesBarColor,"orange");
232 strcpy(BgColor,"#ffffff");
233 strcpy(TxColor,"#000000");
234 strcpy(TxBgColor,"lavender");
235 strcpy(TiColor,"darkblue");
236 strcpy(Width,"80");
237 strcpy(Height,"45");
238 strcpy(LogoTextColor,"#000000");
239 strcpy(HeaderColor,"darkblue");
240 strcpy(HeaderBgColor,"#dddddd");
241 strcpy(LogoTextColor,"#006699");
242 strcpy(FontSize,"9px");
243 strcpy(TempDir,"/tmp");
244 strcpy(OutputDir,"/var/www/html/squid-reports");
245 AnonymousOutputFiles=false;
246 Ip2Name=false;
247 strcpy(DateFormat,"u");
248 OverwriteReport=false;
249 RemoveTempFiles=true;
250 strcpy(ReplaceIndex,"index.html");
251 Index=INDEX_YES;
252 RecordsWithoutUser=RECORDWITHOUTUSER_IP;
253 UseComma=0;
254 strcpy(MailUtility,"mailx");
255 TopSitesNum=100;
256 TopUsersNum=0;
257 UserIp=0;
258 TopuserSort=TOPUSER_SORT_BYTES | TOPUSER_SORT_REVERSE;
259 UserSort=USER_SORT_BYTES | USER_SORT_REVERSE;
260 TopsitesSort=TOPSITE_SORT_CONNECT | TOPSITE_SORT_REVERSE;
261 LongUrl=0;
262 strcpy(FontFace,"Verdana,Tahoma,Arial");
263 datetimeby=DATETIME_BYTE;
264 strcpy(CharSet,"ISO-8859-1");
265 Privacy=0;
266 strcpy(PrivacyString,"***.***.***.***");
267 strcpy(PrivacyStringColor,"blue");
268 SuccessfulMsg=true;
269 TopUserFields=TOPUSERFIELDS_NUM | TOPUSERFIELDS_DATE_TIME | TOPUSERFIELDS_USERID | TOPUSERFIELDS_CONNECT |
270 TOPUSERFIELDS_BYTES | TOPUSERFIELDS_SETYB | TOPUSERFIELDS_IN_CACHE_OUT |
271 TOPUSERFIELDS_USED_TIME | TOPUSERFIELDS_MILISEC | TOPUSERFIELDS_PTIME |
272 TOPUSERFIELDS_TOTAL | TOPUSERFIELDS_AVERAGE;
273 UserReportFields=USERREPORTFIELDS_CONNECT | USERREPORTFIELDS_BYTES | USERREPORTFIELDS_SETYB |
274 USERREPORTFIELDS_IN_CACHE_OUT | USERREPORTFIELDS_USED_TIME | USERREPORTFIELDS_MILISEC |
275 USERREPORTFIELDS_PTIME | USERREPORTFIELDS_TOTAL | USERREPORTFIELDS_AVERAGE;
276 strcpy(DataFileDelimiter,";");
277 DataFileFields=DATA_FIELD_USER | DATA_FIELD_DATE | DATA_FIELD_TIME | DATA_FIELD_URL | DATA_FIELD_CONNECT |
278 DATA_FIELD_BYTES | DATA_FIELD_IN_CACHE | DATA_FIELD_OUT_CACHE | DATA_FIELD_ELAPSED;
279 ShowReadStatistics=true;
280 strcpy(IndexSortOrder,"D");
281 ShowSargInfo=true;
282 ShowSargLogo=true;
283 ParsedOutputLog[0]='\0';
284 strcpy(ParsedOutputLogCompress,"/bin/gzip -f");
285 DisplayedValues=DISPLAY_ABBREV;
286 strcpy(HeaderFontSize,"9px");
287 strcpy(TitleFontSize,"11px");
288 strcpy(AuthUserTemplateFile,"sarg_htaccess");
289 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");
290 Graphs=true;
291 #if defined(FONTDIR)
292 strcpy(GraphFont,FONTDIR"/DejaVuSans.ttf");
293 #else
294 GraphFont[0]='\0';
295 #endif
296 strcpy(Ulimit,"20000");
297 NtlmUserFormat=NTLMUSERFORMAT_DOMAINUSER;
298 IndexTree=INDEX_TREE_FILE;
299 IndexFields=INDEXFIELDS_DIRSIZE;
300 strcpy(RealtimeTypes,"GET,PUT,CONNECT");
301 RealtimeUnauthRec=REALTIME_UNAUTH_REC_SHOW;
302 RedirectorFilterOutDate=true;
303 DansguardianFilterOutDate=true;
304 DataFileUrl=DATAFILEURL_IP;
305 strcpy(MaxElapsed,"28800000");
306 BytesInSitesUsersReport=0;
307 UserAuthentication=0;
308 strcpy(LDAPHost,"127.0.0.1");
309 LDAPPort=389;
310 LDAPProtocolVersion=3;
311 LDAPBindDN[0]='\0';
312 LDAPBindPW[0]='\0';
313 LDAPBaseSearch[0]='\0';
314 strcpy(LDAPFilterSearch, "(uid=%s)");
315 strcpy(LDAPTargetAttr, "cn");
316 SortTableJs[0]='\0';
317
318 dia[0]='\0';
319 mes[0]='\0';
320 hora[0]='\0';
321 tmp[0]='\0';
322 tmp3[0]='\0';
323 us[0]='\0';
324 date[0]='\0';
325 df[0]='\0';
326 uagent[0]='\0';
327 hexclude[0]='\0';
328 addr[0]='\0';
329 hm=-1;
330 hmf=-1;
331 site[0]='\0';
332 outdir[0]='\0';
333 splitprefix[0]='\0';
334 elap[0]='\0';
335 email[0]='\0';
336 UserInvalidChar[0]='\0';
337 DataFile[0]='\0';
338 SquidGuardConf[0]='\0';
339 DansGuardianConf[0]='\0';
340 start_hour[0]='\0';
341 hm_str[0]='\0';
342 HostAliasFile[0]='\0';
343
344 denied_count=0;
345 download_count=0;
346 authfail_count=0;
347 dansguardian_count=0;
348 redirector_count=0;
349 useragent_count=0;
350 DeniedReportLimit=10;
351 AuthfailReportLimit=10;
352 DansGuardianReportLimit=10;
353 SquidGuardReportLimit=10;
354 DownloadReportLimit=50;
355 UserReportLimit=0;
356 debug=0;
357 debugz=0;
358 debugm=0;
359 iprel=false;
360 userip=false;
361 realt=false;
362 realtime_refresh=3;
363 realtime_access_log_lines=1000;
364 cost=0.01;
365 nocost=50000000;
366 ndownload=0;
367 squid24=false;
368 dfrom=0;
369 duntil=0;
370 KeepTempLog=false;
371
372 bzero(IncludeUsers, sizeof(IncludeUsers));
373 bzero(ExcludeString, sizeof(ExcludeString));
374 first_user_file=NULL;
375 memset(&period,0,sizeof(period));
376
377 NAccessLog=0;
378 for(x=0; x<MAXLOGS; x++)
379 AccessLog[x][0]='\0';
380 AccessLogFromCmdLine=0;
381 RedirectorLogFromCmdLine=0;
382
383 strcpy(Title,_("Squid User Access Report"));
384
385 while((ch = getopt_long_only(argc, argv, "a:b:c:d:e:f:g:hikl:L:mno:P:prs:t:u:vw:xyz",long_options,&option_index)) != -1){
386 switch(ch)
387 {
388 case 0:
389 break;
390 case 2:
391 lastlog=atoi(optarg);
392 break;
393 case 3:
394 lastlog=0;
395 break;
396 case 'a':
397 safe_strcpy(addr,optarg,sizeof(addr));
398 break;
399 case 'b': //unused option
400 safe_strcpy(uagent,optarg,sizeof(uagent));
401 break;
402 case 'c':
403 safe_strcpy(hexclude,optarg,sizeof(hexclude));
404 break;
405 case 'd':
406 safe_strcpy(date,optarg,sizeof(date));
407 date_from(date, sizeof(date), &dfrom, &duntil);
408 break;
409 case 'e':
410 safe_strcpy(email,optarg,sizeof(email));
411 break;
412 case 'f':
413 safe_strcpy(ConfigFile,optarg,sizeof(ConfigFile));
414 break;
415 case 'g':
416 safe_strcpy(df,optarg,sizeof(df));
417 break;
418 case 'h':
419 usage(argv[0]);
420 exit(EXIT_SUCCESS);
421 case 'i':
422 iprel=true;
423 break;
424 case 'k':
425 KeepTempLog=true;
426 break;
427 case 'l':
428 if (NAccessLog>=MAXLOGS) {
429 debuga(_("Too many log files passed on command line with option %s.\n"),"-l");
430 exit(EXIT_FAILURE);
431 }
432 if (strlen(optarg)>=MAX_LOG_FILELEN) {
433 debuga(_("Log file name too long passed on command line with option %s: %s\n"),"-l",optarg);
434 exit(EXIT_FAILURE);
435 }
436 strcpy(AccessLog[NAccessLog],optarg);
437 NAccessLog++;
438 AccessLogFromCmdLine++;
439 break;
440 case 'L':
441 if (NRedirectorLogs>MAX_REDIRECTOR_LOGS) {
442 debuga(_("Too many log files passed on command line with option %s.\n"),"-L");
443 exit(EXIT_FAILURE);
444 }
445 if (strlen(optarg)>=MAX_REDIRECTOR_FILELEN) {
446 debuga(_("Log file name too long passed on command line with option %s: %s\n"),"-L",optarg);
447 exit(EXIT_FAILURE);
448 }
449 strcpy(RedirectorLogs[NRedirectorLogs],optarg);
450 NRedirectorLogs++;
451 RedirectorLogFromCmdLine++;
452 break;
453 case 'm':
454 debugm++;
455 break;
456 case 'n':
457 dns=true;
458 break;
459 case 'o':
460 safe_strcpy(outdir,optarg,sizeof(outdir));
461 break;
462 case 'p':
463 userip=true;
464 break;
465 case 'P':
466 safe_strcpy(splitprefix,optarg,sizeof(splitprefix));
467 break;
468 case 'r':
469 realt=true;
470 break;
471 case 's':
472 safe_strcpy(site,optarg,sizeof(site));
473 break;
474 case 't':
475 {
476 int h1,m1,h2,m2;
477
478 if(strstr(optarg,"-") == 0) {
479 if(sscanf(optarg,"%d:%d",&h1,&m1)!=2) {
480 debuga(_("Time period passed on the command line with option -t must be HH:MM\n"));
481 exit(EXIT_FAILURE);
482 }
483 hm=h1*100+m1;
484 hmf=hm;
485 snprintf(hm_str,sizeof(hm_str),"%02d:%02d",h1,m1);
486 } else {
487 if(sscanf(optarg,"%d:%d-%d:%d",&h1,&m1,&h2,&m2)!=4) {
488 debuga(_("Time range passed on the command line with option -t must be HH:MM-HH:MM\n"));
489 exit(EXIT_FAILURE);
490 }
491 hm=h1*100+m1;
492 hmf=h2*100+m2;
493 snprintf(hm_str,sizeof(hm_str),"%02d:%02d-%02d:%02d",h1,m1,h2,m2);
494 }
495 break;
496 }
497 case 'u':
498 safe_strcpy(us,optarg,sizeof(us));
499 break;
500 case 'v':
501 version();
502 break;
503 case 'w':
504 safe_strcpy(tmp,optarg,sizeof(tmp));
505 break;
506 case 'x':
507 debug++;
508 break;
509 case 'y': //unused option
510 langcode++;
511 break;
512 case 'z':
513 debugz++;
514 break;
515 case ':':
516 debuga(_("Option -%c requires an argument\n"),optopt);
517 exit(EXIT_FAILURE);
518 case '?':
519 usage(argv[0]);
520 exit(EXIT_FAILURE);
521 default:
522 abort();
523 }
524 }
525
526 if (errflg>0) {
527 usage(argv[0]);
528 exit(2);
529 }
530
531 if (optind<argc) {
532 for (iarq=optind ; iarq<argc ; iarq++) {
533 if (NAccessLog>=MAXLOGS) {
534 debuga(_("Too many log files passed on command line.\n"));
535 exit(EXIT_FAILURE);
536 }
537 if (strlen(argv[iarq])>=MAX_LOG_FILELEN) {
538 debuga(_("Log file name too long passed on command line: %s\n"),argv[iarq]);
539 exit(EXIT_FAILURE);
540 }
541 strcpy(AccessLog[NAccessLog],argv[iarq]);
542 NAccessLog++;
543 AccessLogFromCmdLine++;
544 }
545 }
546
547 if(debug) debuga(_("Init\n"));
548
549 if(ConfigFile[0] == '\0') snprintf(ConfigFile,sizeof(ConfigFile),"%s/sarg.conf",SYSCONFDIR);
550 if(access(ConfigFile, R_OK) != 0) {
551 debuga(_("Cannot open file \"%s\": %s\n"),ConfigFile,strerror(errno));
552 exit(EXIT_FAILURE);
553 }
554
555 if(access(ConfigFile, R_OK) == 0)
556 getconf();
557
558 if(userip) UserIp=true;
559
560 if(dns) ip2name_forcedns();
561
562 if (lastlog>=0) LastLog=lastlog;
563
564 if(outdir[0] == '\0') strcpy(outdir,OutputDir);
565 if(outdir[0] != '\0') strcat(outdir,"/");
566
567 if(realt) {
568 realtime();
569 exit(EXIT_SUCCESS);
570 }
571
572 if(IndexTree == INDEX_TREE_FILE)
573 strcpy(ImageFile,"../images");
574 else
575 strcpy(ImageFile,"../../../images");
576
577 dataonly=0;
578 if(DataFile[0] != '\0')
579 dataonly++;
580
581 if(df[0] == '\0') strcpy(df,DateFormat);
582 else strcpy(DateFormat,df);
583
584 if(df[0] == '\0') {
585 strcpy(df,"u");
586 strcpy(DateFormat,"u");
587 }
588 if (df[0]=='w')
589 IndexTree=INDEX_TREE_FILE;
590
591 if(NAccessLog == 0) {
592 strcpy(AccessLog[0],"/var/log/squid/access.log");
593 NAccessLog++;
594 }
595
596 if(output_css) {
597 css_content(stdout);
598 exit(EXIT_SUCCESS);
599 }
600 if(split) {
601 for (iarq=0 ; iarq<NAccessLog ; iarq++)
602 splitlog(AccessLog[iarq], df, dfrom, duntil, convert, splitprefix);
603 exit(EXIT_SUCCESS);
604 }
605 if(convert) {
606 for (iarq=0 ; iarq<NAccessLog ; iarq++)
607 convlog(AccessLog[iarq], df, dfrom, duntil);
608 exit(EXIT_SUCCESS);
609 }
610
611 load_excludecodes(ExcludeCodes);
612
613 if(access(PasswdFile, R_OK) == 0) {
614 getusers(PasswdFile,debug);
615 puser++;
616 }
617
618 if(hexclude[0] == '\0')
619 strcpy(hexclude,ExcludeHosts);
620 if(hexclude[0] != '\0') {
621 gethexclude(hexclude,debug);
622 fhost=true;
623 }
624
625 if(ReportType == 0) {
626 ReportType=REPORT_TYPE_TOPUSERS | REPORT_TYPE_TOPSITES | REPORT_TYPE_USERS_SITES |
627 REPORT_TYPE_SITES_USERS | REPORT_TYPE_DATE_TIME | REPORT_TYPE_DENIED |
628 REPORT_TYPE_AUTH_FAILURES | REPORT_TYPE_SITE_USER_TIME_DATE | REPORT_TYPE_DOWNLOADS;
629 }
630
631 if(access(ExcludeUsers, R_OK) == 0) {
632 getuexclude(ExcludeUsers,debug);
633 fuser=true;
634 }
635 if (HostAliasFile[0] != '\0')
636 read_hostalias(HostAliasFile);
637
638 indexonly=false;
639 if(fuser) {
640 if(is_indexonly())
641 indexonly=true;
642 }
643 if(strcmp(ExcludeUsers,"indexonly") == 0) indexonly=true;
644 if(Index == INDEX_ONLY) indexonly=true;
645
646 if(MaxElapsed[0] != '\0') max_elapsed=atol(MaxElapsed);
647
648 if(uagent[0] == '\0') strcpy(uagent,UserAgentLog);
649
650 if(tmp[0] == '\0') strcpy(tmp,TempDir);
651 else strcpy(TempDir,tmp);
652 /*
653 For historical reasons, the temporary directory is the subdirectory "sarg" of the path
654 provided by the user.
655 */
656 strcat(tmp,"/sarg");
657
658 if (tmp[0]!='\0' && strncmp(outdir,tmp,strlen(tmp))==0) {
659 debuga(_("The output directory \"%s\" must be outside of the temporary directory \"%s\"\n"),outdir,tmp);
660 exit(EXIT_FAILURE);
661 }
662
663 if(email[0] == '\0' && OutputEmail[0] != '\0') strcpy(email,OutputEmail);
664
665 if(email[0] != '\0') {
666 my_mkdir(tmp);
667 strcpy(outdir,tmp);
668 strcat(outdir,"/");
669 }
670
671 if(access(tmp, R_OK) == 0) {
672 if (debug) debuga(_("Deleting temporary directory \"%s\"\n"),tmp);
673 emptytmpdir(tmp);
674 }
675 my_mkdir(tmp);
676 snprintf(denied_unsort,sizeof(denied_unsort),"%s/denied.int_unsort",tmp);
677 snprintf(denied_sort,sizeof(denied_sort),"%s/denied.int_log",tmp);
678 snprintf(authfail_unsort,sizeof(authfail_unsort),"%s/authfail.int_unsort",tmp);
679
680 if(debug) {
681 debuga(_("Parameters:\n"));
682 debuga(_(" Hostname or IP address (-a) = %s\n"),addr);
683 debuga(_(" Useragent log (-b) = %s\n"),uagent);
684 debuga(_(" Exclude file (-c) = %s\n"),hexclude);
685 debuga(_(" Date from-until (-d) = %s\n"),date);
686 debuga(_(" Email address to send reports (-e) = %s\n"),email);
687 debuga(_(" Config file (-f) = %s\n"),ConfigFile);
688 if(strcmp(df,"e") == 0)
689 debuga(_(" Date format (-g) = Europe (dd/mm/yyyy)\n"));
690 if(strcmp(df,"u") == 0)
691 debuga(_(" Date format (-g) = USA (mm/dd/yyyy)\n"));
692 if(strcmp(df,"w") == 0)
693 debuga(_(" Date format (-g) = Sites & Users (yyyy/ww)\n"));
694 debuga(_(" IP report (-i) = %s\n"),(iprel) ? _("Yes") : _("No"));
695 debuga(_(" Keep temporary files (-k) = %s\n"),(KeepTempLog) ? _("Yes") : _("No"));
696 for (iarq=0 ; iarq<NAccessLog ; iarq++)
697 debuga(_(" Input log (-l) = %s\n"),AccessLog[iarq]);
698 for (iarq=0 ; iarq<NRedirectorLogs ; iarq++)
699 debuga(_(" Redirector log (-L) = %s\n"),RedirectorLogs[iarq]);
700 debuga(_(" Resolve IP Address (-n) = %s\n"),(Ip2Name) ? _("Yes") : _("No"));
701 debuga(_(" Output dir (-o) = %s\n"),outdir);
702 debuga(_("Use Ip Address instead of userid (-p) = %s\n"),(UserIp) ? _("Yes") : _("No"));
703 debuga(_(" Accessed site (-s) = %s\n"),site);
704 debuga(_(" Time (-t) = %s\n"),hm_str);
705 debuga(_(" User (-u) = %s\n"),us);
706 debuga(_(" Temporary dir (-w) = %s\n"),tmp);
707 debuga(_(" Debug messages (-x) = %s\n"),(debug) ? _("Yes") : _("No"));
708 debuga(_(" Process messages (-z) = %s\n"),(debugz) ? _("Yes") : _("No"));
709 debuga(_(" Previous reports to keep (--lastlog) = %d\n"),LastLog);
710 debuga("\n");
711 }
712
713 if(debugm) {
714 printf(_("Parameters:\n"));
715 printf(_(" Hostname or IP address (-a) = %s\n"),addr);
716 printf(_(" Useragent log (-b) = %s\n"),uagent);
717 printf(_(" Exclude file (-c) = %s\n"),hexclude);
718 printf(_(" Date from-until (-d) = %s\n"),date);
719 printf(_(" Email address to send reports (-e) = %s\n"),email);
720 printf(_(" Config file (-f) = %s\n"),ConfigFile);
721 if(strcmp(df,"e") == 0)
722 printf(_(" Date format (-g) = Europe (dd/mm/yyyy)\n"));
723 if(strcmp(df,"u") == 0)
724 printf(_(" Date format (-g) = USA (mm/dd/yyyy)\n"));
725 if(strcmp(df,"w") == 0)
726 printf(_(" Date format (-g) = Sites & Users (yyyy/ww)\n"));
727 printf(_(" IP report (-i) = %s\n"),(iprel) ? _("Yes") : _("No"));
728 printf(_(" Keep temporary files (-k) = %s\n"),(KeepTempLog) ? _("Yes") : _("No"));
729 for (iarq=0 ; iarq<NAccessLog ; iarq++)
730 printf(_(" Input log (-l) = %s\n"),AccessLog[iarq]);
731 for (iarq=0 ; iarq<NRedirectorLogs ; iarq++)
732 printf(_(" Redirector log (-L) = %s\n"),RedirectorLogs[iarq]);
733 printf(_(" Resolve IP Address (-n) = %s\n"),(Ip2Name) ? _("Yes") : _("No"));
734 printf(_(" Output dir (-o) = %s\n"),outdir);
735 printf(_("Use Ip Address instead of userid (-p) = %s\n"),(UserIp) ? _("Yes") : _("No"));
736 printf(_(" Accessed site (-s) = %s\n"),site);
737 printf(_(" Time (-t) = %s\n"),hm_str);
738 printf(_(" User (-u) = %s\n"),us);
739 printf(_(" Temporary dir (-w) = %s\n"),tmp);
740 printf(_(" Debug messages (-x) = %s\n"),(debug) ? _("Yes") : _("No"));
741 printf(_(" Process messages (-z) = %s\n"),(debugz) ? _("Yes") : _("No"));
742 printf(_(" Previous reports to keep (--lastlog) = %d\n"),LastLog);
743 printf(_("SARG version: %s\n"),VERSION);
744 }
745
746 if(debug)
747 debuga(_("SARG version: %s\n"),VERSION);
748
749 #ifdef ENABLE_DOUBLE_CHECK_DATA
750 debuga(_("Sarg compiled to report warnings if the output is inconsistent\n"));
751 #endif
752
753 maxopenfiles=MAX_OPEN_USER_FILES;
754 #ifdef HAVE_RLIM_T
755 if (Ulimit[0] != '\0') {
756 struct rlimit rl;
757 long l1, l2;
758 int rc=0;
759
760 #if defined(RLIMIT_NOFILE)
761 getrlimit (RLIMIT_NOFILE, &rl);
762 #elif defined(RLIMIT_OFILE)
763 getrlimit (RLIMIT_OFILE, &rl);
764 #else
765 #warning "No rlimit resource for the number of open files"
766 #endif
767 l1 = rl.rlim_cur;
768 l2 = rl.rlim_max;
769
770 rl.rlim_cur = atol(Ulimit);
771 rl.rlim_max = atol(Ulimit);
772 #if defined(RLIMIT_NOFILE)
773 rc=setrlimit (RLIMIT_NOFILE, &rl);
774 #elif defined(RLIMIT_OFILE)
775 rc=setrlimit (RLIMIT_OFILE, &rl);
776 #else
777 #warning "No rlimit resource for the number of open files"
778 #endif
779 if(rc == -1) {
780 debuga(_("setrlimit error: %s\n"),strerror(errno));
781 }
782
783 if(debug)
784 debuga("Maximum file descriptor: cur=%ld max=%ld, changed to cur="RLIM_STRING" max="RLIM_STRING"\n",l1,l2,rl.rlim_cur,rl.rlim_max);
785 }
786 #endif
787
788 init_usertab(UserTabFile);
789
790 if ((line=longline_create())==NULL) {
791 debuga(_("Not enough memory to read a log file\n"));
792 exit(EXIT_FAILURE);
793 }
794
795 snprintf(sz_Download_Unsort,sizeof(sz_Download_Unsort),"%s/download.int_unsort", tmp);
796
797 if(DataFile[0]=='\0') {
798 if((ReportType & REPORT_TYPE_DENIED) != 0) {
799 if((fp_denied=MY_FOPEN(denied_unsort,"w"))==NULL) {
800 debugapos("log",_("Cannot open file \"%s\": %s\n"),denied_unsort,strerror(errno));
801 exit(EXIT_FAILURE);
802 }
803 }
804
805 if((ReportType & REPORT_TYPE_DENIED) != 0 || (ReportType & REPORT_TYPE_AUTH_FAILURES) != 0) {
806 if((fp_authfail=MY_FOPEN(authfail_unsort,"w"))==NULL) {
807 debugapos("log",_("Cannot open file \"%s\": %s\n"),authfail_unsort,strerror(errno));
808 exit(EXIT_FAILURE);
809 }
810 }
811 }
812
813 read_start_time=time(NULL);
814 for (iarq=0 ; iarq<NAccessLog ; iarq++) {
815 strcpy(arq,AccessLog[iarq]);
816
817 strcpy(arqtt,arq);
818
819 if(strcmp(arq,"-")==0) {
820 if(debug)
821 debuga(_("Reading access log file: from stdin\n"));
822 fp_in=stdin;
823 from_stdin=true;
824 } else {
825 if (date[0]!='\0') {
826 if (stat(arq,&logstat)!=0) {
827 debuga(_("Cannot get the modification time of input log file \"%s\": %s\nProcessing it anyway\n"),arq,strerror(errno));
828 } else {
829 struct tm *logtime=localtime(&logstat.st_mtime);
830 if ((logtime->tm_year+1900)*10000+(logtime->tm_mon+1)*100+logtime->tm_mday<dfrom) {
831 debuga(_("Ignoring old log file %s\n"),arq);
832 continue;
833 }
834 }
835 }
836 fp_in=decomp(arq,&from_pipe);
837 if(fp_in==NULL) {
838 debugapos("log",_("Cannot open file \"%s\": %s\n"),arq,strerror(errno));
839 exit(EXIT_FAILURE);
840 }
841 if(debug) debuga(_("Reading access log file: %s\n"),arq);
842 from_stdin=false;
843 }
844 ilf=ILF_Unknown;
845 download_flag=false;
846 // pre-read the file only if we have to show stats
847 if(ShowReadStatistics && !from_stdin && !from_pipe) {
848 size_t nread,i;
849 bool skipcr=false;
850 char tmp4[MAXLEN];
851
852 recs1=0UL;
853 recs2=0UL;
854
855 while ((nread=fread(tmp4,1,sizeof(tmp4),fp_in))>0) {
856 for (i=0 ; i<nread ; i++)
857 if (skipcr) {
858 if (tmp4[i]!='\n' && tmp4[i]!='\r') {
859 skipcr=false;
860 }
861 } else {
862 if (tmp4[i]=='\n' || tmp4[i]=='\r') {
863 skipcr=true;
864 recs1++;
865 }
866 }
867 }
868 rewind(fp_in);
869 printf(_("SARG: Records in file: %lu, reading: %3.2lf%%"),recs1,0.);
870 putchar('\r');
871 fflush( stdout ) ;
872 }
873
874 longline_reset(line);
875
876 while ((linebuf=longline_read(fp_in,line))!=NULL) {
877 blen=strlen(linebuf);
878 lines_read++;
879
880 if (ilf==ILF_Unknown) {
881 if(strncmp(linebuf,"#Software: Mic",14) == 0) {
882 fixendofline(linebuf);
883 if (debug)
884 debuga(_("Log is from Microsoft ISA: %s\n"),linebuf);
885 ilf=ILF_Isa;
886 ilf_count[ilf]++;
887 continue;
888 }
889
890 if(strncmp(linebuf,"*** SARG Log ***",16) == 0) {
891 if (getperiod_fromsarglog(arqtt,&period)<0) {
892 debuga(_("The name of the file is invalid: %s\n"),arq);
893 exit(EXIT_FAILURE);
894 }
895 ilf=ILF_Sarg;
896 ilf_count[ilf]++;
897 continue;
898 }
899 }
900
901 if(!fp_log && ParsedOutputLog[0] && ilf!=ILF_Sarg) {
902 if(access(ParsedOutputLog,R_OK) != 0) {
903 my_mkdir(ParsedOutputLog);
904 }
905 if (snprintf(arq_log,sizeof(arq_log),"%s/sarg_temp.log",ParsedOutputLog)>=sizeof(arq_log)) {
906 debuga(_("Path too long: "));
907 debuga_more("%s/sarg_temp.log\n",ParsedOutputLog);
908 exit(EXIT_FAILURE);
909 }
910 if((fp_log=MY_FOPEN(arq_log,"w"))==NULL) {
911 debugapos("log",_("Cannot open file \"%s\": %s\n"),arq_log,strerror(errno));
912 exit(EXIT_FAILURE);
913 }
914 fputs("*** SARG Log ***\n",fp_log);
915 }
916
917 recs2++;
918 if( ShowReadStatistics && !from_stdin && !from_pipe && --OutputNonZero<=0) {
919 double perc = recs2 * 100. / recs1 ;
920 printf(_("SARG: Records in file: %lu, reading: %3.2lf%%"),recs2,perc);
921 putchar('\r');
922 fflush (stdout);
923 OutputNonZero = REPORT_EVERY_X_LINES ;
924 }
925 if(blen < 58) continue;
926 if(strstr(linebuf,"HTTP/0.0") != 0) continue;
927 if(strstr(linebuf,"logfile turned over") != 0) continue;
928 if(linebuf[0] == ' ') continue;
929
930 // exclude_string
931 if(ExcludeString[0] != '\0') {
932 bool exstring=false;
933 getword_start(&gwarea,ExcludeString);
934 while(strchr(gwarea.current,':') != 0) {
935 if (getword_multisep(val1,sizeof(val1),&gwarea,':')<0) {
936 debuga(_("Invalid record in exclusion string\n"));
937 exit(EXIT_FAILURE);
938 }
939 if((str=(char *) strstr(linebuf,val1)) != (char *) NULL ) {
940 exstring=true;
941 break;
942 }
943 }
944 if(!exstring && (str=(char *) strstr(linebuf,gwarea.current)) != (char *) NULL )
945 exstring=true;
946 if(exstring) continue;
947 }
948
949 totregsl++;
950 if(debugm)
951 printf("BUF=%s\n",linebuf);
952
953 t=NULL;
954 if (ilf==ILF_Squid || ilf==ILF_Common || ilf==ILF_Unknown) {
955 getword_start(&gwarea,linebuf);
956 if (getword(data,sizeof(data),&gwarea,' ')<0) {
957 debuga(_("Invalid time in file \"%s\"\n"),arq);
958 exit(EXIT_FAILURE);
959 }
960 if((str=(char *) strchr(data, '.')) != (char *) NULL && (str=(char *) strchr(str+1, '.')) != (char *) NULL ) {
961 strcpy(ip,data);
962 strcpy(elap,"0");
963 if(squid24) {
964 if (getword(user,sizeof(user),&gwarea,' ')<0 || getword_skip(255,&gwarea,' ')<0) {
965 debuga(_("Invalid record in file \"%s\"\n"),arq);
966 exit(EXIT_FAILURE);
967 }
968 } else {
969 if (getword_skip(255,&gwarea,' ')<0 || getword(user,sizeof(user),&gwarea,' ')<0) {
970 debuga(_("Invalid record in file \"%s\"\n"),arq);
971 exit(EXIT_FAILURE);
972 }
973 }
974 if (getword(data,sizeof(data),&gwarea,']')<0 || getword_skip(MAXLEN,&gwarea,'"')<0 ||
975 getword(fun,sizeof(fun),&gwarea,' ')<0) {
976 debuga(_("Invalid record in file \"%s\"\n"),arq);
977 exit(EXIT_FAILURE);
978 }
979 if (getword_ptr(linebuf,&full_url,&gwarea,' ')<0) {
980 debuga(_("Invalid url in file \"%s\"\n"),arq);
981 exit(EXIT_FAILURE);
982 }
983 if (getword_skip(MAXLEN,&gwarea,' ')<0) {
984 debuga(_("Invalid record in file \"%s\"\n"),arq);
985 exit(EXIT_FAILURE);
986 }
987 if (getword(code2,sizeof(code2),&gwarea,' ')<0) {
988 debuga(_("Invalid record in file \"%s\"\n"),arq);
989 exit(EXIT_FAILURE);
990 }
991 if (getword(tam,sizeof(tam),&gwarea,' ')<0) {
992 debuga(_("Invalid record in file \"%s\"\n"),arq);
993 exit(EXIT_FAILURE);
994 }
995 if((str=(char *) strchr(gwarea.current, ' ')) != (char *) NULL ) {
996 if (getword(code,sizeof(code),&gwarea,' ')<0) {
997 debuga(_("Invalid record in file \"%s\"\n"),arq);
998 exit(EXIT_FAILURE);
999 }
1000 } else {
1001 if (getword(code,sizeof(code),&gwarea,'\0')<0) {
1002 debuga(_("Invalid record in file \"%s\"\n"),arq);
1003 exit(EXIT_FAILURE);
1004 }
1005 }
1006
1007 if ((str = strchr(code, ':')) != NULL)
1008 *str = '/';
1009
1010 if(strcmp(tam,"\0") == 0)
1011 strcpy(tam,"0");
1012
1013 ilf=ILF_Common;
1014 ilf_count[ilf]++;
1015
1016 getword_start(&gwarea,data+1);
1017 if (getword_multisep(data,sizeof(data),&gwarea,':')<0){
1018 debuga(_("Invalid date in file \"%s\"\n"),arq);
1019 exit(EXIT_FAILURE);
1020 }
1021 if (getword_multisep(hora,sizeof(hora),&gwarea,' ')<0){
1022 debuga(_("Invalid date in file \"%s\"\n"),arq);
1023 exit(EXIT_FAILURE);
1024 }
1025 getword_start(&gwarea,data);
1026 if (getword_atoll(&iday,&gwarea,'/')<0){
1027 debuga(_("Invalid date in file \"%s\"\n"),arq);
1028 exit(EXIT_FAILURE);
1029 }
1030 if (getword(mes,sizeof(mes),&gwarea,'/')<0){
1031 debuga(_("Invalid date in file \"%s\"\n"),arq);
1032 exit(EXIT_FAILURE);
1033 }
1034 if (getword_atoll(&iyear,&gwarea,'/')<0){
1035 debuga(_("Invalid date in file \"%s\"\n"),arq);
1036 exit(EXIT_FAILURE);
1037 }
1038
1039 imonth=month2num(mes)+1;
1040 idata=builddia(iday,imonth,iyear);
1041 computedate(iyear,imonth,iday,&tt);
1042 if (sscanf(hora,"%d:%d:%d",&tt.tm_hour,&tt.tm_min,&tt.tm_sec)!=3 || tt.tm_hour<0 || tt.tm_hour>=24 ||
1043 tt.tm_min<0 || tt.tm_min>=60 || tt.tm_sec<0 || tt.tm_sec>=60) {
1044 debuga(_("Invalid time in file \"%s\"\n"),arq);
1045 exit(EXIT_FAILURE);
1046 }
1047 t=&tt;
1048 }
1049
1050 if(ilf==ILF_Unknown || ilf==ILF_Squid) {
1051 if (getword(elap,sizeof(elap),&gwarea,' ')<0) {
1052 debuga(_("Invalid elapsed time in file \"%s\"\n"),arq);
1053 exit(EXIT_FAILURE);
1054 }
1055 while(strcmp(elap,"") == 0 && gwarea.current[0] != '\0')
1056 if (getword(elap,sizeof(elap),&gwarea,' ')<0) {
1057 debuga(_("Invalid elapsed time in file \"%s\"\n"),arq);
1058 exit(EXIT_FAILURE);
1059 }
1060 if(strlen(elap) < 1) continue;
1061 if (getword(ip,sizeof(ip),&gwarea,' ')<0){
1062 debuga(_("Invalid client IP address in file \"%s\"\n"),arq);
1063 exit(EXIT_FAILURE);
1064 }
1065 if (getword(code,sizeof(code),&gwarea,' ')<0){
1066 debuga(_("Invalid result code in file \"%s\"\n"),arq);
1067 exit(EXIT_FAILURE);
1068 }
1069 if (getword(tam,sizeof(tam),&gwarea,' ')<0){
1070 debuga(_("Invalid amount of data in file \"%s\"\n"),arq);
1071 exit(EXIT_FAILURE);
1072 }
1073 if (getword(fun,sizeof(fun),&gwarea,' ')<0){
1074 debuga(_("Invalid request method in file \"%s\"\n"),arq);
1075 exit(EXIT_FAILURE);
1076 }
1077 if (getword_ptr(linebuf,&full_url,&gwarea,' ')<0){
1078 debuga(_("Invalid url in file \"%s\"\n"),arq);
1079 exit(EXIT_FAILURE);
1080 }
1081 if (getword(user,sizeof(user),&gwarea,' ')<0){
1082 debuga(_("Invalid user ID in file \"%s\"\n"),arq);
1083 exit(EXIT_FAILURE);
1084 }
1085 ilf=ILF_Squid;
1086 ilf_count[ilf]++;
1087
1088 tnum=atoi(data);
1089 t=localtime(&tnum);
1090 if (t == NULL) {
1091 debuga(_("Cannot convert the timestamp from the squid log file\n"));
1092 exit(EXIT_FAILURE);
1093 }
1094
1095 strftime(tbuf2, sizeof(tbuf2), "%H%M", t);
1096
1097 idata=(t->tm_year+1900)*10000+(t->tm_mon+1)*100+t->tm_mday;
1098 }
1099 }
1100 if (ilf==ILF_Sarg) {
1101 getword_start(&gwarea,linebuf);
1102 if (getword(data,sizeof(data),&gwarea,'\t')<0){
1103 debuga(_("Invalid record in file \"%s\"\n"),arq);
1104 exit(EXIT_FAILURE);
1105 }
1106 if (getword(hora,sizeof(hora),&gwarea,'\t')<0) {
1107 debuga(_("Invalid record in file \"%s\"\n"),arq);
1108 exit(EXIT_FAILURE);
1109 }
1110 if (getword(user,sizeof(user),&gwarea,'\t')<0) {
1111 debuga(_("Invalid record in file \"%s\"\n"),arq);
1112 exit(EXIT_FAILURE);
1113 }
1114 if (getword(ip,sizeof(ip),&gwarea,'\t')<0) {
1115 debuga(_("Invalid record in file \"%s\"\n"),arq);
1116 exit(EXIT_FAILURE);
1117 }
1118 if (getword_ptr(linebuf,&full_url,&gwarea,'\t')<0){
1119 debuga(_("Invalid record in file \"%s\"\n"),arq);
1120 exit(EXIT_FAILURE);
1121 }
1122 if (getword(tam,sizeof(tam),&gwarea,'\t')<0){
1123 debuga(_("Invalid record in file \"%s\"\n"),arq);
1124 exit(EXIT_FAILURE);
1125 }
1126 if (getword(code,sizeof(code),&gwarea,'\t')<0){
1127 debuga(_("Invalid record in file \"%s\"\n"),arq);
1128 exit(EXIT_FAILURE);
1129 }
1130 if (getword(elap,sizeof(elap),&gwarea,'\t')<0){
1131 debuga(_("Invalid record in file \"%s\"\n"),arq);
1132 exit(EXIT_FAILURE);
1133 }
1134 if (getword(smartfilter,sizeof(smartfilter),&gwarea,'\0')<0){
1135 debuga(_("Invalid record in file \"%s\"\n"),arq);
1136 exit(EXIT_FAILURE);
1137 }
1138 getword_start(&gwarea,data);
1139 if (getword_atoll(&iday,&gwarea,'/')<0 || iday<1 || iday>31){
1140 debuga(_("Invalid record in file \"%s\"\n"),arq);
1141 exit(EXIT_FAILURE);
1142 }
1143 if (getword_atoll(&imonth,&gwarea,'/')<0 || imonth<1 || imonth>12){
1144 debuga(_("Invalid record in file \"%s\"\n"),arq);
1145 exit(EXIT_FAILURE);
1146 }
1147 if (getword_atoll(&iyear,&gwarea,'\0')<0){
1148 debuga(_("Invalid record in file \"%s\"\n"),arq);
1149 exit(EXIT_FAILURE);
1150 }
1151 idata=builddia(iday,imonth,iyear);
1152 computedate(iyear,imonth,iday,&tt);
1153 if (sscanf(hora,"%d:%d:%d",&tt.tm_hour,&tt.tm_min,&tt.tm_sec)!=3 || tt.tm_hour<0 || tt.tm_hour>=24 ||
1154 tt.tm_min<0 || tt.tm_min>=60 || tt.tm_sec<0 || tt.tm_sec>=60) {
1155 debuga(_("Invalid time in file \"%s\"\n"),arq);
1156 exit(EXIT_FAILURE);
1157 }
1158 t=&tt;
1159 }
1160 if (ilf==ILF_Isa) {
1161 if (linebuf[0] == '#') {
1162 int ncols,cols[ISACOL_Last];
1163
1164 fixendofline(linebuf);
1165 getword_start(&gwarea,linebuf);
1166 // remove the #Fields: column at the beginning of the line
1167 if (getword_skip(1000,&gwarea,' ')<0){
1168 debuga(_("Invalid record in file \"%s\"\n"),arq);
1169 exit(EXIT_FAILURE);
1170 }
1171 for (ncols=0 ; ncols<ISACOL_Last ; ncols++) cols[ncols]=-1;
1172 ncols=0;
1173 while(gwarea.current[0] != '\0') {
1174 if (getword(val1,sizeof(val1),&gwarea,'\t')<0){
1175 debuga(_("Invalid record in file \"%s\"\n"),arq);
1176 exit(EXIT_FAILURE);
1177 }
1178 if(strcmp(val1,"c-ip") == 0) cols[ISACOL_Ip]=ncols;
1179 if(strcmp(val1,"cs-username") == 0) cols[ISACOL_UserName]=ncols;
1180 if(strcmp(val1,"date") == 0) cols[ISACOL_Date]=ncols;
1181 if(strcmp(val1,"time") == 0) cols[ISACOL_Time]=ncols;
1182 if(strcmp(val1,"time-taken") == 0) cols[ISACOL_TimeTaken]=ncols;
1183 if(strcmp(val1,"sc-bytes") == 0) cols[ISACOL_Bytes]=ncols;
1184 if(strcmp(val1,"cs-uri") == 0) cols[ISACOL_Uri]=ncols;
1185 if(strcmp(val1,"sc-status") == 0) cols[ISACOL_Status]=ncols;
1186 ncols++;
1187 }
1188 if (cols[ISACOL_Ip]>=0) {
1189 isa_ncols=ncols;
1190 for (ncols=0 ; ncols<ISACOL_Last ; ncols++)
1191 isa_cols[ncols]=cols[ncols];
1192 }
1193 continue;
1194 }
1195 if (!isa_ncols) continue;
1196 getword_start(&gwarea,linebuf);
1197 for (x=0 ; x<isa_ncols ; x++) {
1198 if (getword_ptr(linebuf,&str,&gwarea,'\t')<0) {
1199 debuga(_("Invalid record in file \"%s\"\n"),arq);
1200 exit(EXIT_FAILURE);
1201 }
1202 if (x==isa_cols[ISACOL_Ip]) {
1203 if (strlen(str)>=sizeof(ip)) {
1204 debuga(_("Invalid IP address in file \"%s\"\n"),arq);
1205 exit(EXIT_FAILURE);
1206 }
1207 strcpy(ip,str);
1208 } else if (x==isa_cols[ISACOL_UserName]) {
1209 if (strlen(str)>=sizeof(user)) {
1210 debuga(_("Invalid user ID in file \"%s\"\n"),arq);
1211 exit(EXIT_FAILURE);
1212 }
1213 strcpy(user,str);
1214 } else if (x==isa_cols[ISACOL_Date]) {
1215 if (strlen(str)>=sizeof(data)) {
1216 debuga(_("Invalid record in file \"%s\"\n"),arq);
1217 exit(EXIT_FAILURE);
1218 }
1219 strcpy(data,str);
1220 } else if (x==isa_cols[ISACOL_Time]) {
1221 if (strlen(str)>=sizeof(hora)) {
1222 debuga(_("Invalid time in file \"%s\"\n"),arq);
1223 exit(EXIT_FAILURE);
1224 }
1225 strcpy(hora,str);
1226 } else if (x==isa_cols[ISACOL_TimeTaken]) {
1227 if (strlen(str)>=sizeof(elap)) {
1228 debuga(_("Invalid download duration in file \"%s\"\n"),arq);
1229 exit(EXIT_FAILURE);
1230 }
1231 strcpy(elap,str);
1232 } else if (x==isa_cols[ISACOL_Bytes]) {
1233 if (strlen(str)>=sizeof(tam)) {
1234 debuga(_("Invalid download size in file \"%s\"\n"),arq);
1235 exit(EXIT_FAILURE);
1236 }
1237 strcpy(tam,str);
1238 } else if (x==isa_cols[ISACOL_Uri]) {
1239 full_url=str;
1240 } else if (x==isa_cols[ISACOL_Status]) {
1241 if (strlen(str)>=sizeof(code)) {
1242 debuga(_("Invalid access code in file \"%s\"\n"),arq);
1243 exit(EXIT_FAILURE);
1244 }
1245 strcpy(code,str);
1246 }
1247 }
1248
1249 if(strcmp(code,"401") == 0 || strcmp(code,"403") == 0 || strcmp(code,"407") == 0) {
1250 sprintf(val1,"DENIED/%s",code);
1251 strcpy(code,val1);
1252 }
1253 getword_start(&gwarea,data);
1254 if (getword_atoll(&iyear,&gwarea,'-')<0){
1255 debuga(_("Invalid year in file \"%s\"\n"),arq);
1256 exit(EXIT_FAILURE);
1257 }
1258 if (getword_atoll(&imonth,&gwarea,'-')<0){
1259 debuga(_("Invalid month in file \"%s\"\n"),arq);
1260 exit(EXIT_FAILURE);
1261 }
1262 if (getword_atoll(&iday,&gwarea,'\0')<0){
1263 debuga(_("Invalid day in file \"%s\"\n"),arq);
1264 exit(EXIT_FAILURE);
1265 }
1266
1267 idata=builddia(iday,imonth,iyear);
1268 computedate(iyear,imonth,iday,&tt);
1269 if (isa_cols[ISACOL_Time]>=0) {
1270 if (sscanf(hora,"%d:%d:%d",&tt.tm_hour,&tt.tm_min,&tt.tm_sec)!=3 || tt.tm_hour<0 || tt.tm_hour>=24 ||
1271 tt.tm_min<0 || tt.tm_min>=60 || tt.tm_sec<0 || tt.tm_sec>=60) {
1272 debuga(_("Invalid time in file \"%s\"\n"),arq);
1273 exit(EXIT_FAILURE);
1274 }
1275 }
1276 t=&tt;
1277 }
1278 if (t==NULL) {
1279 debuga(_("Unknown input log file format\n"));
1280 break;
1281 }
1282
1283 strftime(dia, sizeof(dia), "%d/%m/%Y", t);
1284 snprintf(hora,sizeof(hora),"%02d:%02d:%02d",t->tm_hour,t->tm_min,t->tm_sec);
1285
1286 if(debugm)
1287 printf("DATE=%s IDATA=%d DFROM=%d DUNTIL=%d\n",date,idata,dfrom,duntil);
1288
1289 if(date[0] != '\0'){
1290 if(idata < dfrom || idata > duntil) continue;
1291 }
1292
1293 // Record only hours usage which is required
1294 if (t) {
1295 if( bsearch( &( t -> tm_wday ), weekdays.list, weekdays.len, sizeof( int ), compar ) == NULL )
1296 continue;
1297
1298 if( bsearch( &( t -> tm_hour ), hours.list, hours.len, sizeof( int ), compar ) == NULL )
1299 continue;
1300 }
1301
1302
1303 if(strlen(user) > MAX_USER_LEN) {
1304 if (debugm) printf(_("User ID too long: %s\n"),user);
1305 totregsx++;
1306 continue;
1307 }
1308
1309 // include_users
1310 if(IncludeUsers[0] != '\0') {
1311 snprintf(val1,sizeof(val1),":%s:",user);
1312 if((str=(char *) strstr(IncludeUsers,val1)) == (char *) NULL )
1313 continue;
1314 }
1315
1316 if(vercode(code)) {
1317 if (debugm) printf(_("Excluded code: %s\n"),code);
1318 totregsx++;
1319 continue;
1320 }
1321
1322 if(testvaliduserchar(user))
1323 continue;
1324
1325 #if 0
1326 if((str = strstr(user,"%20")) != NULL) {
1327 /*
1328 This is a patch introduced to solve bug #1624251 reported at sourceforge but
1329 the side effect is to truncate the name at the first space and merge the reports
1330 of people whose name is identical up to the first space.
1331
1332 The old code used to truncate the user name at the first % if a %20 was
1333 found anywhere in the string. That means the string could be truncated
1334 at the wrong place if another % occured before the %20. This new code should
1335 avoid that problem and only truncate at the space. There is no bug
1336 report indicating that anybody noticed this.
1337 */
1338 *str='\0';
1339 }
1340
1341 /*
1342 Code prior to 2.2.7 used to replace any %xx by a dot as long as a %5c was
1343 found in the user name.
1344 */
1345 while((str = strstr(user,"%5c")) != NULL) {
1346 *str='.';
1347 for (x=3 ; str[x] ; x++) str[x-2]=str[x];
1348 }
1349 #endif
1350 // replace any tab by a single space
1351 for (str=full_url ; *str ; str++)
1352 if (*str=='\t') *str=' ';
1353 for (str=code ; *str ; str++)
1354 if (*str=='\t') *str=' ';
1355
1356 if(ilf!=ILF_Sarg) {
1357 /*
1358 The full URL is not saved in sarg log. There is no point in testing the URL to detect
1359 a downloaded file.
1360 */
1361 download_flag=is_download_suffix(full_url);
1362 if (download_flag) {
1363 safe_strcpy(download_url,full_url,sizeof(download_url));
1364 download_count++;
1365 }
1366 } else
1367 download_flag=false;
1368
1369 url=process_url(full_url,LongUrl);
1370 if (!url || url[0] == '\0') continue;
1371
1372 if(addr[0] != '\0'){
1373 if(strcmp(addr,ip)!=0) continue;
1374 }
1375 if(fhost) {
1376 if(!vhexclude(url)) {
1377 if (debugm) printf(_("Excluded site: %s\n"),url);
1378 totregsx++;
1379 continue;
1380 }
1381 }
1382
1383 if(hm >= 0 && hmf >= 0) {
1384 hmr=t->tm_hour*100+t->tm_min;
1385 if(hmr < hm || hmr > hmf) continue;
1386 }
1387
1388 if(site[0] != '\0'){
1389 if(strstr(url,site)==0) continue;
1390 }
1391
1392 if(UserIp) {
1393 strcpy(user,ip);
1394 id_is_ip=true;
1395 } else {
1396 id_is_ip=false;
1397 if(strcmp(user,"-") == 0 || strcmp(user," ") == 0 || strcmp(user,"") == 0) {
1398 if(RecordsWithoutUser == RECORDWITHOUTUSER_IP) {
1399 strcpy(user,ip);
1400 id_is_ip=true;
1401 }
1402 if(RecordsWithoutUser == RECORDWITHOUTUSER_IGNORE)
1403 continue;
1404 if(RecordsWithoutUser == RECORDWITHOUTUSER_EVERYBODY)
1405 strcpy(user,"everybody");
1406 } else {
1407 strlow(user);
1408 if(NtlmUserFormat == NTLMUSERFORMAT_USER) {
1409 if ((str=strchr(user,'+'))!=NULL || (str=strchr(user,'\\'))!=NULL || (str=strchr(user,'_'))!=NULL) {
1410 strcpy(warea,str+1);
1411 strcpy(user,warea);
1412 }
1413 }
1414 }
1415 }
1416
1417 if(us[0] != '\0'){
1418 if(strcmp(user,us)!=0) continue;
1419 }
1420
1421 if(puser) {
1422 snprintf(wuser,sizeof(wuser),":%s:",user);
1423 if(strstr(userfile, wuser) == 0)
1424 continue;
1425 }
1426
1427 if(fuser) {
1428 if(!vuexclude(user)) {
1429 if (debugm) printf(_("Excluded user: %s\n"),user);
1430 totregsx++;
1431 continue;
1432 }
1433 }
1434
1435 if(strcmp(user,"-") ==0 || strcmp(user," ") ==0 || strcmp(user,"") ==0 || strcmp(user,":") ==0)
1436 continue;
1437
1438 nbytes=atoll(tam);
1439 if (nbytes<0) nbytes=0;
1440
1441 elap_time=atol(elap);
1442 if (elap_time<0) elap_time=0;
1443 if(max_elapsed) {
1444 if(elap_time>max_elapsed) {
1445 elap_time=0;
1446 }
1447 }
1448
1449 if((str=(char *) strstr(linebuf, "[SmartFilter:")) != (char *) NULL ) {
1450 fixendofline(str);
1451 snprintf(smartfilter,sizeof(smartfilter),"\"%s\"",str+1);
1452 } else strcpy(smartfilter,"\"\"");
1453
1454 nopen=0;
1455 prev_ufile=NULL;
1456 for (ufile=first_user_file ; ufile && strcmp(user,ufile->user->id)!=0 ; ufile=ufile->next) {
1457 prev_ufile=ufile;
1458 if (ufile->file) nopen++;
1459 }
1460 if (!ufile) {
1461 ufile=malloc(sizeof(*ufile));
1462 if (!ufile) {
1463 debuga(_("Not enough memory to store user %s\n"),user);
1464 exit(EXIT_FAILURE);
1465 }
1466 memset(ufile,0,sizeof(*ufile));
1467 ufile->next=first_user_file;
1468 first_user_file=ufile;
1469 uinfo=userinfo_create(user,ip);
1470 ufile->user=uinfo;
1471 uinfo->id_is_ip=id_is_ip;
1472 nusers++;
1473 } else {
1474 if (prev_ufile) {
1475 prev_ufile->next=ufile->next;
1476 ufile->next=first_user_file;
1477 first_user_file=ufile;
1478 }
1479 }
1480 #ifdef ENABLE_DOUBLE_CHECK_DATA
1481 ufile->user->nbytes+=nbytes;
1482 ufile->user->elap+=elap_time;
1483 #endif
1484
1485 if (ufile->file==NULL) {
1486 if (nopen>=maxopenfiles) {
1487 x=0;
1488 for (ufile1=first_user_file ; ufile1 ; ufile1=ufile1->next) {
1489 if (ufile1->file!=NULL) {
1490 if (x>=maxopenfiles) {
1491 if (fclose(ufile1->file)==EOF) {
1492 debuga(_("Failed to close file \"%s\": %s\n"),ufile1->user->id,strerror(errno));
1493 exit(EXIT_FAILURE);
1494 }
1495 ufile1->file=NULL;
1496 }
1497 x++;
1498 }
1499 }
1500 }
1501 if (snprintf (tmp3, sizeof(tmp3), "%s/%s.user_unsort", tmp, ufile->user->filename)>=sizeof(tmp3)) {
1502 debuga(_("Path too long: "));
1503 debuga_more("%s/%s.user_unsort\n", tmp, ufile->user->filename);
1504 exit(EXIT_FAILURE);
1505 }
1506 if ((ufile->file = MY_FOPEN (tmp3, "a")) == NULL) {
1507 debugapos("log",_("Cannot open file \"%s\": %s\n"), tmp3, strerror(errno));
1508 exit (1);
1509 }
1510 }
1511
1512 if (fprintf(ufile->file, "%s\t%s\t%s\t%s\t%"PRIi64"\t%s\t%ld\t%s\n",dia,hora,ip,url,(int64_t)nbytes,code,elap_time,smartfilter)<=0) {
1513 debuga(_("Write error in the log file of user %s\n"),user);
1514 exit(EXIT_FAILURE);
1515 }
1516 records_kept++;
1517
1518 if(fp_log && ilf!=ILF_Sarg)
1519 fprintf(fp_log, "%s\t%s\t%s\t%s\t%s\t%"PRIi64"\t%s\t%ld\t%s\n",dia,hora,user,ip,url,(int64_t)nbytes,code,elap_time,smartfilter);
1520
1521 totregsg++;
1522
1523 if(!dataonly && download_flag && strstr(code,"DENIED") == 0) {
1524 ndownload = 1;
1525
1526 if ( ! fp_Download_Unsort ) {
1527 if ((fp_Download_Unsort = MY_FOPEN ( sz_Download_Unsort, "a")) == NULL) {
1528 debugapos("log",_("Cannot open file \"%s\": %s\n"),sz_Download_Unsort, strerror(errno));
1529 exit (1);
1530 }
1531 }
1532 fprintf(fp_Download_Unsort,"%s\t%s\t%s\t%s\t%s\n",dia,hora,user,ip,download_url);
1533 }
1534
1535 if((ReportType & REPORT_TYPE_DENIED) != 0) {
1536 if(fp_denied && strstr(code,"DENIED/403") != 0) {
1537 fprintf(fp_denied, "%s\t%s\t%s\t%s\t%s\n",dia,hora,user,ip,full_url);
1538 denied_count++;
1539 }
1540 }
1541 if((ReportType & REPORT_TYPE_AUTH_FAILURES) != 0) {
1542 if(fp_authfail && (strstr(code,"DENIED/401") != 0 || strstr(code,"DENIED/407") != 0)) {
1543 fprintf(fp_authfail, "%s\t%s\t%s\t%s\t%s\n",dia,hora,user,ip,full_url);
1544 authfail_count++;
1545 }
1546 }
1547
1548 if (ilf!=ILF_Sarg) {
1549 if(!totper || idata<mindate){
1550 mindate=idata;
1551 memcpy(&period.start,t,sizeof(*t));
1552 strcpy(start_hour,tbuf2);
1553 }
1554 if (!totper || idata>maxdate) {
1555 maxdate=idata;
1556 memcpy(&period.end,t,sizeof(*t));
1557 }
1558 totper=true;
1559 }
1560
1561 if(debugm){
1562 printf("IP=\t%s\n",ip);
1563 printf("USER=\t%s\n",user);
1564 printf("ELAP=\t%ld\n",elap_time);
1565 printf("DATE=\t%s\n",dia);
1566 printf("TIME=\t%s\n",hora);
1567 printf("FUNC=\t%s\n",fun);
1568 printf("URL=\t%s\n",url);
1569 printf("CODE=\t%s\n",code);
1570 printf("LEN=\t%"PRIi64"\n",(int64_t)nbytes);
1571 }
1572 }
1573 if (!from_stdin) {
1574 if (from_pipe)
1575 pclose(fp_in);
1576 else {
1577 fclose(fp_in);
1578 if( ShowReadStatistics ) {
1579 printf(_("SARG: Records in file: %lu, reading: %3.2lf%%"),recs1,100.);
1580 putchar('\n');
1581 }
1582 }
1583 }
1584 }
1585 read_end_time=time(NULL);
1586 read_elapsed=(double)read_end_time-(double)read_start_time;
1587
1588 if (debug)
1589 debuga(_(" Records read: %ld, written: %ld, excluded: %ld\n"),totregsl,totregsg,totregsx);
1590
1591 longline_destroy(&line);
1592 if ( fp_Download_Unsort )
1593 fclose (fp_Download_Unsort);
1594
1595 for (ufile=first_user_file ; ufile ; ufile=ufile1) {
1596 ufile1=ufile->next;
1597 if (ufile->file!=NULL) fclose(ufile->file);
1598 free(ufile);
1599 }
1600
1601 free_download();
1602 free_excludecodes();
1603 free_exclude();
1604
1605 if(debug) {
1606 int totalcount=0;
1607
1608 for (ilf=0 ; ilf<ILF_Last ; ilf++) totalcount+=ilf_count[ilf];
1609
1610 if(ilf_count[ILF_Common]>0 && ilf_count[ILF_Squid]>0)
1611 debuga(_("Log with mixed records format (squid and common log)\n"));
1612
1613 if(ilf_count[ILF_Common]>0 && ilf_count[ILF_Squid]==0)
1614 debuga(_("Common log format\n"));
1615
1616 if(ilf_count[ILF_Common]==0 && ilf_count[ILF_Squid]>0)
1617 debuga(_("Squid log format\n"));
1618
1619 if(ilf_count[ILF_Sarg]>0)
1620 debuga(_("Sarg log format\n"));
1621
1622 if(totalcount==0 && totregsg)
1623 debuga(_("Log with invalid format\n"));
1624 }
1625
1626 if(!totregsg){
1627 debuga(_("No records found\n"));
1628 debuga(_("End\n"));
1629 if(fp_denied) fclose(fp_denied);
1630 if(fp_authfail) fclose(fp_authfail);
1631 userinfo_free();
1632 if(userfile) free(userfile);
1633 close_usertab();
1634 exit(EXIT_SUCCESS);
1635 }
1636
1637 if (date[0]!='\0') {
1638 char date0[30], date1[30];
1639
1640 strftime(date0,sizeof(date0),"%d/%m/%Y",&period.start);
1641 strftime(date1,sizeof(date1),"%d/%m/%Y",&period.end);
1642 debuga(_("Period covered by log files: %s-%s\n"),date0,date1);
1643 getperiod_fromrange(&period,dfrom,duntil);
1644 }
1645 if (getperiod_buildtext(&period)<0) {
1646 debuga(_("Failed to build the string representation of the date range\n"));
1647 exit(EXIT_FAILURE);
1648 }
1649
1650 if(debugz){
1651 debugaz(_("date=%s\n"),dia);
1652 debugaz(_("period=%s\n"),period.text);
1653 }
1654
1655 if(debug) {
1656 debuga(_("Period: %s"),period.text);
1657 debuga_more("\n");
1658 }
1659
1660 if(fp_denied)
1661 fclose(fp_denied);
1662 if(fp_authfail)
1663 fclose(fp_authfail);
1664
1665 if(fp_log != NULL) {
1666 char end_hour[128];
1667 char val2[40];
1668 char val4[255];//val4 must not be bigger than arq_log without fixing the strcpy below
1669
1670 fclose(fp_log);
1671 safe_strcpy(end_hour,tbuf2,sizeof(end_hour));
1672 strftime(val2,sizeof(val2),"%d%m%Y",&period.start);
1673 strftime(val1,sizeof(val1),"%d%m%Y",&period.end);
1674 if (snprintf(val4,sizeof(val4),"%s/sarg-%s_%s-%s_%s.log",ParsedOutputLog,val2,start_hour,val1,end_hour)>=sizeof(val4)) {
1675 debuga(_("Path too long: "));
1676 debuga_more("%s/sarg-%s_%s-%s_%s.log\n",ParsedOutputLog,val2,start_hour,val1,end_hour);
1677 exit(EXIT_FAILURE);
1678 }
1679 if (rename(arq_log,val4)) {
1680 debuga(_("Failed to rename \"%s\" into \"%s\": %s\n"),arq_log,val4,strerror(errno));
1681 } else {
1682 strcpy(arq_log,val4);
1683
1684 if(strcmp(ParsedOutputLogCompress,"nocompress") != 0 && ParsedOutputLogCompress[0] != '\0') {
1685 /*
1686 No double quotes around ParsedOutputLogCompress because it may contain command line options. If double quotes are
1687 necessary around the command name, put them in the configuration file.
1688 */
1689 if (snprintf(val1,sizeof(val1),"%s \"%s\"",ParsedOutputLogCompress,arq_log)>=sizeof(val1)) {
1690 /* TRANSLATORS: The message is followed by the command that's too long. */
1691 debuga(_("Command too long: "));
1692 debuga_more("%s \"%s\"\n",ParsedOutputLogCompress,arq_log);
1693 exit(EXIT_FAILURE);
1694 }
1695 cstatus=system(val1);
1696 if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
1697 debuga(_("command return status %d\n"),WEXITSTATUS(cstatus));
1698 debuga(_("command: %s\n"),val1);
1699 exit(EXIT_FAILURE);
1700 }
1701 }
1702 }
1703 if(debug)
1704 debuga(_("Sarg parsed log saved as %s\n"),arq_log);
1705 }
1706
1707 if(DataFile[0] == '\0' && (ReportType & REPORT_TYPE_DENIED) != 0) {
1708 if (snprintf(csort,sizeof(csort),"sort -T \"%s\" -t \"\t\" -k 3,3 -k 5,5 -o \"%s\" \"%s\"",tmp,denied_sort,denied_unsort)>=sizeof(csort)) {
1709 debuga(_("Command too long: "));
1710 debuga_more("sort -T \"%s\" -t \"\t\" -k 3,3 -k 5,5 -o \"%s\" \"%s\"",tmp,denied_sort,denied_unsort);
1711 exit(EXIT_FAILURE);
1712 }
1713 cstatus=system(csort);
1714 if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
1715 debuga(_("sort command return status %d\n"),WEXITSTATUS(cstatus));
1716 debuga(_("sort command: %s\n"),csort);
1717 exit(EXIT_FAILURE);
1718 }
1719 if (!KeepTempLog && unlink(denied_unsort)) {
1720 debuga(_("Cannot delete \"%s\": %s\n"),denied_unsort,strerror(errno));
1721 exit(EXIT_FAILURE);
1722 }
1723 }
1724
1725 process_start_time=time(NULL);
1726 if(DataFile[0] != '\0')
1727 data_file(tmp);
1728 else
1729 gerarel();
1730 process_end_time=time(NULL);
1731 process_elapsed=(double)process_end_time-(double)process_start_time;
1732
1733 if((ReportType & REPORT_TYPE_DENIED) != 0) {
1734 if (!KeepTempLog && unlink(denied_sort) && errno!=ENOENT)
1735 debuga(_("Cannot delete \"%s\": %s\n"),denied_sort,strerror(errno));
1736 }
1737
1738 if(!KeepTempLog && strcmp(tmp,"/tmp") != 0) {
1739 unlinkdir(tmp,0);
1740 }
1741
1742 ip2name_cleanup();
1743 free_hostalias();
1744 userinfo_free();
1745 if(userfile)
1746 free(userfile);
1747 close_usertab();
1748
1749 end_time=time(NULL);
1750
1751 if (show_statis) {
1752 double elapsed=(double)end_time-(double)start_time;
1753 debuga(_("Total execution time: %.0lf seconds\n"),elapsed);
1754 if (read_elapsed>0.) {
1755 debuga(_("Lines read: %lu lines in %.0lf seconds (%.0lf lines/s)\n"),lines_read,read_elapsed,(double)lines_read/read_elapsed);
1756 }
1757 if (process_elapsed>0.) {
1758 debuga(_("Processed records: %lu records in %.0lf seconds (%.0lf records/s)\n"),records_kept,process_elapsed,(double)records_kept/process_elapsed);
1759 debuga(_("Users: %lu users in %.0lf seconds (%.0lf users/s)\n"),nusers,process_elapsed,(double)nusers/process_elapsed);
1760 }
1761 }
1762
1763 if(debug)
1764 debuga(_("End\n"));
1765
1766 exit(EXIT_SUCCESS);
1767 }
1768
1769
1770 static void getusers(const char *pwdfile, int debug)
1771 {
1772 FILE *fp_usr;
1773 char buf[255];
1774 char *str;
1775 long int nreg=0;
1776
1777 if(debug)
1778 debuga(_("Loading password file from %s\n"),pwdfile);
1779
1780 if ((fp_usr = fopen(pwdfile, "r")) == NULL) {
1781 debugapos("getusers",_("Cannot open file \"%s\": %s\n"),pwdfile,strerror(errno));
1782 exit(EXIT_FAILURE);
1783 }
1784
1785 if (fseek(fp_usr, 0, SEEK_END)==-1) {
1786 debuga(_("Failed to move till the end of file \"%s\": %s\n"),pwdfile,strerror(errno));
1787 exit(EXIT_FAILURE);
1788 }
1789 nreg = ftell(fp_usr);
1790 if (nreg<0) {
1791 debuga(_("Cannot get the size of file \"%s\": %s\n"),pwdfile,strerror(errno));
1792 exit(EXIT_FAILURE);
1793 }
1794 nreg = nreg+5000;
1795 if (fseek(fp_usr, 0, SEEK_SET)==-1) {
1796 debuga(_("Failed to rewind file \"%s\": %s\n"),pwdfile,strerror(errno));
1797 exit(EXIT_FAILURE);
1798 }
1799
1800 if((userfile=(char *) malloc(nreg))==NULL){
1801 debuga(_("malloc failed to allocate %ld bytes\n"),nreg);
1802 exit(EXIT_FAILURE);
1803 }
1804
1805 bzero(userfile,nreg);
1806 strcpy(userfile,":");
1807
1808 while(fgets(buf,sizeof(buf),fp_usr)!=NULL) {
1809 str=strchr(buf,':');
1810 if (!str) {
1811 debuga(_("Invalid user in file \"%s\"\n"),pwdfile);
1812 exit(EXIT_FAILURE);
1813 }
1814 str[1]='\0';
1815 strcat(userfile,buf);
1816 }
1817
1818 fclose(fp_usr);
1819
1820 return;
1821 }