]> git.ipfire.org Git - thirdparty/sarg.git/blob - readlog_sarg.c
Rename configure.in as configure.ac
[thirdparty/sarg.git] / readlog_sarg.c
1 /*
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
3 * 1998, 2015
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 #include "include/readlog.h"
30
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;
37
38 /*!
39 A new file is being read. The name of the file is \a FileName.
40 */
41 static void Sarg_NewFile(const char *FileName)
42 {
43 InSargLog=false;
44 InvalidFileName=(getperiod_fromsarglog(FileName,&SargPeriod)<0);
45 }
46
47 /*!
48 Read one entry from a sarg generated log.
49
50 \param Line One line from the input log file.
51 \param Entry Where to store the information parsed from the line.
52
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.
56 */
57 static enum ReadLogReturnCodeEnum Sarg_ReadEntry(char *Line,struct ReadLogStruct *Entry)
58 {
59 const char *Begin;
60 int IpLen;
61 int HttpCodeLen;
62 int UrlLen;
63 int UserLen;
64 int Day;
65 int Month;
66 int Year;
67 int Hour;
68 int Minute;
69 int Second;
70 char *Ip;
71 char *User;
72
73 if (strncmp(Line,"*** SARG Log ***",16)==0) {
74 if (InvalidFileName) {
75 debuga(__FILE__,__LINE__,_("The name of the file is invalid for a sarg log\n"));
76 exit(EXIT_FAILURE);
77 }
78 getperiod_merge(&period,&SargPeriod);
79 InSargLog=true;
80 return(RLRC_Ignore);
81 }
82 if (!InSargLog) return(RLRC_Unknown);
83
84 // get the date
85 Day=0;
86 while (isdigit(*Line)) Day=Day*10+(*Line++-'0');
87 if (*Line!='/' || Day<1 || Day>31) return(RLRC_Unknown);
88
89 ++Line;
90 Month=0;
91 while (isdigit(*Line)) Month=Month*10+(*Line++-'0');
92 if (*Line!='/') return(RLRC_Unknown);
93 if (Month<=0 || Month>12) return(RLRC_Unknown);
94
95 ++Line;
96 Year=0;
97 while (isdigit(*Line)) Year=Year*10+(*Line++-'0');
98 if (*Line!='\t' || Year<1900 || Year>2200) return(RLRC_Unknown);
99
100 // get the time
101 ++Line;
102 Hour=0;
103 while (isdigit(*Line)) Hour=Hour*10+(*Line++-'0');
104 if (*Line!=':' || Hour>=24) return(RLRC_Unknown);
105 ++Line;
106 Minute=0;
107 while (isdigit(*Line)) Minute=Minute*10+(*Line++-'0');
108 if (*Line!=':' || Minute>=60) return(RLRC_Unknown);
109 ++Line;
110 Second=0;
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
113
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;
121
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);
126
127 // get IP address
128 Entry->Ip=Ip=++Line;
129 for (IpLen=0 ; *Line && *Line!='\t' ; IpLen++) Line++;
130 if (*Line!='\t' || IpLen==0) return(RLRC_Unknown);
131
132 // get the URL
133 Entry->Url=++Line;
134 for (UrlLen=0 ; *Line && *Line!='\t' ; UrlLen++) Line++;
135 if (*Line!='\t' || UrlLen==0) return(RLRC_Unknown);
136
137 // get the number of transfered bytes.
138 Begin=++Line;
139 Entry->DataSize=0LL;
140 while (isdigit(*Line)) Entry->DataSize=Entry->DataSize*10+(*Line++-'0');
141 if (*Line!='\t' || Begin==Line) return(RLRC_Unknown);
142
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);
147
148 // get the elapsed time.
149 Begin=++Line;
150 Entry->ElapsedTime=0L;
151 while (isdigit(*Line)) Entry->ElapsedTime=Entry->ElapsedTime*10+(*Line++-'0');
152 if (*Line!='\t' || Line==Begin) return(RLRC_Unknown);
153
154 // get the smart filter
155 //! \bug Smart filter ignored from sarg log format.
156
157 // check the entry time
158 if (mktime(&Entry->EntryTime)==-1) {
159 debuga(__FILE__,__LINE__,_("Invalid date or time found in the common log file\n"));
160 return(RLRC_InternalError);
161 }
162
163 // it is safe to alter the line buffer now that we are returning a valid entry
164 Ip[IpLen]='\0';
165 Entry->HttpCode[HttpCodeLen]='\0';
166 Entry->Url[UrlLen]='\0';
167 User[UserLen]='\0';
168
169 return(RLRC_NoError);
170 }
171
172 //! \brief Object to read a standard squid log format.
173 const struct ReadLogProcessStruct ReadSargLog=
174 {
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"),
177 Sarg_NewFile,
178 Sarg_ReadEntry
179 };