]> git.ipfire.org Git - thirdparty/sarg.git/blame - squidguard_log.c
Store the period internaly and get rid of the sarg-period file.
[thirdparty/sarg.git] / squidguard_log.c
CommitLineData
25697a35 1/*
94ff9470 2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
1164c474 3 * 1998, 2010
25697a35
GS
4 *
5 * SARG donations:
6 * please look at http://sarg.sourceforge.net/donations.php
1164c474
FM
7 * Support:
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
25697a35
GS
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"
5f3cfd1d 28#include "include/defs.h"
25697a35 29
d6e703cc
FM
30static char **files_done = NULL;
31static int nfiles_done = 0;
32
33
5f3cfd1d 34static void read_log(const char *wentp, FILE *fp_ou)
491b862f
GS
35{
36 FILE *fp_in = NULL;
06b39c87 37 char buf[MAXLEN];
491b862f 38 char leks[5], sep[2], res[MAXLEN];
2240dcea 39 char mon[20], day[3], year[5], hour[15];
491b862f
GS
40 char list[MAXLEN];
41 char wdata[127];
ac422f9b 42 char url[MAX_URL_LEN];
2240dcea 43 char user[MAX_USER_LEN];
06b39c87 44 char ip[25];
2240dcea 45 int idata=0;
d6e703cc 46 int i;
06e3cc62 47 char *str;
9c7c6346
FM
48 struct getwordstruct gwarea;
49 struct getwordstruct gwarea1;
491b862f
GS
50
51 if(debug) {
f76230ca 52 debuga(_("Reading squidGuard log file %s\n"),wentp);
491b862f 53 }
d6e703cc
FM
54
55 /* With squidGuard, you can log groups in only one log file.
56 We must parse each log files only one time. Example :
57 dest porn {
58 domainlist porn/domains
59 urllist porn/urls
60 log file1.log
61 }
62 dest aggressive {
63 domainlist aggressive/domains
64 urllist aggressive/urls
65 log file2.log
66 }
67 dest audio-video {
68 domainlist audio-video/domains
69 urllist audio-video/urls
70 log file1.log
71 }
72 */
73 for (i=0; i<nfiles_done; i++)
74 if (!strcmp(wentp, files_done[i])) return;
06e3cc62 75
d6e703cc
FM
76 nfiles_done++;
77 files_done = realloc(files_done, nfiles_done*sizeof(char *));
78 if (!files_done) {
d574e592 79 debuga(_("Not enough memory to store the name of the new squidGuard log to be read - %s\n"),strerror(errno));
f76230ca 80 exit(EXIT_FAILURE);
d6e703cc
FM
81 }
82 files_done[nfiles_done-1] = strdup(wentp);
83 if (!files_done[nfiles_done-1]) {
d574e592 84 debuga(_("Not enough memory to store the name of the new squidGuard log to be read - %s\n"),strerror(errno));
f76230ca 85 exit(EXIT_FAILURE);
d6e703cc
FM
86 }
87
491b862f 88 if ((fp_in=fopen(wentp,"r"))==NULL) {
f76230ca 89 debuga(_("(squidguard) Cannot open log file %s\n"),wentp);
06b39c87 90 exit(EXIT_FAILURE);
491b862f 91 }
06e3cc62 92
491b862f 93 while (fgets(buf,sizeof(buf),fp_in) != NULL) {
9c7c6346
FM
94 getword_start(&gwarea,buf);
95 if(SquidGuardLogFormat[0] != '\0') {
96 getword_start(&gwarea1,SquidGuardLogFormat);
491b862f 97 leks[0]='\0';
9c7c6346 98 if (getword(leks,sizeof(leks),&gwarea1,'#')<0) {
10210234 99 debuga(_("There is a broken record or garbage in your %s file\n"),wentp);
06b39c87 100 exit(EXIT_FAILURE);
4bcb77cf 101 }
491b862f 102 while(strcmp(leks,"end") != 0) {
9c7c6346 103 if (getword(leks,sizeof(leks),&gwarea1,'#')<0 || getword(sep,sizeof(sep),&gwarea1,'#')<0) {
10210234 104 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),wentp);
06b39c87 105 exit(EXIT_FAILURE);
4bcb77cf 106 }
491b862f 107 if(strcmp(leks,"end") != 0) {
9c7c6346 108 if (getword(res,sizeof(res),&gwarea,sep[0])<0) {
10210234 109 debuga(_("Maybe you have a broken record or garbage in your %s file\n"),wentp);
06b39c87 110 exit(EXIT_FAILURE);
4bcb77cf 111 }
2240dcea
FM
112 if(strcmp(leks,"year") == 0) {
113 if (strlen(res)>=sizeof(year)) {
10210234 114 debuga(_("Year string too long in squidGuard log file %s\n"),wentp);
06b39c87 115 exit(EXIT_FAILURE);
2240dcea 116 }
491b862f 117 strcpy(year,res);
2240dcea
FM
118 } else if(strcmp(leks,"mon") == 0) {
119 if (strlen(res)>=sizeof(mon)) {
10210234 120 debuga(_("Month string too long in squidGuard log file %s\n"),wentp);
06b39c87 121 exit(EXIT_FAILURE);
2240dcea 122 }
491b862f 123 strcpy(mon,res);
2240dcea
FM
124 } else if(strcmp(leks,"day") == 0) {
125 if (strlen(res)>=sizeof(day)) {
10210234 126 debuga(_("Day string too long in squidGuard log file %s\n"),wentp);
06b39c87 127 exit(EXIT_FAILURE);
2240dcea 128 }
491b862f 129 strcpy(day,res);
2240dcea
FM
130 } else if(strcmp(leks,"hour") == 0) {
131 if (strlen(res)>=sizeof(hour)) {
10210234 132 debuga(_("Hour string too long in squidGuard log file %s\n"),wentp);
06b39c87 133 exit(EXIT_FAILURE);
2240dcea 134 }
491b862f 135 strcpy(hour,res);
2240dcea
FM
136 } else if(strcmp(leks,"list") == 0) {
137 if (strlen(res)>=sizeof(list)) {
10210234 138 debuga(_("Banning list name too long in squidGuard log file %s\n"),wentp);
06b39c87 139 exit(EXIT_FAILURE);
2240dcea 140 }
491b862f 141 strcpy(list,res);
2240dcea
FM
142 } else if(strcmp(leks,"ip") == 0) {
143 if (strlen(res)>=sizeof(ip)) {
10210234 144 debuga(_("IP address too long in squidGuard log file %s\n"),wentp);
06b39c87 145 exit(EXIT_FAILURE);
2240dcea 146 }
491b862f 147 strcpy(ip,res);
2240dcea
FM
148 } else if(strcmp(leks,"user") == 0) {
149 if (strlen(res)>=sizeof(user)) {
10210234 150 debuga(_("User ID too long in squidGuard log file %s\n"),wentp);
06b39c87 151 exit(EXIT_FAILURE);
2240dcea 152 }
491b862f 153 strcpy(user,res);
2240dcea
FM
154 } else if(strcmp(leks,"url") == 0) {
155 if (strlen(res)>=sizeof(url)) {
10210234 156 debuga(_("URL too long in squidGuard log file %s\n"),wentp);
06b39c87 157 exit(EXIT_FAILURE);
2240dcea 158 }
491b862f 159 strcpy(url,res);
2240dcea 160 }
491b862f
GS
161 }
162 }
163 } else {
9c7c6346
FM
164 if (getword(year,sizeof(year),&gwarea,'-')<0 || getword(mon,sizeof(mon),&gwarea,'-')<0 ||
165 getword(day,sizeof(day),&gwarea,' ')<0 || getword(hour,sizeof(hour),&gwarea,' ')<0 ||
166 getword_skip(MAXLEN,&gwarea,'/')<0 || getword(list,sizeof(list),&gwarea,'/')<0 ||
c11e2033 167 getword_skip(MAXLEN,&gwarea,' ')<0 || getword(url,sizeof(url),&gwarea,' ')<0 ||
9c7c6346
FM
168 getword(ip,sizeof(ip),&gwarea,'/')<0 || getword_skip(MAXLEN,&gwarea,' ')<0 ||
169 getword(user,sizeof(user),&gwarea,' ')<0) {
10210234 170 debuga(_("There is a broken record or garbage in your %s file\n"),wentp);
06b39c87 171 exit(EXIT_FAILURE);
4bcb77cf 172 }
c11e2033
FM
173 /*
174 The URL may be "http://url:port/data" if the method is GET or simply "url:port/" if the method is CONNECT.
175 The following code removes the protocol:// if it is detected and always truncates the URL after the domain name.
176 It will fail if the URL doesn't start with the protocol and contains two consecutive / in the path (i.e.
177 the URL is not normalized).
178 */
06e3cc62 179 str=strchr(url,'/');
c11e2033
FM
180 if (str) {
181 if (str[1]=='/') {
182 str+=2;
183 for (i=0 ; *str && *str!='/' ; i++) url[i]=*str++;
184 url[i]='\0';
185 } else {
186 *str='\0';
187 }
188 }
491b862f
GS
189 }
190
191 sprintf(warea,"%s%s%s",year,mon,day);
192 sprintf(wdata,"%s%s%s",year,mon,day);
193 idata = atoi(wdata);
194
e6414a9d 195 if(SquidguardIgnoreDate) {
28e2bf65 196 if(idata < dfrom || idata > duntil)
491b862f
GS
197 continue;
198 }
199
200 if (strcmp(user,"-") == 0) {
201 strcpy(user,ip);
c11e2033 202 ip[0]='\0';
491b862f 203 }
120d768c 204 fprintf(fp_ou,"%s\t%s%s%s\t%s\t%s\t%s\t%s\n",user,year,mon,day,hour,ip,url,list);
491b862f
GS
205 squidguard_count++;
206 }
207 if (fp_in) fclose(fp_in);
208 return;
209}
210
211
32e71fa4 212void squidguard_log(void)
25697a35 213{
491b862f 214 FILE *fp_ou = NULL, *fp_guard = NULL;
06b39c87 215 char buf[MAXLEN];
25697a35
GS
216 char guard_in[MAXLEN];
217 char guard_ou[MAXLEN];
218 char logdir[MAXLEN];
25697a35 219 char user[MAXLEN];
2240dcea 220 char tmp6[MAXLEN];
5f3cfd1d 221 int y;
456d78a5 222 int cstatus;
5f3cfd1d
FM
223 char *str;
224 char *str2;
25697a35 225
d6e703cc
FM
226 str2 = user;
227
fa6552b0 228 if(SquidGuardConf[0] == '\0' && SquidGuardLogAlternate[0] == '\0')
25697a35
GS
229 return;
230
9c7c6346 231 if (SquidGuardLogAlternate[0] != '\0')
491b862f 232 SquidGuardConf[0]='\0';
25697a35
GS
233
234 sprintf(guard_in,"%s/squidguard.unsort",tmp);
235 sprintf(guard_ou,"%s/squidguard.log",tmp);
25697a35 236 if((fp_ou=fopen(guard_in,"a"))==NULL) {
f76230ca 237 debuga(_("(squidguard) Cannot open log file %s\n"),guard_in);
06b39c87 238 exit(EXIT_FAILURE);
25697a35
GS
239 }
240
e6414a9d 241 if(SquidguardIgnoreDate) {
fa6552b0
FM
242 dfrom=(period.start.tm_year+1900)*10000+(period.start.tm_mon+1)*100+period.start.tm_mday;
243 duntil=(period.end.tm_year+1900)*10000+(period.end.tm_mon+1)*100+period.end.tm_mday;
491b862f 244 }
25697a35 245
120d768c 246 if(SquidGuardConf[0] != 0) {
491b862f 247 if(access(SquidGuardConf, R_OK) != 0) {
10210234 248 debuga(_("Cannot open squidGuard config file: %s\n"),SquidGuardConf);
06b39c87 249 exit(EXIT_FAILURE);
491b862f 250 }
25697a35 251
491b862f 252 if((fp_guard=fopen(SquidGuardConf,"r"))==NULL) {
f76230ca 253 debuga(_("(squidguard) Cannot open log file %s\n"),SquidGuardConf);
06b39c87 254 exit(EXIT_FAILURE);
491b862f 255 }
5f3cfd1d
FM
256
257 logdir[0]=0;
491b862f 258 while(fgets(buf,sizeof(buf),fp_guard)!=NULL) {
9c7c6346 259 fixendofline(buf);
5f3cfd1d 260 if((str=get_param_value("logdir",buf))!=NULL) {
9c7c6346
FM
261 /*
262 We want to tolerate spaces inside the directory name but we must also
263 remove the trailing spaces left by the editor after the directory name.
264 This should not be a problem as nobody use a file name with trailing spaces.
265 */
266 for (y=strlen(str)-1 ; y>=0 && (unsigned char)str[y]<=' ' ; y--);
267 if (y>=sizeof(logdir)-1) y=sizeof(logdir)-2;
268 logdir[y+1] = '\0';
269 while (y>=0) {
270 logdir[y] = str[y];
271 y--;
4bcb77cf 272 }
5f3cfd1d
FM
273 } else if((str=get_param_value("log",buf))!=NULL) {
274 if((str2=get_param_value("anonymous",str))!=NULL)
275 str=str2;
d6e703cc 276
5f3cfd1d
FM
277 /*
278 If logdir is defined, we prepend it to the log file name, otherwise, we assume
279 the log directive provides an absolute file name to the log file. Therefore,
280 we don't need to add an additionnal / at the beginning of the log file name.
281 */
282 y=(logdir[0]) ? sprintf(wentp,"%s/",logdir) : 0;
283 /*
284 Spaces are allowed in the name of the log file. The file name ends at the first #
285 because it is assumed it is an end of line comment. Any space before the # is then
286 removed. Any control character (i.e. a character with a code lower than 32) ends
287 the file name. That includes the terminating zero.
288 */
289 while((unsigned char)*str>=' ' && *str!='#' && y<sizeof(wentp)-1)
290 wentp[y++]=*str++;
291 if(*str=='#') {
292 str--;
293 while(*str==' ' && y>0) {
294 str--;
295 y--;
4bcb77cf 296 }
d6e703cc 297 }
5f3cfd1d 298 wentp[y]=0;
491b862f 299 read_log(wentp,fp_ou);
25697a35 300 }
25697a35 301 }
491b862f 302 } else {
f76230ca 303 strcpy(wentp,SquidGuardLogAlternate);
491b862f
GS
304 read_log(wentp,fp_ou);
305 }
306
307 if (fp_guard) fclose(fp_guard);
308 if (fp_ou) fclose(fp_ou);
309
c274f011
FM
310 if (files_done) {
311 for (y=0; y<nfiles_done; y++)
312 if (files_done[y]) free(files_done[y]);
313 free(files_done);
314 }
315
491b862f 316 if(debug) {
10210234 317 debuga(_("Sorting file: %s\n"),guard_ou);
25697a35
GS
318 }
319
9a2efbd0 320 sprintf(tmp6,"sort -k 1,1 -k 2,2 -k 4,4 \"%s\" -o \"%s\"",guard_in, guard_ou);
456d78a5
FM
321 cstatus=system(tmp6);
322 if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
f76230ca
FM
323 debuga(_("sort command return status %d\n"),WEXITSTATUS(cstatus));
324 debuga(_("sort command: %s\n"),tmp6);
06b39c87 325 exit(EXIT_FAILURE);
456d78a5 326 }
491b862f 327
25697a35
GS
328 unlink(guard_in);
329 return;
330}