]> git.ipfire.org Git - thirdparty/sarg.git/blame - readlog_common.c
Store the entry time in a structure instead of a pointer
[thirdparty/sarg.git] / readlog_common.c
CommitLineData
1c91da07
FM
1/*
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
3 * 1998, 2012
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"
29
30/*!
31A new file is being read. The name of the file is \a FileName.
32*/
33static void Common_NewFile(const char *FileName)
34{
35}
36
37/*!
38Read one entry from a standard squid log format.
39
40\param Line One line from the input log file.
41\param Entry Where to store the information parsed from the line.
42
43\retval RLRC_NoError One valid entry is parsed.
44\retval RLRC_Unknown The line is invalid.
45\retval RLRC_InternalError An internal error was encountered.
46*/
47static enum ReadLogReturnCodeEnum Common_ReadEntry(char *Line,struct ReadLogStruct *Entry)
48{
49 const char *Begin;
50 int IpLen;
51 int HttpCodeLen;
52 int UrlLen;
53 int UserLen;
54 int Day;
55 char MonthName[4];
56 int MonthNameLen;
57 int Month;
58 int Year;
59 int Hour;
60 int Minute;
61 int Second;
1c91da07
FM
62
63 // get IP address
64 Entry->Ip=Line;
65 for (IpLen=0 ; *Line && *Line!=' ' ; IpLen++) Line++;
66 if (*Line!=' ' || IpLen==0) return(RLRC_Unknown);
67
68 if (!squid24) {
69 // squid version <= 2.4 store the user ID in the second column: skip the first column here
70 Begin=++Line;
71 while (*Line && *Line!=' ') Line++;
72 if (*Line!=' '|| Line==Begin) return(RLRC_Unknown);
73 }
74
75 // the ID of the user or - if the user is unidentified
76 Entry->User=++Line;
77 for (UserLen=0 ; *Line && *Line!=' ' ; UserLen++) Line++;
78 if (*Line!=' ' || UserLen==0) return(RLRC_Unknown);
79
80 if (squid24) {
81 // squid version > 2.4 store the user ID in the first column: skip the second column here
82 Begin=++Line;
83 while (*Line && *Line!=' ') Line++;
84 if (*Line!=' '|| Line==Begin) return(RLRC_Unknown);
85 }
86
87 // get the date enclosed within square brackets
88 ++Line;
89 if (*Line!='[') return(RLRC_Unknown);
90 ++Line;
91 Day=0;
92 while (isdigit(*Line)) Day=Day*10+(*Line++-'0');
93 if (*Line!='/' || Day<1 || Day>31) return(RLRC_Unknown);
94
95 ++Line;
96 for (MonthNameLen=0 ; MonthNameLen<sizeof(MonthName)-1 && isalpha(*Line) ; MonthNameLen++) MonthName[MonthNameLen]=*Line++;
97 if (*Line!='/') return(RLRC_Unknown);
98 MonthName[MonthNameLen]='\0';
99 Month=month2num(MonthName);
100 if (Month>=12) return(RLRC_Unknown);
101
102 ++Line;
103 Year=0;
104 while (isdigit(*Line)) Year=Year*10+(*Line++-'0');
105 if (*Line!=':' || Year<1900 || Year>2200) return(RLRC_Unknown);
106
107 // get the time
108 ++Line;
109 Hour=0;
110 while (isdigit(*Line)) Hour=Hour*10+(*Line++-'0');
111 if (*Line!=':' || Hour>=24) return(RLRC_Unknown);
112 ++Line;
113 Minute=0;
114 while (isdigit(*Line)) Minute=Minute*10+(*Line++-'0');
115 if (*Line!=':' || Minute>=60) return(RLRC_Unknown);
116 ++Line;
117 Second=0;
118 while (isdigit(*Line)) Second=Second*10+(*Line++-'0');
119 if (*Line!=' ' || Second>60) return(RLRC_Unknown); //second can be 60 due to a leap second
120
121 // skip the timezone up to the closing ]
122 while (*Line && *Line!=']') Line++;
123 if (*Line!=']') return(RLRC_Unknown);
124
cb53374b
FM
125 Entry->EntryTime.tm_year=Year-1900;
126 Entry->EntryTime.tm_mon=Month;
127 Entry->EntryTime.tm_mday=Day;
128 Entry->EntryTime.tm_hour=Hour;
129 Entry->EntryTime.tm_min=Minute;
130 Entry->EntryTime.tm_sec=Second;
1c91da07
FM
131
132 // the URL is enclosed between double qhotes
133 ++Line;
134 if (*Line!=' ') return(RLRC_Unknown);
135 ++Line;
136 if (*Line!='\"') return(RLRC_Unknown);
137
138 // skip the HTTP function
139 Begin=++Line;
140 while (isalpha(*Line)) Line++;
141 if (*Line!=' ' || Line==Begin) return(RLRC_Unknown);
142
143 // get the URL
144 Entry->Url=++Line;
145 for (UrlLen=0 ; *Line && *Line!=' ' ; UrlLen++) Line++;
146 if (*Line!=' ' || UrlLen==0) return(RLRC_Unknown);
147
148 // skip the HTTP/...
149 ++Line;
150 while (*Line && *Line!='\"') Line++;
151 if (*Line!='\"') return(RLRC_Unknown);
152 ++Line;
153 if (*Line!=' ') return(RLRC_Unknown);
154
155 // get the HTTP code.
156 Entry->HttpCode=++Line;
157 for (HttpCodeLen=0 ; *Line && *Line!=' ' ; HttpCodeLen++) Line++;
158 if (*Line!=' ' || HttpCodeLen==0) return(RLRC_Unknown);
159
160 // get the number of transfered bytes.
161 Begin=++Line;
162 Entry->DataSize=0LL;
163 while (isdigit(*Line)) Entry->DataSize=Entry->DataSize*10+(*Line++-'0');
164 if (*Line!=' ' || Begin==Line) return(RLRC_Unknown);
165
166 // it is safe to alter the line buffer now that we are returning a valid entry
167 Entry->Ip[IpLen]='\0';
168 Entry->HttpCode[HttpCodeLen]='\0';
169 Entry->Url[UrlLen]='\0';
170 Entry->User[UserLen]='\0';
171
172 return(RLRC_NoError);
173}
174
175//! \brief Object to read a standard common log format.
176const struct ReadLogProcessStruct ReadCommonLog=
177{
178 /* TRANSLATORS: This is the name of the log format displayed when this format is detected in an input log file. */
179 N_("common log format"),
180 Common_NewFile,
181 Common_ReadEntry
182};