2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
6 * please look at http://sarg.sourceforge.net/donations.php
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
9 * ---------------------------------------------------------------------
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
27 #include "include/conf.h"
28 #include "include/defs.h"
29 #include "include/readlog.h"
31 //! \c True if the current log is known to be a sarg parsed log.
32 static bool InSargLog
=false;
33 //! \c True if the file name is invalid.
34 static bool InvalidFileName
=true;
35 //! The last period extracted from the log file name.
36 static struct periodstruct SargPeriod
;
39 A new file is being read. The name of the file is \a FileName.
41 static void Sarg_NewFile(const char *FileName
)
44 InvalidFileName
=(getperiod_fromsarglog(FileName
,&SargPeriod
)<0);
48 Read one entry from a sarg generated log.
50 \param Line One line from the input log file.
51 \param Entry Where to store the information parsed from the line.
53 \retval RLRC_NoError One valid entry is parsed.
54 \retval RLRC_Unknown The line is invalid.
55 \retval RLRC_InternalError An internal error was encountered.
57 static enum ReadLogReturnCodeEnum
Sarg_ReadEntry(char *Line
,struct ReadLogStruct
*Entry
)
73 if (strncmp(Line
,"*** SARG Log ***",16)==0) {
74 if (InvalidFileName
) {
75 debuga(_("The name of the file is invalid for a sarg log\n"));
78 getperiod_merge(&period
,&SargPeriod
);
82 if (!InSargLog
) return(RLRC_Unknown
);
86 while (isdigit(*Line
)) Day
=Day
*10+(*Line
++-'0');
87 if (*Line
!='/' || Day
<1 || Day
>31) return(RLRC_Unknown
);
91 while (isdigit(*Line
)) Month
=Month
*10+(*Line
++-'0');
92 if (*Line
!='/') return(RLRC_Unknown
);
93 if (Month
<=0 || Month
>12) return(RLRC_Unknown
);
97 while (isdigit(*Line
)) Year
=Year
*10+(*Line
++-'0');
98 if (*Line
!='\t' || Year
<1900 || Year
>2200) return(RLRC_Unknown
);
103 while (isdigit(*Line
)) Hour
=Hour
*10+(*Line
++-'0');
104 if (*Line
!=':' || Hour
>=24) return(RLRC_Unknown
);
107 while (isdigit(*Line
)) Minute
=Minute
*10+(*Line
++-'0');
108 if (*Line
!=':' || Minute
>=60) return(RLRC_Unknown
);
111 while (isdigit(*Line
)) Second
=Second
*10+(*Line
++-'0');
112 if (*Line
!='\t' || Second
>60) return(RLRC_Unknown
); //second can be 60 due to a leap second
114 Entry
->EntryTime
.tm_year
=Year
-1900;
115 Entry
->EntryTime
.tm_mon
=Month
-1;
116 Entry
->EntryTime
.tm_mday
=Day
;
117 Entry
->EntryTime
.tm_hour
=Hour
;
118 Entry
->EntryTime
.tm_min
=Minute
;
119 Entry
->EntryTime
.tm_sec
=Second
;
120 Entry
->EntryTime
.tm_isdst
=-1;
122 // the ID of the user
123 Entry
->User
=User
=++Line
;
124 for (UserLen
=0 ; *Line
&& *Line
!='\t' ; UserLen
++) Line
++;
125 if (*Line
!='\t' || UserLen
==0) return(RLRC_Unknown
);
129 for (IpLen
=0 ; *Line
&& *Line
!='\t' ; IpLen
++) Line
++;
130 if (*Line
!='\t' || IpLen
==0) return(RLRC_Unknown
);
134 for (UrlLen
=0 ; *Line
&& *Line
!='\t' ; UrlLen
++) Line
++;
135 if (*Line
!='\t' || UrlLen
==0) return(RLRC_Unknown
);
137 // get the number of transfered bytes.
140 while (isdigit(*Line
)) Entry
->DataSize
=Entry
->DataSize
*10+(*Line
++-'0');
141 if (*Line
!='\t' || Begin
==Line
) return(RLRC_Unknown
);
143 // get the HTTP code.
144 Entry
->HttpCode
=++Line
;
145 for (HttpCodeLen
=0 ; *Line
&& *Line
!='\t' ; HttpCodeLen
++) Line
++;
146 if (*Line
!='\t' || HttpCodeLen
==0) return(RLRC_Unknown
);
148 // get the elapsed time.
150 Entry
->ElapsedTime
=0L;
151 while (isdigit(*Line
)) Entry
->ElapsedTime
=Entry
->ElapsedTime
*10+(*Line
++-'0');
152 if (*Line
!='\t' || Line
==Begin
) return(RLRC_Unknown
);
154 // get the smart filter
155 //! \bug Smart filter ignored from sarg log format.
157 // check the entry time
158 if (mktime(&Entry
->EntryTime
)==-1) {
159 debuga(_("Invalid date or time found in the common log file\n"));
160 return(RLRC_InternalError
);
163 // it is safe to alter the line buffer now that we are returning a valid entry
165 Entry
->HttpCode
[HttpCodeLen
]='\0';
166 Entry
->Url
[UrlLen
]='\0';
169 return(RLRC_NoError
);
172 //! \brief Object to read a standard squid log format.
173 const struct ReadLogProcessStruct ReadSargLog
=
175 /* TRANSLATORS: This is the name of the log format displayed when this format is detected in an input log file. */
176 N_("sarg log format"),