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