From: Frederic Marchal Date: Sun, 7 Jun 2015 19:07:20 +0000 (+0200) Subject: Accept multiple useragent logs X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=137eb63d31882c0a250bc568c58e0c64a6100c1b;p=thirdparty%2Fsarg.git Accept multiple useragent logs Command line option -b can be repeated to add more useragent logs. The useragent_log configuration option can be repeated multiple time to scan several files. --- diff --git a/filelist.c b/filelist.c index fb43165..4902590 100644 --- a/filelist.c +++ b/filelist.c @@ -296,6 +296,21 @@ bool FileList_AddFile(FileListObject FObj,const char *FileName) return(FileList_AddFileRecursive(FObj,&FObj->First,FileName)); } +/*! + * \brief Is the file list empty? + * + * \param FObj The file list to check. + * + * \return \c True if the file list is empty or \c false if + * there is at least one file in the list. + */ +bool FileList_IsEmpty(FileListObject FObj) +{ + if (!FObj) return(true); + if (FObj->First==NULL) return(true); + return(false); +} + /*! * Recursively measure the tree depth. * @@ -327,6 +342,7 @@ FileListIterator FileListIter_Open(FileListObject FObj) struct _FileListIterator *FIter; struct DirEntryStruct *Dir; + if (!FObj) return(NULL); FIter=(FileListIterator)calloc(1,sizeof(*FIter)); if (!FIter) return(NULL); FIter->Parent=FObj; diff --git a/getconf.c b/getconf.c index 8454e5d..9ae0e40 100644 --- a/getconf.c +++ b/getconf.c @@ -36,6 +36,8 @@ extern int PerUserLimitsNumber; extern struct PerUserLimitStruct PerUserLimits[MAX_USER_LIMITS]; extern enum PerUserFileCreationEnum PerUserFileCreation; extern char ImageDir[MAXLEN]; +extern FileListObject UserAgentLog; +extern bool UserAgentFromCmdLine; struct param_list { @@ -246,7 +248,7 @@ static int getparam_string(const char *param,char *buf,char *value,int value_siz * file. * * \return A pointer to the beginning of the parameter value or NULL if - * the line is not for the requtested parameter. + * the line is not for the requested parameter. */ static char *getparam_stringptr(const char *param,char *buf) { @@ -688,7 +690,18 @@ static void parmtest(char *buf) return; } - if (getparam_string("useragent_log",buf,UserAgentLog,sizeof(UserAgentLog))>0) return; + if (is_param("useragent_log",buf)>0) { + if (!UserAgentFromCmdLine) { + if (!UserAgentLog) + UserAgentLog=FileList_Create(); + char *FileName=getparam_stringptr("useragent_log",buf); + if (!FileList_AddFile(UserAgentLog,FileName)) { + debuga(__FILE__,__LINE__,_("Not enough memory to store a user agent file name\n")); + exit(EXIT_FAILURE); + } + } + return; + } if (getparam_string("exclude_hosts",buf,ExcludeHosts,sizeof(ExcludeHosts))>0) return; diff --git a/include/conf.h b/include/conf.h index aa59b05..44d5384 100644 --- a/include/conf.h +++ b/include/conf.h @@ -356,7 +356,6 @@ char OutputDir[MAXLEN]; char OutputEmail[MAXLEN]; unsigned long int TopuserSort; unsigned long int UserSort; -char UserAgentLog[255]; char module[255]; char ExcludeHosts[255]; char ExcludeUsers[255]; diff --git a/include/filelist.h b/include/filelist.h index 22392c3..ef145b7 100644 --- a/include/filelist.h +++ b/include/filelist.h @@ -11,6 +11,7 @@ FileListObject FileList_Create(void); void FileList_Destroy(FileListObject *FPtr); bool FileList_AddFile(FileListObject FObj,const char *FileName); +bool FileList_IsEmpty(FileListObject FObj); FileListIterator FileListIter_Open(FileListObject FObj); const char *FileListIter_Next(FileListIterator FIter); diff --git a/log.c b/log.c index 681197a..905fa29 100644 --- a/log.c +++ b/log.c @@ -41,10 +41,12 @@ struct ReadLogDataStruct ReadFilter; //! List of the input log files to process. FileListObject AccessLog=NULL; - - //! Selected locale set through the environment variable. char *CurrentLocale=NULL; +//! Set to \c true if a useragent log is provided on the command line. +bool UserAgentFromCmdLine=false; + +extern FileListObject UserAgentLog; static void getusers(const char *pwdfile, int debug); @@ -55,7 +57,6 @@ int main(int argc,char *argv[]) extern char *optarg; char hm_str[15]; - char uagent[MAXLEN]; char hexclude[MAXLEN]; char splitprefix[MAXLEN]; int ch; @@ -121,7 +122,6 @@ int main(int argc,char *argv[]) LogoText[0]='\0'; PasswdFile[0]='\0'; OutputEmail[0]='\0'; - UserAgentLog[0]='\0'; ExcludeHosts[0]='\0'; ExcludeUsers[0]='\0'; ConfigFile[0]='\0'; @@ -228,7 +228,6 @@ int main(int argc,char *argv[]) us[0]='\0'; ReadFilter.DateRange[0]='\0'; df='\0'; - uagent[0]='\0'; hexclude[0]='\0'; addr[0]='\0'; ReadFilter.StartTime=-1; @@ -297,7 +296,13 @@ int main(int argc,char *argv[]) safe_strcpy(addr,optarg,sizeof(addr)); break; case 'b': //unused option - safe_strcpy(uagent,optarg,sizeof(uagent)); + UserAgentFromCmdLine=true; + if (!UserAgentLog) + UserAgentLog=FileList_Create(); + if (!FileList_AddFile(UserAgentLog,optarg)) { + debuga(__FILE__,__LINE__,_("Not enough memory to store a user agent file name\n")); + exit(EXIT_FAILURE); + } break; case 'c': safe_strcpy(hexclude,optarg,sizeof(hexclude)); @@ -549,8 +554,6 @@ int main(int argc,char *argv[]) else ReadFilter.max_elapsed=0; - if(uagent[0] != '\0') strcpy(UserAgentLog,uagent); - if(tmp[0] == '\0') strcpy(tmp,TempDir); else strcpy(TempDir,tmp); /* @@ -583,7 +586,10 @@ int main(int argc,char *argv[]) debuga(__FILE__,__LINE__,_("Parameters:\n")); debuga(__FILE__,__LINE__,_(" Hostname or IP address (-a) = %s\n"),addr); - debuga(__FILE__,__LINE__,_(" Useragent log (-b) = %s\n"),uagent); + FIter=FileListIter_Open(UserAgentLog); + while ((file=FileListIter_NextWithMask(FIter))!=NULL) + debuga(__FILE__,__LINE__,_(" Useragent log (-b) = %s\n"),file); + FileListIter_Close(FIter); debuga(__FILE__,__LINE__,_(" Exclude file (-c) = %s\n"),hexclude); debuga(__FILE__,__LINE__,_(" Date from-until (-d) = %s\n"),ReadFilter.DateRange); debuga(__FILE__,__LINE__,_(" Email address to send reports (-e) = %s\n"),email); @@ -727,6 +733,7 @@ int main(int argc,char *argv[]) if(userfile) free(userfile); close_usertab(); + FileList_Destroy(&UserAgentLog); end_time=time(NULL); diff --git a/report.c b/report.c index df609f4..8ff2c5f 100644 --- a/report.c +++ b/report.c @@ -26,12 +26,15 @@ #include "include/conf.h" #include "include/defs.h" +#include "include/filelist.h" //! The global statistics of the whole log read. struct globalstatstruct globstat; //! \c True to enable the smart filter. bool smartfilter=false; +extern FileListObject UserAgentLog; + //! The file to store the HTML page where the time of access is reported for one site and one user. static FILE *fp_tt=NULL; //! The name of the file containing the access time of the site/user. @@ -100,7 +103,7 @@ void gerarel(void) debugaz(__FILE__,__LINE__,_("outdirname=%s\n"),outdirname); } - if(UserAgentLog[0] != '\0' && email[0] == '\0') useragent(); + if (!FileList_IsEmpty(UserAgentLog) && email[0] == '\0') useragent(); snprintf(wdirname,sizeof(wdirname),"%s/sarg-general",outdirname); if((fp_gen=MY_FOPEN(wdirname,"w"))==NULL){ diff --git a/topuser.c b/topuser.c index f272fa5..ec49a91 100644 --- a/topuser.c +++ b/topuser.c @@ -26,9 +26,11 @@ #include "include/conf.h" #include "include/defs.h" +#include "include/filelist.h" extern struct globalstatstruct globstat; extern bool smartfilter; +extern FileListObject UserAgentLog; /*! Save the total number of users. The number is written in sarg-users and set @@ -251,7 +253,7 @@ void topuser(void) if (is_denied()) fprintf(fp_top3,"%s\n",_("Denied accesses")); if (is_authfail()) fprintf(fp_top3,"%s\n",_("Authentication Failures")); if(smartfilter) fprintf(fp_top3,"%s\n",_("SmartFilter")); - if(UserAgentLog[0] != '\0' && useragent_count) fprintf(fp_top3,"%s\n",_("Useragent")); + if (!FileList_IsEmpty(UserAgentLog) && useragent_count) fprintf(fp_top3,"%s\n",_("Useragent")); fputs("\n\n",fp_top3); } diff --git a/useragent.c b/useragent.c index fd4179f..8d649d4 100644 --- a/useragent.c +++ b/useragent.c @@ -26,6 +26,9 @@ #include "include/conf.h" #include "include/defs.h" +#include "include/filelist.h" + +FileListObject UserAgentLog=NULL; void useragent(void) { @@ -42,12 +45,14 @@ void useragent(void) char tmp3[MAXLEN]; char day[4],month[5],year[5], wdate[20]; char csort[MAXLEN]; + const char *FileName; int agentot=0, agentot2=0, agentdif=0, cont=0, nagent; unsigned long totregsl=0; int cstatus; int ndate; double perc; struct getwordstruct gwarea, gwarea1; + FileListIterator FIter; ip[0]='\0'; data[0]='\0'; @@ -61,64 +66,75 @@ void useragent(void) sprintf(tmp3,"%s/squagent.int_unsort",tmp); sprintf(tmp2,"%s/squagent.int_log",tmp); - if((fp_in=fopen(UserAgentLog,"r"))==NULL) { - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),UserAgentLog,strerror(errno)); - exit(EXIT_FAILURE); - } if((fp_ou=fopen(tmp3,"w"))==NULL) { debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),tmp3,strerror(errno)); exit(EXIT_FAILURE); } - if(debug) { - debuga(__FILE__,__LINE__,_("Reading useragent log \"%s\"\n"),UserAgentLog); - } - - while(fgets(buf,sizeof(buf),fp_in)!=NULL) { - totregsl++; - getword_start(&gwarea,buf); - if (getword(ip,sizeof(ip),&gwarea,' ')<0 || getword_skip(MAXLEN,&gwarea,'[')<0 || - getword(data,sizeof(data),&gwarea,' ')<0) { - debuga(__FILE__,__LINE__,_("Invalid record in file \"%s\"\n"),UserAgentLog); - exit(EXIT_FAILURE); - } - getword_start(&gwarea1,data); - if (getword(day,sizeof(day),&gwarea1,'/')<0 || getword(month,sizeof(month),&gwarea1,'/')<0 || - getword(year,sizeof(year),&gwarea1,':')<0) { - debuga(__FILE__,__LINE__,_("Invalid date in file \"%s\"\n"),UserAgentLog); + FIter=FileListIter_Open(UserAgentLog); + while ((FileName=FileListIter_Next(FIter))!=NULL) + { + if((fp_in=fopen(FileName,"r"))==NULL) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),FileName,strerror(errno)); exit(EXIT_FAILURE); } - if (dfrom!=0 || duntil!=0){ - buildymd(day,month,year,wdate,sizeof(wdate)); - ndate=atoi(wdate); - if (ndateduntil) break; - } - if(totregsl == 1) - strcpy(idate,data); - strcpy(fdate,data); - if (getword_skip(MAXLEN,&gwarea,'"')<0 || getword(agent,sizeof(agent),&gwarea,'"')<0) { - debuga(__FILE__,__LINE__,_("Invalid useragent in file \"%s\"\n"),UserAgentLog); - exit(EXIT_FAILURE); + + if(debug) { + debuga(__FILE__,__LINE__,_("Reading useragent log \"%s\"\n"),FileName); } - if(gwarea.current[0]!='\0') { - if (getword_skip(MAXLEN,&gwarea,' ')<0 || getword(user,sizeof(user),&gwarea,'\n')<0) { - debuga(__FILE__,__LINE__,_("Invalid record in file \"%s\"\n"),UserAgentLog); + while(fgets(buf,sizeof(buf),fp_in)!=NULL) { + totregsl++; + getword_start(&gwarea,buf); + if (getword(ip,sizeof(ip),&gwarea,' ')<0 || getword_skip(MAXLEN,&gwarea,'[')<0 || + getword(data,sizeof(data),&gwarea,' ')<0) { + debuga(__FILE__,__LINE__,_("Invalid record in file \"%s\"\n"),FileName); exit(EXIT_FAILURE); } - if(user[0] == '-') - strcpy(user,ip); - if(user[0] == '\0') + getword_start(&gwarea1,data); + if (getword(day,sizeof(day),&gwarea1,'/')<0 || getword(month,sizeof(month),&gwarea1,'/')<0 || + getword(year,sizeof(year),&gwarea1,':')<0) { + debuga(__FILE__,__LINE__,_("Invalid date in file \"%s\"\n"),FileName); + exit(EXIT_FAILURE); + } + if (dfrom!=0 || duntil!=0){ + buildymd(day,month,year,wdate,sizeof(wdate)); + ndate=atoi(wdate); + if (ndateduntil) break; + } + if(totregsl == 1) + strcpy(idate,data); + strcpy(fdate,data); + if (getword_skip(MAXLEN,&gwarea,'"')<0 || getword(agent,sizeof(agent),&gwarea,'"')<0) { + debuga(__FILE__,__LINE__,_("Invalid useragent in file \"%s\"\n"),FileName); + exit(EXIT_FAILURE); + } + + if(gwarea.current[0]!='\0') { + if (getword_skip(MAXLEN,&gwarea,' ')<0 || getword(user,sizeof(user),&gwarea,'\n')<0) { + debuga(__FILE__,__LINE__,_("Invalid record in file \"%s\"\n"),FileName); + exit(EXIT_FAILURE); + } + if(user[0] == '-') + strcpy(user,ip); + if(user[0] == '\0') + strcpy(user,ip); + } else { strcpy(user,ip); - } else { - strcpy(user,ip); + } + + fprintf(fp_ou,"%s\t%s\t%s\n",ip,agent,user); + useragent_count++; } - fprintf(fp_ou,"%s\t%s\t%s\n",ip,agent,user); - useragent_count++; + if (fclose(fp_in)==EOF) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),FileName,strerror(errno)); + exit(EXIT_FAILURE); + } } + FileListIter_Close(FIter); if(debug) { debuga(__FILE__,__LINE__,_(" Records read: %ld\n"),totregsl); @@ -128,11 +144,6 @@ void useragent(void) debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),tmp3,strerror(errno)); exit(EXIT_FAILURE); } - if (fclose(fp_in)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),UserAgentLog,strerror(errno)); - exit(EXIT_FAILURE); - } - if(debug) { debuga(__FILE__,__LINE__,_("Sorting file \"%s\"\n"),tmp2); }