/*
* SARG Squid Analysis Report Generator http://sarg.sourceforge.net
- * 1998, 2012
+ * 1998, 2015
*
* SARG donations:
* please look at http://sarg.sourceforge.net/donations.php
#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.
{
}
+/*!
+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.
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);
}
// 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;
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;
// 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++;
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);
}