X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=getconf.c;h=8454e5d549b82e6dd4ec50d4de02ee6bffda3579;hb=ffc9b006b8358644c054c5e4c2929791efec7475;hp=549d6ff331bd7d60e178c36d87db1b999e5b54b2;hpb=227153528d900c4b3d213349e91bd1198f164a75;p=thirdparty%2Fsarg.git diff --git a/getconf.c b/getconf.c index 549d6ff..8454e5d 100644 --- a/getconf.c +++ b/getconf.c @@ -1,6 +1,6 @@ /* * SARG Squid Analysis Report Generator http://sarg.sourceforge.net - * 1998, 2011 + * 1998, 2015 * * SARG donations: * please look at http://sarg.sourceforge.net/donations.php @@ -26,10 +26,16 @@ #include "include/conf.h" #include "include/defs.h" +#include "include/filelist.h" #define SET_LIST(list) list,sizeof(list)/sizeof(list[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]; struct param_list { @@ -49,6 +55,14 @@ struct sort_list unsigned long int value; }; +struct select_list +{ + //! The name of the value of the parameter. + const char *name; + //! The value to assign when the name is selected. + int value; +}; + static struct param_list report_type_values[]= { {"users_sites",REPORT_TYPE_USERS_SITES,0}, @@ -80,6 +94,7 @@ static struct param_list topuserfields_values[]= {"NUM",TOPUSERFIELDS_NUM,0}, {"DATE_TIME",TOPUSERFIELDS_DATE_TIME,0}, {"USERID",TOPUSERFIELDS_USERID,0}, + {"USERIP",TOPUSERFIELDS_USERIP,0}, {"CONNECT",TOPUSERFIELDS_CONNECT,0}, {"BYTES",TOPUSERFIELDS_BYTES,0}, {"%BYTES",TOPUSERFIELDS_SETYB,0}, @@ -174,6 +189,7 @@ struct sort_list topsite_sort[]= {"BYTES",TOPSITE_SORT_BYTES}, {"CONNECT",TOPSITE_SORT_CONNECT}, {"TIME",TOPSITE_SORT_TIME}, + {"USER",TOPSITE_SORT_USER}, }; struct sort_list user_sort[]= @@ -184,6 +200,12 @@ struct sort_list user_sort[]= {"TIME",USER_SORT_TIME}, }; +static struct select_list per_user_limit_create_file[]= +{ + {"always",PUFC_Always}, //always create an empty file + {"as_required",PUFC_AsRequired}, //create the file if necessary (no empty file is created) +}; + static int is_param(const char *param,const char *buf) { int plen; @@ -206,7 +228,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); @@ -214,6 +236,31 @@ static int getparam_string(const char *param,char *buf,char *value,int value_siz return(1); } +/*! + * Get a pointer to the beginning of the string value defined by the + * parameter. The returned value is NULL if the buffer doesn't contain + * the parameter. + * + * \param param The parameter to look for. + * \param buf The buffer containing the line read from the configuration + * file. + * + * \return A pointer to the beginning of the parameter value or NULL if + * the line is not for the requtested parameter. + */ +static char *getparam_stringptr(const char *param,char *buf) +{ + int plen; + + plen=strlen(param); + if (strncmp(buf,param,plen) != 0) return(NULL); + buf+=plen; + if ((unsigned char)*buf>' ') return(NULL); + while (*buf && (unsigned char)*buf<=' ') buf++; + + return(buf); +} + static int getparam_quoted(const char *param,char *buf,char *value,int value_size) { int plen; @@ -226,7 +273,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++; @@ -238,7 +285,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); @@ -259,11 +306,11 @@ static int getparam_2words(const char *param,char *buf,char *word1,int word1_siz for (i=0 ; i' ' ; 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; @@ -273,7 +320,7 @@ static int getparam_2words(const char *param,char *buf,char *word1,int word1_siz for (i=0 ; i' ' ; 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; @@ -296,7 +343,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); @@ -348,11 +395,11 @@ static int getparam_list(const char *param,struct param_list *options,int noptio } for (i=0 ; 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; @@ -383,7 +430,7 @@ static int getparam_sort(const char *param,struct sort_list *options,int noption } for (i=0 ; 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; @@ -398,7 +445,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); } } @@ -407,17 +454,139 @@ static int getparam_sort(const char *param,struct sort_list *options,int noption return(1); } +static int getparam_select(const char *param,struct select_list *options,int noptions,char *buf,int *value) +{ + int plen; + char *str; + int i; + + plen=strlen(param); + if (strncmp(buf,param,plen) != 0) return(0); + buf+=plen; + if ((unsigned char)*buf>' ') return(0); + while (*buf && (unsigned char)*buf<=' ') buf++; + + str=buf; + while (*buf && (unsigned char)*buf>' ' && *buf!=';') buf++; + *buf='\0'; + for (i=0 ; i=noptions) { + debuga(__FILE__,__LINE__,_("Unknown value \"%s\" for parameter \"%s\"\n"),str,param); + exit(EXIT_FAILURE); + } + *value=options[i].value; + return(1); +} + +static int getparam_userlimit(const char *param,char *buf) +{ + int plen; + char *file_begin,*file_end; + int limit; + int digit; + char *str; + int i; + enum PerUserOutputEnum output; + const struct + { + const char *name; + enum PerUserOutputEnum value; + } output_types[]= + { + {"id",PUOE_UserId}, + {"ip",PUOE_UserIp}, + }; + + plen=strlen(param); + if (strncmp(buf,param,plen) != 0) return(0); + buf+=plen; + if ((unsigned char)*buf>' ') return(0); + while (*buf && (unsigned char)*buf<=' ') buf++; + + /* + options are made of a file name, an integer limit and an optional + integer flag. The file name may contain spaces. We keep searching + until a valid number is found after a space. + */ + file_begin=buf; + do { + while (*buf && (unsigned char)*buf>' ') buf++; + if (*buf!=' ') { + debuga(__FILE__,__LINE__,_("Missing limit in per_user_limit\n")); + exit(EXIT_FAILURE); + } + file_end=buf; + while (*buf && (unsigned char)*buf<=' ') buf++; + limit=0; + while (*buf && isdigit(*buf)) { + digit=*buf-'0'; + if (limit>=(INT_MAX-digit)/10) break; + limit=limit*10+digit; + buf++; + } + } while (*buf && *buf!=' '); + + output=PUOE_UserId; + if (*buf==' ') { + while (*buf && (unsigned char)*buf<=' ') buf++; + str=buf; + while (*buf && (unsigned char)*buf>' ') buf++; + *buf='\0'; + for (i=sizeof(output_types)/sizeof(output_types[0])-1 ; i>=0 ; i--) + if (strcasecmp(output_types[i].name,str)==0) { + output=output_types[i].value; + break; + } + if (i<0) { + debuga(__FILE__,__LINE__,_("Invalid output type in per_user_limit\n")); + exit(EXIT_FAILURE); + } + } + + if (PerUserLimitsNumber>=MAX_USER_LIMITS) { + debuga(__FILE__,__LINE__,_("Too many per_user_limit\n")); + exit(EXIT_FAILURE); + } + *file_end='\0'; + safe_strcpy(PerUserLimits[PerUserLimitsNumber].File,file_begin,sizeof(PerUserLimits[PerUserLimitsNumber].File)); + PerUserLimits[PerUserLimitsNumber].Limit=limit; + PerUserLimits[PerUserLimitsNumber].Output=output; + PerUserLimitsNumber++; + + return(1); +} + +static void ccharset(char *CharSet) +{ + if (strcmp(CharSet,"Latin2") == 0) strcpy(CharSet,"ISO-8859-2"); + else if (strcmp(CharSet,"Latin3") == 0) strcpy(CharSet,"ISO-8859-3"); + else if (strcmp(CharSet,"Latin4") == 0) strcpy(CharSet,"ISO-8859-4"); + else if (strcmp(CharSet,"Cyrillic") == 0) strcpy(CharSet,"ISO-8859-5"); + else if (strcmp(CharSet,"Arabic") == 0) strcpy(CharSet,"ISO-8859-6"); + else if (strcmp(CharSet,"Greek") == 0) strcpy(CharSet,"ISO-8859-7"); + else if (strcmp(CharSet,"Hebrew") == 0) strcpy(CharSet,"ISO-8859-8"); + else if (strcmp(CharSet,"Latin5") == 0) strcpy(CharSet,"ISO-8859-9"); + else if (strcmp(CharSet,"Latin6") == 0) strcpy(CharSet,"ISO-8859-10"); + else if (strcmp(CharSet,"Japan") == 0) strcpy(CharSet,"EUC-JP"); + else if (strcmp(CharSet,"Koi8-r") == 0) strcpy(CharSet,"KOI8-R"); + /* + * Any other encoding name is left unchanged. + */ + return; +} + static void parmtest(char *buf) { char wbuf[2048]; struct getwordstruct gwarea; + int iVal; while (*buf && (unsigned char)*buf<=' ') buf++; 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; @@ -456,7 +625,9 @@ static void parmtest(char *buf) if (getparam_quoted("title",buf,Title,sizeof(Title))>0) return; - if (getparam_bool("resolve_ip",buf,&Ip2Name)>0) return; + if (strncasecmp(buf,"resolve_ip",10)==0) { + if (ip2name_config(buf+10)>0) return; + } if (getparam_bool("user_ip",buf,&UserIp)>0) return; @@ -465,17 +636,16 @@ 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); } - strncpy(DateFormat,gwarea.current,1); - fixnone(DateFormat); + DateFormat=gwarea.current[0]; return; } 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; @@ -483,7 +653,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; @@ -495,12 +665,13 @@ static void parmtest(char *buf) if (is_param("access_log",buf)>0) { if (AccessLogFromCmdLine==0) { - if (NAccessLog>=MAXLOGS) { - debuga(_("Too many log files in configuration file\n")); + char *FileName=getparam_stringptr("access_log",buf); + if (!AccessLog) + AccessLog=FileList_Create(); + if (!FileList_AddFile(AccessLog,FileName)) { + debuga(__FILE__,__LINE__,_("Not enough memory to store the input log file names\n")); exit(EXIT_FAILURE); } - getparam_string("access_log",buf,AccessLog[NAccessLog],MAX_LOG_FILELEN); - NAccessLog++; } return; } @@ -508,7 +679,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); @@ -537,8 +708,10 @@ static void parmtest(char *buf) if (getparam_string("output_email",buf,OutputEmail,sizeof(OutputEmail))>0) return; - if (getparam_2words("per_user_limit",buf,PerUserLimitFile,sizeof(PerUserLimitFile),wbuf,sizeof(wbuf))>0) { - PerUserLimit=atoi(wbuf); + if (getparam_userlimit("per_user_limit",buf)>0) return; + + if (getparam_select("per_user_limit_file_create",SET_LIST(per_user_limit_create_file),buf,&iVal)>0) { + PerUserFileCreation=(enum PerUserFileCreationEnum)iVal; return; } @@ -605,6 +778,8 @@ static void parmtest(char *buf) if (getparam_bool("show_read_statistics",buf,&ShowReadStatistics)>0) return; + if (getparam_bool("show_read_percent",buf,&ShowReadPercent)>0) return; + if (getparam_list("topuser_fields",SET_LIST(topuserfields_values),buf,&TopUserFields)>0) return; if (getparam_bool("bytes_in_sites_users_report",buf,&BytesInSitesUsersReport)>0) return; @@ -652,14 +827,14 @@ static void parmtest(char *buf) 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); } - strcpy(AuthUserTemplateFile,wbuf); + safe_strcpy(AuthUserTemplateFile,wbuf,sizeof(AuthUserTemplateFile)); } else { - strcpy(dir,ConfigFile); + safe_strcpy(dir,ConfigFile,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); } } @@ -674,13 +849,20 @@ static void parmtest(char *buf) return; } - if (getparam_bool("graphs",buf,&Graphs)>0) return; + if (getparam_bool("graphs",buf,&Graphs)>0) { +#ifndef HAVE_GD + if (Graphs) + debugaz(__FILE__,__LINE__,_("No graphs available as sarg was not compiled with libgd. Set \"graphs\" to \"no\" in %s to disable this warning\n"), + ConfigFile); +#endif + return; + } if (getparam_string("graph_days_bytes_bar_color",buf,GraphDaysBytesBarColor,sizeof(GraphDaysBytesBarColor))>0) 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; } @@ -689,19 +871,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; } @@ -734,12 +916,22 @@ static void parmtest(char *buf) if (getparam_string("LDAPTargetAttr",buf,LDAPTargetAttr,sizeof(LDAPTargetAttr))>0) return; + if (getparam_string("LDAPNativeCharset",buf,LDAPNativeCharset,sizeof(LDAPNativeCharset))>0) return; + if (getparam_string("graph_font",buf,GraphFont,sizeof(GraphFont))>0) return; if (getparam_string("sorttable",buf,SortTableJs,sizeof(SortTableJs))>0) return; if (getparam_string("hostalias",buf,HostAliasFile,sizeof(HostAliasFile))>0) return; - + + if (getparam_string("useralias",buf,UserAliasFile,sizeof(UserAliasFile))>0) return; + + if (getparam_bool("keep_temp_log",buf,&KeepTempLog)>0) return; + + if (getparam_int("max_successive_log_errors",buf,&NumLogSuccessiveErrors)>0) return; + + if (getparam_int("max_total_log_errors",buf,&NumLogTotalErrors)>0) return; + if(strstr(buf,"squid24") != 0) { squid24=true; return; @@ -748,18 +940,20 @@ 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); } @@ -769,23 +963,26 @@ void getconf(void) char buf[MAXLEN]; if(debug) - debuga(_("Loading configuration from %s\n"),ConfigFile); + debuga(__FILE__,__LINE__,_("Loading configuration from \"%s\"\n"),ConfigFile); if ((fp_in = fopen(ConfigFile, "r")) == NULL) { - debuga(_("(getconf) Cannot open file %s\n"),ConfigFile); + debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),ConfigFile,strerror(errno)); exit(EXIT_FAILURE); } while (fgets(buf, sizeof(buf), fp_in) != NULL) { fixendofline(buf); - if(debugm) + if (debugz>=LogLevel_Data) printf("SYSCONFDIR %s\n",buf); parmtest(buf); } - fclose(fp_in); + if (fclose(fp_in)==EOF) { + debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),ConfigFile,strerror(errno)); + exit(EXIT_FAILURE); + } return; }