]> git.ipfire.org Git - thirdparty/sarg.git/blob - squidguard_log.c
Use boolean to enable all the options instead of string compares.
[thirdparty/sarg.git] / squidguard_log.c
1 /*
2 * AUTHOR: Pedro Lineu Orso pedro.orso@gmail.com
3 * 1998, 2008
4 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
5 *
6 * SARG donations:
7 * please look at http://sarg.sourceforge.net/donations.php
8 * ---------------------------------------------------------------------
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
23 *
24 */
25
26 #include "include/conf.h"
27 #include "include/defs.h"
28
29 static char **files_done = NULL;
30 static int nfiles_done = 0;
31
32
33 static void read_log(const char *wentp, FILE *fp_ou)
34 {
35 FILE *fp_in = NULL;
36 char leks[5], sep[2], res[MAXLEN];
37 char mon[10], hour[15];
38 char list[MAXLEN];
39 char wdata[127];
40 int idata=0;
41 int i;
42 char *str;
43 struct getwordstruct gwarea;
44 struct getwordstruct gwarea1;
45
46 if(debug) {
47 getword_start(&gwarea,text[7]);
48 if (getword(urly,sizeof(urly),&gwarea,' ')<0 || getword(href,sizeof(href),&gwarea,' ')<0) {
49 printf("SARG: Maybe you have a broken record or garbage in your %s string.\n",text[7]);
50 exit(1);
51 }
52 debuga("%s squidGuard %s: %s",urly,gwarea.current,wentp);
53 }
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;
75
76 nfiles_done++;
77 files_done = realloc(files_done, nfiles_done*sizeof(char *));
78 if (!files_done) {
79 perror("parse squidGuard - realloc");
80 exit(EXIT_FAILURE);
81 }
82 files_done[nfiles_done-1] = strdup(wentp);
83 if (!files_done[nfiles_done-1]) {
84 perror("parse squidGuard - strdup");
85 exit(EXIT_FAILURE);
86 }
87
88 if ((fp_in=fopen(wentp,"r"))==NULL) {
89 fprintf(stderr, "SARG: (squidguard) %s: %s\n",text[8],wentp);
90 exit(1);
91 }
92
93 while (fgets(buf,sizeof(buf),fp_in) != NULL) {
94 getword_start(&gwarea,buf);
95 if(SquidGuardLogFormat[0] != '\0') {
96 getword_start(&gwarea1,SquidGuardLogFormat);
97 leks[0]='\0';
98 if (getword(leks,sizeof(leks),&gwarea1,'#')<0) {
99 printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wentp);
100 exit(1);
101 }
102 while(strcmp(leks,"end") != 0) {
103 if (getword(leks,sizeof(leks),&gwarea1,'#')<0 || getword(sep,sizeof(sep),&gwarea1,'#')<0) {
104 printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wentp);
105 exit(1);
106 }
107 if(strcmp(leks,"end") != 0) {
108 if (getword(res,sizeof(res),&gwarea,sep[0])<0) {
109 printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wentp);
110 exit(1);
111 }
112 if(strcmp(leks,"year") == 0)
113 strcpy(year,res);
114 else if(strcmp(leks,"year") == 0)
115 strcpy(year,res);
116 else if(strcmp(leks,"mon") == 0)
117 strcpy(mon,res);
118 else if(strcmp(leks,"day") == 0)
119 strcpy(day,res);
120 else if(strcmp(leks,"hour") == 0)
121 strcpy(hour,res);
122 else if(strcmp(leks,"list") == 0)
123 strcpy(list,res);
124 else if(strcmp(leks,"ip") == 0)
125 strcpy(ip,res);
126 else if(strcmp(leks,"user") == 0)
127 strcpy(user,res);
128 else if(strcmp(leks,"url") == 0)
129 strcpy(url,res);
130 }
131 }
132 } else {
133 if (getword(year,sizeof(year),&gwarea,'-')<0 || getword(mon,sizeof(mon),&gwarea,'-')<0 ||
134 getword(day,sizeof(day),&gwarea,' ')<0 || getword(hour,sizeof(hour),&gwarea,' ')<0 ||
135 getword_skip(MAXLEN,&gwarea,'/')<0 || getword(list,sizeof(list),&gwarea,'/')<0 ||
136 getword_skip(MAXLEN,&gwarea,'/')<0 || getword_skip(MAXLEN,&gwarea,'/')<0 ||
137 getword(url,sizeof(url),&gwarea,' ')<0 ||
138 getword(ip,sizeof(ip),&gwarea,'/')<0 || getword_skip(MAXLEN,&gwarea,' ')<0 ||
139 getword(user,sizeof(user),&gwarea,' ')<0) {
140 printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wentp);
141 exit(1);
142 }
143 str=strchr(url,'/');
144 if (str) *str='\0';
145 }
146
147 sprintf(warea,"%s%s%s",year,mon,day);
148 sprintf(wdata,"%s%s%s",year,mon,day);
149 idata = atoi(wdata);
150
151 if(SquidguardIgnoreDate) {
152 if(idata < dfrom || idata > duntil)
153 continue;
154 }
155
156 if (strcmp(user,"-") == 0) {
157 strcpy(user,ip);
158 memset(ip,0,sizeof(ip));
159 }
160 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);
161 squidguard_count++;
162 }
163 if (fp_in) fclose(fp_in);
164 return;
165 }
166
167
168 void squidguard_log(void)
169 {
170 FILE *fp_ou = NULL, *fp_guard = NULL;
171 char guard_in[MAXLEN];
172 char guard_ou[MAXLEN];
173 char logdir[MAXLEN];
174 char year[10], day[10], mon[10];
175 char user[MAXLEN];
176 int y;
177 int cstatus;
178 char *str;
179 char *str2;
180
181 str2 = user;
182
183 if(strlen(SquidGuardConf) < 1 && strlen(SquidGuardLogAlternate) < 1)
184 return;
185
186 if (SquidGuardLogAlternate[0] != '\0')
187 SquidGuardConf[0]='\0';
188
189 sprintf(guard_in,"%s/squidguard.unsort",tmp);
190 sprintf(guard_ou,"%s/squidguard.log",tmp);
191 if((fp_ou=fopen(guard_in,"a"))==NULL) {
192 fprintf(stderr, "SARG: (squidguard) %s: %s\n",text[8],guard_in);
193 exit(1);
194 }
195
196 bzero(day, 3);
197 bzero(mon, 4);
198 bzero(year, 5);
199
200 if(SquidguardIgnoreDate) {
201 if(strcmp(df,"e") == 0) {
202 strncpy(day,period,2);
203 strncpy(mon,period+2,3);
204 strncpy(year,period+5,4);
205 conv_month(mon);
206 sprintf(warea,"%s%s%s",year,mon,day);
207 dfrom=atoi(warea);
208 strncpy(day,period+10,2);
209 strncpy(mon,period+12,3);
210 strncpy(year,period+15,4);
211 conv_month(mon);
212 sprintf(warea,"%s%s%s",year,mon,day);
213 duntil=atoi(warea);
214 } else {
215 strncpy(day,period+7,2);
216 strncpy(mon,period+4,3);
217 strncpy(year,period,4);
218 conv_month(mon);
219 sprintf(warea,"%s%s%s",year,mon,day);
220 dfrom=atoi(warea);
221 strncpy(day,period+17,2);
222 strncpy(mon,period+14,3);
223 strncpy(year,period+10,4);
224 conv_month(mon);
225 sprintf(warea,"%s%s%s",year,mon,day);
226 duntil=atoi(warea);
227 }
228 }
229
230 if(SquidGuardConf[0] != 0) {
231 if(access(SquidGuardConf, R_OK) != 0) {
232 debuga("Cannot open squidGuard config file: %s",SquidGuardConf);
233 exit(1);
234 }
235
236 if((fp_guard=fopen(SquidGuardConf,"r"))==NULL) {
237 fprintf(stderr, "SARG: (squidguard) %s: %s\n",text[8],SquidGuardConf);
238 exit(1);
239 }
240
241 logdir[0]=0;
242 while(fgets(buf,sizeof(buf),fp_guard)!=NULL) {
243 fixendofline(buf);
244 if((str=get_param_value("logdir",buf))!=NULL) {
245 /*
246 We want to tolerate spaces inside the directory name but we must also
247 remove the trailing spaces left by the editor after the directory name.
248 This should not be a problem as nobody use a file name with trailing spaces.
249 */
250 for (y=strlen(str)-1 ; y>=0 && (unsigned char)str[y]<=' ' ; y--);
251 if (y>=sizeof(logdir)-1) y=sizeof(logdir)-2;
252 logdir[y+1] = '\0';
253 while (y>=0) {
254 logdir[y] = str[y];
255 y--;
256 }
257 } else if((str=get_param_value("log",buf))!=NULL) {
258 if((str2=get_param_value("anonymous",str))!=NULL)
259 str=str2;
260
261 /*
262 If logdir is defined, we prepend it to the log file name, otherwise, we assume
263 the log directive provides an absolute file name to the log file. Therefore,
264 we don't need to add an additionnal / at the beginning of the log file name.
265 */
266 y=(logdir[0]) ? sprintf(wentp,"%s/",logdir) : 0;
267 /*
268 Spaces are allowed in the name of the log file. The file name ends at the first #
269 because it is assumed it is an end of line comment. Any space before the # is then
270 removed. Any control character (i.e. a character with a code lower than 32) ends
271 the file name. That includes the terminating zero.
272 */
273 while((unsigned char)*str>=' ' && *str!='#' && y<sizeof(wentp)-1)
274 wentp[y++]=*str++;
275 if(*str=='#') {
276 str--;
277 while(*str==' ' && y>0) {
278 str--;
279 y--;
280 }
281 }
282 wentp[y]=0;
283 read_log(wentp,fp_ou);
284 }
285 }
286 } else {
287 sprintf(wentp,"%s",SquidGuardLogAlternate);
288 read_log(wentp,fp_ou);
289 }
290
291 if (fp_guard) fclose(fp_guard);
292 if (fp_ou) fclose(fp_ou);
293
294 if (files_done) {
295 for (y=0; y<nfiles_done; y++)
296 if (files_done[y]) free(files_done[y]);
297 free(files_done);
298 }
299
300 if(debug) {
301 debuga("%s: %s",text[54],guard_ou);
302 }
303
304 sprintf(tmp6,"sort -k 1,1 -k 2,2 -k 4,4 \"%s\" -o \"%s\"",guard_in, guard_ou);
305 cstatus=system(tmp6);
306 if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
307 fprintf(stderr, "SARG: sort command return status %d\n",WEXITSTATUS(cstatus));
308 fprintf(stderr, "SARG: sort command: %s\n",tmp6);
309 exit(1);
310 }
311
312 unlink(guard_in);
313 return;
314 }