#!/bin/bash

#/**
#@file    setserveraddr
#@brief   Assign default IP address to OpenGnsys services.
#@usage   setserveraddr { IPAddress | NetIface }
#@param   IPAddress  IP address assigned to a network interface
#@param   NetIface   network interface name defined by the operating system
#@version Initial version.
#@author  Ramón M. Gómez - ETSII Univ. Sevilla
#@date    2011-01-25
#@version 1.0.5 - Regenerate configuration files.
#@author  Ramón M. Gómez - ETSII Univ. Sevilla
#@date    2014-06-06
#@version 1.1.1 - Updating menu URLs and PXE files.
#@author  Ramón M. Gómez - ETSII Univ. Sevilla
#@date    2018-11-15
#*/ ##


# Variables.
PROG=$(basename $0)
OPENGNSYS=${OPENGNSYS:-"/opt/opengnsys"}
PXEDIRS="$OPENGNSYS/tftpboot/menu.lst $OPENGNSYS/tftpboot/grub"
DEFAULTFILE=/etc/default/opengnsys

# Functions.
source $OPENGNSYS/lib/ogfunctions.sh || exit 1

# Show help or version number.
[ "$*" == "help" ] && help
[ "$*" == "version" ] && version
# Checking parameters.
[ "$USER" != "root" ] && raiseError access "Need to be root"
[ $# -ne 1 ] && raiseError usage
[ -r $DEFAULTFILE ] || raiseError access "Cannot read default configuration file"
for f in $OPENGNSYS/{etc/{ogAdmServer,ogAdmRepo,ogAdmAgent}.cfg,www/controlacceso.php,client/etc/ogAdmClient.cfg}; do
	[ -w $f ] || raiseError access "Cannot write to file: $f"
done

# Detecting network interfaces.
DEVICES=$(ip -o link show up | awk -F: '$2!~/lo/ {print $2}')
for DEV in $DEVICES; do
	# If the network interface is found, get its IP address.
	IP=$(ip -o addr show dev "$DEV" | awk '$3~/inet$/ {sub (/\/.*/, ""); print ($4)}')
	if [ "$DEV" == "$1" ] || [ "$IP" == "$1" ]; then
		SERVERIP="$IP"
		SERVERDEV="$DEV"
	fi
done

# Checking if IP address has been detected.
if [ -n "$SERVERIP" ]; then
	# Showing warning to inform that initiated clients may hang.
	read -rp "WARNING: initiated clients can hang. Continue? (y/n): " ANSWER
	[ "${ANSWER,,}" != "y" ] && raiseError cancel "Do nothing"
	# Temporary files.
	tmpfile=$(mktemp /tmp/og.XXXXX)
	trap "rm -f $tmpfile" 1 2 3 6 9 15

	# Checking whether the DHCP settings need to be changed.
	CHANGE=0
	for f in /etc/{dhcp,hcp3}/dhcpd.conf; do
		if [ -f $f ]; then
			# Changing DHCP "next-server" parameter.
			file="${f/./-$SERVERDEV.}"
			sed -e "s/next-server.*/next-server $SERVERIP;/" \
			    -e "s/option routers ;/option routers ${SERVERIP%.*}.1;/" $file >$tmpfile
			# Copying and linking file if there are changes.
			if [ ! $f -ef $file ] || ! diff -q $tmpfile $file &>/dev/null; then
				mv $tmpfile $file
				chmod 644 $file
				ln -f $file $f
				CHANGE=1
			fi
		fi
	done
	# Restarting DHCP service if its configuration has changed.
	if [ $CHANGE == 1 ]; then
		for s in isc-dhcp-server dhcp3-server dhcpd; do
			restart $s &>/dev/null && break
		done
	else
		echolog "DHCP configuration has not changed."
	fi

	# Saving old IP address.
	source $OPENGNSYS/etc/ogAdmServer.cfg
	OLDSERVERIP=$ServidorAdm
	# Checking if configuration files need to be modified.
	CHANGE=0
	for f in $OPENGNSYS/{etc/{ogAdmServer,ogAdmRepo,ogAdmAgent}.cfg,www/controlacceso.php,client/etc/ogAdmClient.cfg}; do
		# Updating configuration variables (if URL does not contain "localhost").
		sed -e "s,\(ServidorAdm\|IPlocal\)=.*,\1=$SERVERIP," \
		    -e "s,^INTERFACE=.*,INTERFACE=$SERVERDEV," \
		    -e "s,UrlMenu=https?://\([^/]*\)/\(.*\),UrlMenu=https://$SERVERIP/\2," \
		    -e '/localhost/!s,https\?://[^/]*/\(.*\),https://'$SERVERIP'/\1,' $f >$tmpfile
		file="${f/./-$SERVERDEV.}"
		# Copying updated file, if needed.
		if [ ! $f -ef $file ] || ! diff -q $tmpfile $file &>/dev/null; then
			cp $tmpfile $file
			ln -f $file $f
			CHANGE=1
		fi
	done

	# Processing when something has changed.
	if [ $CHANGE == 1 ]; then
		# Restart OpenGnsys services.
		echolog "Restarting services..."
		restart opengnsys >/dev/null
		source $DEFAULTFILE
		# If OpenGnsys Server is active, updating the database.
		if [ "$RUN_OGADMSERVER" == "yes" ]; then
			# Updating IP addresses and menu URLs.
			dbexec "
UPDATE entornos
   SET ipserveradm='$SERVERIP'
 WHERE identorno=1;
UPDATE repositorios
   SET ip='$SERVERIP'
 WHERE ip='$OLDSERVERIP';
UPDATE menus
   SET htmlmenupub = REPLACE(htmlmenupub, '$OLDSERVERIP', '$SERVERIP'),
       htmlmenupri = REPLACE(htmlmenupri, '$OLDSERVERIP', '$SERVERIP');"
			# Updating all PXE files.
			find $PXEDIRS -name "01-*" -exec sed -i -e "s/$OLDSERVERIP/$SERVERIP/g" {} \;
		fi

		# Showing manual task to do after execution.
		echolog "Default server interface set to: $SERVERDEV ($SERVERIP)"
		cat << EOT

Manual tasks:
- Check DHCP configuration file and restart service, if needed.
- Check PXE files.
- Log-in as Web Console user:
  - Check menu URLs.
- Note: Run "settoken" script to update authentication tokens.
EOT
	else
		# Showing message if nothing changes.
		echolog "Default interface has not changed: $1"
	fi
else
	# Error if network interface is not found.
	raiseError notfound "Network device"
fi

# Removing temporary files.
rm -f $tmpfile

