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