From: Frederic Marchal Date: Tue, 9 Jun 2015 18:17:08 +0000 (+0200) Subject: Allow the use of wildcards in the access.log and useragent.log X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fsarg.git;a=commitdiff_plain;h=2b41f02c8e5e89edf25167e5c58a8ca2002dc38b Allow the use of wildcards in the access.log and useragent.log A file name can contain * or ? if configure was not run with --without-glob. It is possible to see if file globbing was compiled in by running sarg with -x -V. --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 4006537..d2d9960 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,6 +119,7 @@ CHECK_INCLUDE_FILE(stdbool.h HAVE_STDBOOL_H) CHECK_INCLUDE_FILE(getopt.h HAVE_GETOPT_H) CHECK_INCLUDE_FILE(fcntl.h HAVE_FCNTL_H) CHECK_INCLUDE_FILE(fnmatch.h HAVE_FNMATCH_H) +CHECK_INCLUDE_FILE(glob.h HAVE_GLOB_H) IF(!HAVE_GETOPT_H) MESSAGE(SEND_ERROR "getopt.h is required to compile sarg") diff --git a/configure.ac b/configure.ac index b51a2f9..3be9cc6 100644 --- a/configure.ac +++ b/configure.ac @@ -150,6 +150,16 @@ else pcre_status="disabled" fi +# Build with file globbing +AC_ARG_WITH([glob], +AS_HELP_STRING([--without-glob],[Ignore wildcards in file names]), +[with_glob=no],[with_glob=yes]) +if ( test "x$with_glob" != "xno" ) ; then + AC_CHECK_HEADERS(glob.h) +else + glob_status="disabled" +fi + dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_STRUCT_TM @@ -393,3 +403,7 @@ if ( test "x$ldap_status" = "xdisabled" ) ; then elif ( test "x$ldap_status" = "xnot found" ) ; then AC_MSG_NOTICE([ldap header files not found so LDAP is not available to resolve user's names]) fi + +if ( test "x$glob_status" = "xdisabled" ) ; then + AC_MSG_NOTICE([Not building with file globbing as requested on the configuration command line]) +fi diff --git a/filelist.c b/filelist.c index 4902590..e851a00 100644 --- a/filelist.c +++ b/filelist.c @@ -28,6 +28,9 @@ #include "include/defs.h" #include "include/stringbuffer.h" #include "include/filelist.h" +#ifdef HAVE_GLOB_H +#include +#endif struct DirEntryStruct { @@ -85,6 +88,12 @@ struct _FileListIterator int Level; //! The current node at each level. struct DirEntryIterator *DirNodes; +#ifdef HAVE_GLOB_H + //! Next globbed file to return + int NextGlob; + //! Buffer with the globbed files. + glob_t Glob; +#endif }; @@ -417,42 +426,54 @@ static void FileListIter_GetNext(struct _FileListIterator *FIter) */ const char *FileListIter_Next(struct _FileListIterator *FIter) { - int Length; - int Level; - struct DirEntryIterator *DIter; - - if (!FIter) return(NULL); - if (!FIter->DirNodes) return(NULL); - if (FIter->Level<0 || FIter->Level>=FIter->TreeDepth) return(NULL); + const char *Path; - // how much space to store the path - Length=FIter->DirNodes[FIter->CurrentPathLevel].PathLength; - for (Level=FIter->CurrentPathLevel ; Level<=FIter->Level ; Level++) +#ifdef HAVE_GLOB_H + if (FIter->NextGlob>0) { - DIter=FIter->DirNodes+Level; - DIter->PathLength=Length;; - Length+=strlen(DIter->Dir->Name)+1; - } - - // get the memory to store the path - if (Length>FIter->CurrentPathSize) - { - char *temp=realloc(FIter->CurrentPath,Length); - if (!temp) return(NULL); - FIter->CurrentPath=temp; - FIter->CurrentPathSize=Length; + if (FIter->NextGlobGlob.gl_pathc) + { + Path=FIter->Glob.gl_pathv[FIter->NextGlob++]; + return(Path); + } + globfree(&FIter->Glob); + FIter->NextGlob=0; } - - for (Level=FIter->CurrentPathLevel ; Level<=FIter->Level ; Level++) + /* + * Try every pattern until the list is exhausted or a real error + * occurs or a file is matched. + */ + while ((Path=FileListIter_NextWithMask(FIter))!=NULL) { - DIter=FIter->DirNodes+Level; - if (Level>0) FIter->CurrentPath[DIter->PathLength-1]='/'; - strcpy(FIter->CurrentPath+DIter->PathLength,DIter->Dir->Name); + int ErrCode=glob(Path,GLOB_ERR | GLOB_NOSORT,NULL,&FIter->Glob); + if (ErrCode==0)//success + { + Path=FIter->Glob.gl_pathv[0]; + FIter->NextGlob=1; + break; + } + if (ErrCode!=GLOB_NOMATCH) + { + switch (ErrCode) + { + case GLOB_NOSPACE: + debuga(__FILE__,__LINE__,_("Not enough memory to read the files matching \"%s\"\n"),Path); + break; + case GLOB_ABORTED: + debuga(__FILE__,__LINE__,_("Read error while listing the files matching \"%s\"\n"),Path); + break; + } + exit(EXIT_FAILURE); + } } - FIter->CurrentPathLevel=Level; - - FileListIter_GetNext(FIter); - return(FIter->CurrentPath); +#else + /* + * Fall back to a simple enumeration. In that case, the user cannot use + * wildcards as they won't be expended. + */ + Path=FileListIter_NextWithMask(FIter); +#endif + return(Path); } /*! @@ -479,7 +500,7 @@ const char *FileListIter_NextWithMask(struct _FileListIterator *FIter) for (Level=FIter->CurrentPathLevel ; Level<=FIter->Level ; Level++) { DIter=FIter->DirNodes+Level; - DIter->PathLength=Length;; + DIter->PathLength=Length; Length+=strlen(DIter->Dir->Name)+1; } @@ -511,6 +532,9 @@ void FileListIter_Close(struct _FileListIterator *FIter) { if (FIter) { +#ifdef HAVE_GLOB_H + if (FIter->NextGlob>0) globfree(&FIter->Glob); +#endif if (FIter->CurrentPath) free(FIter->CurrentPath); if (FIter->DirNodes) free(FIter->DirNodes); free(FIter); diff --git a/include/config.h.in b/include/config.h.in index dc57c7f..e77c5da 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -53,6 +53,7 @@ #cmakedefine HAVE_PCRE_H #cmakedefine HAVE_FNMATCH_H #cmakedefine HAVE_DIRECT_H +#cmakedefine HAVE_GLOB_H #cmakedefine IBERTY_LIB diff --git a/sarg.conf b/sarg.conf index 351b01f..5a32ffc 100644 --- a/sarg.conf +++ b/sarg.conf @@ -10,6 +10,10 @@ # safety against incomplete reporting due to problems occuring with the # logs. # +# If the file globbing was compiled in, the file name can contain shell +# wildcards such as * and ?. Tilde expension and variable expension are +# not supported. Special characters can be escaped with a backslash. +# # If some files are passed on the command line with "sarg -l file" or # "sarg file", the files listed here are ignored. # @@ -215,7 +219,11 @@ #exclude_hosts none # TAG: useragent_log file -# useragent.log file patch to generate useragent report. +# useragent.log file to generate useragent report. +# +# This option may be repeated multiple times to process several files. +# +# Wildcards are allowed (see access_log). # #useragent_log none diff --git a/util.c b/util.c index d350c34..8cf7aa7 100644 --- a/util.c +++ b/util.c @@ -2178,6 +2178,13 @@ void version(void) printf(_("If this message is in English, then your language is not supported or not correctly installed.\n")); } #endif + if (debug) { +#ifdef HAVE_GLOB_H + printf(_("File globbing compiled in.\n")); +#else + printf(_("File globbing NOT compiled in.\n")); +#endif + } exit(EXIT_SUCCESS); }