]>
Commit | Line | Data |
---|---|---|
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 | //! \c True if the current log is known to be a sarg parsed log. | |
32 | static bool InSargLog=false; | |
9427469a FM |
33 | //! \c True if the file name is invalid. |
34 | static bool InvalidFileName=true; | |
cc6af460 FM |
35 | //! The last period extracted from the log file name. |
36 | static struct periodstruct SargPeriod; | |
1c91da07 FM |
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; | |
cc6af460 | 44 | InvalidFileName=(getperiod_fromsarglog(FileName,&SargPeriod)<0); |
1c91da07 FM |
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; | |
f83d7b44 FM |
70 | char *Ip; |
71 | char *User; | |
0c87646f | 72 | |
1c91da07 | 73 | if (strncmp(Line,"*** SARG Log ***",16)==0) { |
9427469a FM |
74 | if (InvalidFileName) { |
75 | debuga(_("The name of the file is invalid for a sarg log\n")); | |
76 | exit(EXIT_FAILURE); | |
77 | } | |
cc6af460 | 78 | getperiod_merge(&period,&SargPeriod); |
1c91da07 FM |
79 | InSargLog=true; |
80 | return(RLRC_Ignore); | |
81 | } | |
82 | if (!InSargLog) return(RLRC_Unknown); | |
0c87646f | 83 | |
1c91da07 FM |
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); | |
0c87646f | 99 | |
1c91da07 FM |
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 | ||
cb53374b FM |
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; | |
7dbbca70 | 120 | Entry->EntryTime.tm_isdst=-1; |
1c91da07 FM |
121 | |
122 | // the ID of the user | |
f83d7b44 | 123 | Entry->User=User=++Line; |
1c91da07 FM |
124 | for (UserLen=0 ; *Line && *Line!='\t' ; UserLen++) Line++; |
125 | if (*Line!='\t' || UserLen==0) return(RLRC_Unknown); | |
0c87646f | 126 | |
1c91da07 | 127 | // get IP address |
f83d7b44 | 128 | Entry->Ip=Ip=++Line; |
1c91da07 FM |
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); | |
0c87646f | 136 | |
1c91da07 FM |
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); | |
0c87646f | 142 | |
1c91da07 FM |
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 | |
7dbbca70 FM |
155 | //! \bug Smart filter ignored from sarg log format. |
156 | ||
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); | |
161 | } | |
162 | ||
1c91da07 | 163 | // it is safe to alter the line buffer now that we are returning a valid entry |
f83d7b44 | 164 | Ip[IpLen]='\0'; |
1c91da07 FM |
165 | Entry->HttpCode[HttpCodeLen]='\0'; |
166 | Entry->Url[UrlLen]='\0'; | |
f83d7b44 | 167 | User[UserLen]='\0'; |
0c87646f | 168 | |
1c91da07 FM |
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 | }; |