]> git.ipfire.org Git - thirdparty/sarg.git/blame - redirector.c
Perform the user's ID processing in one function
[thirdparty/sarg.git] / redirector.c
CommitLineData
25697a35 1/*
94ff9470 2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
110ce984 3 * 1998, 2015
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
bca2fdfd
FM
33//! The number of invalid lines found in the redirector report.
34static int RedirectorErrors=0;
cf1a88b9
FM
35//! The file containing the sorted entries.
36static char redirector_sorted[MAXLEN]="";
c6b23f2e
FM
37
38extern char StripUserSuffix[MAX_USER_LEN];
2c058416 39extern int StripSuffixLen;
d6e703cc 40
2f2e57cc 41static void parse_log(FILE *fp_ou,char *buf,int dfrom,int duntil)
491b862f 42{
9bd92830
FM
43 char leks[5], sep[2], res[MAXLEN];
44 char hour[15];
45 char source[128], list[128];
0a6722a1
FM
46 char full_url[MAX_URL_LEN];
47 const char *url;
9bd92830 48 char user[MAX_USER_LEN];
ad4353be 49 char ip[45];
b6b6cb8c 50 char userlabel[MAX_USER_LEN];
9bd92830
FM
51 long long int lmon, lday, lyear;
52 int mon, day, year;
53 int idata=0;
9bd92830
FM
54 bool id_is_ip;
55 struct getwordstruct gwarea;
56 struct getwordstruct gwarea1;
57 struct userinfostruct *uinfo;
bca2fdfd
FM
58
59 getword_start(&gwarea,buf);
60 if(RedirectorLogFormat[0] != '\0') {
61 getword_start(&gwarea1,RedirectorLogFormat);
62 leks[0]='\0';
63 if (getword(leks,sizeof(leks),&gwarea1,'#')<0) {
af961877 64 debuga(__FILE__,__LINE__,_("Invalid \"redirector_log_format\" option in your sarg.conf (too many characters before first tag)\n"));
bca2fdfd
FM
65 exit(EXIT_FAILURE);
66 }
67 year=0;
68 mon=0;
69 day=0;
70 hour[0]='\0';
71 source[0]='\0';
72 list[0]='\0';
73 ip[0]='\0';
74 user[0]='\0';
75 full_url[0]='\0';
76 while(strcmp(leks,"end") != 0) {
77 if (getword(leks,sizeof(leks),&gwarea1,'#')<0) {
af961877 78 debuga(__FILE__,__LINE__,_("Invalid \"redirector_log_format\" option in your sarg.conf (missing # at end of tag)\n"));
bca2fdfd
FM
79 exit(EXIT_FAILURE);
80 }
81 if (getword(sep,sizeof(sep),&gwarea1,'#')<0) {
af961877 82 debuga(__FILE__,__LINE__,_("Invalid \"redirector_log_format\" option in your sarg.conf (too many characters in column separator)\n"));
bca2fdfd
FM
83 exit(EXIT_FAILURE);
84 }
85 if(strcmp(leks,"end") != 0) {
86 if (getword_limit(res,sizeof(res),&gwarea,sep[0])<0) {
af961877 87 debuga(__FILE__,__LINE__,_("Parsing of tag \"%s\" in redirector log \"%s\" returned no result\n"),leks,wentp);
bca2fdfd
FM
88 RedirectorErrors++;
89 return;
90 }
91 if(strcmp(leks,"year") == 0) {
92 year=atoi(res);
93 } else if(strcmp(leks,"mon") == 0) {
94 mon=atoi(res);
95 } else if(strcmp(leks,"day") == 0) {
96 day=atoi(res);
97 } else if(strcmp(leks,"hour") == 0) {
98 if (strlen(res)>=sizeof(hour)) {
af961877 99 debuga(__FILE__,__LINE__,_("Hour string too long in redirector log file \"%s\"\n"),wentp);
bca2fdfd
FM
100 RedirectorErrors++;
101 return;
102 }
103 strcpy(hour,res);
104 } else if(strcmp(leks,"source") == 0) {
105 if (strlen(res)>=sizeof(source)) {
af961877 106 debuga(__FILE__,__LINE__,_("Banning source name too long in redirector log file \"%s\"\n"),wentp);
bca2fdfd
FM
107 RedirectorErrors++;
108 return;
109 }
110 strcpy(source,res);
111 } else if(strcmp(leks,"list") == 0) {
112 if (strlen(res)>=sizeof(list)) {
af961877 113 debuga(__FILE__,__LINE__,_("Banning list name too long in redirector log file \"%s\"\n"),wentp);
bca2fdfd
FM
114 RedirectorErrors++;
115 return;
116 }
117 strcpy(list,res);
118 } else if(strcmp(leks,"ip") == 0) {
119 if (strlen(res)>=sizeof(ip)) {
af961877 120 debuga(__FILE__,__LINE__,_("IP address too long in redirector log file \"%s\"\n"),wentp);
bca2fdfd
FM
121 RedirectorErrors++;
122 return;
123 }
124 strcpy(ip,res);
125 } else if(strcmp(leks,"user") == 0) {
126 if (strlen(res)>=sizeof(user)) {
af961877 127 debuga(__FILE__,__LINE__,_("User ID too long in redirector log file \"%s\"\n"),wentp);
bca2fdfd
FM
128 RedirectorErrors++;
129 return;
130 }
131 strcpy(user,res);
132 } else if(strcmp(leks,"url") == 0) {
d19124ac
FM
133 /*
134 * Don't worry about the url being truncated as we only keep the host name
135 * any way...
136 */
137 safe_strcpy(full_url,res,sizeof(full_url));
bca2fdfd
FM
138 }
139 }
140 }
141 } else {
142 if (getword_atoll(&lyear,&gwarea,'-')<0 || getword_atoll(&lmon,&gwarea,'-')<0 ||
143 getword_atoll(&lday,&gwarea,' ')<0) {
af961877 144 debuga(__FILE__,__LINE__,_("Invalid date in file \"%s\"\n"),wentp);
bca2fdfd
FM
145 RedirectorErrors++;
146 return;
147 }
148 year=(int)lyear;
149 mon=(int)lmon;
150 day=(int)lday;
151 if (getword(hour,sizeof(hour),&gwarea,' ')<0) {
af961877 152 debuga(__FILE__,__LINE__,_("Invalid time in file \"%s\"\n"),wentp);
bca2fdfd
FM
153 RedirectorErrors++;
154 return;
155 }
156 if (getword_skip(MAXLEN,&gwarea,'(')<0 || getword(source,sizeof(source),&gwarea,'/')<0) {
af961877 157 debuga(__FILE__,__LINE__,_("Invalid redirected source in file \"%s\"\n"),wentp);
bca2fdfd
FM
158 RedirectorErrors++;
159 return;
160 }
161 if (getword(list,sizeof(list),&gwarea,'/')<0) {
af961877 162 debuga(__FILE__,__LINE__,_("Invalid redirected list in file \"%s\"\n"),wentp);
bca2fdfd
FM
163 RedirectorErrors++;
164 return;
165 }
166 if (getword_skip(MAXLEN,&gwarea,' ')<0 || getword_limit(full_url,sizeof(full_url),&gwarea,' ')<0) {
af961877 167 debuga(__FILE__,__LINE__,_("Invalid url in file \"%s\"\n"),wentp);
bca2fdfd
FM
168 RedirectorErrors++;
169 return;
170 }
171 if (getword(ip,sizeof(ip),&gwarea,'/')<0) {
af961877 172 debuga(__FILE__,__LINE__,_("Invalid source IP in file \"%s\"\n"),wentp);
bca2fdfd
FM
173 RedirectorErrors++;
174 return;
175 }
176 if (getword_skip(MAXLEN,&gwarea,' ')<0 || getword(user,sizeof(user),&gwarea,' ')<0) {
af961877 177 debuga(__FILE__,__LINE__,_("Invalid user in file \"%s\"\n"),wentp);
bca2fdfd
FM
178 RedirectorErrors++;
179 return;
180 }
181 }
182 url=process_url(full_url,false);
183
184 //sprintf(warea,"%04d%02d%02d",year,mon,day);
185
2f2e57cc 186 if (RedirectorFilterOutDate) {
bca2fdfd
FM
187 idata = year*10000+mon*100+day;
188 if(idata < dfrom || idata > duntil)
189 return;
190 }
191
c6b23f2e
FM
192 if (StripSuffixLen>0)
193 {
194 int x=strlen(user);
195 if (x>StripSuffixLen && strcasecmp(user+(x-StripSuffixLen),StripUserSuffix)==0)
196 user[x-StripSuffixLen]='\0';
197 }
bca2fdfd
FM
198 if(UserIp) {
199 strcpy(user,ip);
200 id_is_ip=true;
201 } else {
202 id_is_ip=false;
81a022d8 203 if (user[0]=='\0' || (user[1]=='\0' && (user[0]=='-' || user[0]==' '))) {
bca2fdfd
FM
204 if(RecordsWithoutUser == RECORDWITHOUTUSER_IP) {
205 strcpy(user,ip);
206 id_is_ip=true;
207 }
208 if(RecordsWithoutUser == RECORDWITHOUTUSER_IGNORE)
209 return;
210 if(RecordsWithoutUser == RECORDWITHOUTUSER_EVERYBODY)
211 strcpy(user,"everybody");
212 }
213 }
214 uinfo=userinfo_find_from_id(user);
215 if (!uinfo) {
aa6ac9f2 216 uinfo=userinfo_create(user,(id_is_ip) ? NULL : ip);
bca2fdfd
FM
217 uinfo->no_report=true;
218 if(Ip2Name && id_is_ip) ip2name(user,sizeof(user));
b6b6cb8c
FM
219 user_find(userlabel,MAX_USER_LEN, user);
220 userinfo_label(uinfo,userlabel);
bca2fdfd
FM
221 }
222 fprintf(fp_ou,"%s\t%04d%02d%02d\t%s\t%s\t%s\t",uinfo->id,year,mon,day,hour,ip,url);
223 if (source[0] && list[0])
224 fprintf(fp_ou,"%s/%s\n",source,list);
225 else if (source[0])
226 fprintf(fp_ou,"%s\n",source);
227 else
228 fprintf(fp_ou,"%s\n",list);
229 redirector_count++;
230}
231
232static void read_log(const char *wentp, FILE *fp_ou,int dfrom,int duntil)
233{
800eafb8 234 FileObject *fp_in = NULL;
bca2fdfd
FM
235 char *buf;
236 int i;
9bd92830 237 longline line;
491b862f 238
9bd92830 239 if(debug) {
af961877 240 debuga(__FILE__,__LINE__,_("Reading redirector log file \"%s\"\n"),wentp);
9bd92830 241 }
d6e703cc 242
9bd92830
FM
243 /* With squidGuard, you can log groups in only one log file.
244 We must parse each log files only one time. Example :
245 dest porn {
246 domainlist porn/domains
247 urllist porn/urls
248 log file1.log
249 }
250 dest aggressive {
251 domainlist aggressive/domains
252 urllist aggressive/urls
253 log file2.log
254 }
255 dest audio-video {
256 domainlist audio-video/domains
257 urllist audio-video/urls
258 log file1.log
259 }
260 */
261 for (i=0; i<nfiles_done; i++)
262 if (!strcmp(wentp, files_done[i])) return;
06e3cc62 263
9bd92830
FM
264 nfiles_done++;
265 files_done = realloc(files_done, nfiles_done*sizeof(char *));
266 if (!files_done) {
af961877 267 debuga(__FILE__,__LINE__,_("Not enough memory to store the name of the new redirector log to be read - %s\n"),strerror(errno));
9bd92830
FM
268 exit(EXIT_FAILURE);
269 }
270 files_done[nfiles_done-1] = strdup(wentp);
271 if (!files_done[nfiles_done-1]) {
af961877 272 debuga(__FILE__,__LINE__,_("Not enough memory to store the name of the new redirector log to be read - %s\n"),strerror(errno));
9bd92830
FM
273 exit(EXIT_FAILURE);
274 }
d6e703cc 275
800eafb8
FM
276 if ((fp_in=FileObject_Open(wentp))==NULL) {
277 debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),wentp,FileObject_GetLastOpenError());
9bd92830
FM
278 exit(EXIT_FAILURE);
279 }
06e3cc62 280
9bd92830 281 if ((line=longline_create())==NULL) {
af961877 282 debuga(__FILE__,__LINE__,_("Not enough memory to read file \"%s\"\n"),wentp);
9bd92830
FM
283 exit(EXIT_FAILURE);
284 }
2d4c92a1 285
9bd92830 286 while ((buf=longline_read(fp_in,line)) != NULL) {
2f2e57cc 287 parse_log(fp_ou,buf,dfrom,duntil);
9bd92830 288 }
800eafb8
FM
289 if (FileObject_Close(fp_in)) {
290 debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),wentp,FileObject_GetLastCloseError());
204781f4
FM
291 exit(EXIT_FAILURE);
292 }
9bd92830
FM
293 longline_destroy(&line);
294 return;
491b862f
GS
295}
296
297
330b1c52 298void redirector_log(void)
25697a35 299{
9bd92830
FM
300 FILE *fp_ou = NULL, *fp_guard = NULL;
301 char buf[MAXLEN];
302 char guard_in[MAXLEN];
9bd92830
FM
303 char logdir[MAXLEN];
304 char user[MAXLEN];
305 char tmp6[MAXLEN];
306 int i;
307 int y;
308 int cstatus;
309 int dfrom, duntil;
310 char *str;
311 char *str2;
25697a35 312
9bd92830 313 str2 = user;
d6e703cc 314
9f93fec3 315 if(SquidGuardConf[0] == '\0' && NRedirectorLogs == 0) {
af961877 316 if (debugz>=LogLevel_Process) debugaz(__FILE__,__LINE__,_("No redirector logs provided to produce that kind of report\n"));
007905af 317 return;
9f93fec3 318 }
25697a35 319
c98d6a0f 320 snprintf(guard_in,sizeof(guard_in),"%s/redirector.int_unsort",tmp);
cf1a88b9 321 if((fp_ou=fopen(guard_in,"w"))==NULL) {
af961877 322 debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),guard_in,strerror(errno));
9bd92830
FM
323 exit(EXIT_FAILURE);
324 }
25697a35 325
9bd92830
FM
326 dfrom=(period.start.tm_year+1900)*10000+(period.start.tm_mon+1)*100+period.start.tm_mday;
327 duntil=(period.end.tm_year+1900)*10000+(period.end.tm_mon+1)*100+period.end.tm_mday;
25697a35 328
9bd92830
FM
329 if (NRedirectorLogs>0) {
330 for (i=0 ; i<NRedirectorLogs ; i++)
331 read_log(RedirectorLogs[i],fp_ou,dfrom,duntil);
332 } else {
333 if(access(SquidGuardConf, R_OK) != 0) {
af961877 334 debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),SquidGuardConf,strerror(errno));
9bd92830
FM
335 exit(EXIT_FAILURE);
336 }
25697a35 337
9bd92830 338 if((fp_guard=fopen(SquidGuardConf,"r"))==NULL) {
af961877 339 debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),SquidGuardConf,strerror(errno));
9bd92830
FM
340 exit(EXIT_FAILURE);
341 }
5f3cfd1d 342
9bd92830
FM
343 logdir[0]=0;
344 while(fgets(buf,sizeof(buf),fp_guard)!=NULL) {
345 fixendofline(buf);
346 if((str=get_param_value("logdir",buf))!=NULL) {
347 /*
348 We want to tolerate spaces inside the directory name but we must also
349 remove the trailing spaces left by the editor after the directory name.
350 This should not be a problem as nobody use a file name with trailing spaces.
351 */
352 for (y=strlen(str)-1 ; y>=0 && (unsigned char)str[y]<=' ' ; y--);
353 if (y>=sizeof(logdir)-1) y=sizeof(logdir)-2;
354 logdir[y+1] = '\0';
355 while (y>=0) {
356 logdir[y] = str[y];
357 y--;
358 }
359 } else if((str=get_param_value("log",buf))!=NULL) {
360 if((str2=get_param_value("anonymous",str))!=NULL)
361 str=str2;
d6e703cc 362
9bd92830
FM
363 /*
364 If logdir is defined, we prepend it to the log file name, otherwise, we assume
365 the log directive provides an absolute file name to the log file. Therefore,
366 we don't need to add an additionnal / at the beginning of the log file name.
367 */
368 y=(logdir[0]) ? sprintf(wentp,"%s/",logdir) : 0;
369 /*
370 Spaces are allowed in the name of the log file. The file name ends at the first #
371 because it is assumed it is an end of line comment. Any space before the # is then
372 removed. Any control character (i.e. a character with a code lower than 32) ends
373 the file name. That includes the terminating zero.
374 */
375 while((unsigned char)*str>=' ' && *str!='#' && y<sizeof(wentp)-1)
376 wentp[y++]=*str++;
377 if(*str=='#') {
378 str--;
379 while(*str==' ' && y>0) {
380 str--;
381 y--;
382 }
383 }
384 wentp[y]=0;
385 read_log(wentp,fp_ou,dfrom,duntil);
386 }
387 }
204781f4 388 if (fclose(fp_guard)==EOF) {
af961877 389 debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),SquidGuardConf,strerror(errno));
204781f4
FM
390 exit(EXIT_FAILURE);
391 }
9bd92830 392 }
491b862f 393
507460ae 394 if (fp_ou && fclose(fp_ou)==EOF) {
af961877 395 debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),guard_in,strerror(errno));
507460ae
FM
396 exit(EXIT_FAILURE);
397 }
491b862f 398
9bd92830
FM
399 if (files_done) {
400 for (y=0; y<nfiles_done; y++)
401 if (files_done[y]) free(files_done[y]);
402 free(files_done);
403 }
c274f011 404
cf1a88b9
FM
405 if (redirector_count) {
406 snprintf(redirector_sorted,sizeof(redirector_sorted),"%s/redirector.int_log",tmp);
407 if(debug) {
af961877 408 debuga(__FILE__,__LINE__,_("Sorting file \"%s\"\n"),redirector_sorted);
cf1a88b9 409 }
25697a35 410
cf1a88b9 411 if (snprintf(tmp6,sizeof(tmp6),"sort -t \"\t\" -k 1,1 -k 2,2 -k 4,4 \"%s\" -o \"%s\"",guard_in, redirector_sorted)>=sizeof(tmp6)) {
af961877 412 debuga(__FILE__,__LINE__,_("Sort command too long when sorting file \"%s\" to \"%s\"\n"),guard_in,redirector_sorted);
cf1a88b9
FM
413 exit(EXIT_FAILURE);
414 }
415 cstatus=system(tmp6);
416 if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
af961877
FM
417 debuga(__FILE__,__LINE__,_("sort command return status %d\n"),WEXITSTATUS(cstatus));
418 debuga(__FILE__,__LINE__,_("sort command: %s\n"),tmp6);
cf1a88b9
FM
419 exit(EXIT_FAILURE);
420 }
9bd92830 421 }
491b862f 422
11767c6a 423 if (!KeepTempLog && unlink(guard_in)) {
af961877 424 debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),guard_in,strerror(errno));
08f9b029
FM
425 exit(EXIT_FAILURE);
426 }
9bd92830 427 return;
25697a35 428}
330b1c52 429
7ae50eee
FM
430static void show_ignored_redirector(FILE *fp_ou,int count)
431{
432 char ignored[80];
433
434 snprintf(ignored,sizeof(ignored),ngettext("%d more redirector entry not shown here&hellip;","%d more redirector entries not shown here&hellip;",count),count);
435 fprintf(fp_ou,"<tr><td class=\"data\"></td><td class=\"data\"></td><td class=\"data\"></td><td class=\"data2 more\">%s</td><td class=\"data\"></td></tr>\n",ignored);
436}
437
330b1c52
FM
438void redirector_report(void)
439{
800eafb8
FM
440 FileObject *fp_in = NULL;
441 FILE *fp_ou = NULL;
330b1c52
FM
442
443 char *buf;
444 char *url;
330b1c52
FM
445 char report[MAXLEN];
446 char ip[45];
447 char rule[255];
448 char oip[45];
449 char user[MAXLEN];
450 char ouser[MAXLEN];
451 char data[15];
452 char hora[15];
453 char ouser2[255];
454 char oname[MAXLEN];
455 bool z=false;
456 int count=0;
457 long long int data2;
458 bool new_user;
459 struct getwordstruct gwarea;
460 const struct userinfostruct *uinfo;
461 struct tm t;
462 longline line;
463
464 ouser[0]='\0';
465 ouser2[0]='\0';
466
330b1c52 467 if(!redirector_count) {
cb59dc47 468 if (debugz>=LogLevel_Process) {
cf1a88b9 469 if (redirector_sorted[0])
af961877 470 debugaz(__FILE__,__LINE__,_("Redirector report not generated because it is empty\n"));
cf1a88b9 471 }
330b1c52
FM
472 return;
473 }
474
475 snprintf(report,sizeof(report),"%s/redirector.html",outdirname);
476
800eafb8
FM
477 if((fp_in=FileObject_Open(redirector_sorted))==NULL) {
478 debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),redirector_sorted,FileObject_GetLastOpenError());
330b1c52
FM
479 exit(EXIT_FAILURE);
480 }
481
482 if((fp_ou=fopen(report,"w"))==NULL) {
af961877 483 debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),report,strerror(errno));
330b1c52
FM
484 exit(EXIT_FAILURE);
485 }
486
487 if ((line=longline_create())==NULL) {
af961877 488 debuga(__FILE__,__LINE__,_("Not enough memory to read file \"%s\"\n"),redirector_sorted);
330b1c52
FM
489 exit(EXIT_FAILURE);
490 }
491
492 write_html_header(fp_ou,(IndexTree == INDEX_TREE_DATE) ? 3 : 1,_("Redirector report"),HTML_JS_NONE);
493 fputs("<tr><td class=\"header_c\">",fp_ou);
494 fprintf(fp_ou,_("Period: %s"),period.html);
495 fputs("</td></tr>\n",fp_ou);
496 fprintf(fp_ou,"<tr><th class=\"header_c\">%s</th></tr>\n",_("Redirector report"));
497 close_html_header(fp_ou);
498
499 fputs("<div class=\"report\"><table cellpadding=1 cellspacing=2>\n",fp_ou);
500 fprintf(fp_ou,"<tr><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th></tr>\n",_("USERID"),_("IP/NAME"),_("DATE/TIME"),_("ACCESSED SITE"),_("RULE"));
501
502 while((buf=longline_read(fp_in,line))!=NULL) {
503 getword_start(&gwarea,buf);
504 if (getword(user,sizeof(user),&gwarea,'\t')<0) {
af961877 505 debuga(__FILE__,__LINE__,_("Invalid user in file \"%s\"\n"),redirector_sorted);
330b1c52
FM
506 exit(EXIT_FAILURE);
507 }
508 if (getword_atoll(&data2,&gwarea,'\t')<0) {
af961877 509 debuga(__FILE__,__LINE__,_("Invalid date in file \"%s\"\n"),redirector_sorted);
330b1c52
FM
510 exit(EXIT_FAILURE);
511 }
512 if (getword(hora,sizeof(hora),&gwarea,'\t')<0) {
af961877 513 debuga(__FILE__,__LINE__,_("Invalid time in file \"%s\"\n"),redirector_sorted);
330b1c52
FM
514 exit(EXIT_FAILURE);
515 }
516 if (getword(ip,sizeof(ip),&gwarea,'\t')<0) {
af961877 517 debuga(__FILE__,__LINE__,_("Invalid IP address in file \"%s\"\n"),redirector_sorted);
330b1c52
FM
518 exit(EXIT_FAILURE);
519 }
520 if (getword_ptr(buf,&url,&gwarea,'\t')<0) {
af961877 521 debuga(__FILE__,__LINE__,_("Invalid url in file \"%s\"\n"),redirector_sorted);
330b1c52
FM
522 exit(EXIT_FAILURE);
523 }
524 if (getword(rule,sizeof(rule),&gwarea,'\n')<0) {
af961877 525 debuga(__FILE__,__LINE__,_("Invalid rule in file \"%s\"\n"),redirector_sorted);
330b1c52
FM
526 exit(EXIT_FAILURE);
527 }
528
529 uinfo=userinfo_find_from_id(user);
530 if (!uinfo) {
af961877 531 debuga(__FILE__,__LINE__,_("Unknown user ID %s in file \"%s\"\n"),user,redirector_sorted);
330b1c52
FM
532 exit(EXIT_FAILURE);
533 }
534
535 computedate(data2/10000,(data2/100)%10,data2%100,&t);
536 strftime(data,sizeof(data),"%x",&t);
537
538 new_user=false;
539 if(!z) {
540 strcpy(ouser,user);
541 strcpy(oip,ip);
542 strcpy(oname,ip);
543 if (Ip2Name && !uinfo->id_is_ip) ip2name(oname,sizeof(oname));
544 z=true;
545 new_user=true;
546 } else {
547 if(strcmp(ouser,user) != 0) {
548 strcpy(ouser,user);
549 new_user=true;
550 }
551 if(strcmp(oip,ip) != 0) {
552 strcpy(oip,ip);
553 strcpy(oname,ip);
554 if (Ip2Name && !uinfo->id_is_ip) ip2name(oname,sizeof(oname));
555 new_user=true;
556 }
557 }
558
559 if(SquidGuardReportLimit) {
560 if(strcmp(ouser2,uinfo->label) == 0) {
561 count++;
562 } else {
7ae50eee
FM
563 if(count>SquidGuardReportLimit && SquidGuardReportLimit>0)
564 show_ignored_redirector(fp_ou,count-SquidGuardReportLimit);
330b1c52
FM
565 count=1;
566 strcpy(ouser2,uinfo->label);
567 }
7ae50eee 568 if(count > SquidGuardReportLimit)
330b1c52
FM
569 continue;
570 }
571
572 if (new_user)
573 fprintf(fp_ou,"<tr><td class=\"data2\">%s</td><td class=\"data2\">%s</td>",uinfo->label,ip);
574 else
575 fputs("<tr><td class=\"data2\"></td><td class=\"data2\"></td>",fp_ou);
576 fprintf(fp_ou,"<td class=\"data2\">%s-%s</td><td class=\"data2\">",data,hora);
6fa33a32 577 output_html_link(fp_ou,url,100);
330b1c52
FM
578 fprintf(fp_ou,"</td><td class=\"data2\">%s</td></tr>\n",rule);
579 }
800eafb8
FM
580 if (FileObject_Close(fp_in)) {
581 debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),redirector_sorted,FileObject_GetLastCloseError());
204781f4
FM
582 exit(EXIT_FAILURE);
583 }
330b1c52
FM
584 longline_destroy(&line);
585
7ae50eee
FM
586 if(count>SquidGuardReportLimit && SquidGuardReportLimit>0)
587 show_ignored_redirector(fp_ou,count-SquidGuardReportLimit);
588
bca2fdfd 589 fputs("</table>\n",fp_ou);
bd43d81f 590
bca2fdfd
FM
591 if (RedirectorErrors>0)
592 {
593 fputs("<div class=\"warn\"><span>",fp_ou);
594 fprintf(fp_ou,ngettext("%d error found in the log file. Some entries may be missing.","%d errors found in the log file. Some entries may be missing.",RedirectorErrors),RedirectorErrors);
595 fputs("</span></div>\n",fp_ou);
596 }
bd43d81f 597
bca2fdfd 598 fputs("</div>\n",fp_ou);
342bd723 599 write_html_trailer(fp_ou);
507460ae 600 if (fclose(fp_ou)==EOF) {
af961877 601 debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),report,strerror(errno));
507460ae
FM
602 exit(EXIT_FAILURE);
603 }
330b1c52 604
cf1a88b9 605 if (!KeepTempLog && unlink(redirector_sorted)) {
af961877 606 debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),redirector_sorted,strerror(errno));
330b1c52
FM
607 exit(EXIT_FAILURE);
608 }
609
610 return;
611}