#!/bin/bash

# Copyright (C) 2007-2014 X2Go Project - http://wiki.x2go.org
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
#
# Copyright (C) 2007-2014 Oleksandr Shneyder <oleksandr.shneyder@obviously-nice.de>
# Copyright (C) 2007-2014 Heinz-Markus Graesing <heinz-m.graesing@obviously-nice.de>

SESSION_NAME="$1"
X2GO_GEOMETRY="$2"
X2GO_LINK="$3"
X2GO_PACK="$4"
X2GO_KBD_LAYOUT="$5"
X2GO_KBD_TYPE="$6"
X2GO_SET_KBD="$7"

X2GO_LIB_PATH="$(x2gopath libexec)";
X2GO_AGENT_PID=`$X2GO_LIB_PATH/x2gogetagent "$SESSION_NAME"`

X2GO_ROOT="${HOME}/.x2go"
X2GO_RESIZE=1
X2GO_FULLSCREEN=0

NX_XINERAMA_CONF="$X2GO_ROOT/C-$SESSION_NAME/xinerama.conf"
if [ -e "$NX_XINERAMA_CONF" ]
then
	rm "$NX_XINERAMA_CONF"
fi

$X2GO_LIB_PATH/x2gosyslog "$0" "info" "$(basename $0) called with options: $@"


# rootless sessions of geometry fullscreen are invalid
if [ "$X2GO_GEOMETRY" == "fullscreen" ] && [ "$SESSION_TYPE" == "R" ]; then
	X2GO_GEOMETRY=""
fi

# no geometry for desktop sessions shall result in fullscreen desktop sessions
if [ "$X2GO_GEOMETRY" == "" ] && [ "$SESSION_TYPE" == "D" ]; then
	X2GO_GEOMETRY="fullscreen"
fi
if [ "$X2GO_GEOMETRY" == "fullscreen" ]; then
	X2GO_FULLSCREEN=1
fi


SESSIONINFO=`x2golistsessions | grep "${SESSION_NAME}" | sed "s/|/,/g"`

GR_PORT=`echo "$SESSIONINFO" | awk -F, {'print $9'}`
SOUND_PORT=`echo "$SESSIONINFO" | awk -F, {'print $10'}`
FS_PORT=`echo "$SESSIONINFO" | awk -F, {'print $14'}`
SERVER=`echo "$SESSIONINFO" | awk -F, {'print $4'}`

$X2GO_LIB_PATH/x2gosyslog "$0" "debug" "old ports: $GR_PORT, $SOUND_PORT, $FS_PORT"

#Get all used in system ports from ss output
ss=$(PATH="$PATH:/usr/sbin:/sbin" type -P ss);
USED_PORTS=$(
	"$ss" -nt -all |
	awk '{ n=split($0,lines,"\n"); for(i=1;i<=n;i++){split (lines[i],words," ");delim=split(words[4],ports,":"); if(delim>1)printf ("|%s|\n",ports[delim])} }';
);

#check if saved in DB ports free
if grep -q "|${GR_PORT}|" <<<$SYSTEM_PORTS ; then
	$X2GO_LIB_PATH/x2gosyslog "$0" "debug" "port $GR_PORT is already in use"
	$X2GO_LIB_PATH/x2gormport "$HOSTNAME" "$SESSION_NAME" "$GR_PORT"
	GR_PORT=""
fi
if grep -q "|${SOUND_PORT}|" <<<$SYSTEM_PORTS ; then
	$X2GO_LIB_PATH/x2gosyslog "$0" "debug" "port $SOUND_PORT is already in use"
	$X2GO_LIB_PATH/x2gormport "$HOSTNAME" "$SESSION_NAME" "$SOUND_PORT"
	SOUND_PORT=""
fi
if grep -q "|${FS_PORT}|" <<<$SYSTEM_PORTS ; then
	$X2GO_LIB_PATH/x2gosyslog "$0" "debug" "port "$FS_PORT" is already in use"
	$X2GO_LIB_PATH/x2gormport "$HOSTNAME" "$SESSION_NAME" "$FS_PORT"
	FS_PORT=""
fi

SSH_PORT=30000 #First ssh port 30001

#Get all used in system ports from X2Go database and netstat output
USED_PORTS=`$X2GO_LIB_PATH/x2gogetports "$HOSTNAME"; netstat -nt -all | awk '{ n=split($0,lines,"\n"); for(i=1;i<=n;i++){split (lines[i],words," ");delim=split(words[4],ports,":"); if(delim>1)printf ("|%s|\n",ports[delim])} }'`

while [ "$GR_PORT" == "" ] || [ "$SOUND_PORT" == "" ] || [ "$FS_PORT" == "" ]; do
	OUTPUT=""
	while [ "$OUTPUT"  != "inserted" ]; do
		SSH_PORT=$(($SSH_PORT + 1))

		#get free port
		SSH_PORT=`echo "for(\\$i=$SSH_PORT;\\$br ne \"true\";\\$i++){ if(\"$USED_PORTS\" =~ m/\\|\\$i\\|/){\\$br=\"false\";}else{\\$br=\"true\";print \\$i;}}"|perl`

		#check if port in /etc/services
		SERV=`grep $SSH_PORT /etc/services`
		if [ "$SERV" == "" ]; then
			OUTPUT=`$X2GO_LIB_PATH/x2goinsertport "$HOSTNAME" "$SESSION_NAME" "$SSH_PORT"`
		fi
	done
	if [ "$GR_PORT" == "" ]; then
		GR_PORT="$SSH_PORT"
	elif [ "$SOUND_PORT" == "" ]; then
		SOUND_PORT="$SSH_PORT"
	else
		FS_PORT="$SSH_PORT"
	fi
