]> git.ipfire.org Git - thirdparty/sarg.git/blob - exclude.c
Update the translation files
[thirdparty/sarg.git] / exclude.c
1 /*
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
3 * 1998, 2012
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
30 struct hostip4struct
31 {
32 //! The IP address.
33 unsigned long int address;
34 //! The mask to match the address of the URL.
35 unsigned long int mask;
36 };
37
38 struct hostip6struct
39 {
40 //! The IP address.
41 unsigned short int address[8];
42 //! The number of bits in the prefix.
43 int nbits;
44 };
45
46 struct hostnamestruct
47 {
48 //! The URL to match without any leading wildcard.
49 char *url;
50 //! The number of dots in the url if a wildcard is present or -1 if the address is complete (no wildcard)
51 int ndots;
52 };
53
54 static struct hostip4struct *exclude_ip4=NULL;
55 static int num_exclude_ip4=0;
56 static struct hostip6struct *exclude_ip6=NULL;
57 static int num_exclude_ip6=0;
58 static struct hostnamestruct *exclude_name=NULL;
59 static int num_exclude_name=0;
60 static int ip4allocated=0;
61 static int ip6allocated=0;
62 static int nameallocated=0;
63
64 static char *excludeuser=NULL;
65
66 /*!
67 Store a IPv4 address to exclude from the reported URL.
68
69 \param addr The 4 char of the address.
70 \param nbits The number of bits to keep in the prefix.
71 */
72 static void store_exclude_ip4(unsigned char *addr,int nbits)
73 {
74 int i;
75
76 if (num_exclude_ip4>=ip4allocated) {
77 struct hostip4struct *temp;
78
79 ip4allocated+=5;
80 temp=realloc(exclude_ip4,ip4allocated*sizeof(*temp));
81 if (temp==NULL) {
82 debuga(_("Not enough memory to store the exlcluded IP addresses\n"));
83 exit(EXIT_FAILURE);
84 }
85 exclude_ip4=temp;
86 }
87 exclude_ip4[num_exclude_ip4].address=0UL;
88 for (i=0 ; i<4 ; i++)
89 exclude_ip4[num_exclude_ip4].address=(exclude_ip4[num_exclude_ip4].address<<8) | (unsigned char)(addr[i] & 0xFFU);
90 exclude_ip4[num_exclude_ip4].mask=(0xFFFFFFFFUL << (32-nbits));
91 num_exclude_ip4++;
92 }
93
94 /*!
95 Store a IPv6 address to exclude from the reported URL.
96
97 \param addr The 8 short int of the address.
98 \param nbits The number of bits to keep in the prefix.
99 */
100 static void store_exclude_ip6(unsigned short *addr,int nbits)
101 {
102 int i;
103
104 if (num_exclude_ip6>=ip6allocated) {
105 struct hostip6struct *temp;
106
107 ip6allocated+=5;
108 temp=realloc(exclude_ip6,ip6allocated*sizeof(*temp));
109 if (temp==NULL) {
110 debuga(_("Not enough memory to store the exlcluded IP addresses\n"));
111 exit(EXIT_FAILURE);
112 }
113 exclude_ip6=temp;
114 }
115 for (i=0 ; i<8 ; i++)
116 exclude_ip6[num_exclude_ip6].address[i]=addr[i];
117 exclude_ip6[num_exclude_ip6].nbits=nbits;
118 num_exclude_ip6++;
119 }
120
121 /*!
122 Store a host name to exclude from the report.
123
124 \param url The host name to exclude.
125 */
126 static void store_exclude_url(const char *url,const char *next)
127 {
128 int start;
129 int i;
130 int length;
131 int ndots, firstdot;
132 struct hostnamestruct *item;
133
134 start=0;
135 ndots=-1;
136 firstdot=0;
137 length=next-url;
138 for (i=0 ; i<length ; i++)
139 if (url[i]=='*') {
140 firstdot=1;
141 } else if (url[i]=='.') {
142 if (firstdot) {
143 firstdot=0;
144 ndots=1;
145 start=i+1;
146 } else if (ndots>=0)
147 ndots++;
148 }
149 if (start>=length || firstdot) return;
150 if (start>0) {
151 url+=start;
152 length-=start;
153 }
154
155 if (num_exclude_name>=nameallocated) {
156 struct hostnamestruct *temp;
157
158 nameallocated+=5;
159 temp=realloc(exclude_name,nameallocated*sizeof(*temp));
160 if (temp==NULL) {
161 debuga(_("Not enough memory to store the excluded URLs\n"));
162 exit(EXIT_FAILURE);
163 }
164 exclude_name=temp;
165 }
166
167 item=exclude_name+num_exclude_name;
168 num_exclude_name++;
169 item->url=malloc(length+1);
170 if (!item->url) {
171 debuga(_("Not enough memory to store the excluded URLs\n"));
172 exit(EXIT_FAILURE);
173 }
174 safe_strcpy(item->url,url,length+1);
175 item->ndots=(ndots>0) ? ndots : -1;
176 }
177
178 /*!
179 Read the file listing the host to exclude from the report.
180
181 \param hexfile The name of the file.
182 \param debug \c True to print debug information.
183 */
184 void gethexclude(const char *hexfile, int debug)
185 {
186 FILE *fp_ex;
187 char buf[255];
188 int type;
189 const char *name;
190 unsigned char ipv4[4];
191 unsigned short int ipv6[8];
192 int nbits;
193 const char *next;
194
195 if(access(hexfile, R_OK) != 0) {
196 debuga(_("Cannot open exclude_hosts file: %s - %s\n"),hexfile,strerror(errno));
197 exit(EXIT_FAILURE);
198 }
199 if(debug)
200 debuga(_("Loading exclude host file from: %s\n"),hexfile);
201
202 if ((fp_ex = fopen(hexfile, "r")) == NULL) {
203 debuga(_("(gethexclude) Cannot open file %s - %s\n"),hexfile,strerror(errno));
204 exit(EXIT_FAILURE);
205 }
206
207 while(fgets(buf,sizeof(buf),fp_ex)!=NULL){
208 if(buf[0]=='#')
209 continue;
210 fixendofline(buf);
211
212 type=extract_address_mask(buf,&name,ipv4,ipv6,&nbits,&next);
213 if (type<0) {
214 debuga(_("While reading \"%s\"\n"),hexfile);
215 exit(EXIT_FAILURE);
216 }
217
218 if (type==1) {
219 store_exclude_url(name,next);
220 } else if (type==2) {
221 store_exclude_ip4(ipv4,nbits);
222 } else if (type==3) {
223 store_exclude_ip6(ipv6,nbits);
224 }
225 }
226
227 fclose(fp_ex);
228 return;
229 }
230
231 /*!
232 Check if the URL is excluded as per the host exclusion list.
233
234 \param url The URL to check.
235
236 \retval 1 Keep the URL.
237 \retval 0 Exclude the URL.
238 */
239 int vhexclude(const char *url)
240 {
241 int i, j;
242 int length;
243 int type;
244 const char *name;
245 unsigned char ipv4[4];
246 unsigned short int ipv6[8];
247 unsigned long int addr4;
248 int dotpos[50];
249 int ndots;
250
251 type=extract_address_mask(url,&name,ipv4,ipv6,NULL,NULL);
252 if (type==1) {
253 if (exclude_name == NULL) return(1);
254 ndots=0;
255 for (length=0 ; (unsigned char)name[length]>' ' && name[length]!=':' && name[length]!='/' && name[length]!='?' ; length++)
256 if (name[length]=='.') {
257 /*
258 We store the position of each dots of the URL to match it against any
259 wildcard in the excluded list. The size of dotpos is big enough for the most
260 ambitious URL but we have a safety mechanism that shift the positions should there be too
261 many dots in the URL.
262 */
263 if (ndots<sizeof(dotpos)/sizeof(dotpos[0]))
264 dotpos[ndots++]=length+1;
265 else {
266 for (j=1 ; j<ndots ; j++) dotpos[j-1]=dotpos[j];
267 dotpos[ndots-1]=length+1;
268 }
269 }
270 if (length>0) {
271 for (i=0 ; i<num_exclude_name ; i++) {
272 if (exclude_name[i].ndots>0) {
273 const char *wurl=name;
274 int len=length;
275 if (exclude_name[i].ndots<=ndots) {
276 wurl+=dotpos[ndots-exclude_name[i].ndots];
277 len-=dotpos[ndots-exclude_name[i].ndots];
278 }
279 if (strncmp(exclude_name[i].url,wurl,len)==0 && exclude_name[i].url[len]=='\0') return(0);
280 } else {
281 if (strncmp(exclude_name[i].url,url,length)==0 && exclude_name[i].url[length]=='\0') return(0);
282 }
283 }
284 }
285 } else if (type==2) {
286 if (exclude_ip4 == NULL) return(1);
287 addr4=0UL;
288 for (i=0 ; i<4 ; i++) addr4=(addr4 << 8) | ipv4[i];
289 for (i=0 ; i<num_exclude_ip4 ; i++) {
290 if (((exclude_ip4[i].address ^ addr4) & exclude_ip4[i].mask)==0) return(0);
291 }
292 } else if (type==3) {
293 if (exclude_ip6 == NULL) return(1);
294 for (i=0 ; i<num_exclude_ip6 ; i++) {
295 length=exclude_ip6[i].nbits;
296 for (j=length/16-1 ; j>=0 && ipv6[j]==exclude_ip6[i].address[j] ; j--);
297 if (j>=0) return(1);
298 j=length/16;
299 if (j>=8 || length%16==0 || ((ipv6[j] ^ exclude_ip6[i].address[j]) & (0xFFFF<<(length-j*16)))==0)
300 return(0);
301 }
302 }
303 return(1);
304 }
305
306
307 void getuexclude(const char *uexfile, int debug)
308 {
309 FILE *fp_ex;
310 char buf[255];
311 long int nreg=0;
312
313 if(debug)
314 debuga(_("Loading exclude file from: %s\n"),uexfile);
315
316 if ((fp_ex = fopen(uexfile, "r")) == NULL) {
317 debuga(_("(gethexclude) Cannot open file %s - %s\n"),uexfile,strerror(errno));
318 exit(EXIT_FAILURE);
319 }
320
321 if (fseek(fp_ex, 0, SEEK_END)==-1) {
322 debuga(_("Failed to move till the end of the excluded users file %s: %s\n"),uexfile,strerror(errno));
323 exit(EXIT_FAILURE);
324 }
325 nreg = ftell(fp_ex);
326 if (nreg<0) {
327 debuga(_("Cannot get the size of file %s\n"),uexfile);
328 exit(EXIT_FAILURE);
329 }
330 nreg += 11;
331 if (fseek(fp_ex, 0, SEEK_SET)==-1) {
332 debuga(_("Failed to rewind the excluded users file %s: %s\n"),uexfile,strerror(errno));
333 exit(EXIT_FAILURE);
334 }
335
336 if((excludeuser=(char *) malloc(nreg))==NULL){
337 debuga(_("malloc error (%ld bytes required)\n"),nreg);
338 exit(EXIT_FAILURE);
339 }
340
341 bzero(excludeuser,nreg);
342
343 while(fgets(buf,sizeof(buf),fp_ex)!=NULL){
344 if(strchr(buf,'#') != NULL)
345 continue;
346 fixendofline(buf);
347 strcat(excludeuser,buf);
348 strcat(excludeuser," ");
349 }
350
351 strcat(excludeuser,"*END* ");
352
353 fclose(fp_ex);
354
355 return;
356 }
357
358 int vuexclude(const char *user)
359 {
360 const char *wuser;
361 int len;
362
363 if (excludeuser) {
364 len=strlen(user);
365 wuser=excludeuser;
366 while ((wuser=strstr(wuser,user))!=NULL) {
367 if (wuser[len]==' ') return(0);
368 wuser+=len;
369 }
370 }
371
372 return(1);
373 }
374
375 bool is_indexonly(void)
376 {
377 if (excludeuser==NULL) return(false);
378 return(strstr(excludeuser,"indexonly") != NULL);
379 }
380
381 void free_exclude(void)
382 {
383 int i;
384
385 if (exclude_ip4) {
386 free(exclude_ip4);
387 exclude_ip4=NULL;
388 }
389
390 if (exclude_name) {
391 for (i=0 ; i<num_exclude_name ; i++)
392 if (exclude_name[i].url) free(exclude_name[i].url);
393 free(exclude_name);
394 exclude_name=NULL;
395 }
396
397 if(excludeuser) {
398 free(excludeuser);
399 excludeuser=NULL;
400 }
401 }