sarg
2.4.0
About: SARG ia a Squid Analysis Report Generator. Fossies Dox: sarg-2.4.0.tar.gz ("unofficial" and yet experimental doxygen-generated source code documentation) 
|
Go to the documentation of this file.
54 int main(
int argc,
char *argv[])
73 time_t read_start_time;
75 time_t process_start_time;
76 time_t process_end_time;
78 double process_elapsed;
82 static int output_css=0;
83 static int show_statis=0;
84 static int show_version=0;
86 static struct option long_options[]=
88 {
"convert",no_argument,&convert,1},
89 {
"css",no_argument,&output_css,1},
90 {
"help",no_argument,NULL,
'h'},
91 {
"lastlog",required_argument,NULL,2},
92 {
"keeplogs",no_argument,NULL,3},
93 {
"split",no_argument,&split,1},
94 {
"splitprefix",required_argument,NULL,
'P'},
95 {
"statistics",no_argument,&show_statis,1},
96 {
"version",no_argument,&show_version,
'V'},
100 start_time=time(NULL);
103 setlocale(LC_TIME,
"");
106 #if defined(ENABLE_NLS) && defined(HAVE_LOCALE_H)
109 fprintf(stderr,
"SARG: Cannot set the locale LC_ALL to the environment variable\n");
113 fprintf(stderr,
"SARG: Cannot bind to text domain %s in directory %s (%s)\n",PACKAGE_NAME,LOCALEDIR,strerror(errno));
117 fprintf(stderr,
"SARG: Cannot set gettext domain for %s PACKAGE_NAME (%s)\n",PACKAGE_NAME,strerror(errno));
154 strcpy(
OutputDir,
"/var/www/html/squid-reports");
172 strcpy(
FontFace,
"Verdana,Tahoma,Arial");
200 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");
203 strcpy(
GraphFont,FONTDIR
"/DejaVuSans.ttf");
286 strcpy(
Title,
_(
"Squid User Access Report"));
288 while((ch = getopt_long(argc, argv,
"a:b:c:d:e:f:g:hikl:L:no:P:prs:t:u:Vw:xyz",long_options,&option_index)) != -1){
294 lastlog=atoi(optarg);
307 debuga(__FILE__,__LINE__,
_(
"Not enough memory to store a user agent file name\n"));
340 debuga(__FILE__,__LINE__,
_(
"Not enough memory to store the input log file names\n"));
347 debuga(__FILE__,__LINE__,
_(
"Too many redirector logs passed on command line with option -L.\n"));
351 debuga(__FILE__,__LINE__,
_(
"Redirector log file name too long passed on command line with opton -L: %s\n"),optarg);
368 safe_strcpy(splitprefix,optarg,
sizeof(splitprefix));
380 if (strstr(optarg,
"-") == 0) {
381 if (sscanf(optarg,
"%d:%d",&h1,&m1)!=2) {
382 debuga(__FILE__,__LINE__,
_(
"Time period passed on the command line with option -t must be HH:MM\n"));
387 snprintf(hm_str,
sizeof(hm_str),
"%02d:%02d",h1,m1);
389 if (sscanf(optarg,
"%d:%d-%d:%d",&h1,&m1,&h2,&m2)!=4) {
390 debuga(__FILE__,__LINE__,
_(
"Time range passed on the command line with option -t must be HH:MM-HH:MM\n"));
395 snprintf(hm_str,
sizeof(hm_str),
"%02d:%02d-%02d:%02d",h1,m1,h2,m2);
418 debuga(__FILE__,__LINE__,
_(
"Option -%c requires an argument\n"),optopt);
444 for (iarq=optind ; iarq<argc ; iarq++) {
446 debuga(__FILE__,__LINE__,
_(
"Not enough memory to store the input log file names\n"));
457 debuga(__FILE__,__LINE__,
_(
"Cannot open file \"%s\": %s\n"),
ConfigFile,strerror(errno));
468 if (lastlog>=0)
LastLog=lastlog;
481 if (
df==
'\0')
df=
'u';
488 debuga(__FILE__,__LINE__,
_(
"Not enough memory to store the input log file names\n"));
525 if (hexclude[0] ==
'\0')
527 if (hexclude[0] !=
'\0') {
581 if (mkdtemp(
tmp) == NULL) {
582 debuga(__FILE__,__LINE__,
_(
"Failed to get a unique temporary directory name based on template \"%s\": %s\n"),
tmp, strerror(errno));
588 debuga(__FILE__,__LINE__,
_(
"The output directory \"%s\" must be outside of the temporary directory \"%s\"\n"),
outdir,
tmp);
595 if (
email[0] !=
'\0') {
606 debuga(__FILE__,__LINE__,
_(
"Parameters:\n"));
607 debuga(__FILE__,__LINE__,
_(
" Hostname or IP address (-a) = %s\n"),
addr);
610 debuga(__FILE__,__LINE__,
_(
" Useragent log (-b) = %s\n"),file);
612 debuga(__FILE__,__LINE__,
_(
" Exclude file (-c) = %s\n"),hexclude);
614 debuga(__FILE__,__LINE__,
_(
" Email address to send reports (-e) = %s\n"),
email);
617 debuga(__FILE__,__LINE__,
_(
" Date format (-g) = Europe (dd/mm/yyyy)\n"));
619 debuga(__FILE__,__LINE__,
_(
" Date format (-g) = USA (mm/dd/yyyy)\n"));
621 debuga(__FILE__,__LINE__,
_(
" Date format (-g) = Sites & Users (yyyy/ww)\n"));
622 debuga(__FILE__,__LINE__,
_(
" IP report (-i) = %s\n"),(
iprel) ?
_(
"Yes") :
_(
"No"));
623 debuga(__FILE__,__LINE__,
_(
" Keep temporary files (-k) = %s\n"),(
KeepTempLog) ?
_(
"Yes") :
_(
"No"));
626 debuga(__FILE__,__LINE__,
_(
" Input log (-l) = %s\n"),file);
630 debuga(__FILE__,__LINE__,
_(
" Resolve IP Address (-n) = %s\n"),(
Ip2Name) ?
_(
"Yes") :
_(
"No"));
631 debuga(__FILE__,__LINE__,
_(
" Output dir (-o) = %s\n"),
outdir);
632 debuga(__FILE__,__LINE__,
_(
"Use Ip Address instead of userid (-p) = %s\n"),(
UserIp) ?
_(
"Yes") :
_(
"No"));
633 debuga(__FILE__,__LINE__,
_(
" Accessed site (-s) = %s\n"),
site);
634 debuga(__FILE__,__LINE__,
_(
" Time (-t) = %s\n"),hm_str);
635 debuga(__FILE__,__LINE__,
_(
" User (-u) = %s\n"),
us);
636 debuga(__FILE__,__LINE__,
_(
" Temporary dir (-w) = %s\n"),
tmp);
637 debuga(__FILE__,__LINE__,
_(
" Debug messages (-x) = %s\n"),(
debug) ?
_(
"Yes") :
_(
"No"));
638 debuga(__FILE__,__LINE__,
_(
" Process messages (-z) = %d\n"),
debugz);
639 debuga(__FILE__,__LINE__,
_(
" Previous reports to keep (--lastlog) = %d\n"),
LastLog);
640 debuga(__FILE__,__LINE__,
"\n");
646 #ifdef ENABLE_DOUBLE_CHECK_DATA
647 debuga(__FILE__,__LINE__,
_(
"Sarg compiled to report warnings if the output is inconsistent\n"));
656 #if defined(RLIMIT_NOFILE)
657 getrlimit (RLIMIT_NOFILE, &rl);
658 #elif defined(RLIMIT_OFILE)
659 getrlimit (RLIMIT_OFILE, &rl);
661 #warning "No rlimit resource for the number of open files"
666 rl.rlim_cur = atol(
Ulimit);
667 rl.rlim_max = atol(
Ulimit);
668 #if defined(RLIMIT_NOFILE)
669 rc=setrlimit (RLIMIT_NOFILE, &rl);
670 #elif defined(RLIMIT_OFILE)
671 rc=setrlimit (RLIMIT_OFILE, &rl);
673 #warning "No rlimit resource for the number of open files"
676 debuga(
_(
"setrlimit error: %s\n"),strerror(errno));
680 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);
684 read_start_time=time(NULL);
686 read_end_time=time(NULL);
687 read_elapsed=(double)read_end_time-(
double)read_start_time;
695 char date0[30], date1[30];
699 strftime(date0,
sizeof(date0),
"%x",&Start);
700 strftime(date1,
sizeof(date1),
"%x",&End);
702 debuga(__FILE__,__LINE__,
_(
"Period covered by log files: %s-%s\n"),date0,date1);
707 debuga(__FILE__,__LINE__,
_(
"No records found\n"));
708 debuga(__FILE__,__LINE__,
_(
"End\n"));
716 char date0[30], date1[30];
719 strftime(date1,
sizeof(date1),
"%x",&
period.
end);
721 debuga(__FILE__,__LINE__,
_(
"Period extracted from log files: %s-%s\n"),date0,date1);
727 debuga(__FILE__,__LINE__,
_(
"Failed to build the string representation of the date range\n"));
731 process_start_time=time(NULL);
736 process_end_time=time(NULL);
737 process_elapsed=(double)process_end_time-(
double)process_start_time;
756 double elapsed=(double)end_time-(
double)start_time;
757 debuga(__FILE__,__LINE__,
_(
"Total execution time: %.0lf seconds\n"),elapsed);
758 if (read_elapsed>0.) {
759 debuga(__FILE__,__LINE__,
_(
"Lines read: %lu lines in %.0lf seconds (%.0lf lines/s)\n"),
lines_read,read_elapsed,(
double)
lines_read/read_elapsed);
761 if (process_elapsed>0.) {
762 debuga(__FILE__,__LINE__,
_(
"Processed records: %lu records in %.0lf seconds (%.0lf records/s)\n"),
records_kept,process_elapsed,(
double)
records_kept/process_elapsed);
763 debuga(__FILE__,__LINE__,
_(
"Users: %lu users in %.0lf seconds (%.0lf users/s)\n"),
nusers,process_elapsed,(
double)
nusers/process_elapsed);
768 debuga(__FILE__,__LINE__,
_(
"End\n"));
781 debuga(__FILE__,__LINE__,
_(
"Loading password file \"%s\"\n"),pwdfile);
783 if ((fp_usr = fopen(pwdfile,
"r")) == NULL) {
784 debuga(__FILE__,__LINE__,
_(
"Cannot open file \"%s\": %s\n"),pwdfile,strerror(errno));
788 if (fseek(fp_usr, 0, SEEK_END)==-1) {
789 debuga(__FILE__,__LINE__,
_(
"Failed to move till the end of file \"%s\": %s\n"),pwdfile,strerror(errno));
792 nreg = ftell(fp_usr);
794 debuga(__FILE__,__LINE__,
_(
"Cannot get the size of file \"%s\"\n"),pwdfile);
798 if (fseek(fp_usr, 0, SEEK_SET)==-1) {
799 debuga(__FILE__,__LINE__,
_(
"Failed to rewind file \"%s\": %s\n"),pwdfile,strerror(errno));
803 if ((
userfile=(
char *) malloc(nreg))==NULL){
804 debuga(__FILE__,__LINE__,
_(
"malloc error (%ld bytes required)\n"),nreg);
811 while(fgets(buf,
sizeof(buf),fp_usr)!=NULL) {
814 debuga(__FILE__,__LINE__,
_(
"Invalid user in file \"%s\"\n"),pwdfile);
821 if (fclose(fp_usr)==EOF) {
822 debuga(__FILE__,__LINE__,
_(
"Read error in \"%s\": %s\n"),pwdfile,strerror(errno));
#define REPORT_TYPE_USERS_SITES
#define USERREPORTFIELDS_MILISEC
#define MAX_REDIRECTOR_FILELEN
const char * FileListIter_NextWithMask(struct _FileListIterator *FIter)
#define TOPSITE_SORT_REVERSE
bool UserFilter
True to filter on users.
struct ReadLogDataStruct ReadFilter
The log file filtering.
bool AnonymousOutputFiles
True to use anonymous file and directory names in the report.
#define USERREPORTFIELDS_TOTAL
#define TOPUSERFIELDS_MILISEC
bool SysUsers
True to restrict the log to the system users.
#define TOPUSERFIELDS_USED_TIME
void append_to_path(char *base_path, int base_path_size, const char *append)
unsigned long int TopsitesSort
bool FileList_IsEmpty(FileListObject FObj)
Is the file list empty?
void debuga(const char *File, int Line, const char *msg,...)
static void CleanTemporaryDir()
#define USERREPORTFIELDS_SETYB
#define TOPUSER_SORT_REVERSE
char HostAliasFile[512]
The name of the file containing the host names to replace by an alias in the report.
void getperiod_fromrange(struct periodstruct *period, const struct ReadLogDataStruct *ReadFilter)
char LDAPNativeCharset[20]
Character set to convert the LDAP returned string to.
void read_hostalias(const char *Filename)
FileListObject UserAgentLog
bool DansguardianFilterOutDate
char UserInvalidChar[255]
#define INDEX_HTML_FILE
Name of the html file containing the index of a report file.
#define USERREPORTFIELDS_USED_TIME
#define REALTIME_UNAUTH_REC_SHOW
bool RedirectorFilterOutDate
#define TOPUSERFIELDS_USERID
#define TOPUSERFIELDS_IN_CACHE_OUT
#define TOPUSERFIELDS_SETYB
const char * FileListIter_Next(struct _FileListIterator *FIter)
bool FileList_AddFile(FileListObject FObj, const char *FileName)
char LDAPFilterSearch[512]
char RedirectorLogFormat[4096]
bool KeepTempLog
True to keep the temporary files for inspection.
void data_file(char *tmp)
#define USERREPORTFIELDS_AVERAGE
char ParsedOutputLog[20000]
char HeaderBgColor[20000]
FileListObject AccessLog
List of the input log files to process.
bool my_mkdir(const char *name)
#define REPORT_TYPE_DATE_TIME
#define REPORT_TYPE_TOPUSERS
void FileListIter_Close(struct _FileListIterator *FIter)
void gethexclude(const char *hexfile, int debug)
int SquidGuardReportLimit
struct tm start
The first date of the period.
#define DATA_FIELD_ELAPSED
#define USERREPORTFIELDS_BYTES
void denied_cleanup(void)
unsigned long int DataFileFields
char LogoTextColor[20000]
Iterator of the file list.
char DansGuardianConf[20000]
unsigned long int lines_read
Count the number of lines read from the input log files.
void unlinkdir(const char *dir, bool contentonly)
unsigned long int DisplayedValues
void free_hostalias(void)
#define TOPUSERFIELDS_PTIME
char GraphDaysBytesBarColor[255]
char * userfile
The list of the system users.
void makeTmpDir(const char *tmp)
void convlog(const char *arq, char df, const struct ReadLogDataStruct *ReadFilter)
unsigned long int UserSort
#define bindtextdomain(Domainname, Dirname)
#define INDEXFIELDS_DIRSIZE
unsigned long int IndexFields
The columns to show in the index of the reports.
int EndDate
Last date to include in the report. The format is year*10000+month+100+day.
#define NTLMUSERFORMAT_DOMAINUSER
unsigned long int ReportType
void date_from(struct ReadLogDataStruct *ReadFilter)
bool GetLogPeriod(struct tm *Start, struct tm *End)
#define textdomain(Domainname)
void authfail_cleanup(void)
#define TOPUSERFIELDS_DATE_TIME
int getperiod_buildtext(struct periodstruct *period)
FileListObject FileList_Create(void)
#define TOPUSERFIELDS_TOTAL
char SortTableJs[256]
The full path to sorttable.js if the table in the reports must be dynamicaly sorted.
unsigned long int IndexTree
How to display the index of the reports.
char * CurrentLocale
Selected locale set through the environment variable.
#define TOPUSERFIELDS_CONNECT
#define DATA_FIELD_OUT_CACHE
void set_download_suffix(const char *list)
bool HostFilter
True to filter on hosts.
#define TOPSITE_SORT_CONNECT
#define TOPUSER_SORT_BYTES
void ip2name_forcedns(void)
int StartTime
The start time to include in the report(H*100+M). Set to -1 to disable.
#define USERREPORTFIELDS_PTIME
int main(int argc, char *argv[])
unsigned long int datetimeby
void usage(const char *prog)
#define DATA_FIELD_CONNECT
void load_excludecodes(const char *ExcludeCodes)
void free_useralias(void)
unsigned long int TopUserFields
Include headers and define global variables. */.
char UserAliasFile[512]
The name of the file containing the user names to replace by an alias in the report.
char ParsedOutputLogCompress[512]
int ReadLogFile(struct ReadLogDataStruct *Filter)
unsigned long int RealtimeUnauthRec
char ExcludeString[20000]
bool BytesInSitesUsersReport
#define USERREPORTFIELDS_CONNECT
#define USERREPORTFIELDS_IN_CACHE_OUT
void css_content(FILE *fp_css)
char ExternalCSSFile[20000]
void getconf(const char *File)
void ip2name_cleanup(void)
int RedirectorLogFromCmdLine
#define REPORT_TYPE_DENIED
#define REPORT_TYPE_USERAGENT
FileListIterator FileListIter_Open(FileListObject FObj)
void read_useralias(const char *Filename)
unsigned long int NtlmUserFormat
unsigned long int UserReportFields
#define TOPUSERFIELDS_NUM
#define REPORT_TYPE_DOWNLOADS
void gerarel(const struct ReadLogDataStruct *ReadFilter)
char AuthUserTemplateFile[1024]
#define REPORT_TYPE_AUTH_FAILURES
#define TOPUSERFIELDS_BYTES
void getuexclude(const char *uexfile, int debug)
void download_cleanup(void)
#define USER_SORT_REVERSE
void safe_strcpy(char *dest, const char *src, int length)
int NumLogSuccessiveErrors
The number of consecutive errors allowed in an input log file before the process is interrupted.
char SquidGuardConf[20000]
int EndTime
The end time to include in the report(H*100+M). Set to -1 to disable.
char PrivacyStringColor[30]
static void getusers(const char *pwdfile, int debug)
unsigned long int TopuserSort
Declaration of the structures and functions.
#define MAX_REDIRECTOR_LOGS
void splitlog(const char *arq, char df, const struct ReadLogDataStruct *ReadFilter, int convert, const char *splitprefix)
void free_excludecodes(void)
#define REPORT_TYPE_SITES_USERS
#define REPORT_TYPE_TOPSITES
char DataFileDelimiter[3]
unsigned long int RecordsWithoutUser
char RedirectorLogs[64][1024]
int DansGuardianReportLimit
char DateRange[255]
The filtering date range.
struct periodstruct period
int realtime_access_log_lines
unsigned long int DataFileUrl
char MailUtility[PATH_MAX]
bool ShowReadStatistics
if true, show the number of lines read from the input log file during the reading of the file.
void FileList_Destroy(FileListObject *FPtr)
#define TOPUSERFIELDS_AVERAGE
#define RECORDWITHOUTUSER_IP
int StartDate
First date to include in the report. The format is year*10000+month+100+day.
unsigned long int nusers
Count the number of users.
struct tm end
The last date of the period.
unsigned long int records_kept
Count the number of records kept for the processing.
#define REPORT_TYPE_SITE_USER_TIME_DATE
#define DATA_FIELD_IN_CACHE
long int max_elapsed
Maximum elpased time allowed. Any time greater than this value is set to zero.
bool UserAgentFromCmdLine
Set to true if a useragent log is provided on the command line.