#! /bin/bash
#
### BEGIN INIT INFO
# Provides: $network
# Required-Start: network
# Required-Stop: network
# Default-Start: 2 3 4 5
# Short-Description: Wait for the hotplugged network to be up
# Description: Wait for all network interfaces started asynchronously
#              at boot time.
### END INIT INFO

# Source function library.
. /etc/init.d/functions

if [ -z "$NETWORKDELAY" ]; then
    NETWORKDELAY=20
fi
if [ -z "$MIN_LINK_DETECTION_DELAY" ]; then
    MIN_LINK_DETECTION_DELAY=6
fi

ELAPSED_TIME=0
MAX_LINK_DETECTION_DELAY=$MIN_LINK_DETECTION_DELAY

. /etc/sysconfig/network

# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 0
cd /etc/sysconfig/network-scripts

. network-functions

# find all the interfaces besides loopback.
# ignore aliases, alternative configurations, and editor backup files
interfaces=$(ls ifcfg* | \
	    LANG=C sed -e "$__sed_discard_ignored_files" \
		       -e '/\(ifcfg-lo\|:\|ifcfg-.*-range\)/d' \
		       -e '/ifcfg-[A-Za-z0-9\._-]\+$/ { s/^ifcfg-//g;s/[0-9]/ &/}' | \
	    LANG=C sort -k 1,1 -k 2n | \
	    LANG=C sed 's/ //')

function should_wait_network() {
	local NETWORK_UP=1
	for i in $interfaces; do
		unset DEVICE TYPE BOOTPROTO MII_NOT_SUPPORTED
		LINK_DETECTION_DELAY=0
		eval $(LANG=C fgrep "DEVICE=" ifcfg-$i)
		eval $(LANG=C fgrep "TYPE=" ifcfg-$i)
		eval $(LANG=C fgrep "BOOTPROTO=" ifcfg-$i)
		eval $(LANG=C fgrep "MII_NOT_SUPPORTED=" ifcfg-$i)
		eval $(LANG=C fgrep "LINK_DETECTION_DELAY=" ifcfg-$i)

		if [ -z "$DEVICE" ] ; then DEVICE="$i"; fi
		if [ "$BOOTPROTO" != "static" ] && [ "$BOOTPROTO" != "dhcp" ] && [ "$BOOTPROTO" != "bootp" ]; then
		    continue
		fi
		# only check interfaces using ifplug
		# other interfaces are started synchronously from the network service
		# and this service requires the network service
		if [ "$MII_NOT_SUPPORTED" = "yes" ]; then
			continue
		fi
		if LANG=C egrep -q "^ONBOOT=['\"]?[Nn][Oo]['\"]?" ifcfg-$i; then
			continue
		fi
		# no need to check the interface if there is no link
		local LINKDELAY=0
		if ! ip -o link show ${DEVICE} &>/dev/null || check_link_down ${DEVICE}; then
			# don't trust link beat reporting before the specified delay
			[ $ELAPSED_TIME -ge $LINK_DETECTION_DELAY ] && continue
		fi
		# assume that the interface is started if it is assigned an address
		ADDR=`ip addr show ${DEVICE} | grep 'inet ' | awk '{print $2;}'`
		if [ -z "$ADDR" ]; then
		    NETWORK_UP=0
		fi
	done
	return $NETWORK_UP
}

case "$1" in
  start)
	gprintf "Waiting for network to be up"

	for i in $interfaces; do
		LINK_DETECTION_DELAY=0
		eval $(LANG=C fgrep "LINK_DETECTION_DELAY=" ifcfg-$i)
                [ "$LINK_DETECTION_DELAY" -gt $MAX_LINK_DETECTION_DELAY ] && MAX_LINK_DETECTION_DELAY=$LINK_DETECTION_DELAY
        done
        NETWORKDELAY=$(( NETWORKDELAY + MAX_LINK_DETECTION_DELAY ))

	while should_wait_network && [ $ELAPSED_TIME -lt $NETWORKDELAY ]; do
	    sleep 1
	    let ELAPSED_TIME=$ELAPSED_TIME+1
	done
	[ $ELAPSED_TIME -ge $NETWORKDELAY ] && failure || success
	echo
	;;
  stop)
	;;
  *)
        gprintf "Usage: %s\n" "$(basename $0) {start|stop}"
        exit 1
esac

exit 0
