All pastes #148931 Raw Edit

Stuff

public text v1 · immutable
#148931 ·published 2006-08-25 13:21 UTC
rendered paste body

#!/sbin/runscript
# Copyright (c) 2004-2005 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header$

# Contributed by Roy Marples (uberlord@gentoo.org)
# Many thanks to Aron Griffis (agriffis@gentoo.org)
# for help, ideas and patches

#NB: Config is in /etc/conf.d/net

if [[ -n ${NET_DEBUG} ]]; then
        set -x
        devnull=/dev/stderr
else
        devnull=/dev/null
fi

# For pcmcia users. note that pcmcia must be added to the same
# runlevel as the net.* script that needs it.
depend() {
        use coldplug hotplug pcmcia usb isdn wlan

        # Load any custom depend functions for the given interface
        # For example, br0 may need eth0 and eth1
        local iface=${myservice##*.}
        [[ $( type -t depend_${iface} ) == "function" ]] && depend_${iface}
}

# Define where our modules are
MODULES_DIR=/lib/rcscripts/net.modules.d

# Load some functions shared between ourselves and our dhcp helpers
source ${MODULES_DIR}/helpers.d/functions

# Make some wrappers to fudge after/before/need/use depend flags.
# These are callbacks so mods[i] will be set.
after() {
        local x="$*"
        [[ $# -gt 1 ]] && x=$( echo -e "${x// /\n}" | sort | xargs )
        eval "${MODULE}_after() { echo \"$x\"; }"
}
before() {
        local x="$*"
        [[ $# -gt 1 ]] && x=$( echo -e "${x// /\n}" | sort | xargs )
        eval "${MODULE}_before() { echo \"$x\"; }"
}
need() {
        local x="$*"
        [[ $# -gt 1 ]] && x=$( echo -e "${x// /\n}" | sort | xargs )
        eval "${MODULE}_need() { echo \"$x\"; }"
}
installed() {
        local x="$*"
        [[ $# -gt 1 ]] && x=$( echo -e "${x// /\n}" | sort | xargs )
        # We deliberately misspell this as _installed will probably be used
        # at some point
        eval "${MODULE}_instlled() { echo \"$x\"; }"
}

sort() {
        LC_ALL=C /bin/sort "$@"
}

# void module_class_wrap(char *module, char *provides)
# Setup class wrappers: interface_up -> iproute2_up, for example
module_class_wrap() {
        local module=${1} provides=${2} x

        # Don't wrap functions if another module already has
        [[ $( type -t ${provides}_provides ) == function ]] && return

        for x in $( typeset -f | grep -o ^${module}_'[^ ]*' ); do
                eval "${provides}${x#${module}}() { ${x} \"\$@\"; }"
        done
}

# bool module_load_minimum(char *module)
#
# Does the minimum checking on a module - even when forcing
module_load_minimum() {
        local f=${1} MODULE=${1##*/}

        if [[ ! -f ${f} ]]; then
                eerror "${f} does not exist"
                return 1
        fi

        if ! source ${f} ; then
                eerror "${MODULE} failed a sanity check"
                return 1
        fi

        for f in check_installed provides check_depends depend; do
                [[ $( type -t ${MODULE}_${f} ) == function ]] && continue
                eerror "${MODULE} does not support the required function ${f}"
                return 1
        done

        # Wrap our before/after/need/use functions
        ${MODULE}_depend

        return 0
}


# bool modules_load_auto()
#
# Load and check each module for sanity
# If the module is not installed, the functions are to be removed
modules_load_auto() {
        local e f i j beforefuncs afterfuncs diffs unload

        # Populate the MODULES array
        MODULES=( $( find ${MODULES_DIR}/ -maxdepth 1 -type f ! -name ".*" | sort ) )

        # Each of these sources into the global namespace, so it's
        # important that module functions and variables are prefixed with
        # the module name, for example iproute2_

        beforefuncs="$( typeset -F )"
        j=${#MODULES[@]}
        loaded_interface=false
        for (( i=0; i<j; i++ )); do

                unload=false
                module_load_minimum ${MODULES[i]} || unload=true
                MODULES[i]=${MODULES[i]##*/}

                ! ${unload} && ${MODULES[i]}_check_installed false || unload=true

                if [[ ${MODULES[i]} == interface ]]; then
                        eerror "interface is a reserved name - cannot load a module called interface"
                        return 1
                fi

                afterfuncs="$( typeset -F )"
                if ${unload} ; then
                        unset MODULES[i]
                        unsetfuncs="${unsetfuncs} $( diff -U0 <( echo "${beforefuncs}" ) <( echo "${a$                                | awk 'BEGIN { ORS = " "; } /+declare -f/ { print $3; }' )"
                fi
                beforefuncs="${afterfuncs}"

        done
        MODULES=( "${MODULES[@]}" )

        return 0
}


# bool modules_check_installed(void)
#
# Ensure that all modules have the required modules loaded
# This enables us to remove modules from the MODULES array
# Whilst other modules can still explicitly call them
# One example of this is essidnet which configures network
# settings for the specific ESSID connected to as the user
# may be using a daemon to configure wireless instead of our
# iwconfig module
modules_check_installed() {
        local i j missingdeps nmods=${#MODULES[@]}

        for (( i=0; i<nmods; i++ )); do
                [[ $( type -t ${MODULES[i]}_instlled ) != function ]] && continue
                for j in $( ${MODULES[i]}_instlled ); do
                        missingdeps=true
                        if [[ $( type -t ${j}_check_installed ) == function ]]; then
                                ${j}_check_installed && missingdeps=false
                        fi
                        ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break
                done
        done

        MODULES=( "${MODULES[@]}" )
        PROVIDES=( "${PROVIDES[@]}" )
}

# bool modules_check_user(void)
modules_check_user() {
        local -a umods
        local i j k l npref nmods=${#MODULES[@]}

        # Has the interface got any specific modules?
        eval umods=( \"\$\{modules_${iface}\[@\]\}\" )

        # Global setting follows interface-specific setting
        umods=( "${umods[@]}" "${modules[@]}" )

        # Add our preferred modules
        npref=3
        umods=( "${umods[@]}" "ifconfig" "dhcpcd" "iwconfig" )

        # First we strip any modules that conflict from user settings
        # So if the user specifies pump then we don't use dhcpcd
        for (( i=0; i<${#umods[@]}; i++ )); do
                # Some users will inevitably put "dhcp" in their modules
                # list.  To keep users from screwing up their system this
                # way, ignore this setting so that the default dhcp
                # module will be used.
                [[ ${umods[i]} == dhcp ]] && continue

                # We remove any modules we explicitly don't want
                if [[ ${umods[i]} == !* ]]; then
                        for (( j=0; j<nmods; j++ )); do
                                [[ -z ${MODULES[j]} ]] && continue
                                if [[ ${umods[i]:1} == ${MODULES[j]} || ${umods[i]:1} == ${PROVIDES[j$                                        # We may need to setup a class wrapper for it even though
                                        # we don't use it directly
                                        ${MODULES[j]}_check_installed && module_class_wrap ${MODULES[$
                                        unset MODULES[j]
                                        unset PROVIDES[j]
                                        break
                                fi
                        done
                        continue
                fi

                if [[ $( type -t ${umods[i]}_provides ) != function ]]; then
                        # If the module is one of our preferred modules, then
                        # ignore this error; whatever is available will be
                        # used instead.
                        (( i < ${#umods[@]} - npref )) || continue
                        eerror "${umods[i]} is not a valid module (missing provides)"
                        return 1
                fi

                # Ensure that the user specified module has its package installed
                if (( i < ${#umods[@]} - npref )); then
                        # $1==true causes check_installed to report its own errors
                        ${umods[i]}_check_installed true || return 1
                else
                        # If this happens on a preferred modules, ignore it;
                        # whatever is available will be used instead.
                        ${umods[i]}_check_installed false || continue
                fi

                mod=$( ${umods[i]}_provides )
                for (( j=0; j<nmods; j++ )); do
                        [[ -z ${MODULES[j]} ]] && continue
                        if [[ ${PROVIDES[j]} == ${mod} && ${umods[i]} != ${MODULES[j]} ]]; then
                                # We don't have a match - now ensure that we still provide an alterna$                                # This is to handle our preferred modules.
                                for (( l=0; l<nmods; l++ )); do
                                        [[ ${l} -eq ${j} || -z ${MODULES[l]} ]] && continue
                                        if [[ ${PROVIDES[l]} == ${mod} ]]; then
                                                unset MODULES[j]
                                                unset PROVIDES[j]
                                                break
                                        fi
                                done
                        fi
                done
        done

        # Then we strip conflicting modules.
        # We only need to do this for 3rd party modules that conflict with
        # our own modules and the preferred list AND the user modules
        # list doesn't specify a preference.
        for (( i=0; i<nmods-1; i++ )); do
                [[ -z ${MODULES[i]} ]] && continue
                for (( j=i+1; j<nmods; j++)); do