]> git.ipfire.org Git - thirdparty/sarg.git/blobdiff - getconf.c
Add support to decompress xz files
[thirdparty/sarg.git] / getconf.c
index ddd8830683db0ca89201d8db25567b608f102a1b..8c3060a13e6d7392d43a878db219ca985a21664a 100644 (file)
--- a/getconf.c
+++ b/getconf.c
@@ -1,6 +1,6 @@
 /*
  * 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
 {
@@ -73,6 +84,7 @@ static struct param_list report_type_values[]=
        {"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[]=
@@ -227,7 +239,7 @@ static int getparam_string(const char *param,char *buf,char *value,int value_siz
        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);
@@ -245,7 +257,7 @@ static int getparam_string(const char *param,char *buf,char *value,int value_siz
  * 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)
 {
@@ -272,7 +284,7 @@ static int getparam_quoted(const char *param,char *buf,char *value,int value_siz
        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++;
@@ -284,7 +296,7 @@ static int getparam_quoted(const char *param,char *buf,char *value,int value_siz
        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);
@@ -305,11 +317,11 @@ static int getparam_2words(const char *param,char *buf,char *word1,int word1_siz
        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;
@@ -319,7 +331,7 @@ static int getparam_2words(const char *param,char *buf,char *word1,int word1_siz
        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;
@@ -342,7 +354,7 @@ static int getparam_int(const char *param,char *buf,int *value)
 
        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);
@@ -394,11 +406,11 @@ static int getparam_list(const char *param,struct param_list *options,int noptio
                }
                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;
@@ -429,7 +441,7 @@ static int getparam_sort(const char *param,struct sort_list *options,int noption
        }
        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;
@@ -444,7 +456,7 @@ static int getparam_sort(const char *param,struct sort_list *options,int noption
                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);
                }
        }
@@ -470,7 +482,7 @@ static int getparam_select(const char *param,struct select_list *options,int nop
        *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;
@@ -511,7 +523,7 @@ static int getparam_userlimit(const char *param,char *buf)
        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;
@@ -537,13 +549,13 @@ static int getparam_userlimit(const char *param,char *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';
@@ -574,7 +586,7 @@ static void ccharset(char *CharSet)
        return;
 }
 
-static void parmtest(char *buf)
+static void parmtest(char *buf,const char *File)
 {
        char wbuf[2048];
        struct getwordstruct gwarea;
@@ -635,7 +647,7 @@ static void parmtest(char *buf)
        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];
@@ -644,7 +656,7 @@ static void parmtest(char *buf)
 
        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;
@@ -652,7 +664,7 @@ static void parmtest(char *buf)
 
        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;
@@ -668,7 +680,7 @@ static void parmtest(char *buf)
                        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);
                        }
                }
@@ -678,7 +690,7 @@ static void parmtest(char *buf)
        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);
@@ -687,7 +699,18 @@ static void parmtest(char *buf)
                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;
 
@@ -822,18 +845,18 @@ static void parmtest(char *buf)
        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);
                        }
                }
@@ -851,9 +874,10 @@ static void parmtest(char *buf)
        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;
        }
 
@@ -861,7 +885,7 @@ static void parmtest(char *buf)
 
        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;
        }
 
@@ -870,19 +894,19 @@ static void parmtest(char *buf)
                /*
                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;
        }
@@ -891,6 +915,11 @@ static void parmtest(char *buf)
 
        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;
@@ -939,44 +968,65 @@ static void parmtest(char *buf)
        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 (getparam_string("include",buf,IncludeFile,sizeof(IncludeFile))>0) {
+                       getconf(IncludeFile);
+                       continue;
+               }
+
                if (debugz>=LogLevel_Data)
                        printf("SYSCONFDIR %s\n",buf);
 
-               parmtest(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--;
 }