redirector.c (sarg-2.3.11) | : | redirector.c (sarg-2.4.0) | ||
---|---|---|---|---|
/* | /* | |||
* SARG Squid Analysis Report Generator http://sarg.sourceforge.net | * SARG Squid Analysis Report Generator http://sarg.sourceforge.net | |||
* 1998, 2013 | * 1998, 2015 | |||
* | * | |||
* SARG donations: | * SARG donations: | |||
* please look at http://sarg.sourceforge.net/donations.php | * please look at http://sarg.sourceforge.net/donations.php | |||
* Support: | * Support: | |||
* http://sourceforge.net/projects/sarg/forums/forum/363374 | * http://sourceforge.net/projects/sarg/forums/forum/363374 | |||
* --------------------------------------------------------------------- | * --------------------------------------------------------------------- | |||
* | * | |||
* This program is free software; you can redistribute it and/or modify | * This program is free software; you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation; either version 2 of the License, or | * the Free Software Foundation; either version 2 of the License, or | |||
skipping to change at line 35 | skipping to change at line 35 | |||
*/ | */ | |||
#include "include/conf.h" | #include "include/conf.h" | |||
#include "include/defs.h" | #include "include/defs.h" | |||
static char **files_done = NULL; | static char **files_done = NULL; | |||
static int nfiles_done = 0; | static int nfiles_done = 0; | |||
//! The number of invalid lines found in the redirector report. | //! The number of invalid lines found in the redirector report. | |||
static int RedirectorErrors=0; | static int RedirectorErrors=0; | |||
//! Name of the sorted report. | //! The file containing the sorted entries. | |||
static char redirector_sorted[MAXLEN]=""; | static char redirector_sorted[MAXLEN]=""; | |||
static void parse_log(FILE *fp_ou,char *buf) | extern char StripUserSuffix[MAX_USER_LEN]; | |||
extern int StripSuffixLen; | ||||
static void parse_log(FILE *fp_ou,char *buf,int dfrom,int duntil,const struct Re | ||||
adLogDataStruct *ReadFilter) | ||||
{ | { | |||
char leks[5], sep[2], res[MAXLEN]; | char leks[5], sep[2], res[MAXLEN]; | |||
char hour[15]; | char hour[15]; | |||
char source[128], list[128]; | char source[128], list[128]; | |||
char full_url[MAX_URL_LEN]; | char full_url[MAX_URL_LEN]; | |||
const char *url; | const char *url; | |||
char user[MAX_USER_LEN]; | char UserBuf[MAX_USER_LEN]; | |||
const char *user; | ||||
char ip[45]; | char ip[45]; | |||
char userlabel[MAX_USER_LEN]; | ||||
char IpBuf[MAX_USER_LEN]; | ||||
long long int lmon, lday, lyear; | long long int lmon, lday, lyear; | |||
int mon, day, year; | int mon, day, year; | |||
int idata=0; | int idata=0; | |||
bool id_is_ip; | bool id_is_ip; | |||
struct getwordstruct gwarea; | struct getwordstruct gwarea; | |||
struct getwordstruct gwarea1; | struct getwordstruct gwarea1; | |||
struct userinfostruct *uinfo; | struct userinfostruct *uinfo; | |||
enum UserProcessError PUser; | ||||
getword_start(&gwarea,buf); | getword_start(&gwarea,buf); | |||
if(RedirectorLogFormat[0] != '\0') { | if (RedirectorLogFormat[0] != '\0') { | |||
getword_start(&gwarea1,RedirectorLogFormat); | getword_start(&gwarea1,RedirectorLogFormat); | |||
leks[0]='\0'; | leks[0]='\0'; | |||
if (getword(leks,sizeof(leks),&gwarea1,'#')<0) { | if (getword(leks,sizeof(leks),&gwarea1,'#')<0) { | |||
debuga(_("Invalid \"redirector_log_format\" option in you r sarg.conf (too many characters before first tag)\n")); | debuga(__FILE__,__LINE__,_("Invalid \"redirector_log_form at\" option in your sarg.conf (too many characters before first tag)\n")); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
year=0; | year=0; | |||
mon=0; | mon=0; | |||
day=0; | day=0; | |||
hour[0]='\0'; | hour[0]='\0'; | |||
source[0]='\0'; | source[0]='\0'; | |||
list[0]='\0'; | list[0]='\0'; | |||
ip[0]='\0'; | ip[0]='\0'; | |||
user[0]='\0'; | UserBuf[0]='\0'; | |||
full_url[0]='\0'; | full_url[0]='\0'; | |||
while(strcmp(leks,"end") != 0) { | while(strcmp(leks,"end") != 0) { | |||
if (getword(leks,sizeof(leks),&gwarea1,'#')<0) { | if (getword(leks,sizeof(leks),&gwarea1,'#')<0) { | |||
debuga(_("Invalid \"redirector_log_format\" optio n in your sarg.conf (missing # at end of tag)\n")); | debuga(__FILE__,__LINE__,_("Invalid \"redirector_ log_format\" option in your sarg.conf (missing # at end of tag)\n")); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (getword(sep,sizeof(sep),&gwarea1,'#')<0) { | if (getword(sep,sizeof(sep),&gwarea1,'#')<0) { | |||
debuga(_("Invalid \"redirector_log_format\" optio n in your sarg.conf (too many characters in column separator)\n")); | debuga(__FILE__,__LINE__,_("Invalid \"redirector_ log_format\" option in your sarg.conf (too many characters in column separator)\ n")); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if(strcmp(leks,"end") != 0) { | if (strcmp(leks,"end") != 0) { | |||
if (getword_limit(res,sizeof(res),&gwarea,sep[0]) <0) { | if (getword_limit(res,sizeof(res),&gwarea,sep[0]) <0) { | |||
debuga(_("Parsing of tag \"%s\" in redire ctor log \"%s\" returned no result\n"),leks,wentp); | debuga(__FILE__,__LINE__,_("Parsing of ta g \"%s\" in redirector log \"%s\" returned no result\n"),leks,wentp); | |||
RedirectorErrors++; | RedirectorErrors++; | |||
return; | return; | |||
} | } | |||
if(strcmp(leks,"year") == 0) { | if (strcmp(leks,"year") == 0) { | |||
year=atoi(res); | year=atoi(res); | |||
} else if(strcmp(leks,"mon") == 0) { | } else if (strcmp(leks,"mon") == 0) { | |||
mon=atoi(res); | mon=atoi(res); | |||
} else if(strcmp(leks,"day") == 0) { | } else if (strcmp(leks,"day") == 0) { | |||
day=atoi(res); | day=atoi(res); | |||
} else if(strcmp(leks,"hour") == 0) { | } else if (strcmp(leks,"hour") == 0) { | |||
if (strlen(res)>=sizeof(hour)) { | if (strlen(res)>=sizeof(hour)) { | |||
debuga(_("Hour string too long in redirector log file %s\n"),wentp); | debuga(__FILE__,__LINE__,_("Hour string too long in redirector log file \"%s\"\n"),wentp); | |||
RedirectorErrors++; | RedirectorErrors++; | |||
return; | return; | |||
} | } | |||
strcpy(hour,res); | strcpy(hour,res); | |||
} else if(strcmp(leks,"source") == 0) { | } else if (strcmp(leks,"source") == 0) { | |||
if (strlen(res)>=sizeof(source)) { | if (strlen(res)>=sizeof(source)) { | |||
debuga(_("Banning source name too long in redirector log file %s\n"),wentp); | debuga(__FILE__,__LINE__,_("Banni ng source name too long in redirector log file \"%s\"\n"),wentp); | |||
RedirectorErrors++; | RedirectorErrors++; | |||
return; | return; | |||
} | } | |||
strcpy(source,res); | strcpy(source,res); | |||
} else if(strcmp(leks,"list") == 0) { | } else if (strcmp(leks,"list") == 0) { | |||
if (strlen(res)>=sizeof(list)) { | if (strlen(res)>=sizeof(list)) { | |||
debuga(_("Banning list name too l ong in redirector log file %s\n"),wentp); | debuga(__FILE__,__LINE__,_("Banni ng list name too long in redirector log file \"%s\"\n"),wentp); | |||
RedirectorErrors++; | RedirectorErrors++; | |||
return; | return; | |||
} | } | |||
strcpy(list,res); | strcpy(list,res); | |||
} else if(strcmp(leks,"ip") == 0) { | } else if (strcmp(leks,"ip") == 0) { | |||
if (strlen(res)>=sizeof(ip)) { | if (strlen(res)>=sizeof(ip)) { | |||
debuga(_("IP address too long in redirector log file %s\n"),wentp); | debuga(__FILE__,__LINE__,_("IP ad dress too long in redirector log file \"%s\"\n"),wentp); | |||
RedirectorErrors++; | RedirectorErrors++; | |||
return; | return; | |||
} | } | |||
strcpy(ip,res); | strcpy(ip,res); | |||
} else if(strcmp(leks,"user") == 0) { | } else if (strcmp(leks,"user") == 0) { | |||
if (strlen(res)>=sizeof(user)) { | if (strlen(res)>=sizeof(UserBuf)) { | |||
debuga(_("User ID too long in red | debuga(__FILE__,__LINE__,_("User | |||
irector log file \"%s\"\n"),wentp); | ID too long in redirector log file \"%s\"\n"),wentp); | |||
RedirectorErrors++; | RedirectorErrors++; | |||
return; | return; | |||
} | } | |||
strcpy(user,res); | strcpy(UserBuf,res); | |||
} else if(strcmp(leks,"url") == 0) { | } else if (strcmp(leks,"url") == 0) { | |||
/* | /* | |||
* Don't worry about the url being trunca ted as we only keep the host name | * Don't worry about the url being trunca ted as we only keep the host name | |||
* any way... | * any way... | |||
*/ | */ | |||
safe_strcpy(full_url,res,sizeof(full_url) ); | safe_strcpy(full_url,res,sizeof(full_url) ); | |||
} | } | |||
} | } | |||
} | } | |||
} else { | } else { | |||
if (getword_atoll(&lyear,&gwarea,'-')<0 || getword_atoll(&lmon,&g warea,'-')<0 || | if (getword_atoll(&lyear,&gwarea,'-')<0 || getword_atoll(&lmon,&g warea,'-')<0 || | |||
getword_atoll(&lday,&gwarea,' ')<0) { | getword_atoll(&lday,&gwarea,' ')<0) { | |||
debuga(_("Invalid date in file \"%s\"\n"),wentp); | debuga(__FILE__,__LINE__,_("Invalid date in file \"%s\"\n "),wentp); | |||
RedirectorErrors++; | RedirectorErrors++; | |||
return; | return; | |||
} | } | |||
year=(int)lyear; | year=(int)lyear; | |||
mon=(int)lmon; | mon=(int)lmon; | |||
day=(int)lday; | day=(int)lday; | |||
if (getword(hour,sizeof(hour),&gwarea,' ')<0) { | if (getword(hour,sizeof(hour),&gwarea,' ')<0) { | |||
debuga(_("Invalid time in file \"%s\"\n"),wentp); | debuga(__FILE__,__LINE__,_("Invalid time in file \"%s\"\n "),wentp); | |||
RedirectorErrors++; | RedirectorErrors++; | |||
return; | return; | |||
} | } | |||
if (getword_skip(MAXLEN,&gwarea,'(')<0 || getword(source,sizeof(s ource),&gwarea,'/')<0) { | if (getword_skip(MAXLEN,&gwarea,'(')<0 || getword(source,sizeof(s ource),&gwarea,'/')<0) { | |||
debuga(_("Invalid redirected source in file %s\n"),wentp) ; | debuga(__FILE__,__LINE__,_("Invalid redirected source in file \"%s\"\n"),wentp); | |||
RedirectorErrors++; | RedirectorErrors++; | |||
return; | return; | |||
} | } | |||
if (getword(list,sizeof(list),&gwarea,'/')<0) { | if (getword(list,sizeof(list),&gwarea,'/')<0) { | |||
debuga(_("Invalid redirected list in file \"%s\"\n"),went p); | debuga(__FILE__,__LINE__,_("Invalid redirected list in fi le \"%s\"\n"),wentp); | |||
RedirectorErrors++; | RedirectorErrors++; | |||
return; | return; | |||
} | } | |||
if (getword_skip(MAXLEN,&gwarea,' ')<0 || getword_limit(full_url, sizeof(full_url),&gwarea,' ')<0) { | if (getword_skip(MAXLEN,&gwarea,' ')<0 || getword_limit(full_url, sizeof(full_url),&gwarea,' ')<0) { | |||
debuga(_("Invalid url in file \"%s\"\n"),wentp); | debuga(__FILE__,__LINE__,_("Invalid url in file \"%s\"\n" ),wentp); | |||
RedirectorErrors++; | RedirectorErrors++; | |||
return; | return; | |||
} | } | |||
if (getword(ip,sizeof(ip),&gwarea,'/')<0) { | if (getword(ip,sizeof(ip),&gwarea,'/')<0) { | |||
debuga(_("Invalid source IP in file \"%s\"\n"),wentp); | debuga(__FILE__,__LINE__,_("Invalid source IP in file \"% s\"\n"),wentp); | |||
RedirectorErrors++; | RedirectorErrors++; | |||
return; | return; | |||
} | } | |||
if (getword_skip(MAXLEN,&gwarea,' ')<0 || getword(user,sizeof(use | if (getword_skip(MAXLEN,&gwarea,' ')<0 || getword(UserBuf,sizeof( | |||
r),&gwarea,' ')<0) { | UserBuf),&gwarea,' ')<0) { | |||
debuga(_("Invalid user in file \"%s\"\n"),wentp); | debuga(__FILE__,__LINE__,_("Invalid user in file \"%s\"\n | |||
"),wentp); | ||||
RedirectorErrors++; | RedirectorErrors++; | |||
return; | return; | |||
} | } | |||
} | } | |||
url=process_url(full_url,false); | url=process_url(full_url,false); | |||
//sprintf(warea,"%04d%02d%02d",year,mon,day); | //sprintf(warea,"%04d%02d%02d",year,mon,day); | |||
if(RedirectorFilterOutDate) { | if (RedirectorFilterOutDate) | |||
{ | ||||
idata = year*10000+mon*100+day; | idata = year*10000+mon*100+day; | |||
if(idata < dfrom || idata > duntil) | if (idata<dfrom || idata>duntil) | |||
return; | return; | |||
} | if (ReadFilter->StartTime>=0 && ReadFilter->EndTime>=0) | |||
{ | ||||
if(UserIp) { | int h,m,hmr; | |||
strcpy(user,ip); | ||||
id_is_ip=true; | if (sscanf(hour,"%d:%d",&h,&m)!=2) | |||
} else { | { | |||
id_is_ip=false; | debuga(__FILE__,__LINE__,_("Can't parse time \"%s | |||
if(strcmp(user,"-") == 0 || strcmp(user," ") == 0 || strcmp(user, | \" found in \"%s\"\n"),hour,wentp); | |||
"") == 0) { | RedirectorErrors++; | |||
if(RecordsWithoutUser == RECORDWITHOUTUSER_IP) { | return; | |||
strcpy(user,ip); | ||||
id_is_ip=true; | ||||
} | } | |||
if(RecordsWithoutUser == RECORDWITHOUTUSER_IGNORE) | hmr=h*100+m; | |||
if (hmr<ReadFilter->StartTime || hmr>=ReadFilter->EndTime | ||||
) | ||||
return; | return; | |||
if(RecordsWithoutUser == RECORDWITHOUTUSER_EVERYBODY) | ||||
strcpy(user,"everybody"); | ||||
} | } | |||
} | } | |||
user=UserBuf; | ||||
PUser=process_user(&user,ip,&id_is_ip); | ||||
if (PUser!=USERERR_NoError) return; | ||||
uinfo=userinfo_find_from_id(user); | uinfo=userinfo_find_from_id(user); | |||
if (!uinfo) { | if (!uinfo) { | |||
uinfo=userinfo_create(user,ip); | uinfo=userinfo_create(user,(id_is_ip) ? NULL : ip); | |||
uinfo->id_is_ip=id_is_ip; | ||||
uinfo->no_report=true; | uinfo->no_report=true; | |||
if(Ip2Name && id_is_ip) ip2name(user,sizeof(user)); | if (Ip2Name && id_is_ip) { | |||
user_find(uinfo->label,MAX_USER_LEN, user); | strcpy(IpBuf,user); | |||
ip2name(IpBuf,sizeof(IpBuf)); | ||||
user=IpBuf; | ||||
} | ||||
user_find(userlabel,MAX_USER_LEN, user); | ||||
userinfo_label(uinfo,userlabel); | ||||
} | } | |||
fprintf(fp_ou,"%s\t%04d%02d%02d\t%s\t%s\t%s\t",uinfo->id,year,mon,day,hou r,ip,url); | fprintf(fp_ou,"%s\t%04d%02d%02d\t%s\t%s\t%s\t",uinfo->id,year,mon,day,hou r,ip,url); | |||
if (source[0] && list[0]) | if (source[0] && list[0]) | |||
fprintf(fp_ou,"%s/%s\n",source,list); | fprintf(fp_ou,"%s/%s\n",source,list); | |||
else if (source[0]) | else if (source[0]) | |||
fprintf(fp_ou,"%s\n",source); | fprintf(fp_ou,"%s\n",source); | |||
else | else | |||
fprintf(fp_ou,"%s\n",list); | fprintf(fp_ou,"%s\n",list); | |||
redirector_count++; | redirector_count++; | |||
} | } | |||
static void read_log(const char *wentp, FILE *fp_ou,int dfrom,int duntil) | static void read_log(const char *wentp, FILE *fp_ou,int dfrom,int duntil,const s truct ReadLogDataStruct *ReadFilter) | |||
{ | { | |||
FILE *fp_in = NULL; | FileObject *fp_in = NULL; | |||
char *buf; | char *buf; | |||
int i; | int i; | |||
longline line; | longline line; | |||
if(debug) { | if (debug) { | |||
debuga(_("Reading redirector log file \"%s\"\n"),wentp); | debuga(__FILE__,__LINE__,_("Reading redirector log file \"%s\"\n" | |||
),wentp); | ||||
} | } | |||
/* With squidGuard, you can log groups in only one log file. | /* With squidGuard, you can log groups in only one log file. | |||
We must parse each log files only one time. Example : | We must parse each log files only one time. Example : | |||
dest porn { | dest porn { | |||
domainlist porn/domains | domainlist porn/domains | |||
urllist porn/urls | urllist porn/urls | |||
log file1.log | log file1.log | |||
} | } | |||
dest aggressive { | dest aggressive { | |||
skipping to change at line 257 | skipping to change at line 271 | |||
urllist audio-video/urls | urllist audio-video/urls | |||
log file1.log | log file1.log | |||
} | } | |||
*/ | */ | |||
for (i=0; i<nfiles_done; i++) | for (i=0; i<nfiles_done; i++) | |||
if (!strcmp(wentp, files_done[i])) return; | if (!strcmp(wentp, files_done[i])) return; | |||
nfiles_done++; | nfiles_done++; | |||
files_done = realloc(files_done, nfiles_done*sizeof(char *)); | files_done = realloc(files_done, nfiles_done*sizeof(char *)); | |||
if (!files_done) { | if (!files_done) { | |||
debuga(_("Not enough memory to store the name of the new redirect or log to be read - %s\n"),strerror(errno)); | debuga(__FILE__,__LINE__,_("Not enough memory to store the name o f the new redirector log to be read - %s\n"),strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
files_done[nfiles_done-1] = strdup(wentp); | files_done[nfiles_done-1] = strdup(wentp); | |||
if (!files_done[nfiles_done-1]) { | if (!files_done[nfiles_done-1]) { | |||
debuga(_("Not enough memory to store the name of the new redirect or log to be read - %s\n"),strerror(errno)); | debuga(__FILE__,__LINE__,_("Not enough memory to store the name o f the new redirector log to be read - %s\n"),strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if ((fp_in=fopen(wentp,"r"))==NULL) { | if ((fp_in=decomp(wentp))==NULL) { | |||
debugapos("squidguard",_("Cannot open file \"%s\": %s\n"),wentp,s | debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),wentp | |||
trerror(errno)); | ,FileObject_GetLastOpenError()); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if ((line=longline_create())==NULL) { | if ((line=longline_create())==NULL) { | |||
debuga(_("Not enough memory to read file \"%s\"\n"),wentp); | debuga(__FILE__,__LINE__,_("Not enough memory to read file \"%s\" \n"),wentp); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
while ((buf=longline_read(fp_in,line)) != NULL) { | while ((buf=longline_read(fp_in,line)) != NULL) { | |||
parse_log(fp_ou,buf); | parse_log(fp_ou,buf,dfrom,duntil,ReadFilter); | |||
} | ||||
if (FileObject_Close(fp_in)) { | ||||
debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),wentp,Fi | ||||
leObject_GetLastCloseError()); | ||||
exit(EXIT_FAILURE); | ||||
} | } | |||
fclose(fp_in); | ||||
longline_destroy(&line); | longline_destroy(&line); | |||
return; | return; | |||
} | } | |||
void redirector_log(void) | void redirector_log(const struct ReadLogDataStruct *ReadFilter) | |||
{ | { | |||
FILE *fp_ou = NULL, *fp_guard = NULL; | FILE *fp_ou = NULL, *fp_guard = NULL; | |||
char buf[MAXLEN]; | char buf[MAXLEN]; | |||
char guard_in[MAXLEN]; | char guard_in[MAXLEN]; | |||
char logdir[MAXLEN]; | char logdir[MAXLEN]; | |||
char user[MAXLEN]; | char user[MAXLEN]; | |||
char tmp6[MAXLEN]; | char tmp6[MAXLEN]; | |||
int i; | int i; | |||
int y; | int y; | |||
int cstatus; | int cstatus; | |||
int dfrom, duntil; | int dfrom, duntil; | |||
char *str; | char *str; | |||
char *str2; | char *str2; | |||
str2 = user; | str2 = user; | |||
if(SquidGuardConf[0] == '\0' && NRedirectorLogs == 0) { | if (SquidGuardConf[0] == '\0' && NRedirectorLogs == 0) { | |||
if (debugz) debugaz(_("No redirector logs provided to produce tha | if (debugz>=LogLevel_Process) debugaz(__FILE__,__LINE__,_("No red | |||
t kind of report\n")); | irector logs provided to produce that kind of report\n")); | |||
return; | return; | |||
} | } | |||
snprintf(guard_in,sizeof(guard_in),"%s/redirector.int_unsort",tmp); | format_path(__FILE__, __LINE__, guard_in, sizeof(guard_in), "%s/redirecto | |||
snprintf(redirector_sorted,sizeof(redirector_sorted),"%s/redirector.int_l | r.int_unsort", tmp); | |||
og",tmp); | if ((fp_ou=fopen(guard_in,"w"))==NULL) { | |||
if((fp_ou=fopen(guard_in,"a"))==NULL) { | debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),guard | |||
debugapos("squidguard",_("Cannot open file \"%s\": %s\n"),guard_i | _in,strerror(errno)); | |||
n,strerror(errno)); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
dfrom=(period.start.tm_year+1900)*10000+(period.start.tm_mon+1)*100+perio | getperiod_torange(&period,&dfrom,&duntil); | |||
d.start.tm_mday; | ||||
duntil=(period.end.tm_year+1900)*10000+(period.end.tm_mon+1)*100+period.e | ||||
nd.tm_mday; | ||||
if (NRedirectorLogs>0) { | if (NRedirectorLogs>0) { | |||
for (i=0 ; i<NRedirectorLogs ; i++) | for (i=0 ; i<NRedirectorLogs ; i++) | |||
read_log(RedirectorLogs[i],fp_ou,dfrom,duntil); | read_log(RedirectorLogs[i],fp_ou,dfrom,duntil,ReadFilter) ; | |||
} else { | } else { | |||
if(access(SquidGuardConf, R_OK) != 0) { | if (access(SquidGuardConf, R_OK) != 0) { | |||
debuga(_("Cannot open squidGuard config file: %s\n"),Squi | debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n | |||
dGuardConf); | "),SquidGuardConf,strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if((fp_guard=fopen(SquidGuardConf,"r"))==NULL) { | if ((fp_guard=fopen(SquidGuardConf,"r"))==NULL) { | |||
debugapos("squidguard",_("Cannot open file \"%s\": %s\n") | debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n | |||
,SquidGuardConf,strerror(errno)); | "),SquidGuardConf,strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
logdir[0]=0; | logdir[0]=0; | |||
while(fgets(buf,sizeof(buf),fp_guard)!=NULL) { | while(fgets(buf,sizeof(buf),fp_guard)!=NULL) { | |||
fixendofline(buf); | fixendofline(buf); | |||
if((str=get_param_value("logdir",buf))!=NULL) { | if ((str=get_param_value("logdir",buf))!=NULL) { | |||
/* | /* | |||
We want to tolerate spaces inside the directory n ame but we must also | We want to tolerate spaces inside the directory n ame but we must also | |||
remove the trailing spaces left by the editor aft er the directory name. | remove the trailing spaces left by the editor aft er the directory name. | |||
This should not be a problem as nobody use a file name with trailing spaces. | This should not be a problem as nobody use a file name with trailing spaces. | |||
*/ | */ | |||
for (y=strlen(str)-1 ; y>=0 && (unsigned char)str [y]<=' ' ; y--); | for (y=strlen(str)-1 ; y>=0 && (unsigned char)str [y]<=' ' ; y--); | |||
if (y>=sizeof(logdir)-1) y=sizeof(logdir)-2; | if (y>=sizeof(logdir)-1) y=sizeof(logdir)-2; | |||
logdir[y+1] = '\0'; | logdir[y+1] = '\0'; | |||
while (y>=0) { | while (y>=0) { | |||
logdir[y] = str[y]; | logdir[y] = str[y]; | |||
y--; | y--; | |||
} | } | |||
} else if((str=get_param_value("log",buf))!=NULL) { | } else if ((str=get_param_value("log",buf))!=NULL) { | |||
if((str2=get_param_value("anonymous",str))!=NULL) | if ((str2=get_param_value("anonymous",str))!=NULL | |||
) | ||||
str=str2; | str=str2; | |||
/* | /* | |||
If logdir is defined, we prepend it to the log fi le name, otherwise, we assume | If logdir is defined, we prepend it to the log fi le name, otherwise, we assume | |||
the log directive provides an absolute file name to the log file. Therefore, | the log directive provides an absolute file name to the log file. Therefore, | |||
we don't need to add an additionnal / at the begi nning of the log file name. | we don't need to add an additionnal / at the begi nning of the log file name. | |||
*/ | */ | |||
y=(logdir[0]) ? sprintf(wentp,"%s/",logdir) : 0; | y=(logdir[0]) ? format_path(__FILE__, __LINE__, w entp, sizeof(wentp),"%s/", logdir) : 0; | |||
/* | /* | |||
Spaces are allowed in the name of the log file. T he file name ends at the first # | Spaces are allowed in the name of the log file. T he file name ends at the first # | |||
because it is assumed it is an end of line commen t. Any space before the # is then | because it is assumed it is an end of line commen t. Any space before the # is then | |||
removed. Any control character (i.e. a character with a code lower than 32) ends | removed. Any control character (i.e. a character with a code lower than 32) ends | |||
the file name. That includes the terminating zero . | the file name. That includes the terminating zero . | |||
*/ | */ | |||
while((unsigned char)*str>=' ' && *str!='#' && y< sizeof(wentp)-1) | while((unsigned char)*str>=' ' && *str!='#' && y< sizeof(wentp)-1) | |||
wentp[y++]=*str++; | wentp[y++]=*str++; | |||
if(*str=='#') { | if (*str=='#') { | |||
str--; | str--; | |||
while(*str==' ' && y>0) { | while(*str==' ' && y>0) { | |||
str--; | str--; | |||
y--; | y--; | |||
} | } | |||
} | } | |||
wentp[y]=0; | wentp[y]=0; | |||
read_log(wentp,fp_ou,dfrom,duntil); | read_log(wentp,fp_ou,dfrom,duntil,ReadFilter); | |||
} | } | |||
} | } | |||
if (fclose(fp_guard)==EOF) { | ||||
debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"), | ||||
SquidGuardConf,strerror(errno)); | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
} | } | |||
if (fp_guard) fclose(fp_guard); | if (fp_ou && fclose(fp_ou)==EOF) { | |||
if (fp_ou) fclose(fp_ou); | debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),guard_i | |||
n,strerror(errno)); | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
if (files_done) { | if (files_done) { | |||
for (y=0; y<nfiles_done; y++) | for (y=0; y<nfiles_done; y++) | |||
if (files_done[y]) free(files_done[y]); | if (files_done[y]) free(files_done[y]); | |||
free(files_done); | free(files_done); | |||
} | } | |||
if(debug) { | if (redirector_count) { | |||
debuga(_("Sorting file \"%s\"\n"),redirector_sorted); | format_path(__FILE__,__LINE__, redirector_sorted, sizeof(redirect | |||
} | or_sorted), "%s/redirector.int_log", tmp); | |||
if (debug) { | ||||
debuga(__FILE__,__LINE__,_("Sorting file \"%s\"\n"),redir | ||||
ector_sorted); | ||||
} | ||||
if (snprintf(tmp6,sizeof(tmp6),"sort -t \"\t\" -k 1,1 -k 2,2 -k 4,4 \"%s\ | if (snprintf(tmp6,sizeof(tmp6),"sort -t \"\t\" -k 1,1 -k 2,2 -k 4 | |||
" -o \"%s\"",guard_in, redirector_sorted)>=sizeof(tmp6)) { | ,4 \"%s\" -o \"%s\"",guard_in, redirector_sorted)>=sizeof(tmp6)) { | |||
debuga(_("Command too long: ")); | debuga(__FILE__,__LINE__,_("Sort command too long when so | |||
debuga_more("sort -t \"\t\" -k 1,1 -k 2,2 -k 4,4 \"%s\" -o \"%s\" | rting file \"%s\" to \"%s\"\n"),guard_in,redirector_sorted); | |||
",guard_in, redirector_sorted); | exit(EXIT_FAILURE); | |||
exit(EXIT_FAILURE); | } | |||
} | cstatus=system(tmp6); | |||
cstatus=system(tmp6); | if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) { | |||
if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) { | debuga(__FILE__,__LINE__,_("sort command return status %d | |||
debuga(_("sort command return status %d\n"),WEXITSTATUS(cstatus)) | \n"),WEXITSTATUS(cstatus)); | |||
; | debuga(__FILE__,__LINE__,_("sort command: %s\n"),tmp6); | |||
debuga(_("sort command: %s\n"),tmp6); | exit(EXIT_FAILURE); | |||
exit(EXIT_FAILURE); | } | |||
} | } | |||
if (!KeepTempLog && unlink(guard_in)) { | if (!KeepTempLog && unlink(guard_in)) { | |||
debuga(_("Cannot delete \"%s\": %s\n"),guard_in,strerror(errno)); | debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),guard_in ,strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
return; | return; | |||
} | } | |||
static void show_ignored_redirector(FILE *fp_ou,int count) | static void show_ignored_redirector(FILE *fp_ou,int count) | |||
{ | { | |||
char ignored[80]; | char ignored[80]; | |||
snprintf(ignored,sizeof(ignored),ngettext("%d more redirector entry not s hown here…","%d more redirector entries not shown here…",count),co unt); | snprintf(ignored,sizeof(ignored),ngettext("%d more redirector entry not s hown here…","%d more redirector entries not shown here…",count),co unt); | |||
fprintf(fp_ou,"<tr><td class=\"data\"></td><td class=\"data\"></td><td cl ass=\"data\"></td><td class=\"data2 more\">%s</td><td class=\"data\"></td></tr>\ n",ignored); | fprintf(fp_ou,"<tr><td class=\"data\"></td><td class=\"data\"></td><td cl ass=\"data\"></td><td class=\"data2 more\">%s</td><td class=\"data\"></td></tr>\ n",ignored); | |||
} | } | |||
void redirector_report(void) | void redirector_report(void) | |||
{ | { | |||
FILE *fp_in = NULL, *fp_ou = NULL; | FileObject *fp_in = NULL; | |||
FILE *fp_ou = NULL; | ||||
char *buf; | char *buf; | |||
char *url; | char *url; | |||
char report[MAXLEN]; | char report[MAXLEN]; | |||
char ip[45]; | char ip[45]; | |||
char rule[255]; | char rule[255]; | |||
char oip[45]; | char oip[45]; | |||
char user[MAXLEN]; | char user[MAXLEN]; | |||
char ouser[MAXLEN]; | char ouser[MAXLEN]; | |||
char data[15]; | char data[15]; | |||
skipping to change at line 445 | skipping to change at line 469 | |||
long long int data2; | long long int data2; | |||
bool new_user; | bool new_user; | |||
struct getwordstruct gwarea; | struct getwordstruct gwarea; | |||
const struct userinfostruct *uinfo; | const struct userinfostruct *uinfo; | |||
struct tm t; | struct tm t; | |||
longline line; | longline line; | |||
ouser[0]='\0'; | ouser[0]='\0'; | |||
ouser2[0]='\0'; | ouser2[0]='\0'; | |||
if(!redirector_count) { | if (!redirector_count) { | |||
if (!KeepTempLog && redirector_sorted[0]!='\0' && unlink(redirect | if (debugz>=LogLevel_Process) { | |||
or_sorted)) | if (redirector_sorted[0]) | |||
debuga(_("Cannot delete \"%s\": %s\n"),redirector_sorted, | debugaz(__FILE__,__LINE__,_("Redirector report no | |||
strerror(errno)); | t generated because it is empty\n")); | |||
if (debugz) debugaz(_("Redirector report not generated because it | } | |||
is empty\n")); | ||||
return; | return; | |||
} | } | |||
snprintf(report,sizeof(report),"%s/redirector.html",outdirname); | format_path(__FILE__,__LINE__, report, sizeof(report), "%s/redirector.htm l", outdirname); | |||
if((fp_in=fopen(redirector_sorted,"r"))==NULL) { | if ((fp_in=FileObject_Open(redirector_sorted))==NULL) { | |||
debugapos("squidguard",_("Cannot open file \"%s\": %s\n"),redirec | debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),redir | |||
tor_sorted,strerror(errno)); | ector_sorted,FileObject_GetLastOpenError()); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if((fp_ou=fopen(report,"w"))==NULL) { | if ((fp_ou=fopen(report,"w"))==NULL) { | |||
debugapos("squidguard",_("Cannot open file \"%s\": %s\n"),report, | debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),repor | |||
strerror(errno)); | t,strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if ((line=longline_create())==NULL) { | if ((line=longline_create())==NULL) { | |||
debuga(_("Not enough memory to read file \"%s\"\n"),redirector_so rted); | debuga(__FILE__,__LINE__,_("Not enough memory to read file \"%s\" \n"),redirector_sorted); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
write_html_header(fp_ou,(IndexTree == INDEX_TREE_DATE) ? 3 : 1,_("Redirec tor report"),HTML_JS_NONE); | write_html_header(fp_ou,(IndexTree == INDEX_TREE_DATE) ? 3 : 1,_("Redirec tor report"),HTML_JS_NONE); | |||
fputs("<tr><td class=\"header_c\">",fp_ou); | fputs("<tr><td class=\"header_c\">",fp_ou); | |||
fprintf(fp_ou,_("Period: %s"),period.html); | fprintf(fp_ou,_("Period: %s"),period.html); | |||
fputs("</td></tr>\n",fp_ou); | fputs("</td></tr>\n",fp_ou); | |||
fprintf(fp_ou,"<tr><th class=\"header_c\">%s</th></tr>\n",_("Redirector r eport")); | fprintf(fp_ou,"<tr><th class=\"header_c\">%s</th></tr>\n",_("Redirector r eport")); | |||
close_html_header(fp_ou); | close_html_header(fp_ou); | |||
fputs("<div class=\"report\"><table cellpadding=1 cellspacing=2>\n",fp_ou ); | fputs("<div class=\"report\"><table cellpadding=1 cellspacing=2>\n",fp_ou ); | |||
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=\"he ader_l\">%s</th></tr>\n",_("USERID"),_("IP/NAME"),_("DATE/TIME"),_("ACCESSED SIT E"),_("RULE")); | 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=\"he ader_l\">%s</th></tr>\n",_("USERID"),_("IP/NAME"),_("DATE/TIME"),_("ACCESSED SIT E"),_("RULE")); | |||
while((buf=longline_read(fp_in,line))!=NULL) { | while((buf=longline_read(fp_in,line))!=NULL) { | |||
getword_start(&gwarea,buf); | getword_start(&gwarea,buf); | |||
if (getword(user,sizeof(user),&gwarea,'\t')<0) { | if (getword(user,sizeof(user),&gwarea,'\t')<0) { | |||
debuga(_("Invalid user found in file \"%s\"\n"),redirecto r_sorted); | debuga(__FILE__,__LINE__,_("Invalid user in file \"%s\"\n "),redirector_sorted); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (getword_atoll(&data2,&gwarea,'\t')<0) { | if (getword_atoll(&data2,&gwarea,'\t')<0) { | |||
debuga(_("Invalid date in file \"%s\"\n"),redirector_sort ed); | debuga(__FILE__,__LINE__,_("Invalid date in file \"%s\"\n "),redirector_sorted); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (getword(hora,sizeof(hora),&gwarea,'\t')<0) { | if (getword(hora,sizeof(hora),&gwarea,'\t')<0) { | |||
debuga(_("Invalid time in file \"%s\"\n"),redirector_sort ed); | debuga(__FILE__,__LINE__,_("Invalid time in file \"%s\"\n "),redirector_sorted); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (getword(ip,sizeof(ip),&gwarea,'\t')<0) { | if (getword(ip,sizeof(ip),&gwarea,'\t')<0) { | |||
debuga(_("Invalid IP address in file \"%s\"\n"),redirecto r_sorted); | debuga(__FILE__,__LINE__,_("Invalid IP address in file \" %s\"\n"),redirector_sorted); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (getword_ptr(buf,&url,&gwarea,'\t')<0) { | if (getword_ptr(buf,&url,&gwarea,'\t')<0) { | |||
debuga(_("Invalid url in file \"%s\"\n"),redirector_sorte d); | debuga(__FILE__,__LINE__,_("Invalid url in file \"%s\"\n" ),redirector_sorted); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (getword(rule,sizeof(rule),&gwarea,'\n')<0) { | if (getword(rule,sizeof(rule),&gwarea,'\n')<0) { | |||
debuga(_("Invalid rule in file \"%s\"\n"),redirector_sort ed); | debuga(__FILE__,__LINE__,_("Invalid rule in file \"%s\"\n "),redirector_sorted); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
uinfo=userinfo_find_from_id(user); | uinfo=userinfo_find_from_id(user); | |||
if (!uinfo) { | if (!uinfo) { | |||
debuga(_("Unknown user ID %s in file \"%s\"\n"),user,redi rector_sorted); | debuga(__FILE__,__LINE__,_("Unknown user ID %s in file \" %s\"\n"),user,redirector_sorted); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
computedate(data2/10000,(data2/100)%10,data2%100,&t); | computedate(data2/10000,(data2/100)%100,data2%100,&t); | |||
strftime(data,sizeof(data),"%x",&t); | strftime(data,sizeof(data),"%x",&t); | |||
new_user=false; | new_user=false; | |||
if(!z) { | if (!z) { | |||
strcpy(ouser,user); | strcpy(ouser,user); | |||
strcpy(oip,ip); | strcpy(oip,ip); | |||
strcpy(oname,ip); | strcpy(oname,ip); | |||
if (Ip2Name && !uinfo->id_is_ip) ip2name(oname,sizeof(ona me)); | if (Ip2Name && !uinfo->id_is_ip) ip2name(oname,sizeof(ona me)); | |||
z=true; | z=true; | |||
new_user=true; | new_user=true; | |||
} else { | } else { | |||
if(strcmp(ouser,user) != 0) { | if (strcmp(ouser,user) != 0) { | |||
strcpy(ouser,user); | strcpy(ouser,user); | |||
new_user=true; | new_user=true; | |||
} | } | |||
if(strcmp(oip,ip) != 0) { | if (strcmp(oip,ip) != 0) { | |||
strcpy(oip,ip); | strcpy(oip,ip); | |||
strcpy(oname,ip); | strcpy(oname,ip); | |||
if (Ip2Name && !uinfo->id_is_ip) ip2name(oname,si zeof(oname)); | if (Ip2Name && !uinfo->id_is_ip) ip2name(oname,si zeof(oname)); | |||
new_user=true; | new_user=true; | |||
} | } | |||
} | } | |||
if(SquidGuardReportLimit) { | if (SquidGuardReportLimit) { | |||
if(strcmp(ouser2,uinfo->label) == 0) { | if (strcmp(ouser2,uinfo->label) == 0) { | |||
count++; | count++; | |||
} else { | } else { | |||
if(count>SquidGuardReportLimit && SquidGuardRepor tLimit>0) | if (count>SquidGuardReportLimit && SquidGuardRepo rtLimit>0) | |||
show_ignored_redirector(fp_ou,count-Squid GuardReportLimit); | show_ignored_redirector(fp_ou,count-Squid GuardReportLimit); | |||
count=1; | count=1; | |||
strcpy(ouser2,uinfo->label); | strcpy(ouser2,uinfo->label); | |||
} | } | |||
if(count > SquidGuardReportLimit) | if (count > SquidGuardReportLimit) | |||
continue; | continue; | |||
} | } | |||
if (new_user) | if (new_user) | |||
fprintf(fp_ou,"<tr><td class=\"data2\">%s</td><td class=\ "data2\">%s</td>",uinfo->label,ip); | fprintf(fp_ou,"<tr><td class=\"data2\">%s</td><td class=\ "data2\">%s</td>",uinfo->label,ip); | |||
else | else | |||
fputs("<tr><td class=\"data2\"></td><td class=\"data2\">< /td>",fp_ou); | fputs("<tr><td class=\"data2\"></td><td class=\"data2\">< /td>",fp_ou); | |||
fprintf(fp_ou,"<td class=\"data2\">%s-%s</td><td class=\"data2\"> ",data,hora); | fprintf(fp_ou,"<td class=\"data2\">%s-%s</td><td class=\"data2\"> ",data,hora); | |||
output_html_link(fp_ou,url,100); | output_html_link(fp_ou,url,100); | |||
fprintf(fp_ou,"</td><td class=\"data2\">%s</td></tr>\n",rule); | fprintf(fp_ou,"</td><td class=\"data2\">%s</td></tr>\n",rule); | |||
} | } | |||
fclose(fp_in); | if (FileObject_Close(fp_in)) { | |||
debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),redirect | ||||
or_sorted,FileObject_GetLastCloseError()); | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
longline_destroy(&line); | longline_destroy(&line); | |||
if(count>SquidGuardReportLimit && SquidGuardReportLimit>0) | if (count>SquidGuardReportLimit && SquidGuardReportLimit>0) | |||
show_ignored_redirector(fp_ou,count-SquidGuardReportLimit); | show_ignored_redirector(fp_ou,count-SquidGuardReportLimit); | |||
fputs("</table>\n",fp_ou); | fputs("</table>\n",fp_ou); | |||
if (RedirectorErrors>0) | if (RedirectorErrors>0) | |||
{ | { | |||
fputs("<div class=\"warn\"><span>",fp_ou); | fputs("<div class=\"warn\"><span>",fp_ou); | |||
fprintf(fp_ou,ngettext("%d error found in the log file. Some entr ies may be missing.","%d errors found in the log file. Some entries may be missi ng.",RedirectorErrors),RedirectorErrors); | fprintf(fp_ou,ngettext("%d error found in the log file. Some entr ies may be missing.","%d errors found in the log file. Some entries may be missi ng.",RedirectorErrors),RedirectorErrors); | |||
fputs("</span></div>\n",fp_ou); | fputs("</span></div>\n",fp_ou); | |||
} | } | |||
fputs("</div>\n",fp_ou); | fputs("</div>\n",fp_ou); | |||
if (write_html_trailer(fp_ou)<0) | write_html_trailer(fp_ou); | |||
debuga(_("Write error in file \"%s\"\n"),report); | if (fclose(fp_ou)==EOF) { | |||
if (fclose(fp_ou)==EOF) | debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),report, | |||
debuga(_("Failed to close file \"%s\": %s\n"),report,strerror(err | strerror(errno)); | |||
no)); | exit(EXIT_FAILURE); | |||
} | ||||
if (!KeepTempLog && unlink(redirector_sorted)) { | if (!KeepTempLog && unlink(redirector_sorted)) { | |||
debuga(_("Cannot delete \"%s\": %s\n"),redirector_sorted,strerror (errno)); | debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),redirect or_sorted,strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
return; | return; | |||
} | } | |||
End of changes. 91 change blocks. | ||||
155 lines changed or deleted | 191 lines changed or added |