diff options
| author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2007-02-26 20:04:04 +0000 | 
|---|---|---|
| committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2007-02-26 20:04:04 +0000 | 
| commit | 79386b5db780fee3d1469941e640c2cbe2598a5c (patch) | |
| tree | acecda110ad48b648a8f3a3666786581034f00e2 /package/base-files/files/lib/config/validate_spec.awk | |
| parent | ddc24aa87ea2f11859e9e56a64210d5a268dbee8 (diff) | |
Integrate basic UCI config file validation support
Needs more testing and validation is not enforced yet
Code contributed by Fraunhofer Fokus
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@6391 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/base-files/files/lib/config/validate_spec.awk')
| -rw-r--r-- | package/base-files/files/lib/config/validate_spec.awk | 171 | 
1 files changed, 171 insertions, 0 deletions
diff --git a/package/base-files/files/lib/config/validate_spec.awk b/package/base-files/files/lib/config/validate_spec.awk new file mode 100644 index 000000000..0816c0829 --- /dev/null +++ b/package/base-files/files/lib/config/validate_spec.awk @@ -0,0 +1,171 @@ +# AWK file for validating uci specification files +# +# Copyright (C) 2006 by Fokus Fraunhofer <carsten.tittel@fokus.fraunhofer.de> +# Copyright (C) 2007 by Felix Fietkau <nbd@openwrt.org> +# +# 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 +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# +# general: unfortunately, the development was done using gawk providing +#  a different match() functions than e.g. mawk on debian systems +#  - therefore, the script was changed to run on most awk's  +#  - even things like [:space:] are not used +# +# - script  parses the config section definition contained in one  +#   specification file +# global variables: +# * section  - contains the current config section name +# * var      - contains the name of the current config option +# * type     - contains the type of the current config option +# * required - contains the requirements of the current config option +# * optional - contains the optional scope of the current config option +# * vars[]  - array, contains the name of all config options valid within +#	      a certain config section, format: csv +# +# XXX todo: more than one config option with the same in different section +# will clash for the following tables +# * types[] - contains the type of a config option +# * reqs[]  - contains the requirements of a config option +# * opts[]  - contains the optional scope of a config option +# + +# - check requirement validates, if the config option is required in +#   the config section type and if so, if it is defined +# - the functions exits with error in case of non-conforming  +#   behaviour +# XXX todo: use return instead of exit +# +function check_requirements(vsec,var) { +	# check, if config option is required in all cases +	if (reqs[vsec "_" var] == 1) { +		# option is always required, is it defined? +		if (!length(ENVIRON["CONFIG_" vsec "_" var])) { +			print STDERR "Error: missing config option " var " in " vsec +			exit 1 +		} + +	# check, if config option is required only when other options +	# have certain values +	} else if (length(reqs[vsec "_" var])) { +		# - check all requirements, e.g. proto=static,proto=pptp +		# - note, that the required flag is tiggered if at least one +		#   of the conditions is met +		split(reqs[vsec "_" var],arr,","); +		for (idx in arr) { +			# parse the condition space tolerant +			if (!match(arr[idx],"^[ \t\n]*[^ \t\n=]+"\ +				"[ \t\n]*=.+")) { +				print STDERR "Error: invalid requirement "\ +					"in spec file for " var " : " arr[idx] +				exit 1 +			} +			# get the name of the variable +			match(arr[idx],"[^ \t\n=]+"); +			name=substr(arr[idx],RSTART,RLENGTH) +			mrest=substr(arr[idx],RSTART+RLENGTH) +			# get the spaces +			match(mrest,"[ \t\n]*=[ \t\n]*") +			val=substr(mrest,RSTART+RLENGTH) +			# check the condition +			if (ENVIRON["CONFIG_" vsec "_" name] == val) { +				# condition is met, check requirement +				if (!length(ENVIRON["CONFIG_" vsec "_" var])) { +					print STDERR "Error: missing config " \ +						"option " var " in " vsec  +					exit 1 +				} +			} +		} +	} +} + +# is_valid just returns true(1)/false(0) if the +# given value is conform with the type definition  +# NOTE: this function needs the type validating function from +# validate_config.awk +# +function is_valid(type,value) { + +	# the enum type contains a definition of all allowed values as csv +	# e.g. enum,alpha,beta,gamma +	if (type ~ "enum" ) { +		split(type,tarr,",") +		for (num in tarr) { +			if (num > 0) { +				gsub("^[ \t\n]*","",tarr[num]); +				gsub("[ \t\n]*$","",tarr[num]); +				if (tarr[num] == value) { +					return 1 +				}	 +			} +		} +		return 0; +	} + +	# all other types are checked as defined in the former validate.awk +	if (type ~ "int") return is_int(value) +	if (type ~ "ip" ) return is_ip(value) +	if (type ~ "netmask" ) return is_netmask(value) +	if (type ~ "string" ) return is_string(value) +	if (type ~ "wep" ) return is_wep(value) +	if (type ~ "hostname" ) return is_hostname(value) +	if (type ~ "mac" ) return is_mac(value) +	if (type ~ "port" ) return is_port(value) +	if (type ~ "ports" ) return is_ports(value) +	if (type ~ "wpapsk" ) return is_wpapsk(value) +} + +# validate_config compares the specification as parsed from the spec file +# with the environment variables +# CONFIG_SECTION contains the relevant config section name, e.g. wan +# CONFIG_<section>_TYPE contains the type of the config, e.g. interface +# CONFIG_<section>_<var> contains the value of the config option <var> +# +function validate_config() { +	# get the config section name +	vname=ENVIRON["CONFIG_SECTION"] +	if (!length(vname)) { +		print STDERR "Error: no current configuration" +		exit 1 +	} +	# get the config section type +	vsec=ENVIRON["CONFIG_" vname "_TYPE"] +	if (!length(vsec)) { +		print STDERR "Error: section " vsec " not found" +		exit 1 +	} + +	# loop through all config options specified for this section type +	split(vars[vsec],options,",") +	for (oidx in options) { +		# first, look for all required attributes +		var=options[oidx] +		check_requirements(vname,var) + +		# next look at each option and validate it +		val=ENVIRON["CONFIG_" vname "_" var] +		if (length(val)) { +			if (!is_valid(types[vsec "_" var],val)) { +				print "Error: type validation error for '" var "' in section '" vname "'" +				exit 1 +			} +		} +	} +} + + +END { +	validate_config() +}  | 
