#! /bin/bash

. /usr/lib/network/globals


## Check if a string represents a network interface
# $1: potential interface name
is_interface() {
    # Strip any old school alias specifier
    [[ -d "/sys/class/net/${1%%:?*}" ]]
}

## Check if an interface is up
# $1: interface name
interface_is_up() {
    local flags
    read flags < "/sys/class/net/${1%%:?*}/flags"
    # IFF_UP is defined as 0x1 in linux/if.h
    (( flags & 0x1 ))
}

## Activate an interface
# $1: interface name
bring_interface_up() {
    local interface=$1
    ip link set dev "$interface" up &>/dev/null
    timeout_wait "${TimeoutUp:-5}" 'interface_is_up "$interface"'
}

## Deactivate an interface
# $1: interface name
bring_interface_down() {
    local interface=$1
    ip link set dev "$interface" down &>/dev/null
    # We reuse the up timeout (down normally is faster)
    timeout_wait "${TimeoutUp:-5}" '! interface_is_up "$interface"'
}


if [[ $# -ne 2 || $1 != @(start|stop) ]]; then
    exit_error "Usage: $0 {start|stop} <profile>"
fi
ensure_root netctl
# Ensure we are not in a transient directory
cd /

# Expose the profile name
Profile=$2
load_profile "$Profile"
case $1 in
  start)
    report_notice "Starting network profile '$Profile'..."
    if is_interface "$Interface" && interface_is_up "$Interface" && \
       ! is_yes "${ForceConnect:-no}"; then
        report_error "The interface of network profile '$Profile' is already up"
        exit 1
    fi
    if ! "${Connection}_up"; then
        report_error "Failed to bring the network up for profile '$Profile'"
        exit 1
    fi
    # JP: sandbox the eval
    if ! ( eval $ExecUpPost ); then
        report_error "ExecUpPost failed for network profile '$Profile'"
        # Failing ExecUpPost will take the connection down
        "${Connection}_down"
        exit 1
    fi
    report_notice "Started network profile '$Profile'"
  ;;
  stop)
    report_notice "Stopping network profile '$Profile'..."
    # JP: sandbox the eval
    if ! ( eval $ExecDownPre ); then
        report_error "ExecDownPre failed for network profile '$Profile'"
        # Failing ExecDownPre will leave the profile active
        exit 1
    fi
    if ! "${Connection}_down"; then
        report_error "Failed to bring the network down for profile '$Profile'"
        exit 1
    fi
    if is_interface "$Interface" && interface_is_up "$Interface" && \
       ! is_yes "${ForceConnect:-no}"; then
        report_error "The interface of network profile '$Profile' did not go down"
        exit 1
    fi
    report_notice "Stopped network profile '$Profile'"
  ;;
esac


# vim: ft=sh ts=4 et sw=4:
