/*
* SARG Squid Analysis Report Generator http://sarg.sourceforge.net
- * 1998, 2013
+ * 1998, 2015
*
* SARG donations:
* please look at http://sarg.sourceforge.net/donations.php
#define SET_LIST(list) list,sizeof(list)/sizeof(list[0])
+//! The configuration file from which the graph option was loaded
+char GraphConfigFile[MAXLEN]="";
+
+//! How many include directives were followed.
+static int IncludeLevel=0;
+
extern numlist hours, weekdays;
extern FileListObject AccessLog;
extern int PerUserLimitsNumber;
extern struct PerUserLimitStruct PerUserLimits[MAX_USER_LIMITS];
extern enum PerUserFileCreationEnum PerUserFileCreation;
+extern char ImageDir[MAXLEN];
+extern FileListObject UserAgentLog;
+extern bool UserAgentFromCmdLine;
+extern char StripUserSuffix[MAX_USER_LEN];
+extern int StripSuffixLen;
struct param_list
{
{"auth_failures",REPORT_TYPE_AUTH_FAILURES,0},
{"site_user_time_date",REPORT_TYPE_SITE_USER_TIME_DATE,0},
{"downloads",REPORT_TYPE_DOWNLOADS,0},
+ {"user_agent",REPORT_TYPE_USERAGENT,0},
};
static struct param_list data_field_values[]=
while (*buf && (unsigned char)*buf<=' ') buf++;
if (strlen(buf)>=value_size) {
- debuga(_("The string value of parameter \"%s\" is too long\n"),param);
+ debuga(__FILE__,__LINE__,_("The string value of parameter \"%s\" is too long\n"),param);
exit(EXIT_FAILURE);
}
strcpy(value,buf);
* file.
*
* \return A pointer to the beginning of the parameter value or NULL if
- * the line is not for the requtested parameter.
+ * the line is not for the requested parameter.
*/
static char *getparam_stringptr(const char *param,char *buf)
{
while (*buf && (unsigned char)*buf<=' ') buf++;
if (*buf != '\"') {
- debuga(_("Missing double quote after parameter \"%s\"\n"),param);
+ debuga(__FILE__,__LINE__,_("Missing double quote after parameter \"%s\"\n"),param);
exit(EXIT_FAILURE);
}
buf++;
value[i]='\0';
if (*buf != '\"') {
- debuga(_("Missing double quote after parameter \"%s\" or value is more than %d bytes long\n"),param,value_size);
+ debuga(__FILE__,__LINE__,_("Missing double quote after parameter \"%s\" or value is more than %d bytes long\n"),param,value_size);
exit(EXIT_FAILURE);
}
fixnone(value);
for (i=0 ; i<word1_size && *buf && (unsigned char)*buf>' ' ; i++)
word1[i]=*buf++;
if (i>=word1_size) {
- debuga(_("The first word of parameter \"%s\" is more than %d bytes long\n"),param,word1_size-1);
+ debuga(__FILE__,__LINE__,_("The first word of parameter \"%s\" is more than %d bytes long\n"),param,word1_size-1);
exit(EXIT_FAILURE);
}
if (*buf!=' ') {
- debuga(_("Missing second word for parameter \"%s\"\n"),param);
+ debuga(__FILE__,__LINE__,_("Missing second word for parameter \"%s\"\n"),param);
exit(EXIT_FAILURE);
}
word1[i]=0;
for (i=0 ; i<word2_size && *buf && (unsigned char)*buf>' ' ; i++)
word2[i]=*buf++;
if (i>=word2_size) {
- debuga(_("The second word of parameter \"%s\" is more than %d bytes long\n"),param,word2_size-1);
+ debuga(__FILE__,__LINE__,_("The second word of parameter \"%s\" is more than %d bytes long\n"),param,word2_size-1);
exit(EXIT_FAILURE);
}
word2[i]=0;
next=0;
if (sscanf(buf,"%d%n",value,&next) != 1 || (unsigned char)buf[next] > ' ') {
- debuga(_("The integer value of parameter \"%s\" is invalid\n"),param);
+ debuga(__FILE__,__LINE__,_("The integer value of parameter \"%s\" is invalid\n"),param);
exit(EXIT_FAILURE);
}
return(1);
}
for (i=0 ; i<noptions && strcasecmp(buf,options[i].name) ; i++);
if (i>=noptions) {
- debuga(_("Unknown value \"%s\" for parameter \"%s\"\n"),buf,param);
+ debuga(__FILE__,__LINE__,_("Unknown value \"%s\" for parameter \"%s\"\n"),buf,param);
exit(EXIT_FAILURE);
}
if ((*value & options[i].exclude)!=0) {
- debuga(_("Value \"%s\" conflicts with other selected values for parameter \"%s\"\n"),buf,param);
+ debuga(__FILE__,__LINE__,_("Value \"%s\" conflicts with other selected values for parameter \"%s\"\n"),buf,param);
exit(EXIT_FAILURE);
}
*value|=options[i].value;
}
for (i=0 ; i<noptions && strcasecmp(buf,options[i].name) ; i++);
if (i>=noptions) {
- debuga(_("Unknown sort criterion \"%s\" for parameter \"%s\"\n"),buf,param);
+ debuga(__FILE__,__LINE__,_("Unknown sort criterion \"%s\" for parameter \"%s\"\n"),buf,param);
exit(EXIT_FAILURE);
}
*value=options[i].value;
if (strcasecmp(order,"reverse")==0 || strcasecmp(order,"D")==0) {
*value|=SORT_REVERSE;
} else if (strcasecmp(order,"normal")!=0 && strcasecmp(order,"A")!=0) {
- debuga(_("Unknown sort order \"%s\" for parameter \"%s\"\n"),order,param);
+ debuga(__FILE__,__LINE__,_("Unknown sort order \"%s\" for parameter \"%s\"\n"),order,param);
exit(EXIT_FAILURE);
}
}
*buf='\0';
for (i=0 ; i<noptions && strcasecmp(str,options[i].name) ; i++);
if (i>=noptions) {
- debuga(_("Unknown value \"%s\" for parameter \"%s\"\n"),str,param);
+ debuga(__FILE__,__LINE__,_("Unknown value \"%s\" for parameter \"%s\"\n"),str,param);
exit(EXIT_FAILURE);
}
*value=options[i].value;
do {
while (*buf && (unsigned char)*buf>' ') buf++;
if (*buf!=' ') {
- debuga(_("Missing limit in per_user_limit\n"));
+ debuga(__FILE__,__LINE__,_("Missing limit in per_user_limit\n"));
exit(EXIT_FAILURE);
}
file_end=buf;
break;
}
if (i<0) {
- debuga(_("Invalid output type in per_user_limit\n"));
+ debuga(__FILE__,__LINE__,_("Invalid output type in per_user_limit\n"));
exit(EXIT_FAILURE);
}
}
if (PerUserLimitsNumber>=MAX_USER_LIMITS) {
- debuga(_("Too many per_user_limit\n"));
+ debuga(__FILE__,__LINE__,_("Too many per_user_limit\n"));
exit(EXIT_FAILURE);
}
*file_end='\0';
return;
}
-static void parmtest(char *buf)
+static void parmtest(char *buf,const char *File)
{
char wbuf[2048];
struct getwordstruct gwarea;
if(*buf == '#' || *buf == '\0')
return;
- if(debugz)
+ if(debugz>=LogLevel_Process)
printf(_("SARG: TAG: %s\n"),buf);
if (getparam_string("background_color",buf,BgColor,sizeof(BgColor))>0) return;
if (is_param("date_format",buf)) {
getword_start(&gwarea,buf);
if (getword_multisep(wbuf,sizeof(wbuf),&gwarea,' ')<0) {
- debuga(_("Maybe you have a broken record or garbage in \"date_format\" parameter\n"));
+ debuga(__FILE__,__LINE__,_("Invalid record in \"date_format\" parameter\n"));
exit(EXIT_FAILURE);
}
DateFormat=gwarea.current[0];
if (is_param("hours",buf)) {
if( getnumlist( buf, &hours, 24, 24 ) ) {
- debuga(_("Error: Invalid syntax in hours tag!\n"));
+ debuga(__FILE__,__LINE__,_("Error: Invalid syntax in hours tag!\n"));
exit( 1 );
}
return;
if (is_param("weekdays",buf)) {
if( getnumlist( buf, &weekdays, 7, 7 ) ) {
- debuga(_("Error: Invalid syntax in weekdays tag!\n"));
+ debuga(__FILE__,__LINE__,_("Error: Invalid syntax in weekdays tag!\n"));
exit( 1 );
}
return;
if (!AccessLog)
AccessLog=FileList_Create();
if (!FileList_AddFile(AccessLog,FileName)) {
- debuga(_("Not enough memory to store the input log file names\n"));
+ debuga(__FILE__,__LINE__,_("Not enough memory to store the input log file names\n"));
exit(EXIT_FAILURE);
}
}
if (is_param("redirector_log",buf)>0) {
if (RedirectorLogFromCmdLine==0) {
if (NRedirectorLogs>=MAX_REDIRECTOR_LOGS) {
- debuga(_("Too many redirector log files in configuration file\n"));
+ debuga(__FILE__,__LINE__,_("Too many redirector log files in configuration file\n"));
exit(EXIT_FAILURE);
}
getparam_string("redirector_log",buf,RedirectorLogs[NRedirectorLogs],MAX_REDIRECTOR_FILELEN);
return;
}
- if (getparam_string("useragent_log",buf,UserAgentLog,sizeof(UserAgentLog))>0) return;
+ if (is_param("useragent_log",buf)>0) {
+ if (!UserAgentFromCmdLine) {
+ if (!UserAgentLog)
+ UserAgentLog=FileList_Create();
+ char *FileName=getparam_stringptr("useragent_log",buf);
+ if (!FileList_AddFile(UserAgentLog,FileName)) {
+ debuga(__FILE__,__LINE__,_("Not enough memory to store a user agent file name\n"));
+ exit(EXIT_FAILURE);
+ }
+ }
+ return;
+ }
if (getparam_string("exclude_hosts",buf,ExcludeHosts,sizeof(ExcludeHosts))>0) return;
if (getparam_bool("user_authentication",buf,&UserAuthentication)>0) return;
if (getparam_string("AuthUserTemplateFile",buf,wbuf,sizeof(wbuf))>0) {
- char dir[MAXLEN];
-
if (is_absolute(wbuf)) {
if (strlen(wbuf)>=sizeof(AuthUserTemplateFile)) {
- debuga(_("Template file name is too long in parameter \"AuthUserTemplateFile\"\n"));
+ debuga(__FILE__,__LINE__,_("Template file name is too long in parameter \"AuthUserTemplateFile\"\n"));
exit(EXIT_FAILURE);
}
safe_strcpy(AuthUserTemplateFile,wbuf,sizeof(AuthUserTemplateFile));
} else {
- safe_strcpy(dir,ConfigFile,sizeof(dir));
+ char dir[MAXLEN];
+
+ safe_strcpy(dir,File,sizeof(dir));
if (snprintf(AuthUserTemplateFile,sizeof(AuthUserTemplateFile),"%s/%s",dirname(dir),wbuf)>=sizeof(AuthUserTemplateFile)) {
- debuga(_("Template file name is too long in parameter \"AuthUserTemplateFile\"\n"));
+ debuga(__FILE__,__LINE__,_("Template file name is too long in parameter \"AuthUserTemplateFile\"\n"));
exit(EXIT_FAILURE);
}
}
if (getparam_bool("graphs",buf,&Graphs)>0) {
#ifndef HAVE_GD
if (Graphs)
- debugaz(_("No graphs available as sarg was not compiled with libgd. Set \"graphs\" to \"no\" in %s to disable this warning\n"),
- ConfigFile);
+ debugaz(__FILE__,__LINE__,_("No graphs available as sarg was not compiled with libgd. Set \"graphs\" to \"no\" in %s to disable this warning\n"),
+ File);
#endif
+ safe_strcpy(GraphConfigFile,File,sizeof(GraphConfigFile));
return;
}
if (getparam_string("redirector_log_format",buf,RedirectorLogFormat,sizeof(RedirectorLogFormat))>0) return;
if (getparam_string("squidguard_log_format",buf,RedirectorLogFormat,sizeof(RedirectorLogFormat))>0) {
- debuga(_("squidguard_log_format is deprecated and has been replaced by redirector_log_format. Please update your configuration file.\n"));
+ debuga(__FILE__,__LINE__,_("squidguard_log_format is deprecated and has been replaced by redirector_log_format. Please update your configuration file.\n"));
return;
}
/*
Due to an old bug in sarg before version 2.3, the option was having the opposite action than implied by the name.
*/
- debuga(_("redirector_ignore_date is deprecated and has been replaced by redirector_filter_out_date that does the action implied by its name as opposed to redirector_ignore_date. Please update your configuration file.\n"));
+ debuga(__FILE__,__LINE__,_("redirector_ignore_date is deprecated and has been replaced by redirector_filter_out_date that does the action implied by its name as opposed to redirector_ignore_date. Please update your configuration file.\n"));
RedirectorFilterOutDate=!RedirectorFilterOutDate;
return;
}
if (getparam_bool("squidguard_ignore_date",buf,&RedirectorFilterOutDate)>0) {
- debuga(_("squidguard_ignore_date is deprecated and has been replaced by redirector_filter_out_date that does the action implied by its name as opposed to squidguard_ignore_date. Please update your configuration file.\n"));
+ debuga(__FILE__,__LINE__,_("squidguard_ignore_date is deprecated and has been replaced by redirector_filter_out_date that does the action implied by its name as opposed to squidguard_ignore_date. Please update your configuration file.\n"));
RedirectorFilterOutDate=!RedirectorFilterOutDate;
return;
}
if (getparam_bool("dansguardian_filter_out_date",buf,&DansguardianFilterOutDate)>0) return;
if (getparam_bool("dansguardian_ignore_date",buf,&DansguardianFilterOutDate)>0) {
- debuga(_("dansguardian_ignore_date is deprecated and has been replaced by dansguardian_filter_out_date that does the action implied by its name as opposed to dansguardian_ignore_date. Please update your configuration file.\n"));
+ debuga(__FILE__,__LINE__,_("dansguardian_ignore_date is deprecated and has been replaced by dansguardian_filter_out_date that does the action implied by its name as opposed to dansguardian_ignore_date. Please update your configuration file.\n"));
DansguardianFilterOutDate=!DansguardianFilterOutDate;
return;
}
if (getparam_list("ntlm_user_format",SET_LIST(ntml_userformat_values),buf,&NtlmUserFormat)>0) return;
+ if (getparam_string("strip_user_suffix",buf,StripUserSuffix,sizeof(StripUserSuffix))>0) {
+ StripSuffixLen=strlen(StripUserSuffix);
+ return;
+ }
+
if (getparam_string("realtime_types",buf,RealtimeTypes,sizeof(RealtimeTypes))>0) return;
if (getparam_list("realtime_unauthenticated_records",SET_LIST(realtime_unauth_values),buf,&RealtimeUnauthRec)>0) return;
if(strstr(buf,"byte_cost") != 0) {
getword_start(&gwarea,buf);
if (getword_multisep(wbuf,sizeof(wbuf),&gwarea,' ')<0) {
- debuga(_("The \"byte_cost\" parameter of the configuration file is invalid\n"));
+ debuga(__FILE__,__LINE__,_("The \"byte_cost\" parameter of the configuration file is invalid\n"));
exit(EXIT_FAILURE);
}
cost=atol(gwarea.current);
if (getword_multisep(wbuf,sizeof(wbuf),&gwarea,' ')<0) {
- debuga(_("The \"byte_cost\" parameter of the configuration file is invalid\n"));
+ debuga(__FILE__,__LINE__,_("The \"byte_cost\" parameter of the configuration file is invalid\n"));
exit(EXIT_FAILURE);
}
nocost=my_atoll(gwarea.current);
return;
}
+ if (getparam_string("image_dir",buf,ImageDir,sizeof(ImageDir))>0) return;
+
printf(_("SARG: Unknown option %s\n"),buf);
}
-void getconf(void)
+void getconf(const char *File)
{
FILE *fp_in;
char buf[MAXLEN];
+ char IncludeFile[MAXLEN];
+
+ IncludeLevel++;
+ if (debug) {
+ if (IncludeLevel<=1)
+ debuga(__FILE__,__LINE__,_("Loading configuration file \"%s\"\n"),File);
+ else
+ debuga(__FILE__,__LINE__,_("Including configuration file \"%s\"\n"),File);
+ }
- if(debug)
- debuga(_("Loading configuration from %s\n"),ConfigFile);
+ // stop if include files are producing a loop
+ if (IncludeLevel>5) {
+ debuga(__FILE__,__LINE__,_("Too many nested configuration files included in \"%s\""),ConfigFile);
+ exit(EXIT_FAILURE);
+ }
- if ((fp_in = fopen(ConfigFile, "r")) == NULL) {
- debuga(_("(getconf) Cannot open file %s\n"),ConfigFile);
+ if ((fp_in = fopen(File, "r")) == NULL) {
+ debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),File,strerror(errno));
exit(EXIT_FAILURE);
}
while (fgets(buf, sizeof(buf), fp_in) != NULL) {
fixendofline(buf);
- if(debugm)
- printf("SYSCONFDIR %s\n",buf);
+ if (getparam_string("include",buf,IncludeFile,sizeof(IncludeFile))>0) {
+ getconf(IncludeFile);
+ continue;
+ }
- parmtest(buf);
+ if (debugz>=LogLevel_Data)
+ printf("SYSCONFDIR %s\n",buf);
+ parmtest(buf,File);
}
- fclose(fp_in);
- return;
+ if (fclose(fp_in)==EOF) {
+ debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),File,strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ IncludeLevel--;
}