]> git.ipfire.org Git - thirdparty/sarg.git/blame - readlog_squid.c
Ignore negative elapsed time in squid log
[thirdparty/sarg.git] / readlog_squid.c
CommitLineData
1c91da07
FM
1/*
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
67302a9e 3 * 1998, 2013
1c91da07
FM
4 *
5 * SARG donations:
6 * please look at http://sarg.sourceforge.net/donations.php
7 * Support:
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
9 * ---------------------------------------------------------------------
10 *
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.
15 *
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.
20 *
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.
24 *
25 */
26
27#include "include/conf.h"
28#include "include/defs.h"
f83d7b44 29#include "include/readlog.h"
1c91da07
FM
30
31/*!
32A new file is being read. The name of the file is \a FileName.
33*/
34static void Squid_NewFile(const char *FileName)
35{
36}
37
38/*!
39Read one entry from a standard squid log format.
40
41\param Line One line from the input log file.
42\param Entry Where to store the information parsed from the line.
43
44\retval RLRC_NoError One valid entry is parsed.
45\retval RLRC_Unknown The line is invalid.
46\retval RLRC_InternalError An internal error was encountered.
47*/
48static enum ReadLogReturnCodeEnum Squid_ReadEntry(char *Line,struct ReadLogStruct *Entry)
49{
50 const char *Begin;
51 time_t log_time;
52 int IpLen;
53 int HttpCodeLen;
54 int UrlLen;
55 int UserLen;
cb53374b 56 struct tm *tt;
f83d7b44
FM
57 char *Ip;
58 char *User;
bd43d81f 59
1c91da07
FM
60 // get log time.
61 Begin=Line;
62 log_time=0;
63 while (isdigit(*Line)) log_time=log_time*10+(*Line++-'0');
64 if (*Line!='.' || Line==Begin) return(RLRC_Unknown);
bd43d81f 65
1c91da07
FM
66 // ignore decimal part to log time.
67 Begin=++Line;
68 while (isdigit(*Line)) Line++;
69 if (*Line!=' ' || Line==Begin) return(RLRC_Unknown);
bd43d81f 70
1c91da07
FM
71 // skip spaces before the elapsed time.
72 while (*Line==' ') Line++;
bd43d81f 73
1c91da07
FM
74 // get the elapsed time.
75 Begin=Line;
76 Entry->ElapsedTime=0L;
7ab27b70
FM
77 if (*Line=='-')
78 {
79 /*
80 * Negative elapsed time happens in squid (see
81 * http://www.squid-cache.org/mail-archive/squid-users/200711/0192.html)
82 * but no answer were provided as to why it happens. Let's just
83 * assume a zero elapsed time and ignore every following digit.
84 */
85 Line++;
86 if (!isdigit(*Line)) return(RLRC_Unknown);
87 while (isdigit(*Line)) Line++;
88 }
89 else
90 {
91 if (!isdigit(*Line)) return(RLRC_Unknown);
92 while (isdigit(*Line)) Entry->ElapsedTime=Entry->ElapsedTime*10+(*Line++-'0');
93 }
1c91da07
FM
94 if (*Line!=' ' || Line==Begin) return(RLRC_Unknown);
95
96 // get IP address. It can be a fqdn if that option is enabled in squid.
f83d7b44 97 Entry->Ip=Ip=++Line;
1c91da07
FM
98 for (IpLen=0 ; *Line && *Line!=' ' ; IpLen++) Line++;
99 if (*Line!=' ' || IpLen==0) return(RLRC_Unknown);
100
101 // get the HTTP code.
102 Entry->HttpCode=++Line;
103 for (HttpCodeLen=0 ; *Line && *Line!=' ' ; HttpCodeLen++) Line++;
104 if (*Line!=' ' || HttpCodeLen==0) return(RLRC_Unknown);
105
106 // get the number of transfered bytes.
107 Begin=++Line;
108 Entry->DataSize=0LL;
109 while (isdigit(*Line)) Entry->DataSize=Entry->DataSize*10+(*Line++-'0');
110 if (*Line!=' ' || Begin==Line) return(RLRC_Unknown);
bd43d81f 111
1c91da07
FM
112 // skip the HTTP function
113 Begin=++Line;
114 while (*Line && *Line!=' ') Line++;
115 if (*Line!=' '|| Line==Begin) return(RLRC_Unknown);
bd43d81f 116
1c91da07
FM
117 // the url
118 Entry->Url=++Line;
119 for (UrlLen=0 ; *Line && *Line!=' ' ; UrlLen++) Line++;
120 if (*Line!=' ' || UrlLen==0) return(RLRC_Unknown);
bd43d81f 121
1c91da07 122 // the ID of the user or - if the user is unidentified
f83d7b44 123 Entry->User=User=++Line;
1c91da07
FM
124 for (UserLen=0 ; *Line && *Line!=' ' ; UserLen++) Line++;
125 if (*Line!=' ' || UserLen==0) return(RLRC_Unknown);
bd43d81f 126
1c91da07 127 // now, the format is known with a good confidence. If the time doesn't decode, it is an error.
cb53374b
FM
128 tt=localtime(&log_time);
129 if (tt==NULL) {
1c91da07
FM
130 debuga(_("Cannot convert the timestamp from the squid log file\n"));
131 return(RLRC_InternalError);
132 }
cb53374b 133 memcpy(&Entry->EntryTime,tt,sizeof(struct tm));
bd43d81f 134
1c91da07 135 // it is safe to alter the line buffer now that we are returning a valid entry
f83d7b44 136 Ip[IpLen]='\0';
1c91da07
FM
137 Entry->HttpCode[HttpCodeLen]='\0';
138 Entry->Url[UrlLen]='\0';
f83d7b44 139 User[UserLen]='\0';
bd43d81f 140
1c91da07
FM
141 return(RLRC_NoError);
142}
143
144//! \brief Object to read a standard squid log format.
145const struct ReadLogProcessStruct ReadSquidLog=
146{
147 /* TRANSLATORS: This is the name of the log format displayed when this format is detected in an input log file. */
148 N_("squid log format"),
149 Squid_NewFile,
150 Squid_ReadEntry
151};