X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=filelist.c;h=c90e23dfe17579a3ff7a251515ef11d70b69b960;hb=cedca1116b4193e322d94a8cf5373c8168d5ac5c;hp=60cabc8958bb3a17fcfd67707b51978685f330d2;hpb=9a803bd3d33f1ca92fc264188dab0757d3843067;p=thirdparty%2Fsarg.git diff --git a/filelist.c b/filelist.c index 60cabc8..c90e23d 100644 --- a/filelist.c +++ b/filelist.c @@ -1,6 +1,6 @@ /* * SARG Squid Analysis Report Generator http://sarg.sourceforge.net - * 1998, 2013 + * 1998, 2015 * * SARG donations: * please look at http://sarg.sourceforge.net/donations.php @@ -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 }; @@ -296,6 +305,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 +351,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; @@ -401,42 +426,50 @@ 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); - - // how much space to store the path - Length=FIter->DirNodes[FIter->CurrentPathLevel].PathLength; - for (Level=FIter->CurrentPathLevel ; Level<=FIter->Level ; Level++) - { - DIter=FIter->DirNodes+Level; - DIter->PathLength=Length;; - Length+=strlen(DIter->Dir->Name)+1; - } + const char *Path; - // get the memory to store the path - if (Length>FIter->CurrentPathSize) +#ifdef HAVE_GLOB_H + if (FIter->NextGlob>0) { - 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++) + Path=FileListIter_NextWithMask(FIter); + if (Path!=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) + { + 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; + case GLOB_NOMATCH: + debuga(__FILE__,__LINE__,_("No files matching \"%s\"\n"),Path); + break; + } + exit(EXIT_FAILURE); + } + Path=FIter->Glob.gl_pathv[0]; + FIter->NextGlob=1; } - 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); } /*! @@ -463,7 +496,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; } @@ -495,6 +528,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);