]> git.ipfire.org Git - thirdparty/sarg.git/blobdiff - readlog.c
Use a library to read gzip access.log files
[thirdparty/sarg.git] / readlog.c
index 31e307ba13947d5ed36ee20cc15f3e2bbf90f151..52caeeb42646d457dfc560f7234ff72bacc1aefb 100644 (file)
--- 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 ; i<nread ; i++)
                                if (skipcr) {
                                        if (tmp4[i]!='\n' && tmp4[i]!='\r') {
@@ -327,7 +385,7 @@ static void ReadOneLogFile(struct ReadLogDataStruct *Filter,const char *arq)
                                        }
                                }
                }
-               rewind(fp_in);
+               FileObject_Rewind(fp_in);
                printf(_("SARG: Records in file: %lu, reading: %3.2f%%"),recs1,(float) 0);
                putchar('\r');
                fflush( stdout ) ;
@@ -731,18 +789,15 @@ static void ReadOneLogFile(struct ReadLogDataStruct *Filter,const char *arq)
        }
        longline_destroy(&line);
 
-       if (!from_stdin) {
-               if (from_pipe)
-                       pclose(fp_in);
-               else {
-                       fclose(fp_in);
-                       if (ShowReadStatistics) {
-                               if (ShowReadPercent)
-                                       printf(_("SARG: Records in file: %lu, reading: %3.2f%%\n"),recs2, (float) 100 );
-                               else
-                                       printf(_("SARG: Records in file: %lu\n"),recs2);
-                       }
-               }
+       if (FileObject_Close(fp_in)) {
+               debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),arq,FileObject_GetLastCloseError());
+               exit(EXIT_FAILURE);
+       }
+       if (ShowReadStatistics) {
+               if (ShowReadPercent)
+                       printf(_("SARG: Records in file: %lu, reading: %3.2f%%\n"),recs2, (float) 100 );
+               else
+                       printf(_("SARG: Records in file: %lu\n"),recs2);
        }
 }