From 800eafb823572ff2ab3bc12eb629550e8ab4e279 Mon Sep 17 00:00:00 2001 From: Frederic Marchal Date: Wed, 10 Jun 2015 21:22:24 +0200 Subject: [PATCH] Use a library to read gzip access.log files LZW compressed files (.Z) are not supported any more until I find out how to read such a file using a library. Bzip2 files (.bz2) are not supported yet even thought an untested non-working code exists in sarg. --- Makefile.in | 3 +- authfail.c | 11 +- configure.ac | 24 ++++ convlog.c | 10 +- datafile.c | 11 +- decomp.c | 335 +++++++++++++++++++++++++++++++++++++------ denied.c | 11 +- download.c | 11 +- email.c | 11 +- fileobject.c | 266 ++++++++++++++++++++++++++++++++++ html.c | 31 ++-- include/defs.h | 6 +- include/fileobject.h | 25 ++++ longline.c | 6 +- readlog.c | 105 ++++++++++---- realtime.c | 10 +- redirector.c | 21 +-- report.c | 10 +- siteuser.c | 11 +- splitlog.c | 10 +- topsites.c | 19 +-- topuser.c | 20 +-- url.c | 10 +- userinfo.c | 10 +- util.c | 10 +- 25 files changed, 819 insertions(+), 178 deletions(-) create mode 100644 fileobject.c create mode 100644 include/fileobject.h diff --git a/Makefile.in b/Makefile.in index bbc6b37..06adb3b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -42,7 +42,7 @@ SRCS = util.c log.c report.c topuser.c email.c sort.c html.c \ redirector.c auth.c download.c grepday.c ip2name_exec.c \ dansguardian_log.c dansguardian_report.c realtime.c btree_cache.c \ usertab.c userinfo.c longline.c url.c fnmatch.c stringbuffer.c \ - filelist.c readlog.c alias.c \ + filelist.c readlog.c alias.c fileobject.c \ readlog_squid.c readlog_sarg.c readlog_extlog.c readlog_common.c all: sarg @@ -62,6 +62,7 @@ readlog_sarg.o: include/readlog.h readlog_squid.o: include/readlog.h stringbuffer.o: include/stringbuffer.h userinfo.o: include/stringbuffer.h include/alias.h +fileobject.o: include/fileobject.h OBJS = $(SRCS:.c=.o) diff --git a/authfail.c b/authfail.c index 4069998..f0a7fb7 100644 --- a/authfail.c +++ b/authfail.c @@ -112,7 +112,8 @@ static void show_ignored_auth(FILE *fp_ou,int count) void authfail_report(void) { - FILE *fp_in = NULL, *fp_ou = NULL; + FileObject *fp_in = NULL; + FILE *fp_ou = NULL; char *buf; char *url; @@ -157,8 +158,8 @@ void authfail_report(void) debuga(__FILE__,__LINE__,_("sort command: %s\n"),csort); exit(EXIT_FAILURE); } - if((fp_in=MY_FOPEN(authfail_sort,"r"))==NULL) { - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),authfail_sort,strerror(errno)); + if((fp_in=FileObject_Open(authfail_sort))==NULL) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),authfail_sort,FileObject_GetLastOpenError()); debuga(__FILE__,__LINE__,_("sort command: %s\n"),csort); exit(EXIT_FAILURE); } @@ -264,8 +265,8 @@ void authfail_report(void) output_html_link(fp_ou,url,100); fputs("\n",fp_ou); } - if (fclose(fp_in)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),authfail_sort,strerror(errno)); + if (FileObject_Close(fp_in)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),authfail_sort,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } longline_destroy(&line); diff --git a/configure.ac b/configure.ac index 3be9cc6..b4b29d7 100644 --- a/configure.ac +++ b/configure.ac @@ -160,6 +160,24 @@ else glob_status="disabled" fi +# Build with zlib +AC_ARG_WITH([zlib], +AS_HELP_STRING([--with-zlib],[Compile with support to decompress gz files]), +[],[with_zlib=check]) +if ( test "x$with_zlib" != "xno" ) ; then + AC_CHECK_HEADERS(zlib.h) + if ( test "x$ac_cv_header_zlib_h" = "xyes" ) ; then + AC_CHECK_LIB(z, gzopen,LIBS="-lz ${LIBS}"; HAVE_ZLIB_LIB="yes", HAVE_ZLIB_LIB="") + if ( test "x$HAVE_ZLIB_LIB" != "xyes" ) ; then + AC_MSG_ERROR([zlib was not found]) + fi + else + zlib_status="not found" + fi +else + zlib_status="disabled" +fi + dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_STRUCT_TM @@ -407,3 +425,9 @@ fi if ( test "x$glob_status" = "xdisabled" ) ; then AC_MSG_NOTICE([Not building with file globbing as requested on the configuration command line]) fi + +if ( test "x$zlib_status" = "xdisabled" ) ; then + AC_MSG_NOTICE([Not building with zlib as requested on the configuration command line]) +elif ( test "x$zlib_status" = "xnot found" ) ; then + AC_MSG_NOTICE([zlib.h was not found so it won't be possible to process gzipped files]) +fi diff --git a/convlog.c b/convlog.c index b66a572..d87efee 100644 --- a/convlog.c +++ b/convlog.c @@ -29,7 +29,7 @@ void convlog(const char *arq, char df, int dfrom, int duntil) { - FILE *fp_in; + FileObject *fp_in; char *buf; char data[30]; char dia[11]; @@ -42,8 +42,8 @@ void convlog(const char *arq, char df, int dfrom, int duntil) if(arq[0] == '\0') arq="/var/log/squid/access.log"; - if((fp_in=MY_FOPEN(arq,"r"))==NULL) { - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),arq,strerror(errno)); + if((fp_in=FileObject_Open(arq))==NULL) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),arq,FileObject_GetLastOpenError()); exit(EXIT_FAILURE); } @@ -78,8 +78,8 @@ void convlog(const char *arq, char df, int dfrom, int duntil) } longline_destroy(&line); - if (fclose(fp_in)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),arq,strerror(errno)); + if (FileObject_Close(fp_in)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),arq,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } } diff --git a/datafile.c b/datafile.c index f120348..54608c6 100644 --- a/datafile.c +++ b/datafile.c @@ -31,7 +31,8 @@ void saverecs(FILE *fp_ou, const struct userinfostruct *uinfo, long long int nac void data_file(char *tmp) { - FILE *fp_in, *fp_ou=NULL; + FileObject *fp_in; + FILE *fp_ou=NULL; char *buf; char accdia[11], acchora[9], accip[MAXLEN], *accurl; @@ -91,8 +92,8 @@ void data_file(char *tmp) exit(EXIT_FAILURE); } - if((fp_in=MY_FOPEN(tmp3,"r"))==NULL){ - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),tmp3,strerror(errno)); + if((fp_in=FileObject_Open(tmp3))==NULL){ + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),tmp3,FileObject_GetLastOpenError()); exit(EXIT_FAILURE); } @@ -190,8 +191,8 @@ void data_file(char *tmp) strcpy(oldacchora,acchora); } - if (fclose(fp_in)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),tmp3,strerror(errno)); + if (FileObject_Close(fp_in)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),tmp3,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } longline_destroy(&line); diff --git a/decomp.c b/decomp.c index 0b4b01b..26873fe 100644 --- a/decomp.c +++ b/decomp.c @@ -26,6 +26,254 @@ #include "include/conf.h" #include "include/defs.h" +#ifdef HAVE_ZLIB_H +#include "zlib.h" +#endif +#ifdef HAVE_BZLIB_H +#include "bzlib.h" +#endif + +#ifdef HAVE_ZLIB_H +/*! + * Read from gzip file. + * + * \param Data The file object. + * \param Buffer The boffer to store the data read. + * \param Size How many bytes to read. + * + * \return The number of bytes read. + */ +static int Gzip_Read(void *Data,void *Buffer,int Size) +{ + return(gzread((gzFile)Data,Buffer,Size)); +} + +/*! + * Check if end of file is reached. + * + * \param Data The file object. + * + * \return \c True if end of file is reached. + */ +static int Gzip_Eof(void *Data) +{ + return(gzeof((gzFile)Data)); +} + +/*! + * Return to the beginnig of the file. + * + * \param Data The file object. + */ +static void Gzip_Rewind(void *Data) +{ + gzrewind((gzFile)Data); +} + +/*! + * Close the file. + * + * \param Data File to close. + * + * \return 0 on success or -1 on error. + */ +static int Gzip_Close(void *Data) +{ + int RetCode=-1; + int Status; + + Status=gzclose((gzFile)Data); + switch (Status) + { + case Z_OK: + RetCode=0; + break; + case Z_STREAM_ERROR: + FileObject_SetLastCloseError(_("Invalid gzip file")); + break; + case Z_ERRNO: + FileObject_SetLastCloseError(_("File operation error")); + break; + case Z_MEM_ERROR: + FileObject_SetLastCloseError(_("Not enough memory")); + break; + case Z_BUF_ERROR: + FileObject_SetLastCloseError(_("Truncated gzip stream")); + break; + default: + FileObject_SetLastCloseError(_("Unknown error returned by zlib")); + break; + } + return(RetCode); +} + +/*! + * Open a file object to read from a gzip file. + * + * \return The object to pass to other function in this module. + */ +static FileObject *Gzip_Open(int fd) +{ + FileObject *File; + + FileObject_SetLastOpenError(NULL); + File=calloc(1,sizeof(*File)); + if (!File) + { + FileObject_SetLastOpenError(_("Not enough memory")); + return(NULL); + } + File->Data=gzdopen(fd,"rb"); + if (!File->Data) + { + free(File); + FileObject_SetLastOpenError(_("Error opening gzip file")); + return(NULL); + } + File->Read=Gzip_Read; + File->Eof=Gzip_Eof; + File->Rewind=Gzip_Rewind; + File->Close=Gzip_Close; + return(File); +} +#endif + +#ifdef HAVE_BZLIB_H + +struct BzlibInternalFile +{ + //! Bzlib object. + BZFILE *BzFile; + //! \c True if end of file is reached. + bool Eof; + //! Copy of the original file handle. + int fd; +} + +/*! + * Read from bzip file. + * + * \param Data The file object. + * \param Buffer The boffer to store the data read. + * \param Size How many bytes to read. + * + * \return The number of bytes read. + */ +static int Bzip_Read(void *Data,void *Buffer,int Size) +{ + struct BzlibInternalFile *BData=(struct BzlibInternalFile *)Data; + int nread; + + nread=BZ2_bzread(BData->BzFile,Buffer,Size); + if (nread==0) BData->Eof=true; + return(nread); +} + +/*! + * Check if end of file is reached. + * + * \param Data The file object. + * + * \return \c True if end of file is reached. + */ +static int Bzip_Eof(void *Data) +{ + struct BzlibInternalFile *BData=(struct BzlibInternalFile *)Data; + return(BData->Eof); +} + +/*! + * Return to the beginnig of the file. + * + * \param Data The file object. + */ +static void Bzip_Rewind(void *Data) +{ + struct BzlibInternalFile *BData=(struct BzlibInternalFile *)Data; + int fd; + + BZ2_bzclose(BData->BzFile); + fd=dup(BData->fd); + if (fd==-1) + { + debuga(__FILE__,__LINE__,_("Cannot rewind bzip file\n")); + exit(EXIT_FAILURE); + } + BData->BzFile=BZ2_bzdopen(fd,"rb"); + if (!BData->BzFile) + { + debuga(__FILE__,__LINE__,_("Cannot rewind bzip file\n")); + exit(EXIT_FAILURE); + } +} + +/*! + * Close the file. + * + * \param Data File to close. + * + * \return 0 on success or -1 on error. + */ +static int Bzip_Close(void *Data) +{ + struct BzlibInternalFile *BData=(struct BzlibInternalFile *)Data; + + BZ2_bzclose(BData->BzFile); + close(BData->fd); + free(BData); + return(0); +} + +/*! + * Open a file object to read from a bzip file. + * + * \return The object to pass to other function in this module. + */ +static FileObject *Bzip_Open(int fd) +{ + FileObject *File; + struct BzlibInternalFile *BData; + + FileObject_SetLastOpenError(NULL); + File=calloc(1,sizeof(*File)); + if (!File) + { + FileObject_SetLastOpenError(_("Not enough memory")); + return(NULL); + } + BData=calloc(1,sizeof(*BData)); + if (!BData) + { + free(File); + FileObject_SetLastOpenError(_("Not enough memory")); + return(NULL); + } + BData->fd=dup(fd); + if (BData->fd==-1) + { + free(BData); + free(File); + FileObject_SetLastOpenError(_("Error duplicating file descriptor")); + return(NULL); + } + File=Data=BData; + BData->BzFile=BZ2_bzdopen(fd,"rb"); + if (!BData->BzFile) + { + close(BData->fd); + free(BData); + free(File); + FileObject_SetLastOpenError(_("Error opening bzip file")); + return(NULL); + } + File->Read=Bzip_Read; + File->Eof=Bzip_Eof; + File->Rewind=Bzip_Rewind; + File->Close=Bzip_Close; + return(File); +} +#endif + /*! Open the log file. If it is compressed, uncompress it through a pipe. @@ -46,47 +294,54 @@ files so it is now used. \date 2010-05-10 - F Marchal\n The function doesn't use a temporary file any more and read the compressed file through a pipe. */ -FILE *decomp(const char *arq, bool *pipe) +FileObject *decomp(const char *arq) { - FILE *fi; - char cmd[1024]; - int arqlen; - - arqlen=strlen(arq); - if(arqlen>3 && strcmp(arq+arqlen-3,".gz") == 0) { - /* - TRANSLATORS: The last %s is the command used to uncompress - the log file such as zcat ou bzip2. - */ - debuga(__FILE__,__LINE__,_("Decompressing log file \"%s\" with %s\n"),arq,"zcat"); - if (snprintf(cmd,sizeof(cmd),"zcat \"%s\"",arq)>=sizeof(cmd)) { - debuga(__FILE__,__LINE__,_("decompression command too long for log file %s\n"),arq); - exit(EXIT_FAILURE); - } - *pipe=true; - fi=popen(cmd,"r"); - } - else if(arqlen>4 && strcmp(arq+arqlen-4,".bz2") == 0) { - debuga(__FILE__,__LINE__,_("Decompressing log file \"%s\" with %s\n"),arq,"bzcat"); - if (snprintf(cmd,sizeof(cmd),"bzcat \"%s\"",arq)>=sizeof(cmd)) { - debuga(__FILE__,__LINE__,_("decompression command too long for log file %s\n"),arq); - exit(EXIT_FAILURE); - } - *pipe=true; - fi=popen(cmd,"r"); - } - else if(arqlen>2 && strcmp(arq+arqlen-2,".Z") == 0) { - debuga(__FILE__,__LINE__,_("Decompressing log file \"%s\" with %s\n"),arq,"zcat"); - if (snprintf(cmd,sizeof(cmd),"zcat \"%s\"",arq)>=sizeof(cmd)) { - debuga(__FILE__,__LINE__,_("decompression command too long for log file %s\n"),arq); - exit(EXIT_FAILURE); - } - *pipe=true; - fi=popen(cmd,"r"); - } - else { - *pipe=false; - fi=MY_FOPEN(arq,"r"); + int fd; + FileObject *fi; + unsigned char buf[3]; + ssize_t nread; + + // guess file type + fd=open(arq,O_RDONLY | O_LARGEFILE); + if (fd==-1) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),arq,strerror(errno)); + exit(EXIT_FAILURE); + } + nread=read(fd,buf,sizeof(buf)); + if (nread==-1) { + debuga(__FILE__,__LINE__,_("Error while reading \"%s\" to guess its type: %s\n"),arq,strerror(errno)); + exit(EXIT_FAILURE); + } + if (nread<3) { + debuga(__FILE__,__LINE__,_("File \"%s\" is too small to guess its type\n"),arq); + exit(EXIT_FAILURE); + } + if (lseek(fd,0,SEEK_SET)==-1) { + debuga(__FILE__,__LINE__,_("Cannot return to the beginning of file \"%s\": %s"),arq,strerror(errno)); + exit(EXIT_FAILURE); + } + + if (buf[0]==0x1F && buf[1]==0x8B && buf[2]==0x08)//gzip file + { +#ifdef HAVE_ZLIB_H + fi=Gzip_Open(fd); +#else + debuga(__FILE__,__LINE__,_("Sarg was not compiled with gzip support to read file \"%s\"\n"),arq); + exit(EXIT_FAILURE); +#endif + } + else if (buf[0]==0x42 && buf[1]==0x5A && buf[2]==0x68)//bzip2 file + { +#ifdef HAVE_BZLIB_H + fi=Bzip_Open(fd); +#else + debuga(__FILE__,__LINE__,_("Sarg was not compiled with bzip support to read file \"%s\"\n"),arq); + exit(EXIT_FAILURE); +#endif + } + else //normal file + { + fi=FileObject_FdOpen(fd); } return(fi); } diff --git a/denied.c b/denied.c index 9044b03..88cd37f 100644 --- a/denied.c +++ b/denied.c @@ -113,7 +113,8 @@ Generate a report containing the denied accesses. */ void gen_denied_report(void) { - FILE *fp_in = NULL, *fp_ou = NULL; + FileObject *fp_in = NULL; + FILE *fp_ou = NULL; char *buf; char *url; @@ -169,8 +170,8 @@ void gen_denied_report(void) sprintf(report,"%s/denied.html",outdirname); - if((fp_in=MY_FOPEN(denied_sort,"r"))==NULL) { - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),denied_sort,strerror(errno)); + if((fp_in=FileObject_Open(denied_sort))==NULL) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),denied_sort,FileObject_GetLastOpenError()); exit(EXIT_FAILURE); } @@ -262,8 +263,8 @@ void gen_denied_report(void) output_html_link(fp_ou,url,100); fputs("\n",fp_ou); } - if (fclose(fp_in)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),denied_sort,strerror(errno)); + if (FileObject_Close(fp_in)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),denied_sort,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } longline_destroy(&line); diff --git a/download.c b/download.c index 103c6fa..f826e70 100644 --- a/download.c +++ b/download.c @@ -161,7 +161,8 @@ is set with set_download_suffix(). */ void download_report(void) { - FILE *fp_in = NULL, *fp_ou = NULL; + FileObject *fp_in = NULL; + FILE *fp_ou = NULL; char *buf; char *url; @@ -204,8 +205,8 @@ void download_report(void) // produce the report. snprintf(report,sizeof(report),"%s/download.html",outdirname); - if((fp_in=MY_FOPEN(report_in,"r"))==NULL) { - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),report_in,strerror(errno)); + if((fp_in=FileObject_Open(report_in))==NULL) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),report_in,FileObject_GetLastOpenError()); exit(EXIT_FAILURE); } @@ -296,8 +297,8 @@ void download_report(void) output_html_link(fp_ou,url,100); fputs("\n",fp_ou); } - if (fclose(fp_in)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),report_in,strerror(errno)); + if (FileObject_Close(fp_in)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),report_in,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } longline_destroy(&line); diff --git a/email.c b/email.c index 0f9cd9a..a04a097 100644 --- a/email.c +++ b/email.c @@ -33,7 +33,8 @@ extern struct globalstatstruct globstat; int geramail(const char *dirname, int debug, const char *outdir, const char *email, const char *TempDir) { - FILE *fp_in, *fp_top1, *fp_top2, *fp_top3; + FileObject *fp_in; + FILE *fp_top1, *fp_top2, *fp_top3; long long int ttnbytes=0, ttnacc=0, tnacc=0; long long int tnbytes=0, ttnelap=0, tnelap=0; long long int nacc, nbytes, elap; @@ -57,8 +58,8 @@ int geramail(const char *dirname, int debug, const char *outdir, const char *ema const struct userinfostruct *uinfo; snprintf(wger,sizeof(wger),"%s/sarg-general",dirname); - if((fp_in=fopen(wger,"r"))==NULL) { - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),wger,strerror(errno)); + if((fp_in=FileObject_Open(wger))==NULL) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),wger,FileObject_GetLastOpenError()); exit(EXIT_FAILURE); } @@ -102,8 +103,8 @@ int geramail(const char *dirname, int debug, const char *outdir, const char *ema tnacc+=item.nacc; tnelap+=item.nelap; } - if (fclose(fp_in)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),wger,strerror(errno)); + if (FileObject_Close(fp_in)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),wger,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } longline_destroy(&line); diff --git a/fileobject.c b/fileobject.c new file mode 100644 index 0000000..579dfb0 --- /dev/null +++ b/fileobject.c @@ -0,0 +1,266 @@ +/* + * SARG Squid Analysis Report Generator http://sarg.sourceforge.net + * 1998, 2015 + * + * SARG donations: + * please look at http://sarg.sourceforge.net/donations.php + * Support: + * http://sourceforge.net/projects/sarg/forums/forum/363374 + * --------------------------------------------------------------------- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ +/*!\file +\brief Encapsulate a file object + +The file can be a standard file of the C library or a gzip file or +a bzip file. +*/ + +#include "include/conf.h" +#include "include/stringbuffer.h" +#include "include/fileobject.h" + +//! Message describing the last open error. +static char LastOpenErrorString[2048]=""; +//! Message describing the last close error. +static char LastCloseErrorString[2048]=""; + +/*! + * Read a file using the standard C api. + * + * \param Data The file object. + * \param Buffer The boffer to store the data read. + * \param Size How many bytes to read. + * + * \return The number of bytes read. + */ +static int Standard_Read(void *Data,void *Buffer,int Size) +{ + return(fread(Buffer,1,Size,(FILE *)Data)); +} + +/*! + * Check if end of file is reached. + * + * \param Data The file object. + * + * \return \c True if end of file is reached. + */ +static int Standard_Eof(void *Data) +{ + return(feof((FILE *)Data)); +} + +/*! + * Return to the beginnig of the file. + * + * \param Data The file object. + */ +static void Standard_Rewind(void *Data) +{ + rewind((FILE *)Data); +} + +/*! + * Close a file using the standard C api. + * + * \param Data File to close. + * + * \return EOF on error. + */ +static int Standard_Close(void *Data) +{ + int RetCode=0; + + if (fclose((FILE *)Data)==EOF) + { + FileObject_SetLastCloseError(strerror(errno)); + RetCode=-1; + } + return(RetCode); +} + +/*! + * Open a file for reading using the standard C api. + * + * \param FileName The file to open. + * + * \return The object to pass to other function in this module. + */ +FileObject *FileObject_Open(const char *FileName) +{ + FileObject *File; + + LastOpenErrorString[0]='\0'; + File=malloc(sizeof(*File)); + if (!File) + { + FileObject_SetLastOpenError(_("Not enough memory")); + return(NULL); + } + File->Data=MY_FOPEN(FileName,"r"); + if (!File->Data) + { + free(File); + FileObject_SetLastOpenError(strerror(errno)); + return(NULL); + } + File->Read=Standard_Read; + File->Eof=Standard_Eof; + File->Rewind=Standard_Rewind; + File->Close=Standard_Close; + return(File); +} + +/*! + * Open a file for reading using the standard C api. + * + * \param FileName The file to open. + * + * \return The object to pass to other function in this module. + */ +FileObject *FileObject_FdOpen(int fd) +{ + FileObject *File; + + LastOpenErrorString[0]='\0'; + File=malloc(sizeof(*File)); + if (!File) + { + FileObject_SetLastOpenError(_("Not enough memory")); + return(NULL); + } + File->Data=fdopen(fd,"r"); + if (!File->Data) + { + free(File); + FileObject_SetLastOpenError(strerror(errno)); + return(NULL); + } + File->Read=Standard_Read; + File->Eof=Standard_Eof; + File->Rewind=Standard_Rewind; + File->Close=Standard_Close; + return(File); +} + +/*! + * Read the content of the file using the function identified + * by the file object. + * + * \param File The file object to read. + * \param Buffer The buffer to write the data into. + * \param Size The maximum number of bytes to read. + * + * \return The number of bytes read or -1. + */ +int FileObject_Read(FileObject *File,void *Buffer,int Size) +{ + return(File->Read(File->Data,Buffer,Size)); +} + +/*! + * Check if the end of file is reached. + * + * \param File The file object. + * + * \return \c True if end of file is reached. + */ +int FileObject_Eof(FileObject *File) +{ + return(File->Eof(File->Data)); +} + +/*! + * Return to the beginning of the file. + * + * \param File The file object. + */ +void FileObject_Rewind(FileObject *File) +{ + File->Rewind(File->Data); +} + +/*! + * Close the file opened. The memory is freed. The object + * cannot be reused after this function returns. + * + * \param File The file object to close. + * + * \return Zero on success or -1 on failure. + */ +int FileObject_Close(FileObject *File) +{ + LastCloseErrorString[0]='\0'; + int RetCode=File->Close(File->Data); + free(File); + return(RetCode); +} + +/*! + * Set the message returned by the last open error. + * + * \param Message The message explaining what error occurred + * when the file was opened. + */ +void FileObject_SetLastOpenError(const char *Message) +{ + if (Message) + { + strncpy(LastOpenErrorString,Message,sizeof(LastOpenErrorString)-1); + LastOpenErrorString[sizeof(LastOpenErrorString)-1]='\0'; + } + else + LastOpenErrorString[0]='\0'; +} + +/*! + * Get a message explaining the last open error. + * + * \return The string to display to the user. + */ +const char *FileObject_GetLastOpenError(void) +{ + return(LastOpenErrorString); +} + +/*! + * Set the message returned by the last close error. + * + * \param Message The message explaining what error occurred + * when the file was closed. + */ +void FileObject_SetLastCloseError(const char *Message) +{ + if (Message) + { + strncpy(LastCloseErrorString,Message,sizeof(LastCloseErrorString)-1); + LastCloseErrorString[sizeof(LastCloseErrorString)-1]='\0'; + } + else + LastCloseErrorString[0]='\0'; +} + +/*! + * Get a message explaining the last close error. + * + * \return The string to display to the user. + */ +const char *FileObject_GetLastCloseError(void) +{ + return(LastCloseErrorString); +} diff --git a/html.c b/html.c index 2d78fac..6689af6 100644 --- a/html.c +++ b/html.c @@ -38,7 +38,10 @@ extern struct globalstatstruct globstat; void htmlrel(void) { - FILE *fp_in, *fp_ou, *fp_ip, *fp_ip2; + FileObject *fp_in; + FileObject *fp_ip; + FILE *fp_ou; + FILE *fp_ip2; long long int nnbytes=0, unbytes=0, tnbytes=0, totbytes=0, totbytes2=0; long long int totelap=0, totelap2=0, nnelap=0, unelap=0, tnelap=0; @@ -145,9 +148,9 @@ void htmlrel(void) debuga(__FILE__,__LINE__,_("Input file name too long: %s/htmlrel.txt\n"),tmp); exit(EXIT_FAILURE); } - if ((fp_in = fopen(arqin, "r")) == 0){ + if ((fp_in = FileObject_Open(arqin)) == 0){ if (uinfo->no_report) continue; - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),arqin,strerror(errno)); + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),arqin,FileObject_GetLastOpenError()); exit(EXIT_FAILURE); } @@ -216,7 +219,7 @@ void htmlrel(void) tnoucache+=ltemp; } - rewind(fp_in); + FileObject_Rewind(fp_in); if ((fp_ou = fopen(arqou, "w")) == 0){ debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),arqou,strerror(errno)); @@ -381,8 +384,8 @@ void htmlrel(void) exit(EXIT_FAILURE); } - if ((fp_ip = fopen(arqip, "r")) == 0){ - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),arqip,strerror(errno)); + if ((fp_ip = FileObject_Open(arqip)) == 0){ + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),arqip,FileObject_GetLastOpenError()); exit(EXIT_FAILURE); } @@ -430,8 +433,8 @@ void htmlrel(void) debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),tmp2,strerror(errno)); exit(EXIT_FAILURE); } - if (fclose(fp_ip)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),arqip,strerror(errno)); + if (FileObject_Close(fp_ip)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),arqip,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } @@ -446,8 +449,8 @@ void htmlrel(void) exit(EXIT_FAILURE); } - if ((fp_ip = MY_FOPEN(tmp3, "r")) == 0) { - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),tmp3,strerror(errno)); + if ((fp_ip = FileObject_Open(tmp3)) == 0) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),tmp3,FileObject_GetLastOpenError()); exit(EXIT_FAILURE); } @@ -503,8 +506,8 @@ void htmlrel(void) unelap+=userelap; } - if (fclose(fp_ip)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),tmp3,strerror(errno)); + if (FileObject_Close(fp_ip)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),tmp3,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } longline_destroy(&line1); @@ -536,8 +539,8 @@ void htmlrel(void) unelap=0; } - if (fclose(fp_in)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),arqin,strerror(errno)); + if (FileObject_Close(fp_in)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),arqin,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } longline_destroy(&line); diff --git a/include/defs.h b/include/defs.h index 012a801..3c5d658 100644 --- a/include/defs.h +++ b/include/defs.h @@ -6,6 +6,8 @@ #define __attribute__(a) #endif +#include "include/fileobject.h" + //! \brief Constants to compare the log level to display messages enum DebugLogLevel { @@ -190,7 +192,7 @@ void dansguardian_report(void); void data_file(char *tmp); // decomp.c -FILE *decomp(const char *arq, bool *pipe); +FileObject *decomp(const char *arq); // denied.c void denied_open(void); @@ -254,7 +256,7 @@ void mklastlog(const char *outdir); // longline.c __attribute__((warn_unused_result)) /*@null@*//*@only@*/longline longline_create(void); void longline_reset(longline line); -/*@null@*/char *longline_read(FILE *fp_in,/*@null@*/longline line); +/*@null@*/char *longline_read(FileObject *fp_in,/*@null@*/longline line); void longline_destroy(/*@out@*//*@only@*//*@null@*/longline *line_ptr); // index.c diff --git a/include/fileobject.h b/include/fileobject.h new file mode 100644 index 0000000..da9b381 --- /dev/null +++ b/include/fileobject.h @@ -0,0 +1,25 @@ +#ifndef FILEOBJECT_H +#define FILEOBJECT_H + +typedef struct FileObjectStruct +{ + void *Data; + int (*Read)(void *Data,void *Buffer,int Size); + int (*Eof)(void *Data); + void (*Rewind)(void *Data); + int (*Close)(void *Data); +} FileObject; + +FileObject *FileObject_Open(const char *FileName); +FileObject *FileObject_FdOpen(int fd); +int FileObject_Read(FileObject *File,void *Buffer,int Size); +int FileObject_Eof(FileObject *File); +void FileObject_Rewind(FileObject *File); +int FileObject_Close(FileObject *File); + +void FileObject_SetLastOpenError(const char *Message); +const char *FileObject_GetLastOpenError(void); +void FileObject_SetLastCloseError(const char *Message); +const char *FileObject_GetLastCloseError(void); + +#endif // FILEOBJECT_H diff --git a/longline.c b/longline.c index ff8b000..e0c18f7 100644 --- a/longline.c +++ b/longline.c @@ -94,7 +94,7 @@ void longline_reset(longline line) } } -char *longline_read(FILE *fp_in,longline line) +char *longline_read(FileObject *fp_in,longline line) { int i; char *newbuf; @@ -108,7 +108,7 @@ char *longline_read(FILE *fp_in,longline line) line->end=i; break; } - nread=(feof(fp_in)!=0) ? 0 : fread(line->buffer,1,line->size,fp_in); + nread=(FileObject_Eof(fp_in)!=0) ? 0 : FileObject_Read(fp_in,line->buffer,line->size); if (nread==0) return(NULL); line->length=nread; line->end=0; @@ -143,7 +143,7 @@ char *longline_read(FILE *fp_in,longline line) } line->buffer=newbuf; } - nread=(feof(fp_in)!=0) ? 0 : fread(line->buffer+line->length,1,line->size-line->length,fp_in); + nread=(FileObject_Eof(fp_in)!=0) ? 0 : FileObject_Read(fp_in,line->buffer+line->length,line->size-line->length); if (nread==0) { if (line->end<=line->start) return(NULL); if (line->end>=line->size) { diff --git a/readlog.c b/readlog.c index 31e307b..52caeeb 100644 --- a/readlog.c +++ b/readlog.c @@ -135,6 +135,68 @@ static int LatestDate=-1; //! The latest date in time format. static struct tm LatestDateTime; +/*! + * Read from standard input. + * + * \param Data The file object. + * \param Buffer The boffer to store the data read. + * \param Size How many bytes to read. + * + * \return The number of bytes read. + */ +static int Stdin_Read(void *Data,void *Buffer,int Size) +{ + return(fread(Buffer,1,Size,(FILE *)Data)); +} + +/*! + * Check if end of file is reached. + * + * \param Data The file object. + * + * \return \c True if end of file is reached. + */ +static int Stdin_Eof(void *Data) +{ + return(feof((FILE *)Data)); +} + +/*! + * Mimic a close of standard input but do nothing + * + * \param Data File to close. + * + * \return EOF on error. + */ +static int Stdin_Close(void *Data) +{ + return(0); +} + +/*! + * Open a file object to read from standard input. + * + * \return The object to pass to other function in this module. + */ +static FileObject *Stdin_Open(void) +{ + FileObject *File; + + FileObject_SetLastOpenError(NULL); + File=calloc(1,sizeof(*File)); + if (!File) + { + FileObject_SetLastOpenError(_("Not enough memory")); + return(NULL); + } + File->Data=stdin; + File->Read=Stdin_Read; + File->Eof=Stdin_Eof; + File->Rewind=NULL; + File->Close=Stdin_Close; + return(File); +} + /*! * Initialize the memory structure needed by LogLine_Parse() to parse * a log line. @@ -256,9 +318,7 @@ static void ReadOneLogFile(struct ReadLogDataStruct *Filter,const char *arq) int maxopenfiles=MAX_OPEN_USER_FILES; unsigned long int recs1=0UL; unsigned long int recs2=0UL; - FILE *fp_in=NULL; - bool from_pipe; - bool from_stdin; + FileObject *fp_in=NULL; bool download_flag=false; bool id_is_ip; enum ReadLogReturnCodeEnum log_entry_status; @@ -278,10 +338,9 @@ static void ReadOneLogFile(struct ReadLogDataStruct *Filter,const char *arq) LogFormats[x]->NewFile(arq); if (arq[0]=='-' && arq[1]=='\0') { + fp_in=Stdin_Open(); if(debug) debuga(__FILE__,__LINE__,_("Reading access log file: from stdin\n")); - fp_in=stdin; - from_stdin=true; } else { if (Filter->DateRange[0]!='\0') { if (stat(arq,&logstat)!=0) { @@ -294,13 +353,12 @@ static void ReadOneLogFile(struct ReadLogDataStruct *Filter,const char *arq) } } } - fp_in=decomp(arq,&from_pipe); - if(fp_in==NULL) { - debuga(__FILE__,__LINE__,_("Cannot open input log file \"%s\": %s\n"),arq,strerror(errno)); + fp_in=decomp(arq); + if (fp_in==NULL) { + debuga(__FILE__,__LINE__,_("Cannot open input log file \"%s\": %s\n"),arq,FileObject_GetLastOpenError()); exit(EXIT_FAILURE); } - if(debug) debuga(__FILE__,__LINE__,_("Reading access log file: %s\n"),arq); - from_stdin=false; + if (debug) debuga(__FILE__,__LINE__,_("Reading access log file: %s\n"),arq); } download_flag=false; @@ -309,12 +367,12 @@ static void ReadOneLogFile(struct ReadLogDataStruct *Filter,const char *arq) recs2=0UL; // pre-read the file only if we have to show stats - if (ShowReadStatistics && ShowReadPercent && !from_stdin && !from_pipe) { + if (ShowReadStatistics && ShowReadPercent && fp_in->Rewind) { size_t nread,i; bool skipcr=false; char tmp4[MAXLEN]; - while ((nread=fread(tmp4,1,sizeof(tmp4),fp_in))>0) { + while ((nread=FileObject_Read(fp_in,tmp4,sizeof(tmp4)))>0) { for (i=0 ; iStoreSize) StoreSize=NextIndex; if (NextIndex>realtime_access_log_lines) NextIndex=0; } - if (fclose(fp)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),file_name,strerror(errno)); + if (FileObject_Close(fp)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),file_name,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } longline_destroy(&line); diff --git a/redirector.c b/redirector.c index 60ab26e..22cefcd 100644 --- a/redirector.c +++ b/redirector.c @@ -222,7 +222,7 @@ static void parse_log(FILE *fp_ou,char *buf) static void read_log(const char *wentp, FILE *fp_ou,int dfrom,int duntil) { - FILE *fp_in = NULL; + FileObject *fp_in = NULL; char *buf; int i; longline line; @@ -264,8 +264,8 @@ static void read_log(const char *wentp, FILE *fp_ou,int dfrom,int duntil) exit(EXIT_FAILURE); } - if ((fp_in=fopen(wentp,"r"))==NULL) { - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),wentp,strerror(errno)); + if ((fp_in=FileObject_Open(wentp))==NULL) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),wentp,FileObject_GetLastOpenError()); exit(EXIT_FAILURE); } @@ -277,8 +277,8 @@ static void read_log(const char *wentp, FILE *fp_ou,int dfrom,int duntil) while ((buf=longline_read(fp_in,line)) != NULL) { parse_log(fp_ou,buf); } - if (fclose(fp_in)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),wentp,strerror(errno)); + if (FileObject_Close(fp_in)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),wentp,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } longline_destroy(&line); @@ -428,7 +428,8 @@ static void show_ignored_redirector(FILE *fp_ou,int count) void redirector_report(void) { - FILE *fp_in = NULL, *fp_ou = NULL; + FileObject *fp_in = NULL; + FILE *fp_ou = NULL; char *buf; char *url; @@ -464,8 +465,8 @@ void redirector_report(void) snprintf(report,sizeof(report),"%s/redirector.html",outdirname); - if((fp_in=fopen(redirector_sorted,"r"))==NULL) { - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),redirector_sorted,strerror(errno)); + if((fp_in=FileObject_Open(redirector_sorted))==NULL) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),redirector_sorted,FileObject_GetLastOpenError()); exit(EXIT_FAILURE); } @@ -567,8 +568,8 @@ void redirector_report(void) output_html_link(fp_ou,url,100); fprintf(fp_ou,"%s\n",rule); } - if (fclose(fp_in)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),redirector_sorted,strerror(errno)); + if (FileObject_Close(fp_in)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),redirector_sorted,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } longline_destroy(&line); diff --git a/report.c b/report.c index 8ff2c5f..7832772 100644 --- a/report.c +++ b/report.c @@ -49,7 +49,7 @@ static void grava_SmartFilter(const char *dirname, const char *user, const char void gerarel(void) { - FILE *fp_in; + FileObject *fp_in; FILE *fp_gen; FILE *fp_tmp=NULL; @@ -131,8 +131,8 @@ void gerarel(void) debuga_more("%s/%s.user_log\n",tmp,uinfo->filename); exit(EXIT_FAILURE); } - if((fp_in=MY_FOPEN(tmp3,"r"))==NULL){ - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),tmp3,strerror(errno)); + if((fp_in=FileObject_Open(tmp3))==NULL){ + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),tmp3,FileObject_GetLastOpenError()); exit(EXIT_FAILURE); } user=uinfo->filename; @@ -333,8 +333,8 @@ void gerarel(void) strcpy(oldaccdia,accdia); strcpy(oldacchora,acchora); } - if (fclose(fp_in)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),tmp3,strerror(errno)); + if (FileObject_Close(fp_in)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),tmp3,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } longline_destroy(&line); diff --git a/siteuser.c b/siteuser.c index 31cecc4..a582b09 100644 --- a/siteuser.c +++ b/siteuser.c @@ -29,7 +29,8 @@ void siteuser(void) { - FILE *fp_in, *fp_ou; + FileObject *fp_in; + FILE *fp_ou; char *buf; char *ourl; @@ -72,8 +73,8 @@ void siteuser(void) exit(EXIT_FAILURE); } - if((fp_in=fopen(general2,"r"))==NULL) { - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),general2,strerror(errno)); + if((fp_in=FileObject_Open(general2))==NULL) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),general2,FileObject_GetLastOpenError()); debuga(__FILE__,__LINE__,_("sort command: %s\n"),csort); exit(EXIT_FAILURE); } @@ -175,8 +176,8 @@ void siteuser(void) } } - if (fclose(fp_in)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),general2,strerror(errno)); + if (FileObject_Close(fp_in)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),general2,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } longline_destroy(&line); diff --git a/splitlog.c b/splitlog.c index c8c9fa2..0816e03 100644 --- a/splitlog.c +++ b/splitlog.c @@ -46,7 +46,7 @@ the files are named after the day they contain prefixed with the string containe */ void splitlog(const char *arq, char df, int dfrom, int duntil, int convert, const char *splitprefix) { - FILE *fp_in; + FileObject *fp_in; FILE *fp_ou=NULL; char *buf; char data[30]; @@ -79,8 +79,8 @@ void splitlog(const char *arq, char df, int dfrom, int duntil, int convert, cons if(arq[0] == '\0') arq="/var/log/squid/access.log"; - if((fp_in=MY_FOPEN(arq,"r"))==NULL) { - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),arq,strerror(errno)); + if((fp_in=FileObject_Open(arq))==NULL) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),arq,FileObject_GetLastOpenError()); exit(EXIT_FAILURE); } @@ -140,8 +140,8 @@ void splitlog(const char *arq, char df, int dfrom, int duntil, int convert, cons } longline_destroy(&line); - if (fclose(fp_in)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),arq,strerror(errno)); + if (FileObject_Close(fp_in)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),arq,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } if (autosplit && fp_ou) { diff --git a/topsites.c b/topsites.c index a102d8d..5992cef 100644 --- a/topsites.c +++ b/topsites.c @@ -33,7 +33,8 @@ extern struct globalstatstruct globstat; void topsites(void) { - FILE *fp_in, *fp_ou; + FileObject *fp_in; + FILE *fp_ou; char *buf; char *url; @@ -93,8 +94,8 @@ void topsites(void) exit(EXIT_FAILURE); } - if((fp_in=fopen(general2,"r"))==NULL) { - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),general2,strerror(errno)); + if((fp_in=FileObject_Open(general2))==NULL) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),general2,FileObject_GetLastOpenError()); debuga(__FILE__,__LINE__,_("sort command: %s\n"),csort); exit(EXIT_FAILURE); } @@ -162,8 +163,8 @@ void topsites(void) ttntime+=item.nelap; #endif } - if (fclose(fp_in)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),general2,strerror(errno)); + if (FileObject_Close(fp_in)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),general2,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } longline_destroy(&line); @@ -221,8 +222,8 @@ void topsites(void) debuga(__FILE__,__LINE__,_("sort command: %s\n"),csort); exit(EXIT_FAILURE); } - if((fp_in=fopen(sites,"r"))==NULL) { - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),sites,strerror(errno)); + if((fp_in=FileObject_Open(sites))==NULL) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),sites,FileObject_GetLastOpenError()); debuga(__FILE__,__LINE__,_("sort command: %s\n"),csort); exit(EXIT_FAILURE); } @@ -319,8 +320,8 @@ void topsites(void) if (SortTableJs[0]) fprintf(fp_ou," sorttable_customkey=\"%d\"",nusers); fprintf(fp_ou,">%s\n",fixnum(nusers,1)); } - if (fclose(fp_in)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),sites,strerror(errno)); + if (FileObject_Close(fp_in)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),sites,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } longline_destroy(&line); diff --git a/topuser.c b/topuser.c index ec49a91..42a5f49 100644 --- a/topuser.c +++ b/topuser.c @@ -58,7 +58,9 @@ static void set_total_users(int totuser) void topuser(void) { - FILE *fp_in = NULL, *fp_top1 = NULL, *fp_top2 = NULL, *fp_top3 = NULL; + FileObject *fp_in = NULL; + FileObject *fp_top1 = NULL; + FILE *fp_top2 = NULL, *fp_top3 = NULL; long long int ttnbytes=0, ttnacc=0, tnacc=0; long long int tnbytes=0, ttnelap=0, tnelap=0; long long int tnincache=0, tnoucache=0, ttnincache=0, ttnoucache=0; @@ -90,8 +92,8 @@ void topuser(void) debuga(__FILE__,__LINE__,_("Creating top users report...\n")); ntopuser = 0; snprintf(wger,sizeof(wger),"%s/sarg-general",outdirname); - if((fp_in=fopen(wger,"r"))==NULL) { - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),wger,strerror(errno)); + if((fp_in=FileObject_Open(wger))==NULL) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),wger,FileObject_GetLastOpenError()); exit(EXIT_FAILURE); } @@ -142,8 +144,8 @@ void topuser(void) tnincache+=item.incache; tnoucache+=item.oucache; } - if (fclose(fp_in)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),wger,strerror(errno)); + if (FileObject_Close(fp_in)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),wger,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } longline_destroy(&line); @@ -209,8 +211,8 @@ void topuser(void) exit(EXIT_FAILURE); } - if((fp_top1=fopen(top1,"r"))==NULL) { - debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),top1,strerror(errno)); + if((fp_top1=FileObject_Open(top1))==NULL) { + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),top1,FileObject_GetLastOpenError()); exit(EXIT_FAILURE); } @@ -428,8 +430,8 @@ void topuser(void) topcount++; } - if (fclose(fp_top1)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),top1,strerror(errno)); + if (FileObject_Close(fp_top1)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),top1,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } if (!KeepTempLog && unlink(top1)) { diff --git a/url.c b/url.c index 8c55610..91a7839 100644 --- a/url.c +++ b/url.c @@ -574,14 +574,14 @@ Read the file containing the host names to alias in the report. */ void read_hostalias(const char *Filename) { - FILE *fi; + FileObject *fi; longline line; char *buf; if (debug) debuga(__FILE__,__LINE__,_("Reading host alias file \"%s\"\n"),Filename); - fi=fopen(Filename,"rt"); + fi=FileObject_Open(Filename); if (!fi) { - debuga(__FILE__,__LINE__,_("Cannot read host name alias file \"%s\": %s\n"),Filename,strerror(errno)); + debuga(__FILE__,__LINE__,_("Cannot read host name alias file \"%s\": %s\n"),Filename,FileObject_GetLastOpenError()); exit(EXIT_FAILURE); } @@ -598,8 +598,8 @@ void read_hostalias(const char *Filename) } longline_destroy(&line); - if (fclose(fi)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),Filename,strerror(errno)); + if (FileObject_Close(fi)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),Filename,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } diff --git a/userinfo.c b/userinfo.c index 301ab1d..1a48778 100644 --- a/userinfo.c +++ b/userinfo.c @@ -311,7 +311,7 @@ Read the file containing the user names to alias in the report. */ void read_useralias(const char *Filename) { - FILE *fi; + FileObject *fi; longline line; char *buf; @@ -323,9 +323,9 @@ void read_useralias(const char *Filename) exit(EXIT_FAILURE); } - fi=fopen(Filename,"rt"); + fi=FileObject_Open(Filename); if (!fi) { - debuga(__FILE__,__LINE__,_("Cannot read user name alias file \"%s\": %s\n"),Filename,strerror(errno)); + debuga(__FILE__,__LINE__,_("Cannot read user name alias file \"%s\": %s\n"),Filename,FileObject_GetLastOpenError()); exit(EXIT_FAILURE); } @@ -342,8 +342,8 @@ void read_useralias(const char *Filename) } longline_destroy(&line); - if (fclose(fi)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),Filename,strerror(errno)); + if (FileObject_Close(fi)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),Filename,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } diff --git a/util.c b/util.c index 8cf7aa7..b19f958 100644 --- a/util.c +++ b/util.c @@ -898,7 +898,7 @@ int obtuser(const char *dirname, const char *name) void obttotal(const char *dirname, const char *name, int nuser, long long int *tbytes, long long int *media) { - FILE *fp_in; + FileObject *fp_in; char *buf; char wdir[MAXLEN]; char user[MAX_USER_LEN]; @@ -914,13 +914,13 @@ void obttotal(const char *dirname, const char *name, int nuser, long long int *t debuga_more("%s%s/sarg-general",dirname,name); exit(EXIT_FAILURE); } - if ((fp_in = fopen(wdir, "r")) == 0) { + if ((fp_in = FileObject_Open(wdir)) == NULL) { if (snprintf(wdir,sizeof(wdir),"%s%s/general",dirname,name)>=sizeof(wdir)) { debuga(__FILE__,__LINE__,_("Buffer too small to store ")); debuga_more("%s%s/general",dirname,name); exit(EXIT_FAILURE); } - if ((fp_in = fopen(wdir, "r")) == 0) { + if ((fp_in = FileObject_Open(wdir)) == NULL) { return; } } @@ -954,8 +954,8 @@ void obttotal(const char *dirname, const char *name, int nuser, long long int *t } break; } - if (fclose(fp_in)==EOF) { - debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),wdir,strerror(errno)); + if (FileObject_Close(fp_in)) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),wdir,FileObject_GetLastCloseError()); exit(EXIT_FAILURE); } longline_destroy(&line); -- 2.47.3