]> git.ipfire.org Git - thirdparty/sarg.git/blame - readlog_sarg.c
Modular reading of some input log formats
[thirdparty/sarg.git] / readlog_sarg.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//! \c True if the current log is known to be a sarg parsed log.
31static bool InSargLog=false;
32
33/*!
34A new file is being read. The name of the file is \a FileName.
35*/
36static void Sarg_NewFile(const char *FileName)
37{
38 InSargLog=false;
39}
40
41/*!
42Read one entry from a sarg generated log.
43
44\param Line One line from the input log file.
45\param Entry Where to store the information parsed from the line.
46
47\retval RLRC_NoError One valid entry is parsed.
48\retval RLRC_Unknown The line is invalid.
49\retval RLRC_InternalError An internal error was encountered.
50*/
51static enum ReadLogReturnCodeEnum Sarg_ReadEntry(char *Line,struct ReadLogStruct *Entry)
52{
53 const char *Begin;
54 int IpLen;
55 int HttpCodeLen;
56 int UrlLen;
57 int UserLen;
58 int Day;
59 int Month;
60 int Year;
61 int Hour;
62 int Minute;
63 int Second;
64 static struct tm tt;
65
66 if (strncmp(Line,"*** SARG Log ***",16)==0) {
67 InSargLog=true;
68 return(RLRC_Ignore);
69 }
70 if (!InSargLog) return(RLRC_Unknown);
71
72 // get the date
73 Day=0;
74 while (isdigit(*Line)) Day=Day*10+(*Line++-'0');
75 if (*Line!='/' || Day<1 || Day>31) return(RLRC_Unknown);
76
77 ++Line;
78 Month=0;
79 while (isdigit(*Line)) Month=Month*10+(*Line++-'0');
80 if (*Line!='/') return(RLRC_Unknown);
81 if (Month<=0 || Month>12) return(RLRC_Unknown);
82
83 ++Line;
84 Year=0;
85 while (isdigit(*Line)) Year=Year*10+(*Line++-'0');
86 if (*Line!='\t' || Year<1900 || Year>2200) return(RLRC_Unknown);
87
88 // get the time
89 ++Line;
90 Hour=0;
91 while (isdigit(*Line)) Hour=Hour*10+(*Line++-'0');
92 if (*Line!=':' || Hour>=24) return(RLRC_Unknown);
93 ++Line;
94 Minute=0;
95 while (isdigit(*Line)) Minute=Minute*10+(*Line++-'0');
96 if (*Line!=':' || Minute>=60) return(RLRC_Unknown);
97 ++Line;
98 Second=0;
99 while (isdigit(*Line)) Second=Second*10+(*Line++-'0');
100 if (*Line!='\t' || Second>60) return(RLRC_Unknown); //second can be 60 due to a leap second
101
102 tt.tm_year=Year-1900;
103 tt.tm_mon=Month-1;
104 tt.tm_mday=Day;
105 tt.tm_hour=Hour;
106 tt.tm_min=Minute;
107 tt.tm_sec=Second;
108 Entry->EntryTime=&tt;
109
110 // the ID of the user
111 Entry->User=++Line;
112 for (UserLen=0 ; *Line && *Line!='\t' ; UserLen++) Line++;
113 if (*Line!='\t' || UserLen==0) return(RLRC_Unknown);
114
115 // get IP address
116 Entry->Ip=++Line;
117 for (IpLen=0 ; *Line && *Line!='\t' ; IpLen++) Line++;
118 if (*Line!='\t' || IpLen==0) return(RLRC_Unknown);
119
120 // get the URL
121 Entry->Url=++Line;
122 for (UrlLen=0 ; *Line && *Line!='\t' ; UrlLen++) Line++;
123 if (*Line!='\t' || UrlLen==0) return(RLRC_Unknown);
124
125 // get the number of transfered bytes.
126 Begin=++Line;
127 Entry->DataSize=0LL;
128 while (isdigit(*Line)) Entry->DataSize=Entry->DataSize*10+(*Line++-'0');
129 if (*Line!='\t' || Begin==Line) return(RLRC_Unknown);
130
131 // get the HTTP code.
132 Entry->HttpCode=++Line;
133 for (HttpCodeLen=0 ; *Line && *Line!='\t' ; HttpCodeLen++) Line++;
134 if (*Line!='\t' || HttpCodeLen==0) return(RLRC_Unknown);
135
136 // get the elapsed time.
137 Begin=++Line;
138 Entry->ElapsedTime=0L;
139 while (isdigit(*Line)) Entry->ElapsedTime=Entry->ElapsedTime*10+(*Line++-'0');
140 if (*Line!='\t' || Line==Begin) return(RLRC_Unknown);
141
142 // get the smart filter
143
144 // it is safe to alter the line buffer now that we are returning a valid entry
145 Entry->Ip[IpLen]='\0';
146 Entry->HttpCode[HttpCodeLen]='\0';
147 Entry->Url[UrlLen]='\0';
148 Entry->User[UserLen]='\0';
149
150 return(RLRC_NoError);
151}
152
153//! \brief Object to read a standard squid log format.
154const struct ReadLogProcessStruct ReadSargLog=
155{
156 /* TRANSLATORS: This is the name of the log format displayed when this format is detected in an input log file. */
157 N_("sarg log format"),
158 Sarg_NewFile,
159 Sarg_ReadEntry
160};