2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
6 * please look at http://sarg.sourceforge.net/donations.php
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
9 * ---------------------------------------------------------------------
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
27 #include "include/conf.h"
28 #include "include/defs.h"
29 #include "include/readlog.h"
30 #include "include/filelist.h"
36 //! The log file filtering.
37 struct ReadLogDataStruct ReadFilter
;
39 //! The list of the system users.
40 /*@null@*/char *userfile
=NULL
;
42 //! List of the input log files to process.
43 FileListObject AccessLog
=NULL
;
46 static void getusers(const char *pwdfile
, int debug
);
48 int main(int argc
,char *argv
[])
56 char hexclude
[MAXLEN
];
57 char splitprefix
[MAXLEN
];
68 time_t read_start_time
;
70 time_t process_start_time
;
71 time_t process_end_time
;
73 double process_elapsed
;
74 FileListIterator FIter
;
77 static int output_css
=0;
78 static int show_statis
=0;
80 static struct option long_options
[]=
82 {"convert",no_argument
,&convert
,1},
83 {"css",no_argument
,&output_css
,1},
84 {"help",no_argument
,NULL
,'h'},
85 {"lastlog",required_argument
,NULL
,2},
86 {"keeplogs",no_argument
,NULL
,3},
87 {"split",no_argument
,&split
,1},
88 {"splitprefix",required_argument
,NULL
,'P'},
89 {"statistics",no_argument
,&show_statis
,1},
93 start_time
=time(NULL
);
96 setlocale(LC_TIME
,"");
99 #if defined(ENABLE_NLS) && defined(HAVE_LOCALE_H)
100 if (!setlocale (LC_ALL
, "")) {
101 fprintf(stderr
,"SARG: Cannot set the locale LC_ALL to the environment variable\n");
104 if (!bindtextdomain (PACKAGE_NAME
, LOCALEDIR
)) {
105 fprintf(stderr
,"SARG: Cannot bind to text domain %s in directory %s (%s)\n",PACKAGE_NAME
,LOCALEDIR
,strerror(errno
));
108 if (!textdomain (PACKAGE_NAME
)) {
109 fprintf(stderr
,"SARG: Cannot set gettext domain for %s PACKAGE_NAME (%s)\n",PACKAGE_NAME
,strerror(errno
));
119 UserAgentLog
[0]='\0';
120 ExcludeHosts
[0]='\0';
121 ExcludeUsers
[0]='\0';
128 ExternalCSSFile
[0]='\0';
129 RedirectorLogFormat
[0]='\0';
132 snprintf(ExcludeCodes
,sizeof(ExcludeCodes
),"%s/exclude_codes",SYSCONFDIR
);
133 strcpy(GraphDaysBytesBarColor
,"orange");
134 strcpy(BgColor
,"#ffffff");
135 strcpy(TxColor
,"#000000");
136 strcpy(TxBgColor
,"lavender");
137 strcpy(TiColor
,"darkblue");
140 strcpy(LogoTextColor
,"#000000");
141 strcpy(HeaderColor
,"darkblue");
142 strcpy(HeaderBgColor
,"#dddddd");
143 strcpy(LogoTextColor
,"#006699");
144 strcpy(FontSize
,"9px");
145 strcpy(TempDir
,"/tmp");
146 strcpy(OutputDir
,"/var/www/html/squid-reports");
147 AnonymousOutputFiles
=false;
150 OverwriteReport
=false;
151 RemoveTempFiles
=true;
152 strcpy(ReplaceIndex
,"index.html");
154 RecordsWithoutUser
=RECORDWITHOUTUSER_IP
;
156 strcpy(MailUtility
,"mailx");
160 TopuserSort
=TOPUSER_SORT_BYTES
| TOPUSER_SORT_REVERSE
;
161 UserSort
=USER_SORT_BYTES
| USER_SORT_REVERSE
;
162 TopsitesSort
=TOPSITE_SORT_CONNECT
| TOPSITE_SORT_REVERSE
;
164 strcpy(FontFace
,"Verdana,Tahoma,Arial");
165 datetimeby
=DATETIME_BYTE
;
166 strcpy(CharSet
,"ISO-8859-1");
168 strcpy(PrivacyString
,"***.***.***.***");
169 strcpy(PrivacyStringColor
,"blue");
171 TopUserFields
=TOPUSERFIELDS_NUM
| TOPUSERFIELDS_DATE_TIME
| TOPUSERFIELDS_USERID
| TOPUSERFIELDS_CONNECT
|
172 TOPUSERFIELDS_BYTES
| TOPUSERFIELDS_SETYB
| TOPUSERFIELDS_IN_CACHE_OUT
|
173 TOPUSERFIELDS_USED_TIME
| TOPUSERFIELDS_MILISEC
| TOPUSERFIELDS_PTIME
|
174 TOPUSERFIELDS_TOTAL
| TOPUSERFIELDS_AVERAGE
;
175 UserReportFields
=USERREPORTFIELDS_CONNECT
| USERREPORTFIELDS_BYTES
| USERREPORTFIELDS_SETYB
|
176 USERREPORTFIELDS_IN_CACHE_OUT
| USERREPORTFIELDS_USED_TIME
| USERREPORTFIELDS_MILISEC
|
177 USERREPORTFIELDS_PTIME
| USERREPORTFIELDS_TOTAL
| USERREPORTFIELDS_AVERAGE
;
178 strcpy(DataFileDelimiter
,";");
179 DataFileFields
=DATA_FIELD_USER
| DATA_FIELD_DATE
| DATA_FIELD_TIME
| DATA_FIELD_URL
| DATA_FIELD_CONNECT
|
180 DATA_FIELD_BYTES
| DATA_FIELD_IN_CACHE
| DATA_FIELD_OUT_CACHE
| DATA_FIELD_ELAPSED
;
181 ShowReadStatistics
=true;
182 ShowReadPercent
=false;
183 strcpy(IndexSortOrder
,"D");
186 ParsedOutputLog
[0]='\0';
187 strcpy(ParsedOutputLogCompress
,"/bin/gzip -f");
188 DisplayedValues
=DISPLAY_ABBREV
;
189 strcpy(HeaderFontSize
,"9px");
190 strcpy(TitleFontSize
,"11px");
191 strcpy(AuthUserTemplateFile
,"sarg_htaccess");
192 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");
195 strcpy(GraphFont
,FONTDIR
"/DejaVuSans.ttf");
199 strcpy(Ulimit
,"20000");
200 NtlmUserFormat
=NTLMUSERFORMAT_DOMAINUSER
;
201 IndexTree
=INDEX_TREE_FILE
;
202 IndexFields
=INDEXFIELDS_DIRSIZE
;
203 strcpy(RealtimeTypes
,"GET,PUT,CONNECT");
204 RealtimeUnauthRec
=REALTIME_UNAUTH_REC_SHOW
;
205 RedirectorFilterOutDate
=true;
206 DansguardianFilterOutDate
=true;
207 DataFileUrl
=DATAFILEURL_IP
;
208 strcpy(MaxElapsed
,"28800000");
209 BytesInSitesUsersReport
=0;
210 UserAuthentication
=0;
211 strcpy(LDAPHost
,"127.0.0.1");
213 LDAPProtocolVersion
=3;
216 LDAPBaseSearch
[0]='\0';
217 strcpy(LDAPFilterSearch
, "(uid=%s)");
218 strcpy(LDAPTargetAttr
, "cn");
219 LDAPNativeCharset
[0]='\0';
224 ReadFilter
.DateRange
[0]='\0';
229 ReadFilter
.StartTime
=-1;
230 ReadFilter
.EndTime
=-1;
235 UserInvalidChar
[0]='\0';
237 SquidGuardConf
[0]='\0';
238 DansGuardianConf
[0]='\0';
240 HostAliasFile
[0]='\0';
241 UserAliasFile
[0]='\0';
243 dansguardian_count
=0;
246 DeniedReportLimit
=10;
247 AuthfailReportLimit
=10;
248 DansGuardianReportLimit
=10;
249 SquidGuardReportLimit
=10;
250 DownloadReportLimit
=50;
259 realtime_access_log_lines
=1000;
266 NumLogSuccessiveErrors
=3;
267 NumLogTotalErrors
=50;
272 bzero(IncludeUsers
, sizeof(IncludeUsers
));
273 bzero(ExcludeString
, sizeof(ExcludeString
));
274 memset(&period
,0,sizeof(period
));
276 AccessLogFromCmdLine
=0;
277 RedirectorLogFromCmdLine
=0;
279 strcpy(Title
,_("Squid User Access Report"));
281 while((ch
= getopt_long(argc
, argv
, "a:b:c:d:e:f:g:hikl:L:mno:P:prs:t:u:vw:xyz",long_options
,&option_index
)) != -1){
287 lastlog
=atoi(optarg
);
293 safe_strcpy(addr
,optarg
,sizeof(addr
));
295 case 'b': //unused option
296 safe_strcpy(uagent
,optarg
,sizeof(uagent
));
299 safe_strcpy(hexclude
,optarg
,sizeof(hexclude
));
302 safe_strcpy(ReadFilter
.DateRange
,optarg
,sizeof(ReadFilter
.DateRange
));
303 date_from(ReadFilter
.DateRange
,sizeof(ReadFilter
.DateRange
), &dfrom
, &duntil
);
306 safe_strcpy(email
,optarg
,sizeof(email
));
309 safe_strcpy(ConfigFile
,optarg
,sizeof(ConfigFile
));
325 AccessLog
=FileList_Create();
326 if (!FileList_AddFile(AccessLog
,optarg
)) {
327 debuga(_("Not enough memory to store the input log file names\n"));
330 AccessLogFromCmdLine
++;
333 if (NRedirectorLogs
>MAX_REDIRECTOR_LOGS
) {
334 debuga(_("Too many redirector logs passed on command line with option -L.\n"));
337 if (strlen(optarg
)>=MAX_REDIRECTOR_FILELEN
) {
338 debuga(_("Redirector log file name too long passed on command line with opton -L: %s\n"),optarg
);
341 strcpy(RedirectorLogs
[NRedirectorLogs
],optarg
);
343 RedirectorLogFromCmdLine
++;
352 safe_strcpy(outdir
,optarg
,sizeof(outdir
));
358 safe_strcpy(splitprefix
,optarg
,sizeof(splitprefix
));
364 safe_strcpy(site
,optarg
,sizeof(site
));
370 if(strstr(optarg
,"-") == 0) {
371 if(sscanf(optarg
,"%d:%d",&h1
,&m1
)!=2) {
372 debuga(_("Time period passed on the command line with option -t must be HH:MM\n"));
375 ReadFilter
.StartTime
=h1
*100+m1
;
376 ReadFilter
.EndTime
=ReadFilter
.StartTime
;
377 snprintf(hm_str
,sizeof(hm_str
),"%02d:%02d",h1
,m1
);
379 if(sscanf(optarg
,"%d:%d-%d:%d",&h1
,&m1
,&h2
,&m2
)!=4) {
380 debuga(_("Time range passed on the command line with option -t must be HH:MM-HH:MM\n"));
383 ReadFilter
.StartTime
=h1
*100+m1
;
384 ReadFilter
.EndTime
=h2
*100+m2
;
385 snprintf(hm_str
,sizeof(hm_str
),"%02d:%02d-%02d:%02d",h1
,m1
,h2
,m2
);
390 safe_strcpy(us
,optarg
,sizeof(us
));
396 safe_strcpy(tmp
,optarg
,sizeof(tmp
));
401 case 'y': //unused option
408 debuga(_("Option -%c requires an argument\n"),optopt
);
430 AccessLog
=FileList_Create();
431 for (iarq
=optind
; iarq
<argc
; iarq
++) {
432 if (!FileList_AddFile(AccessLog
,argv
[iarq
])) {
433 debuga(_("Not enough memory to store the input log file names\n"));
436 AccessLogFromCmdLine
++;
440 if(debug
) debuga(_("Init\n"));
442 if(ConfigFile
[0] == '\0') snprintf(ConfigFile
,sizeof(ConfigFile
),"%s/sarg.conf",SYSCONFDIR
);
443 if(access(ConfigFile
, R_OK
) != 0) {
444 debuga(_("Cannot open config file: %s - %s\n"),ConfigFile
,strerror(errno
));
448 if(access(ConfigFile
, R_OK
) == 0)
451 if(userip
) UserIp
=true;
453 if(dns
) ip2name_forcedns();
455 if (lastlog
>=0) LastLog
=lastlog
;
457 if(outdir
[0] == '\0') strcpy(outdir
,OutputDir
);
458 if(outdir
[0] != '\0') strcat(outdir
,"/");
465 if(IndexTree
== INDEX_TREE_FILE
)
466 strcpy(ImageFile
,"../images");
468 strcpy(ImageFile
,"../../../images");
470 dataonly
=(DataFile
[0] != '\0');
472 if (df
=='\0') df
=DateFormat
;
473 if (df
=='\0') df
='u';
475 IndexTree
=INDEX_TREE_FILE
;
477 if(AccessLog
==NULL
) {
478 AccessLog
=FileList_Create();
479 if (!FileList_AddFile(AccessLog
,"/var/log/squid/access.log")) {
480 debuga(_("Not enough memory to store the input log file names\n"));
488 FIter
=FileListIter_Open(AccessLog
);
489 while ((file
=FileListIter_Next(FIter
))!=NULL
)
490 splitlog(file
, df
, dfrom
, duntil
, convert
, splitprefix
);
491 FileListIter_Close(FIter
);
497 FIter
=FileListIter_Open(AccessLog
);
498 while ((file
=FileListIter_Next(FIter
))!=NULL
)
499 convlog(file
, df
, dfrom
, duntil
);
500 FileListIter_Close(FIter
);
504 load_excludecodes(ExcludeCodes
);
506 if(access(PasswdFile
, R_OK
) == 0) {
507 getusers(PasswdFile
,debug
);
508 ReadFilter
.SysUsers
=true;
510 ReadFilter
.SysUsers
=false;
513 if(hexclude
[0] == '\0')
514 strcpy(hexclude
,ExcludeHosts
);
515 if(hexclude
[0] != '\0') {
516 gethexclude(hexclude
,debug
);
517 ReadFilter
.HostFilter
=true;
519 ReadFilter
.HostFilter
=false;
522 if(ReportType
== 0) {
523 ReportType
=REPORT_TYPE_TOPUSERS
| REPORT_TYPE_TOPSITES
| REPORT_TYPE_USERS_SITES
|
524 REPORT_TYPE_SITES_USERS
| REPORT_TYPE_DATE_TIME
| REPORT_TYPE_DENIED
|
525 REPORT_TYPE_AUTH_FAILURES
| REPORT_TYPE_SITE_USER_TIME_DATE
| REPORT_TYPE_DOWNLOADS
;
528 if(access(ExcludeUsers
, R_OK
) == 0) {
529 getuexclude(ExcludeUsers
,debug
);
530 ReadFilter
.UserFilter
=true;
532 ReadFilter
.UserFilter
=false;
534 if (HostAliasFile
[0] != '\0')
535 read_hostalias(HostAliasFile
);
536 if (UserAliasFile
[0] != '\0')
537 read_useralias(UserAliasFile
);
540 if(ReadFilter
.UserFilter
) {
544 if(strcmp(ExcludeUsers
,"indexonly") == 0) indexonly
=true;
545 if(Index
== INDEX_ONLY
) indexonly
=true;
547 if(MaxElapsed
[0] != '\0')
548 ReadFilter
.max_elapsed
=atol(MaxElapsed
);
550 ReadFilter
.max_elapsed
=0;
552 if(uagent
[0] == '\0') strcpy(uagent
,UserAgentLog
);
554 if(tmp
[0] == '\0') strcpy(tmp
,TempDir
);
555 else strcpy(TempDir
,tmp
);
557 For historical reasons, the temporary directory is the subdirectory "sarg" of the path
558 provided by the user.
562 if (tmp
[0]!='\0' && strncmp(outdir
,tmp
,strlen(tmp
))==0) {
563 debuga(_("The output directory \"%s\" must be outside of the temporary directory \"%s\"\n"),outdir
,tmp
);
567 if(email
[0] == '\0' && OutputEmail
[0] != '\0') strcpy(email
,OutputEmail
);
569 if(email
[0] != '\0') {
575 if(access(tmp
, R_OK
) == 0) {
576 if (debug
) debuga(_("Deleting temporary directory \"%s\"\n"),tmp
);
584 debuga(_("Parameters:\n"));
585 debuga(_(" Hostname or IP address (-a) = %s\n"),addr
);
586 debuga(_(" Useragent log (-b) = %s\n"),uagent
);
587 debuga(_(" Exclude file (-c) = %s\n"),hexclude
);
588 debuga(_(" Date from-until (-d) = %s\n"),ReadFilter
.DateRange
);
589 debuga(_(" Email address to send reports (-e) = %s\n"),email
);
590 debuga(_(" Config file (-f) = %s\n"),ConfigFile
);
592 debuga(_(" Date format (-g) = Europe (dd/mm/yyyy)\n"));
594 debuga(_(" Date format (-g) = USA (mm/dd/yyyy)\n"));
596 debuga(_(" Date format (-g) = Sites & Users (yyyy/ww)\n"));
597 debuga(_(" IP report (-i) = %s\n"),(iprel
) ? _("Yes") : _("No"));
598 debuga(_(" Keep temporary files (-k) = %s\n"),(KeepTempLog
) ? _("Yes") : _("No"));
599 FIter
=FileListIter_Open(AccessLog
);
600 while ((file
=FileListIter_NextWithMask(FIter
))!=NULL
)
601 debuga(_(" Input log (-l) = %s\n"),file
);
602 FileListIter_Close(FIter
);
603 for (iarq
=0 ; iarq
<NRedirectorLogs
; iarq
++)
604 debuga(_(" Redirector log (-L) = %s\n"),RedirectorLogs
[iarq
]);
605 debuga(_(" Resolve IP Address (-n) = %s\n"),(Ip2Name
) ? _("Yes") : _("No"));
606 debuga(_(" Output dir (-o) = %s\n"),outdir
);
607 debuga(_("Use Ip Address instead of userid (-p) = %s\n"),(UserIp
) ? _("Yes") : _("No"));
608 debuga(_(" Accessed site (-s) = %s\n"),site
);
609 debuga(_(" Time (-t) = %s\n"),hm_str
);
610 debuga(_(" User (-u) = %s\n"),us
);
611 debuga(_(" Temporary dir (-w) = %s\n"),tmp
);
612 debuga(_(" Debug messages (-x) = %s\n"),(debug
) ? _("Yes") : _("No"));
613 debuga(_(" Process messages (-z) = %s\n"),(debugz
) ? _("Yes") : _("No"));
614 debuga(_(" Previous reports to keep (--lastlog) = %d\n"),LastLog
);
620 printf(_("Parameters:\n"));
621 printf(_(" Hostname or IP address (-a) = %s\n"),addr
);
622 printf(_(" Useragent log (-b) = %s\n"),uagent
);
623 printf(_(" Exclude file (-c) = %s\n"),hexclude
);
624 printf(_(" Date from-until (-d) = %s\n"),ReadFilter
.DateRange
);
625 printf(_(" Email address to send reports (-e) = %s\n"),email
);
626 printf(_(" Config file (-f) = %s\n"),ConfigFile
);
628 printf(_(" Date format (-g) = Europe (dd/mm/yyyy)\n"));
630 printf(_(" Date format (-g) = USA (mm/dd/yyyy)\n"));
632 printf(_(" Date format (-g) = Sites & Users (yyyy/ww)\n"));
633 printf(_(" IP report (-i) = %s\n"),(iprel
) ? _("Yes") : _("No"));
634 printf(_(" Keep temporary files (-k) = %s\n"),(KeepTempLog
) ? _("Yes") : _("No"));
635 FIter
=FileListIter_Open(AccessLog
);
636 while ((file
=FileListIter_NextWithMask(FIter
))!=NULL
)
637 printf(_(" Input log (-l) = %s\n"),file
);
638 FileListIter_Close(FIter
);
639 for (iarq
=0 ; iarq
<NRedirectorLogs
; iarq
++)
640 printf(_(" Redirector log (-L) = %s\n"),RedirectorLogs
[iarq
]);
641 printf(_(" Resolve IP Address (-n) = %s\n"),(Ip2Name
) ? _("Yes") : _("No"));
642 printf(_(" Output dir (-o) = %s\n"),outdir
);
643 printf(_("Use Ip Address instead of userid (-p) = %s\n"),(UserIp
) ? _("Yes") : _("No"));
644 printf(_(" Accessed site (-s) = %s\n"),site
);
645 printf(_(" Time (-t) = %s\n"),hm_str
);
646 printf(_(" User (-u) = %s\n"),us
);
647 printf(_(" Temporary dir (-w) = %s\n"),tmp
);
648 printf(_(" Debug messages (-x) = %s\n"),(debug
) ? _("Yes") : _("No"));
649 printf(_(" Process messages (-z) = %s\n"),(debugz
) ? _("Yes") : _("No"));
650 printf(_(" Previous reports to keep (--lastlog) = %d\n"),LastLog
);
651 printf(_("sarg version: %s\n"),VERSION
);
655 debuga(_("sarg version: %s\n"),VERSION
);
657 #ifdef ENABLE_DOUBLE_CHECK_DATA
658 debuga(_("Sarg compiled to report warnings if the output is inconsistent\n"));
662 if (Ulimit
[0] != '\0') {
667 #if defined(RLIMIT_NOFILE)
668 getrlimit (RLIMIT_NOFILE
, &rl
);
669 #elif defined(RLIMIT_OFILE)
670 getrlimit (RLIMIT_OFILE
, &rl
);
672 #warning "No rlimit resource for the number of open files"
677 rl
.rlim_cur
= atol(Ulimit
);
678 rl
.rlim_max
= atol(Ulimit
);
679 #if defined(RLIMIT_NOFILE)
680 rc
=setrlimit (RLIMIT_NOFILE
, &rl
);
681 #elif defined(RLIMIT_OFILE)
682 rc
=setrlimit (RLIMIT_OFILE
, &rl
);
684 #warning "No rlimit resource for the number of open files"
687 debuga(_("setrlimit error - %s\n"),strerror(errno
));
691 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
);
695 init_usertab(UserTabFile
);
697 read_start_time
=time(NULL
);
698 LogStatus
=ReadLogFile(&ReadFilter
);
699 read_end_time
=time(NULL
);
700 read_elapsed
=(double)read_end_time
-(double)read_start_time
;
702 FileList_Destroy(&AccessLog
);
708 debuga(_("No records found\n"));
711 if(userfile
) free(userfile
);
716 if (ReadFilter
.DateRange
[0]!='\0') {
717 char date0
[30], date1
[30];
719 strftime(date0
,sizeof(date0
),"%d/%m/%Y",&period
.start
);
720 strftime(date1
,sizeof(date1
),"%d/%m/%Y",&period
.end
);
721 debuga(_("Period covered by log files: %s-%s\n"),date0
,date1
);
722 getperiod_fromrange(&period
,dfrom
,duntil
);
724 if (getperiod_buildtext(&period
)<0) {
725 debuga(_("Failed to build the string representation of the date range\n"));
730 debuga(_("Period: %s\n"),period
.text
);
732 process_start_time
=time(NULL
);
733 if(DataFile
[0] != '\0')
737 process_end_time
=time(NULL
);
738 process_elapsed
=(double)process_end_time
-(double)process_start_time
;
744 if(!KeepTempLog
&& strcmp(tmp
,"/tmp") != 0) {
759 double elapsed
=(double)end_time
-(double)start_time
;
760 debuga(_("Total execution time: %.0lf seconds\n"),elapsed
);
761 if (read_elapsed
>0.) {
762 debuga(_("Lines read: %lu lines in %.0lf seconds (%.0lf lines/s)\n"),lines_read
,read_elapsed
,(double)lines_read
/read_elapsed
);
764 if (process_elapsed
>0.) {
765 debuga(_("Processed records: %lu records in %.0lf seconds (%.0lf records/s)\n"),records_kept
,process_elapsed
,(double)records_kept
/process_elapsed
);
766 debuga(_("Users: %lu users in %.0lf seconds (%.0lf users/s)\n"),nusers
,process_elapsed
,(double)nusers
/process_elapsed
);
777 static void getusers(const char *pwdfile
, int debug
)
785 debuga(_("Loading password file from %s\n"),pwdfile
);
787 if ((fp_usr
= fopen(pwdfile
, "r")) == NULL
) {
788 debuga(_("(getusers) Cannot open file %s - %s\n"),pwdfile
,strerror(errno
));
792 if (fseek(fp_usr
, 0, SEEK_END
)==-1) {
793 debuga(_("Failed to move till the end of the users file %s: %s\n"),pwdfile
,strerror(errno
));
796 nreg
= ftell(fp_usr
);
798 debuga(_("Cannot get the size of file %s\n"),pwdfile
);
802 if (fseek(fp_usr
, 0, SEEK_SET
)==-1) {
803 debuga(_("Failed to rewind the users file %s: %s\n"),pwdfile
,strerror(errno
));
807 if((userfile
=(char *) malloc(nreg
))==NULL
){
808 debuga(_("malloc error (%ld)\n"),nreg
);
812 bzero(userfile
,nreg
);
813 strcpy(userfile
,":");
815 while(fgets(buf
,sizeof(buf
),fp_usr
)!=NULL
) {
818 debuga(_("You have an invalid user in your %s file\n"),pwdfile
);
822 strcat(userfile
,buf
);