#! /bin/sh -e
#
# Notify when the IP address is changed on an interface.
# Arguments:
#	$1 - event name
#	$2 - iface name
#	$3 - ip-address

exec 2>/dev/console
#set -x

# Detects if shell functions, aliases, executables exist.
# Returns only a status code, no output.
exists() {
	local _basename

	[ "$1" ] || {
		logger -p error "$0: exists: argument missing"
		exit 1
	}

	_basename="${1##*/}"
	_basename="${_basename%% *}"

	type "$_basename" > /dev/null 2>&1 || return 1

	return 0
}

running_daemon() {
	local _basename

	[ "$1" ] || {
		logger -p error "$0: running_daemon: argument missing"
		exit 1
	}

	_basename="${1##*/}"
	_basename="${_basename%% *}"

	exists $_basename && [ "$(pidof $_basename)" ] || return 1

	return 0
}

test_invar_nbr() {
	if [ $1 -lt $2 ]; then
		echo $0 "<New|Deleted|NewLink> <interface name> <IP address>"
		logger -p daemon.info "$0: Wrong number of arguments!"
		exit 1
	fi
}

ipv4_addr() {
	echo "$1" | grep -q '^\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}$' || return 1
}

# At least 2 command line arguments are always needed
test_invar_nbr $# 2

iface=$(echo $2 | sed -e 's/:/_/g')
ip_addrs=$(ip address list dev $iface | \
	   sed -rne "s~^[[:space:]]*inet[[:space:]]+([0-9./]+)[[:space:]]+brd.*scope.*$iface~\1~p") || :

case $1 in
	New)
		test_invar_nbr $# 3
		logger -p daemon.info "$0: New IP address for $2 is $3."

		case $2 in
			eth0)
				id_uploader $3
				if exists dnsupdate.script; then
					. /etc/sysconfig/dnsupdate.conf
					if [ "$DNSUPDATE_ENABLED" = yes ]; then
						# This arbitrary number is not good!
						sleep 5
						dnsupdate.script add "$DNSUPDATE_NAME" all
					fi
				fi

				# axisns fails if there are link local IPv4
				# addresses only, so ignore its exit status.
				! exists axisns || axisns add || :

				if [ -e /var/run/upnp/upnp.state ]; then
					/etc/init.d/upnp stop
					rm /var/run/upnp/upnp.state
					sleep 1
					. /etc/conf.d/upnp
					[ "$UPNP_ENABLED" != yes ] ||
						/etc/init.d/upnp start
				fi

				if ipv4_addr $3; then
					if running_daemon libupnp &&
					   [ -x /etc/init.d/libupnp ]; then
						/etc/init.d/libupnp restart
					fi
				fi

				/etc/init.d/rendezvous reload || :

				! running_daemon syslogd ||
					killall -HUP syslogd

				! running_daemon remote_ptzserver ||
					killall -HUP remote_ptzserver

				if running_daemon time_handler; then
					[ ! -r /var/run/time_handler.pid ] || {
						p=$(cat /var/run/time_handler.pid) || :
						[ -z "$p" ] || kill -HUP $p
					}
				fi

				if ipv4_addr $3; then
					if running_daemon media_server; then
						[ ! -r /var/run/media_server/media_server.pid ] || {
							p=$(cat /var/run/media_server/media_server.pid) || :
							[ -z "$p" ] || kill -HUP $p
						}
					fi
				fi
				;;
			*)
				logger -p info "Interface $iface ignored"
				;;
		esac
		;;
	Deleted)
		test_invar_nbr $# 3
		logger -p daemon.info "$0: Removed IP address $3 from $2."

		if ipv4_addr $3; then
			if running_daemon libupnp &&
			   [ -x /etc/init.d/libupnp ]; then
				if [ "$ip_addrs" ]; then
					/etc/init.d/libupnp restart
				else
					/etc/init.d/libupnp stop
				fi
			fi
		fi

		/etc/init.d/rendezvous reload || :
		;;

	NewLink)
		logger -p info "New uplink $iface"
		dmesg | tail >&2

		[ ! -x /etc/init.d/net.$iface ] ||
			/etc/init.d/net.$iface force-reload
		set_led link_up $iface
		;;

	NoLink)
		logger -p info "No uplink $iface"
		dmesg | tail >&2

		set_led link_down $iface
		;;
	*)
		echo "$0 <New|Deleted|NewLink|NoLink>" \
		     "<interface name> <IP address>"
		exit 1
		;;
esac

exit 0
