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