#!/bin/bash
### BEGIN INIT INFO
# Provides:          univention-maintenance
# Required-Start:    $network $remote_fs
# Required-Stop:     $network $remote_fs
# Should-Start:      $named slapd univention-directory-policy
# Should-Stop:       $named slapd
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Univention Updater
### END INIT INFO
# SPDX-FileCopyrightText: 2004-2026 Univention GmbH
# SPDX-License-Identifier: AGPL-3.0-only

# shellcheck source=/dev/null
. /lib/lsb/init-functions
LOG="/var/log/univention/updater.log"

check_policy () {
	eval "$(univention_policy_result -D "${ldap_hostdn:?}" -y /etc/machine.secret -s "${ldap_hostdn:?}")"
	case "$1" in
	stop) [ "${univentionInstallationShutdown:-}" = 1 ] ;;
	start) [ "${univentionInstallationStartup:-}" = 1 ] ;;
	restart) [ "${univentionInstallationShutdown:-}" = 1 ] || [ "${univentionInstallationStartup:-}" = 1 ] ;;
	*) return 2 ;;
	esac
}

case "$1" in
	start|restart|stop|force-reload)

		log_action_begin_msg "Checking network for Univention maintenance"

		dmesg -n 1
		eval "$(univention-config-registry shell)"

		# clean up updater settings
		if [ -n "${update_reboot_required:-}" ]; then
			univention-config-registry unset update/reboot/required >/dev/null 2>&1
		fi

		log_action_cont_msg "ldap[${ldap_server_name:-}]"
		if ! netcat -q0 -w4 "${ldap_server_name:-}" "${ldap_server_port:=7389}" </dev/null >/dev/null 2>&1
		then
			log_action_end_msg 1
			exit 1
		fi
		if ! check_policy "$1"
		then
			log_action_end_msg 0
			exit 0
		fi

		# determine protocol of main repository server
		# shellcheck disable=SC2154
		repository_protocol="${repository_online_server%://*}"
		# use HTTP if no protocol is specified
		[ "$repository_protocol" = "$repository_online_server" ] && repository_protocol="http"
		# use proxy/http as fallback if proxy/https is not specified
		[ -z "${proxy_https:-}" ] && [ -n "${proxy_http:-}" ] && proxy_https="$proxy_http"

		msg_prefix="proxy"
		if [ -n "$proxy_http" ] && [ "$repository_protocol" = "http" ] ; then
			repository_server="${proxy_http}"
		elif [ -n "$proxy_https" ] && [ "$repository_protocol" = "https" ] ; then
			repository_server="${proxy_https}"
		else
			repository_server="$repository_online_server"
			msg_prefix="repository"
		fi
		# get hostname from URL and strip off everything else
		repository_server="${repository_server#*://}"
		repository_server="${repository_server%:*}" # strip port
		repository_server="${repository_server##*@}" # strip login information
		repository_server="${repository_server%/*}" # strip path
		log_action_cont_msg "${msg_prefix}[$repository_server]"

		if ! ping -c 1 "$repository_server" >/dev/null 2>&1
		then
			log_action_end_msg 1
			exit 1
		fi
		log_action_end_msg 0

		if echo "${update_warning_coloured:-}" | grep -E -q -i 'yes|true'
		then
			cred='\033[31;1m'  # red bold
			cgreen='\033[32;1m'  # green bold
			cend='\033[0m'  # reset
		else
			cred='' cgreen='' cend=''
		fi
		down='\033[5B'  # 'CU'rsort 'D'own '5 rows'

		warning_message="$down"
		warning_message+="\\n\\r"
		warning_message+="$cred"
		if echo "${update_warning_lang:-}" | grep -E -q -i '^de$|^ger'
		then
			warning_message+='!!!!!!!!!! Achtung\n\r'
			warning_message+='!!!!!!!!!! die Aktualisierung des Systems kann je nach\n\r'
			warning_message+='!!!!!!!!!! Umfang der Pakete eine lange Zeit in Anspruch\n\r'
			warning_message+='!!!!!!!!!! nehmen.\n\r'
			warning_message+='!!!!!!!!!!\n\r'
			if /sbin/runlevel | grep '2$' > /dev/null 2>&1; then
				warning_message+='!!!!!!!!!! Das System setzt den Startvorgang nach\n\r'
				warning_message+='!!!!!!!!!! der Aktualisierung fort.\n\r'
			elif /sbin/runlevel | grep '0$'> /dev/null 2>&1; then
				warning_message+='!!!!!!!!!! Schalten Sie das System erst aus, wenn die\n\r'
				warning_message+='!!!!!!!!!! Ausgabe \"System halted!\" erscheint.\n\r'
				warning_message+='!!!!!!!!!! Die meisten Systeme schalten sich\n\r'
				warning_message+='!!!!!!!!!! selbstständig aus.\n\r'
			elif /sbin/runlevel | grep '6$'> /dev/null 2>&1; then
				warning_message+='!!!!!!!!!! Das System wird nach der Aktualisierung\n\r'
				warning_message+='!!!!!!!!!! automatisch neu gestartet.\n\r'
			fi
		else
			warning_message+='!!!!!!!!!! Warning\n\r'
			warning_message+='!!!!!!!!!! The update process might take a\n\r'
			warning_message+='!!!!!!!!!! considerable amount of time depending on the\n\r'
			warning_message+='!!!!!!!!!! number and size of installed packages.\n\r'
			warning_message+='!!!!!!!!!!\n\r'
			warning_message+='!!!!!!!!!! Do not switch off the system before\n\r'
			warning_message+='!!!!!!!!!! update is completely finished.\n\r'
			if /sbin/runlevel | grep '2$' > /dev/null 2>&1; then
				warning_message+='!!!!!!!!!! System boot will continue after\n\r'
				warning_message+='!!!!!!!!!! update is finished.\n\r'
			elif /sbin/runlevel | grep '0$'> /dev/null 2>&1; then
				warning_message+='!!!!!!!!!! System can be safely switched off when\n\r'
				warning_message+='!!!!!!!!!! \"System halted!\" is displayed.\n\r'
				warning_message+='!!!!!!!!!! Most modern systems switch off\n\r'
				warning_message+='!!!!!!!!!! automatically.\n\r'
			elif /sbin/runlevel | grep '6$'> /dev/null 2>&1; then
				warning_message+='!!!!!!!!!! System will reboot automatically\n\r'
				warning_message+='!!!!!!!!!! after update finished.\n\r'
			fi
		fi
		warning_message+="$cend"
		warning_message+='\n\r'

		upd_local=0
		if [ "${local_repository:-}" = "yes" ] || [ "${local_repository:-}" = "true" ]; then
			mode="local"
			/usr/share/univention-updater/univention-updater local --silent --check >/dev/null 2>&1 ||
				upd_local=$?
		else
			mode="net"
		fi
		upd_net=0
		if [ "${univentionUpdateActivate:-}" = "TRUE" ]
		then
			/usr/share/univention-updater/univention-updater net --silent --check >/dev/null 2>&1 ||
				upd_net=$?
		fi
		actualise=0
		/usr/share/univention-updater/univention-actualise --dist-upgrade --silent --check >/dev/null 2>&1 ||
			actualise=$?

		if [ "$upd_local$upd_net$actualise" = 000 ]; then
			echo -e "${cgreen}Nothing to do for Univention Updater.${cend}"
			exit 0
		fi

		LOCKFILE="/var/lock/univention-maintenance_$RANDOM"

		if echo "${update_warning:-}" | grep -E -q -i 'yes|true'
		then
			if [ -n "${update_warning_tty:-}" ]; then
				touch "$LOCKFILE"
				while [ -f "$LOCKFILE" ]; do
					for tty in $update_warning_tty  # IFS
					do
						[ -c "$tty" ] &&
							echo -e "$warning_message" >"$tty"
					done
					sleep 2
				done &
				sleep 4
			fi

			[ -c "$SSH_TTY" ] &&
				echo -e "$warning_message" >"$SSH_TTY"
		else
			echo -e "${cred}Univention Updater is updating the system.${cend}"
		fi

				if [ "$univentionUpdateActivate" = "TRUE" ]
				then
					if [ -n "${univentionUpdateVersion:-}" ]
					then
						log_action_msg "Starting Univention Updater [$univentionUpdateVersion]"
						/usr/share/univention-updater/univention-updater "$mode" --noninteractive --updateto "$univentionUpdateVersion" >>"$LOG" 2>&1
					else
						log_action_msg "Starting Univention Updater"
						/usr/share/univention-updater/univention-updater "$mode" --noninteractive >>"$LOG" 2>&1
					fi
					log_action_cont_msg " Univention Actualise"
				else
					log_action_msg "Starting Univention Actualise"
				fi

				/usr/share/univention-updater/univention-actualise --dist-upgrade --silent >>"$LOG" 2>&1

		rm -f "$LOCKFILE"

		log_action_end_msg 0
		dmesg -n 8
		;;
	status)
		;;
	*)
		echo "Usage: $0 {start|stop|restart|force-reload|status}"
		exit 1
		;;
esac

exit 0
