| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- # AWK file for validating uci specification files
- #
- # Copyright (C) 2006 by Fokus Fraunhofer <[email protected]>
- # Copyright (C) 2007 by Felix Fietkau <[email protected]>
- #
- # 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()
- }
|