@@ -14,11 +14,10 @@ case "$2" in
printf '%s' "$profile" > "$PROFILE_FILE"
exit 0
fi
- done < <(list_profiles | while IFS= read -r profile; do
+ done < <(filter_profiles "$1" ethernet | while IFS= read -r profile; do
report_debug "Examining profile '$profile'"
(
- source "$PROFILE_DIR/$profile" > /dev/null
- [[ $Interface == "$1" && $Connection == "ethernet" ]] || exit
+ load_profile "$profile" > /dev/null
# Prioritize dhcp based profiles as they can outright fail, whereas
# it is difficult to tell if a profile with a static address fails
if [[ $IP == "dhcp" || $IP6 == dhcp* ]]; then
@@ -1,7 +1,6 @@
#! /bin/bash
. /usr/lib/netctl/globals
-. "$SUBR_DIR/interface"
. "$SUBR_DIR/ip"
export INTERFACE="$1"
@@ -11,7 +10,6 @@ PROFILE_FILE="$STATE_DIR/netctl-auto-$INTERFACE.profile"
case $ACTION in
CONNECTED)
load_profile "$WPA_ID_STR"
- load_interface_config "$INTERFACE"
DhcpcdOptions+=" -K -L"
ip_set || exit 1
mkdir -p "$(dirname "$PROFILE_FILE")"
@@ -26,7 +24,6 @@ case $ACTION in
DISCONNECTED)
if [[ -s "$PROFILE_FILE" ]]; then
load_profile "$(< "$PROFILE_FILE")"
- load_interface_config "$INTERFACE"
rm -f "$PROFILE_FILE"
# Sandbox the eval
if ! ( do_debug eval "$ExecDownPre" ); then
@@ -103,41 +103,71 @@ timeout_wait() {
### Profile management
-## List all acceptable profiles names separated by newlines
-list_profiles() {
- # Follow aliases with -L, skip forbidden/reserved names
- find -L "$PROFILE_DIR/" -maxdepth 1 -type f -not -name '.*' -not -name '*~' -not -name $'*\n*' -not -name '*.action' -not -name '*.conf' -not -name '*.service' -printf '%f\n'
+## Load all available hooks
+load_hooks() {
+ local hook
+ while IFS= read -r hook; do
+ source "$hook"
+ done < <(find -L "$PROFILE_DIR/hooks" -maxdepth 1 -type f -executable -not -name '.*' -not -name '*~' -not -name $'*\n*' | sort)
}
-## Exit if a profile file is not syntactically correct
-# $1: profile name
-verify_profile() {
- /bin/bash -n "$PROFILE_DIR/$1" || exit 1
+## Load interface configuration, if present
+# $1: interface name
+load_interface_config() {
+ local config_file="$PROFILE_DIR/interfaces/$1"
+ if [[ -x $config_file ]]; then
+ source "$config_file"
+ fi
}
## Sources all hooks and a profile (but no interface configuration)
# $1: profile name
load_profile() {
- local hook
# Expose the profile name
Profile=$1
if [[ -z $Profile || ! -r "$PROFILE_DIR/$Profile" ]]; then
exit_error "Profile '$Profile' does not exist or is not readable"
fi
- while IFS= read -r hook; do
- source "$hook"
- done < <(find -L "$PROFILE_DIR/hooks" -maxdepth 1 -type f -executable -not -name '.*' -not -name '*~' -not -name $'*\n*' | sort -u)
- unset hook
+ load_hooks
source "$PROFILE_DIR/$Profile"
if [[ -z $Interface ]]; then
exit_error "Profile '$Profile' does not specify an interface"
fi
+ load_interface_config "$Interface"
if [[ ! -r "${Connection:+$SUBR_DIR/connections/$Connection}" ]]; then
exit_error "Profile '$Profile' does not specify a valid connection"
fi
source "$SUBR_DIR/connections/$Connection"
}
+## List all acceptable profiles names separated by newlines
+list_profiles() {
+ # Follow aliases with -L, skip forbidden/reserved names
+ find -L "$PROFILE_DIR/" -maxdepth 1 -type f -not -name '.*' -not -name '*~' -not -name $'*\n*' -not -name '*.action' -not -name '*.conf' -not -name '*.service' -printf '%f\n'
+}
+
+## List names of profiles for a given interface and/or connection
+# $1: interface (optional)
+# $2: connection (optional)
+filter_profiles() {
+ list_profiles | while IFS= read -r Profile; do
+ if (
+ source "$PROFILE_DIR/$Profile" || exit
+ [[ -z $1 || $1 == "$Interface" ]] || exit
+ load_interface_config "$Interface"
+ [[ -z $2 || $2 == "$Connection" ]] || exit
+ ); then
+ printf '%s\n' "$Profile"
+ fi
+ done
+}
+
+## Exit if a profile file is not syntactically correct
+# $1: profile name
+verify_profile() {
+ /bin/bash -n "$PROFILE_DIR/$1" || exit 1
+}
+
## Wrapper around systemctl converting profile names to unit names
# $1: systemctl command
# $2...: profile names
@@ -1,15 +1,6 @@
## /usr/lib/netctl/globals needs to be sourced before this file
-## Load interface configuration, if present
-# $1: interface name
-load_interface_config() {
- local config_file="$PROFILE_DIR/interfaces/$1"
- if [[ -x $config_file ]]; then
- source "$config_file"
- fi
-}
-
## Check if a string represents a network interface
# $1: potential interface name
is_interface() {
@@ -88,7 +88,6 @@ elif [[ $# -eq 2 && $1 == @(start|stop) ]]; then
# Expose the command
Command=$1
load_profile "$2"
- load_interface_config "$Interface"
"network_$1"
else
exit_error "Usage: $0 {start|stop|wait-online} [profile]"
@@ -211,12 +211,10 @@ start() {
# Disable p2p to prevent wpa_supplicant from creating another control interface
echo "p2p_disabled=1" >> "$WPAConfigFile"
- local profile
- list_profiles | while IFS= read -r profile; do
+ filter_profiles "$interface" wireless | while IFS= read -r profile; do
report_debug "Examining profile '$profile'"
(
- source "$PROFILE_DIR/$profile"
- [[ $Interface == "$interface" && $Connection == "wireless" ]] || exit
+ load_profile "$profile"
is_yes "${ExcludeAuto:-no}" && exit
# Set default and exclude wpa-config as it does not fit this scheme
[[ ${Security:=none} != "wpa-config" ]] || exit
@@ -71,16 +71,11 @@ stop_all() {
}
switch_to() {
- cd "$PROFILE_DIR"
- # We assume interface names are not quoted
- # Using read removes leading whitespace
- read InterfaceLine < \
- <(grep -om1 '^[[:space:]]*Interface=[[:alnum:]:._-]\+' "$1")
- if [[ -z $InterfaceLine ]]; then
+ Interface=$(. "$PROFILE_DIR/$1" >/dev/null; printf '%s' "$Interface")
+ if [[ -z $Interface ]]; then
exit_error "Profile '$1' does not specify an interface"
fi
- mapfile -t AllProfiles < <(list_profiles)
- mapfile -t Profiles < <(grep -Fl "$InterfaceLine" "${AllProfiles[@]}")
+ mapfile -t Profiles < <(filter_profiles "$Interface")
if (( ${#Profiles[@]} )); then
do_debug sd_call stop "${Profiles[@]}" 2> >(grep -Fv 'not loaded' >&2)
fi