]> git.ipfire.org Git - thirdparty/sarg.git/blobdiff - readlog_common.c
Generate redirector log even if -d is not given
[thirdparty/sarg.git] / readlog_common.c
index 2a53130bda8a62d710574bd03ab56edc63c1e690..b39ee9b9a313c5f8164f25144cd31e8f3223d98f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * SARG Squid Analysis Report Generator      http://sarg.sourceforge.net
- *                                                            1998, 2012
+ *                                                            1998, 2015
  *
  * SARG donations:
  *      please look at http://sarg.sourceforge.net/donations.php
@@ -26,6 +26,7 @@
 
 #include "include/conf.h"
 #include "include/defs.h"
+#include "include/readlog.h"
 
 /*!
 A new file is being read. The name of the file is \a FileName.
@@ -34,6 +35,25 @@ static void Common_NewFile(const char *FileName)
 {
 }
 
+/*!
+Extract a column containing a long long int from \a Line.
+
+The extracted value is stored in \a Value.
+
+The pointer to the next byte just after the number is returned
+by the function.
+*/
+static char *Common_GetLongLongInt(char *Line,long long int *Value)
+{
+       *Value=0LL;
+       if (*Line=='-') {
+               ++Line;
+       } else {
+               while (isdigit(*Line)) *Value=*Value*10+(*Line++-'0');
+       }
+       return(Line);
+}
+
 /*!
 Read one entry from a standard squid log format.
 
@@ -59,10 +79,11 @@ static enum ReadLogReturnCodeEnum Common_ReadEntry(char *Line,struct ReadLogStru
        int Hour;
        int Minute;
        int Second;
-       static struct tm tt;
+       char *Ip;
+       char *User;
 
        // get IP address
-       Entry->Ip=Line;
+       Entry->Ip=Ip=Line;
        for (IpLen=0 ; *Line && *Line!=' ' ; IpLen++) Line++;
        if (*Line!=' ' || IpLen==0) return(RLRC_Unknown);
 
@@ -74,10 +95,10 @@ static enum ReadLogReturnCodeEnum Common_ReadEntry(char *Line,struct ReadLogStru
        }
 
        // the ID of the user or - if the user is unidentified
-       Entry->User=++Line;
+       Entry->User=User=++Line;
        for (UserLen=0 ; *Line && *Line!=' ' ; UserLen++) Line++;
        if (*Line!=' ' || UserLen==0) return(RLRC_Unknown);
-       
+
        if (squid24) {
                // squid version > 2.4 store the user ID in the first column: skip the second column here
                Begin=++Line;
@@ -104,7 +125,7 @@ static enum ReadLogReturnCodeEnum Common_ReadEntry(char *Line,struct ReadLogStru
        Year=0;
        while (isdigit(*Line)) Year=Year*10+(*Line++-'0');
        if (*Line!=':' || Year<1900 || Year>2200) return(RLRC_Unknown);
-       
+
        // get the time
        ++Line;
        Hour=0;
@@ -122,31 +143,31 @@ static enum ReadLogReturnCodeEnum Common_ReadEntry(char *Line,struct ReadLogStru
        // skip the timezone up to the closing ]
        while (*Line && *Line!=']') Line++;
        if (*Line!=']') return(RLRC_Unknown);
-       
-       tt.tm_year=Year-1900;
-       tt.tm_mon=Month;
-       tt.tm_mday=Day;
-       tt.tm_hour=Hour;
-       tt.tm_min=Minute;
-       tt.tm_sec=Second;
-       Entry->EntryTime=&tt;
+
+       Entry->EntryTime.tm_year=Year-1900;
+       Entry->EntryTime.tm_mon=Month;
+       Entry->EntryTime.tm_mday=Day;
+       Entry->EntryTime.tm_hour=Hour;
+       Entry->EntryTime.tm_min=Minute;
+       Entry->EntryTime.tm_sec=Second;
+       Entry->EntryTime.tm_isdst=-1;
 
        // the URL is enclosed between double qhotes
        ++Line;
        if (*Line!=' ') return(RLRC_Unknown);
        ++Line;
        if (*Line!='\"') return(RLRC_Unknown);
-       
+
        // skip the HTTP function
        Begin=++Line;
        while (isalpha(*Line)) Line++;
        if (*Line!=' ' || Line==Begin) return(RLRC_Unknown);
-       
+
        // get the URL
        Entry->Url=++Line;
        for (UrlLen=0 ; *Line && *Line!=' ' ; UrlLen++) Line++;
        if (*Line!=' ' || UrlLen==0) return(RLRC_Unknown);
-       
+
        // skip the HTTP/...
        ++Line;
        while (*Line && *Line!='\"') Line++;
@@ -158,19 +179,25 @@ static enum ReadLogReturnCodeEnum Common_ReadEntry(char *Line,struct ReadLogStru
        Entry->HttpCode=++Line;
        for (HttpCodeLen=0 ; *Line && *Line!=' ' ; HttpCodeLen++) Line++;
        if (*Line!=' ' || HttpCodeLen==0) return(RLRC_Unknown);
-       
+
        // get the number of transfered bytes.
        Begin=++Line;
-       Entry->DataSize=0LL;
-       while (isdigit(*Line)) Entry->DataSize=Entry->DataSize*10+(*Line++-'0');
-       if (*Line!=' ' || Begin==Line) return(RLRC_Unknown);
-       
+       Line=Common_GetLongLongInt(Line,&Entry->DataSize);
+       // some log contains more columns
+       if ((*Line && *Line!=' ') || Begin==Line) return(RLRC_Unknown);
+
+       // check the entry time
+       if (mktime(&Entry->EntryTime)==-1) {
+               debuga(__FILE__,__LINE__,_("Invalid date or time found in the common log file\n"));
+               return(RLRC_InternalError);
+       }
+
        // it is safe to alter the line buffer now that we are returning a valid entry
-       Entry->Ip[IpLen]='\0';
+       Ip[IpLen]='\0';
        Entry->HttpCode[HttpCodeLen]='\0';
        Entry->Url[UrlLen]='\0';
-       Entry->User[UserLen]='\0';
-       
+       User[UserLen]='\0';
+
        return(RLRC_NoError);
 }