Fix hook settings writing and checking
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 27 Dec 2014 13:32:07 +0000 (13:32 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 27 Dec 2014 13:32:07 +0000 (13:32 +0000)
Formerly the check functions were not correctly called in
some cases. Hence passing the check function is now explicitely
required. The {port,zone}_settings_{read,write} functions do
this transparent to the zone/port hooks.

21 files changed:
src/functions/functions.list
src/functions/functions.ports
src/functions/functions.settings
src/functions/functions.util
src/functions/functions.zone
src/header-zone
src/hooks/ports/batman-adv
src/hooks/ports/bonding
src/hooks/ports/dummy
src/hooks/ports/ethernet
src/hooks/ports/vlan
src/hooks/ports/wireless-adhoc
src/hooks/ports/wireless-ap
src/hooks/zones/6rd
src/hooks/zones/6to4-tunnel
src/hooks/zones/aiccu
src/hooks/zones/bridge
src/hooks/zones/modem
src/hooks/zones/pppoe
src/hooks/zones/pptp
src/hooks/zones/wireless

index 062df27..0f11c32 100644 (file)
 
 function list_append() {
        local list=${1}
+       assert isset list
+       shift
+
+       local arg
+       for arg in $@; do
+               list_append_one "${list}" "${arg}"
+       done
+}
+
+function list_append_one() {
+       assert [ $# -eq 2 ]
+
+       local list="${1}"
        shift
 
        assert isset list
index 5bed4d8..58f60cd 100644 (file)
@@ -40,12 +40,11 @@ function port_config_dir() {
 function port_settings_read() {
        local port="${1}"
        assert isset port
-       shift
 
        # Save the HOOK variable.
        local hook="${HOOK}"
 
-       settings_read "$(port_file "${port}")" "$@"
+       settings_read "$(port_file "${port}")" ${HOOK_SETTINGS}
 
        # Restore hook.
        HOOK="${hook}"
@@ -56,7 +55,13 @@ function port_settings_write() {
        assert isset port
        shift
 
-       settings_write "$(port_file "${port}")" "$@"
+       local args
+       if function_exists "hook_check_settings"; then
+               list_append args "--check=\"hook_check_settings\""
+       fi
+       list_append args ${HOOK_SETTINGS}
+
+       settings_write "$(port_file "${port}")" ${args}
 }
 
 function ports_get_all() {
index 8b5ac98..2f2821f 100644 (file)
@@ -132,13 +132,30 @@ function settings_strip() {
 }
 
 function settings_write() {
-       local settings_file=${1}
+       local settings_file="${1}"
        assert isset settings_file
        shift
 
+       local check_func
+
+       local arg
+       while read arg; do
+               case "${arg}" in
+                       --check=*)
+                               check_func="$(cli_get_val "${arg}")"
+                               ;;
+
+                       # Stop argument processing when reaching the first
+                       # configuration parameter
+                       *)
+                               break
+                               ;;
+               esac
+               shift
+       done <<< "$(args $@)"
+
        # Check if all values to be written are sane
-       if ! settings_check; then
-               log CRITICAL "Configuration check failed. No settings have been written."
+       if isset check_func && ! settings_check "${check_func}"; then
                return ${EXIT_ERROR}
        fi
 
@@ -174,13 +191,34 @@ function settings_print() {
 }
 
 function settings_check() {
-       # If there is a function defined that is called __check
-       # we call that function
-       if [ -n "$(type -t hook_check)" ]; then
-               hook_check || return $?
-       fi
-
-       return ${EXIT_OK}
+       local check_func="${1}"
+
+       # Execute the check function
+       "${check_func}"
+       local ret="${?}"
+
+       case "${ret}" in
+               # OK
+               ${EXIT_OK}|${EXIT_TRUE})
+                       log DEBUG "Configuration check succeeded."
+                       return ${EXIT_TRUE}
+                       ;;
+
+               # Error
+               ${EXIT_ERROR}|${EXIT_FALSE})
+                       log CRITICAL "Configuration check failed. No settings have been written."
+                       return ${EXIT_FALSE}
+                       ;;
+
+               # Command not found
+               ${EXIT_COMMAND_NOT_FOUND})
+                       log CRITICAL "Configuration check function '${check_func}' was not found."
+                       return ${EXIT_FALSE}
+                       ;;
+       esac
+
+       log CRITICAL "Unhandled exit code for '${check_func}': ${ret}"
+       return ${EXIT_ERROR}
 }
 
 function settings_set() {
index f627d99..18a8f18 100644 (file)
@@ -436,6 +436,16 @@ function binary_exists() {
        return ${EXIT_ERROR}
 }
 
+function function_exists() {
+       local function="${1}"
+
+       if [ "$(type -t "${function}")" = "function" ]; then
+               return ${EXIT_TRUE}
+       fi
+
+       return ${EXIT_FALSE}
+}
+
 function process_kill() {
        local process=${1}
 
index 26fed66..22688a2 100644 (file)
@@ -855,24 +855,28 @@ function zone_file() {
 
 function zone_settings_read() {
        local zone=${1}
-
        assert isset zone
 
        # Save the HOOK variable.
        local hook="${HOOK}"
 
-       settings_read $(zone_file ${zone})
+       settings_read "${zone}" ${HOOK_SETTINGS}
 
        # Restore hook.
        HOOK="${hook}"
 }
 
 function zone_settings_write() {
-       local zone=${1}
-
+       local zone="${1}"
        assert isset zone
 
-       settings_write $(zone_file ${zone}) ${HOOK_SETTINGS}
+       local args
+       if function_exists "hook_check_settings"; then
+               list_append args "--check=\"hook_check_settings\""
+       fi
+       list_append args ${HOOK_SETTINGS}
+
+       settings_write "$(zone_file ${zone})" ${args}
 }
 
 function zone_settings_set() {
@@ -901,7 +905,8 @@ function zone_settings_get() {
        assert isset key
 
        (
-               zone_settings_read ${zone}
+               zone_settings_read "${zone}" "${key}" \
+                       --ignore-superfluous-settings
 
                echo "${!key}"
        )
@@ -947,8 +952,14 @@ function zone_port_settings_write() {
        local port="${2}"
        shift 2
 
+       local args
+       if function_exists "hook_check_port_settings"; then
+               list_append args "--check=\"hook_check_port_settings\""
+       fi
+       list_append args $@
+
        local path="$(zone_dir "${zone}")/ports/${port}"
-       settings_write "${path}" "$@"
+       settings_write "${path}" ${args}
 }
 
 function zone_port_settings_remove() {
index a9e1ebe..1f3a661 100644 (file)
@@ -34,17 +34,17 @@ function hook_new() {
        assert isset zone
        shift
 
-       settings_read $(zone_dir ${zone})/settings
+       zone_settings_read "${zone}"
 
        hook_parse_cmdline $@
 
-       settings_write $(zone_dir ${zone})/settings ${HOOK_SETTINGS}
+       zone_settings_write "${zone}"
 
        exit ${EXIT_OK}
 }
 
 function hook_edit() {
-       hook_create $@
+       hook_new $@
 }
 
 function hook_remove() {
index 99080cf..40b9735 100644 (file)
@@ -28,7 +28,7 @@ PORT_CHILDREN_VAR="SLAVES"
 ADDRESS=$(mac_generate)
 SLAVES=
 
-function hook_check() {
+function hook_check_settings() {
        assert isset ADDRESS
        assert ismac ADDRESS
 }
index 33a3167..b554c44 100644 (file)
@@ -28,7 +28,7 @@ SLAVES=""
 MIIMON=100
 MODE="balance-rr"
 
-function hook_check() {
+function hook_check_settings() {
        assert isset ADDRESS
        assert ismac ADDRESS
 
index df41ac9..617084e 100644 (file)
@@ -23,7 +23,7 @@
 
 HOOK_SETTINGS="HOOK ADDRESS"
 
-function hook_check() {
+function hook_check_settings() {
        assert ismac ADDRESS
 }
 
index fca74ae..783e0fc 100644 (file)
@@ -26,7 +26,7 @@
 
 HOOK_SETTINGS="HOOK ADDRESS DEVICE"
 
-function hook_check() {
+function hook_check_settings() {
        assert ismac DEVICE
 
        if isset ADDRESS; then
index 6ab0aec..b95f6a9 100644 (file)
@@ -25,7 +25,7 @@ HOOK_SETTINGS="HOOK ADDRESS PARENT_DEVICE TAG"
 
 PORT_PARENTS_VAR="PARENT"
 
-function hook_check() {
+function hook_check_settings() {
        assert isset PARENT_DEVICE
        assert isinteger TAG
 
index 1544473..7c9ea36 100644 (file)
@@ -30,7 +30,7 @@ MTU=1500
 PHY=
 SSID=
 
-function hook_check() {
+function hook_check_settings() {
        assert isset ADDRESS
        assert ismac ADDRESS
        assert isset CHANNEL
index 8de0aba..3ff80d0 100644 (file)
@@ -32,7 +32,7 @@ KEY=""
 MODE="g"
 SSID=
 
-function hook_check() {
+function hook_check_settings() {
        assert isset ADDRESS
        assert ismac ADDRESS
        assert isset BROADCAST_SSID
index 2777c90..a0a9bf9 100644 (file)
@@ -36,7 +36,7 @@ SERVER_ADDRESS=""
 # The public IPv4 address of the tunnel client.
 PUBLIC_ADDRESS=""
 
-function hook_check() {
+function hook_check_settings() {
        assert isset SIX_RD_PREFIX
        assert isset PUBLIC_ADDRESS
        assert isset SERVER_ADDRESS
@@ -101,7 +101,7 @@ function hook_up() {
        assert isset zone
 
        # Read configuration options.
-       zone_settings_read "${zone}" ${HOOK_SETTINGS}
+       zone_settings_read "${zone}"
 
        # Configure the tunnel.
        if ! device_exists "${zone}"; then
@@ -150,7 +150,7 @@ function hook_status() {
 
        cli_device_headline ${zone}
 
-       zone_settings_read "${zone}" ${HOOK_SETTINGS}
+       zone_settings_read "${zone}"
 
        local server_line="${SERVER_ADDRESS}"
        local server_hostname=$(dns_get_hostname ${SERVER_ADDRESS})
index 898d898..2fc91ad 100644 (file)
@@ -44,7 +44,7 @@ TUNNEL_ID=
 USERNAME=
 PASSWORD=
 
-function hook_check() {
+function hook_check_settings() {
        assert isset SERVER_ADDRESS
        assert isset LOCAL_ADDRESS
        assert isset LOCAL_ADDRESS6
@@ -102,7 +102,7 @@ function hook_up() {
        assert isset zone
 
        # Read configuration options.
-       zone_settings_read "${zone}" ${HOOK_SETTINGS}
+       zone_settings_read "${zone}"
 
        if enabled AUTO_UPDATE_ENDPOINT; then
                log DEBUG "Updating tunnel endpoint"
@@ -156,7 +156,7 @@ function hook_status() {
 
        cli_device_headline ${zone}
 
-       zone_settings_read "${zone}" ${HOOK_SETTINGS}
+       zone_settings_read "${zone}"
 
        local server_line="${SERVER_ADDRESS}"
        local server_hostname=$(dns_get_hostname ${SERVER_ADDRESS})
index 86030a4..d8852eb 100644 (file)
@@ -30,7 +30,7 @@ PROTOCOL="tic"
 TUNNEL_ID=
 REQUIRE_TLS="true"
 
-function hook_check() {
+function hook_check_settings() {
        assert isset USERNAME
        assert isset PASSWORD
        assert isset SERVER
@@ -109,7 +109,7 @@ function hook_status() {
 
        cli_device_headline ${zone}
 
-       zone_settings_read "${zone}" ${HOOK_SETTINGS}
+       zone_settings_read "${zone}"
 
        cli_headline 2 "Configuration"
        cli_print_fmt1 2 "User" "${USERNAME}"
index 021e440..b29c968 100644 (file)
@@ -38,7 +38,7 @@ STP_HELLO=2
 STP_MAXAGE=20
 STP_PRIORITY=512
 
-function hook_check() {
+function hook_check_settings() {
        assert ismac MAC
        assert isbool STP
        assert isoneof STP_MODE stp rstp
@@ -84,7 +84,7 @@ function hook_up() {
        local zone=${1}
        assert isset zone
 
-       zone_settings_read "${zone}" ${HOOK_SETTINGS}
+       zone_settings_read "${zone}"
 
        # Create the bridge if it does not already exist.
        if ! device_exists "${zone}"; then
index 7e2e688..441e95e 100644 (file)
@@ -70,7 +70,7 @@ HOOK_SETTINGS="${HOOK_SETTINGS} PHONE_NUMBER"
 IMSI=
 HOOK_SETTINGS="${HOOK_SETTINGS} IMSI"
 
-function hook_check() {
+function hook_check_settings() {
        assert isset DEVICE
        assert isset PHONE_NUMBER
 
@@ -140,14 +140,14 @@ function hook_up() {
        assert isset zone
 
        # Load configuration file.
-       zone_settings_read "${zone}" ${HOOK_SETTINGS}
+       zone_settings_read "${zone}"
 
        # If we have got a PIN, we try to unlock the device first.
        if isset PIN; then
                if ! modem_sim_auto_unlock "${DEVICE}" "${PIN}"; then
                        # Reset the PIN setting.
                        PIN=""
-                       zone_settings_write "${zone}" ${HOOK_SETTINGS}
+                       zone_settings_write "${zone}"
                        error "Could not unlock the SIM card. Removing PIN from settings."
                fi
 
@@ -179,7 +179,7 @@ function hook_status() {
 
        cli_device_headline ${zone}
 
-       zone_settings_read "${zone}" ${HOOK_SETTINGS}
+       zone_settings_read "${zone}"
 
        cli_headline 2 "Configuration"
        cli_print_fmt1 2 "Username" "${USERNAME}"
@@ -272,7 +272,7 @@ function hook_ppp_write_config() {
        assert isset file
 
        # Read in the configuration files.
-       zone_settings_read "${zone}" ${HOOK_SETTINGS}
+       zone_settings_read "${zone}"
 
        pppd_write_config ${file} \
                --interface="${zone}" \
index b201ebe..461d7a9 100644 (file)
@@ -51,7 +51,7 @@ IPV6="true"
 # Use IPv6 prefix delegation.
 PREFIX_DELEGATION="false"
 
-function hook_check() {
+function hook_check_settings() {
        assert isset USERNAME
        assert isset PASSWORD
 
@@ -105,7 +105,7 @@ function hook_up() {
        local zone=${1}
        assert isset zone
 
-       zone_settings_read "${zone}" ${HOOK_SETTINGS}
+       zone_settings_read "${zone}"
 
        # Bring up the port.
        local port=$(__hook_get_port "${zone}")
@@ -121,7 +121,7 @@ function hook_down() {
        local zone=${1}
        assert isset zone
 
-       zone_settings_read "${zone}" ${HOOK_SETTINGS}
+       zone_settings_read "${zone}"
 
        # Stop the ppp daemon.
        pppd_stop ${zone}
@@ -170,7 +170,7 @@ function hook_status() {
 
        cli_device_headline ${zone}
 
-       zone_settings_read "${zone}" ${HOOK_SETTINGS}
+       zone_settings_read "${zone}"
 
        cli_headline 2 "Configuration"
        cli_print_fmt1 2 "Username" "${USERNAME}"
@@ -228,7 +228,7 @@ function hook_ppp_write_config() {
        assert isset file
 
        # Read in the configuration files.
-       zone_settings_read "${zone}" ${HOOK_SETTINGS}
+       zone_settings_read "${zone}"
 
        # A port has to be assigned for this action
        local port=$(__hook_get_port "${zone}")
index 5902a5b..2ce9e93 100644 (file)
@@ -57,7 +57,7 @@ PREFIX_DELEGATION="false"
 # A list of refused authentification methods.
 REFUSED_AUTH_METHODS=""
 
-function hook_check() {
+function hook_check_settings() {
        assert isset USERNAME
        assert isset PASSWORD
        assert isset PEER_ADDRESS
@@ -167,7 +167,7 @@ function hook_up() {
        local zone="${1}"
        assert isset zone
 
-       zone_settings_read "${zone}" ${HOOK_SETTINGS}
+       zone_settings_read "${zone}"
 
        # Check if a port will be used.
        if isset PORT; then
@@ -195,7 +195,7 @@ function hook_down() {
        local zone="${1}"
        assert isset zone
 
-       zone_settings_read "${zone}" ${HOOK_SETTINGS}
+       zone_settings_read "${zone}"
 
        # Stop the ppp daemon.
        pppd_stop "${zone}"
@@ -225,7 +225,7 @@ function hook_status() {
 
        cli_device_headline "${zone}"
 
-       zone_settings_read "${zone}" ${HOOK_SETTINGS}
+       zone_settings_read "${zone}"
 
        # Display port configuration if a port is used.
        if isset PORT; then
@@ -283,7 +283,7 @@ function hook_ppp_write_config() {
        assert isset file
 
        # Read in the configuration files.
-       zone_settings_read "${zone}" ${HOOK_SETTINGS}
+       zone_settings_read "${zone}"
 
        # Prepare the command line options for the pptp plugin.
        local pptp_commandline="pptp ${PEER_ADDRESS} --nolaunchpppd"
index e376ab0..52a3da3 100644 (file)
@@ -31,7 +31,7 @@ SSID=
 KEY=
 ENCRYPTION_MODE=
 
-function hook_check() {
+function hook_check_settings() {
        assert isset SSID
 
        if isset ADDRESS; then
@@ -81,7 +81,7 @@ function hook_up() {
        assert isset zone
 
        # Read zone configuration.
-       zone_settings_read "${zone}" ${HOOK_SETTINGS}
+       zone_settings_read "${zone}"
 
        if ! device_exists ${zone}; then
                #  Create the wireless interface.