#!/bin/sh
# ifupdown like networking.service with /etc/default/networking.
# async: starts ifup of the auto interfaces in its own session and returns at
#        once; output and exit status go to /run/network/networking-async.*.
# start: waits for the ifup of async and passes on its output and exit status,
#        without one runs ifup itself; after a stop also the hotplug interfaces.
# stop:  ends the ifup of async, then takes down all interfaces except lo.
set -a
# shellcheck disable=SC1091
[ -r /etc/default/networking ] && . /etc/default/networking
set +a
R=/run/network
J=$R/networking-async
mkdir -p "$R"

running() { [ -f "$J.pid" ] && kill -0 "$(cat "$J.pid")" 2>/dev/null; }

case $1 in
async)
	running && exit 0
	rm -f "$J.pid" "$J.rc" "$J.log"
	setsid "$0" job </dev/null >"$J.log" 2>&1 &
	echo $! >"$J.pid"
	exit 0
	;;
job)
	ifup -a --read-environment
	rc=$?
	if [ -f "$R/restart-hotplug" ]; then
		ifup -a --read-environment --allow=hotplug || :
	fi
	echo "$rc" >"$J.rc.tmp" && mv -f "$J.rc.tmp" "$J.rc"
	exit "$rc"
	;;
start)
	if [ -f "$J.pid" ]; then
		while [ ! -f "$J.rc" ] && running; do sleep 0.1; done
		[ -s "$J.log" ] && cat "$J.log"
		rc=$(cat "$J.rc" 2>/dev/null)
		rm -f "$J.pid" "$J.rc" "$J.log"
		[ -n "$rc" ] || { echo "networking: ifup of networking-async ended without status" >&2; exit 1; }
		exit "$rc"
	fi
	ifup -a --read-environment
	rc=$?
	if [ -f "$R/restart-hotplug" ]; then
		ifup -a --read-environment --allow=hotplug || :
	fi
	exit $rc
	;;
stop)
	if running; then
		kill -s TERM -- "-$(cat "$J.pid")" 2>/dev/null
		i=0
		while running && [ "$i" -lt 30 ]; do sleep 0.1; i=$((i + 1)); done
	fi
	rm -f "$J.pid" "$J.rc" "$J.log"
	ifdown -a --read-environment --exclude=lo
	rc=$?
	touch "$R/restart-hotplug"
	exit $rc
	;;
*)
	echo "usage: networking async|start|stop" >&2
	exit 100
	;;
esac
