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