#!/bin/sh

### BEGIN INIT INFO
# Provides:         opsi
# Required-Start:   $syslog
# Required-Stop:    $syslog
# Default-Start:    2 3 4 5
# Default-Stop:     0 1 6
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
LOG_FILE=/tmp/log
BOOTIMAGE_VERSION="$(cat /version)"
OPSI_HOST_KEY=""

. /lib/lsb/init-functions

set +e

logMessage(){
	message="$1"
	if [ "${OPSI_HOST_KEY}" != "" ]; then
		message=$(echo "$message" | sed s"/${OPSI_HOST_KEY}/*** confidential ***/g")
	fi
	date +"%b %d %H:%M:%S" | tr -d '\n' >> $LOG_FILE
	echo " [opsiinit] $message" >> $LOG_FILE
}

getOpsiHostKey(){
	CMDLINE="$(cat /proc/cmdline)"
	OPSI_HOST_KEY="${CMDLINE##*pckey=}"
	OPSI_HOST_KEY="${OPSI_HOST_KEY%%[     ]*}"
}

getBootParam(){
	CMDLINE="$(cat /proc/cmdline)"
	logMessage "getBootParam($1): cmdline: $CMDLINE"
	case $CMDLINE in
		*$1=*)
			result="${CMDLINE##*$1=}"
			result="${result%%[     ]*}"
			echo "$result"
			return 0
		;;
		*\ $1\ *|*\ $1)
			return 0
		;;
	esac
	return 1
}

setPasswordHash() {
	pwh=$1
	sep_found="0"
	echo $pwh | grep ":" >/dev/null 2>/dev/null && sep_found="1"
	if [ "sep_found" = "1" ]; then
		sed -i "s|root:.*|root:$pwh|" /etc/shadow
	else
		opt=$(cat /etc/shadow | grep root | cut -d ':' -f3-)
		sed -i "s|root:.*|root:$pwh:$opt|" /etc/shadow
	fi
}

getNetworkDevices() {
	force_link=$1
	[ "$force_link" != "" ] &&  logMessage "getNetworkDevices(): link forced"
	devices_link=""
	devices=""
	for device in `awk -F: '/ens|enp|eno|eth/ {print $1}' /proc/net/dev 2>/dev/null`; do
		link=`ethtool $device | grep -i "link detected" | cut -d ":" -f2 | sed 's/ //g'`
		devices="$devices $device"
		[ "$link" = "yes" ] && devices_link="$devices_link $device"
	done
	logMessage "getNetworkDevices(): device(s) found: $devices, device(s) with link: $devices_link"
	if [ "$devices_link" != "" ]; then
		# link-up devices found, returning link-up devices
		logMessage "getNetworkDevices(): device(s) with link found, returning $devices_link"
		echo $devices_link
		return 0
	else
		if [ "$force_link" != "" ]; then
			# no link-up devices found, returning error
			logMessage "getNetworkDevices(): no devices with link found, returning error"
			return 1
		fi
		# no link-up devices found, returning all devices found
		logMessage "getNetworkDevices(): no devices with link found, returning $devices"
		echo $devices
		return 0
	fi
}

case "$1" in
	start)
		log_begin_msg "Starting opsi init"
		
		logMessage "opsi init script started"
		logMessage "opsi linux bootimage version: $BOOTIMAGE_VERSION"
		
		getOpsiHostKey
		
		# Boot params
		pwh="$(getBootParam pwh 2>/dev/null || true)"
		logMessage "boot param pwh=$pwh"
		[ "$pwh" != "" ] && setPasswordHash $pwh
		
		nodhcp="0"
		getBootParam nodhcp 2>/dev/null
		[ "$?" = "0" ] && nodhcp="1"
		logMessage "boot param nodhcp=$nodhcp"
		
		hn="$(getBootParam hn 2>/dev/null || true)"
		logMessage "boot param hn=$hn"
		
		LANGUAGE="$(getBootParam lang 2>/dev/null || true)"
		logMessage "boot param lang=$LANGUAGE"
		[ -n "$LANGUAGE" ] || LANGUAGE="de"
		
		# Localization
		LOCALE="de_DE.UTF8"
		KEYMAP="de-latin1-nodeadkeys"
		
		case "$LANGUAGE" in
			en)
				# English version
				LOCALE="en_US.UTF8"
				KEYMAP="us"
				;;
			fr)
				# French version
				LOCALE="fr_FR.UTF8"
				KEYMAP="fr"
				;;
			be)
				# Belgian version
				LOCALE="nl_BE.UTF8"
				KEYMAP="be-latin1"
				;;
			da)
				#Danish version
				LOCALE="da_DK.UTF8"
				KEYMAP="dk"
				;;
			it)
				# Italy
				LOCALE="it_IT.UTF8"
				KEYMAP="it"
				;;
		esac
		
		logMessage "loading keymap $KEYMAP"
		loadkeys -q $KEYMAP
		
		logMessage "setting language environment (LANG=$LOCALE, LANGUAGE=$LANGUAGE, LC_ALL=$LOCALE)"
		echo "LANG=\"$LOCALE\""		>  /etc/environment
		echo "LANGUAGE=\"$LANGUAGE\""	>> /etc/environment
		echo "LC_ALL=\"$LOCALE\""	>> /etc/environment
		
		# Networking
		echo "auto lo" > /etc/network/interfaces
		echo "iface lo inet loopback" >> /etc/network/interfaces
		echo "" >> /etc/network/interfaces
		
		failed="1"
		count="0"
		while [ "$failed" = "1" -a "$count" != "10" ]; do
			count=$(($count+1))
			devices="$(getNetworkDevices force_link 2>/dev/null)"
			failed=$?
			if [ "$failed" = "0" ]; then
				logMessage "device(s) found: $devices"
			else
				logMessage "no devices found, sleeping 3 seconds"
				sleep 3
			fi
		done
		
		devices="$(getNetworkDevices 2>/dev/null || true)"
		for device in $devices; do
			if [ "$nodhcp" = "0" ]; then
				logMessage "using dhcp, adding entry for device $device to /etc/network/interfaces"
				echo "auto $device" >> /etc/network/interfaces
				echo "iface $device inet dhcp" >> /etc/network/interfaces
				echo "" >> /etc/network/interfaces
				dhclient $device -lf /var/lib/dhcp/dhclient.leases
				# trying dhclient instead of: ifup $device
			else
				logMessage "not using dhcp, bringing device $device up"
				ifconfig $device up
			fi
		done
		
		# Hostname
		if [ "$hn" != "" ]; then
			logMessage "Setting hostname to $hn as supplied by cmdline"
			hostname $hn
		elif [ "$nodhcp" = "0" ]; then
			for device in $devices; do
				hn=`pump -s -i $device | grep Hostname | cut -d: -f2 2>/dev/null | sed 's/ //g'`
				if [ "$hn" != "" ]; then
					logMessage "Setting hostname to $hn as set by dhcp for device $device"
					hostname $hn
				fi
			done
		fi
		
		logMessage "opsi init script ended"
		
		initctl emit opsi-init &
		
		;;
	*)
		N=/etc/init.d/$NAME
		echo "Usage: $N {start}" >&2
		exit 1
		;;
esac

exit 0
