#!/bin/bash ############################################################################### # # # IPFire.org - A linux based firewall # # Copyright (C) 2010 Michael Tremer & Christian Schmidt # # # # 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 3 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, see . # # # ############################################################################### HOOK_COMMANDS_CONFIG="hook_create hook_down hook_status hook_up" HOOK_COMMANDS_PORT="hook_create hook_down hook_hotplug hook_hotplug_rename \ hook_info hook_status hook_up" HOOK_COMMANDS_ZONE="hook_add hook_create hook_discover hook_down hook_edit hook_help \ hook_info hook_remove hook_status hook_up \ \ hook_config_create hook_config_edit hook_config_remove hook_config_show \ \ hook_port hook_port_add hook_port_edit hook_port_remove hook_port_show \ hook_port_status hook_port_up hook_port_down \ \ hook_ppp_ip_pre_up hook_ppp_ipv4_down hook_ppp_ipv4_up \ hook_ipv6_down hook_ipv6_up hook_ppp_write_config" function hook_dir() { local type=${1} if [ -n "${type}" ]; then type="/${type}s" fi echo "${NETWORK_HOOKS_DIR}${type}" } NETWORK_HOOKS_DIR_ZONES="$(hook_dir zone)" function hook_exists() { local type=${1} local hook=${2} assert isset type assert isset hook # Add the path prefix. hook="$(hook_dir ${type})/${hook}" [ ! -d "${hook}" ] && [ -x "${hook}" ] } function hook_exec() { local type="${1}" assert isset type local hook="${2}" assert isset hook local cmd="${3}" assert isset cmd assert hook_exists "${type}" "${hook}" shift 3 # Complete the hook command by prepending "hook_" local hook_cmd="hook_${cmd}" # Check if the hook action is valid. local valid_commands case "${type}" in "config") valid_commands="${HOOK_COMMANDS_CONFIG}" ;; "port") valid_commands="${HOOK_COMMANDS_PORT}" ;; "zone") valid_commands="${HOOK_COMMANDS_ZONE}" ;; esac isset valid_commands && assert list_match "${hook_cmd}" ${valid_commands} local hook_path="$(hook_dir ${type})/${hook}" # For performance reasons, all hooks are executed # in a subshell and so will inherit the currently # running environment. ( # Set the name of the hook. HOOK=$(basename ${hook}) # Source the code of the hook. source "${hook_path}" # Make sure HOOK is still properly set. assert isset HOOK # Execute the requested command. cmd "${hook_cmd}" "$@" ) local ret=$? case "${ret}" in ${EXIT_COMMAND_NOT_FOUND}) log ERROR "Hook command not implemented: ${hook_command} ($@)" exit ${EXIT_COMMAND_NOT_FOUND} ;; ${EXIT_ERROR_ASSERT}) log ERROR "Hook exited with an assertion error." exit ${EXIT_ERROR_ASSERT} ;; esac return ${ret} } function config_get_hook() { local config=${1} assert isset config assert [ -e "${config}" ] ( . ${config} echo "${HOOK}" ) } function hook_zone_exists() { hook_exists zone $@ } function hook_zone_port_exists() { local hook_zone=${1} local hook_port=${2} hook_exists zone "${hook_zone}.ports/${hook_port}" } function hook_zone_config_exists() { local hook_zone=${1} local hook_config=${2} hook_exists zone "${hook_zone}.configs/${hook_config}" } function hook_zone_has_ports() { local hook=${1} [ -d "${NETWORK_HOOKS_DIR_ZONES}/${hook}.ports" ] } function hook_zone_has_configs() { local hook=${1} [ -d "${NETWORK_HOOKS_DIR_ZONES}/${hook}.configs" ] } function hook_zone_exec() { hook_exec zone $@ } function hook_zone_port_exec() { local hook_zone=${1} local hook_port=${2} shift 2 hook_zone_exec "${hook_zone}.ports/${hook_port}" $@ } function hook_zone_config_exec() { local hook_zone=${1} local hook_port=${2} shift 2 hook_zone_exec "${hook_zone}.configs/${hook_port}" $@ } function hook_zone_get_all() { local type=${1} local hook for hook in $(hook_dir zone)/*; do hook=$(basename ${hook}) hook_zone_exists ${hook} && echo "${hook}" done } function hook_zone_ports_get_all() { local hook=${1} if ! hook_exists zone ${hook}; then error "Hook '${hook}' does not exist." return ${EXIT_ERROR} fi # If the zone hook has got no ports we exit silently if ! hook_zone_has_ports ${hook}; then return ${EXIT_OK} fi local h for h in $(hook_dir zone)/${hook}.ports/*; do h=$(basename ${h}) if hook_zone_port_exists ${hook} ${h}; then echo "${h}" fi done } function hook_zone_configs_get_all() { local hook=${1} if ! hook_exists zone ${hook}; then error "Hook '${hook}' does not exist." return ${EXIT_ERROR} fi # If the zone hook has got no configurations we exit silently if ! hook_zone_has_configs ${hook}; then return ${EXIT_OK} fi local h for h in $(hook_dir zone)/${hook}.configs/*; do h=$(basename ${h}) if hook_zone_config_exists ${hook} ${h}; then echo "${h}" fi done return ${EXIT_OK} }