done


SESSION_DIR="${X2GO_ROOT}/C-${SESSION_NAME}"
OPTIONS=`cat ${SESSION_DIR}/options`

LSTR=`echo "$OPTIONS" | awk -F, {'print $2'}`
PSTR=`echo "$OPTIONS" | awk -F, {'print $3'}`
KTSTR=`echo "$OPTIONS" | awk -F, {'print $12'}`
GSTR=`echo "$OPTIONS" | awk -F, {'print $13'}`
test_GSTR=`echo $GSTR | sed s/geometry=.*//`
if [ -n "$test_GSTR" ]; then
	GSTR="geometry="
	RSTR=`echo "$OPTIONS" | awk -F, {'print $13'}`
	FSTR=`echo "$OPTIONS" | awk -F, {'print $14'}`
	LISTSTR=`echo "$OPTIONS" | awk -F, {'print $16'}`
else
	RSTR=`echo "$OPTIONS" | awk -F, {'print $14'}`
	FSTR=`echo "$OPTIONS" | awk -F, {'print $15'}`
	LISTSTR=`echo "$OPTIONS" | awk -F, {'print $17'}`
fi

KTSTR=`echo "$KTSTR" | sed "s/\//\\\\\\\\\//"`
X2GO_KBD_TYPE=`echo "$X2GO_KBD_TYPE" | sed "s/\//\\\\\\\\\//"`

if [ "$X2GO_SET_KBD" == "0" ] || [ "$X2GO_KBD_TYPE" == "auto" ]; then
	keyboard_type="null\/null"
else
	keyboard_type="$X2GO_KBD_TYPE"
fi

NEWOPTIONS=`echo "$OPTIONS" | sed  -e  "s/$LSTR/link=$X2GO_LINK/"\
 -e "s/$PSTR/pack=$X2GO_PACK/"\
 -e "s/$KTSTR/kbtype=$keyboard_type/"\
 -e "s/$GSTR/geometry=$X2GO_GEOMETRY/"\
 -e "s/$RSTR/resize=$X2GO_RESIZE/"\
 -e "s/$LISTSTR/listen=$GR_PORT/"\
 -e "s/$FSTR/fullscreen=$X2GO_FULLSCREEN/"`

if [ -z "$X2GO_GEOMETRY" ] || [ "$X2GO_GEOMETRY" == "fullscreen" ]; then
	NEWOPTIONS=`echo $NEWOPTIONS | sed -e "s/geometry=${X2GO_GEOMETRY},//"`
fi

X2GO_CLIENT=`echo "$SSH_CLIENT" | awk '{print $1}'`
if [ "$X2GO_CLIENT" == "" ]
then
	X2GO_CLIENT="$HOSTNAME"
fi

echo "$NEWOPTIONS" >"${SESSION_DIR}/options"

# run x2goserver-extensions for pre-resume
x2gofeature X2GO_RUN_EXTENSIONS &>/dev/null && x2goserver-run-extensions "$SESSION_NAME" pre-resume || true

# clear old keyboard file
rm -Rf $SESSION_DIR/keyboard

kill -HUP $X2GO_AGENT_PID &>/dev/null && {

	$X2GO_LIB_PATH/x2goresume  "$X2GO_CLIENT" "$SESSION_NAME"  "$GR_PORT" "$SOUND_PORT" "$FS_PORT" > /dev/null
	$X2GO_LIB_PATH/x2gosyslog "$0" "notice" "client $X2GO_CLIENT has successfully resumed session with ID $SESSION_NAME"

	# set client-side keyboard model, type, variant, etc.
	if [ "$X2GO_SET_KBD" != "0" ] && [ "$X2GO_KBD_TYPE" == "auto" ]; then
		X2GO_DISPLAY=$(echo $SESSION_NAME | cut -d"-" -f2)
		export DISPLAY=:$X2GO_DISPLAY.0
		x2gosetkeyboard "$SESSION_NAME" >/dev/null 2>/dev/null &
	fi

	# resume x2godesktopsharing, if it has been in use before the session got suspended
	x2gofeature X2GO_DESKTOPSHARING &>/dev/null && x2goresume-desktopsharing "$SESSION_NAME" || true

	# run x2goserver-extensions for post-resume
	x2gofeature X2GO_RUN_EXTENSIONS &>/dev/null && x2goserver-run-extensions "$SESSION_NAME" post-resume || true

} || {
	err_msg="ERROR: failed to resume session with ID $SESSION_NAME"
	echo "$err_msg" 1>&2
	$X2GO_LIB_PATH/x2gosyslog "$0" "err" "$err_msg"

	# If we reach here it means that the x2goagent process of the session has vanisshed
	# If this happens than we mark the session as finished...
	$X2GO_LIB_PATH/x2gochangestatus 'F' "$SESSION_NAME"  > /dev/null

	# run x2goserver-extensions for fail-resume
	x2gofeature X2GO_RUN_EXTENSIONS &>/dev/null && x2goserver-run-extensions "$SESSION_NAME" fail-resume || true

}

echo "gr_port=$GR_PORT"
echo "sound_port=$SOUND_PORT"
echo "fs_port=$FS_PORT"

