vncmanager

#!/bin/sh
#
#    Vnc helper script to manage vnc servers
#
#    Copyright (C) 2006  brammeleman@nerdnotes.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
#
###############################################################################

function quit
{
	if [ -e "$VNCINFO" ]
	then
		rm $VNCINFO
	fi

	if [ -e "$TMPFILE" ]
	then
		rm $TMPFILE
	fi
	echo Bye!
	exit 0
}

function novncservers
{
	dialog 	--backtitle "vncmanager" \
		--title "VNC Servers" \
		--msgbox "No running VNC servers found" 15 65
}

function searching
{
	# show waiting message
	dialog 	--backtitle "vncmanager" \
		--title "One moment please" \
		--infobox "Searching for running VNC servers" 15 65
}

function updatevncinfo
{
	searching
	ps hu -C Xvnc | grep $USER | awk '{ print hostname $12 }' hostname=$HOSTNAME > $VNCINFO
	if [ ! -s $VNCINFO ]
	then
		novncservers
		return 1
	fi
}

function vncinfodialog
{
	updatevncinfo
	if [ ! "$?" -eq "0" ]
	then
		# no servers found, go back to main menu
		return 0
	fi

	dialog 	--backtitle "vncmanager" \
		--title "VNC Servers" \
		--msgbox "$(echo 'You have the following VNC servers running:' | cat - $VNCINFO)"  15 65
}

function killvncserver
{
	# takes "hostname:displaynumber" as argument
	VNCSERVER=${1%%.*}
	VNCDISPLAY=${1##*:}
	vncserver -kill :$VNCDISPLAY
}

function killfromlist
{
	# loop until the user cancels or when there are no vnc servers anymore
	while true
	do
		updatevncinfo
		if [ ! "$?" -eq "0" ]
		then
			# no servers found, go back to main menu
			return 0
		fi
		> $TMPFILE
	        exec 3<>$TMPFILE
		# show dialog
		dialog 	--backtitle "vncmanager"    \
			--title "Stop vnc servers" \
			--output-fd 3 \
			--menu "Select the VNC server instance you want to\
			stop:" 15 65 6 \
			$(awk '{ print NR " " $1 }' < $VNCINFO)

		# test if user canceled
		if [ ! "$?" -eq "0" ]
		then
			return 0
		fi
		exec 3>&-
		answer=$(cat $TMPFILE)

		# extract relevant information for next action
		SERVERTOKILL=$(sed "$answer!d" $VNCINFO)

		# ask for confirmation
		> $TMPFILE
		exec 3<>$TMPFILE
		dialog 	--backtitle "vncmanager" \
			--defaultno   \
			--output-fd 3 \
			--yesno "Are you sure you want to stop the vnc server\
				$SERVERTOKILL?" 8 55
		# test if user answered 'Yes'
		if [ "$?" -eq "0" ]
		then
			# kill the remote vnc server
			killvncserver $SERVERTOKILL
		fi
	done
}

function askres
{
	# asks for screen resolution
	> $TMPFILE
	exec 3<>$TMPFILE

	dialog	--backtitle "vncsetup"      \
		--title " Step One " \
		--default-item 2            \
		--output-fd 3               \
		--menu "Enter the screen resolution of your desktop computer
			(computer that runs vncviewer):" 15 65 6 \
		1  " 800 x  600  (4:3)"     \
		2  "1024 x  768  (4:3)"     \
		3  "1152 x  864  (4:3)"     \
		4  "1280 x  768  (15:9)"    \
		5  "1280 x 1024  (5:4)"     \
		6  "1440 x  900  (16:10)"   \
		7  "1400 x 1050  (4:3)"     \
		8  "1600 x 1024  (25:16)"   \
		9  "1680 x 1050  (16:10)"   \
		10 "1600 x 1200  (4:3)"     \
		11 "1920 x 1200  (16:10)"   \
		12 "2048 x 1536  (4:3)"     \
		13 "2560 x 1600  (16:10)"   \
		14 "2560 x 2048  (4:3)"

	if [ ! "$?" -eq "0" ]
	then
		return 1
	fi
	exec 3>&-
	answer=$(cat $TMPFILE)
	case $answer in
	        1  ) SCREENRES=800x600   ;;
	        2  ) SCREENRES=1024x768  ;;
	        3  ) SCREENRES=1152x864  ;;
	        4  ) SCREENRES=1280x768  ;;
	        5  ) SCREENRES=1280x1024 ;;
	        6  ) SCREENRES=1440x900  ;;
	        7  ) SCREENRES=1400x1050 ;;
	        8  ) SCREENRES=1600x1024 ;;
	        9  ) SCREENRES=1680x1050 ;;
	        10 ) SCREENRES=1600x1200 ;;
	        11 ) SCREENRES=1920x1200 ;;
	        12 ) SCREENRES=2048x1536 ;;
	        13 ) SCREENRES=2560x1600 ;;
	        14 ) SCREENRES=2560x2048 ;;
	esac
}

function askwm
{
	# ask for window manager
	> $TMPFILE
	exec 3<>$TMPFILE

	dialog	--backtitle "vncmanager"    \
		--title ""  \
		--default-item 2          \
		--output-fd 3             \
		--menu "Choose a window manager:" 15 65 6 \
		1 "twm   - Tab Window Manager"   \
		2 "GNOME - GNOME desktop environment"   \
		3 "KDE   - K Desktop Environment" \
		4 "other - Use ~/.vnc/xstartup_custom script"

	if [ ! "$?" -eq "0" ]
	then
		return 1
	fi

	exec 3>&-
	answer=$(cat $TMPFILE)

	case $answer in
		1 ) write_xstartup_twm;;
		2 ) write_xstartup_gnome;;
		3 ) write_xstartup_kde;;
		4 ) write_xstartup_custom;;
	esac

	return 0
}

function write_xstartup_twm
{
	cat <<'EOF' > ~/.vnc/xstartup
#!/bin/sh
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources

xsetroot -solid grey
vncconfig -iconic &

# start a terminal
xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &

# start the desktop environment
twm &
EOF

	# make xstartup executable
	chmod +x ~/.vnc/xstartup
}

function write_xstartup_gnome
{
	cat <<'EOF' > ~/.vnc/xstartup
#!/bin/sh
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources

# start a terminal
gnome-terminal &

# start the desktop environment
gnome-session &
EOF

	# make xstartup executable
	chmod +x ~/.vnc/xstartup

}

function write_xstartup_kde
{
	cat <<'EOF' > ~/.vnc/xstartup
#!/bin/sh
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources

# start a terminal
# this somehow gives funny DCOP error messages... so no term for the moment
konsole &

# start the desktop environment
startkde &
EOF

	# make xstartup executable
	chmod +x ~/.vnc/xstartup
}

function write_xstartup_custom
{
	# copy custom script to xstartup
	cp ~/.vnc/xstartup_custom ~/.vnc/xstartup

	# make xstartup executable
	chmod +x ~/.vnc/xstartup
}

function startserver
{
	askres
	[ "$?" -eq "1" ] && return 0

	askwm
	[ "$?" -eq "1" ] && return 0

	# check if a vncpasswd is set (when vncserver invokes the vncpasswd
	# script, the password is world readable)
	if [ ! -f ~/.vnc/passwd ]
	then
		setpw
		[ "$?" -eq "1" ] && return 0
	fi

	# show waiting message
	dialog 	--backtitle "vncmanager" \
		--title "One moment please" \
		--infobox "Starting a VNC server on $HOSTNAME" 15 65

	# start vnc server
	vncserver -geometry $SCREENRES

	# show list of running vnc servers
	vncinfodialog
}

function setpw
{
	# show instruction message
	dialog 	--backtitle "vncmanager" \
		--title "VNC Password" \
		--msgbox "You will be asked to enter a password. You'll need this password when connecting with VNC viewer" 15 65

	# set the password
	vncpasswd

	# check if all went fine
	if [ ! "$?" -eq "0" ]
	then
		# show error message
		dialog 	--backtitle "vncmanager" \
			--title "VNC Password" \
			--msgbox "Setting the password failed." 15 65
		return 1
	fi
	return 0
}

function someinitialchecks
{
	# create ~/.vnc if it doesn't exist yet
	[ ! -d ~/.vnc ] && mkdir ~/.vnc

	if [ ! -f ~/.vnc/xstartup_managed_by_vncmanager ]
	then
		# make backup of ~/.vnc if vncmanager runs for the first time
		cp -r ~/.vnc ~/.vnc.old
		cat <<eof > ~/.vnc.old/README
This is a backup of your vnc settings. It has been made the
first time you ran 'vncmanager'.

If you didn't experience problems using VNC with the vncmanger,
you can simply delete this directory (freeing up some kb's)
EOF
		if [ ! -f ~/.vnc/xstartup ]
		then
			# write default xstartup script
			write_xstartup_gnome
		fi

		# copy existing xstartup script to xstartup_customx
		cp ~/.vnc/xstartup ~/.vnc/xstartup_custom

		# leave a mark, so that this code is only executed once
		touch ~/.vnc/xstartup_managed_by_vncmanager
	fi
}

function mainmenu
{
	# shows the main menu
	> $TMPFILE
	exec 3<>$TMPFILE

	dialog	--backtitle "vncmanager"    \
		--title "Main menu"  \
		--output-fd 3             \
		--menu "What would you like to do:" 15 65 6 \
		1 "List my running VNC servers"   \
		2 "Start a VNC server"   \
		3 "Stop a VNC server"  \
		4 "Set my VNC password" \
		5 "Quit"

	[ ! "$?" -eq "0" ] && quit

	exec 3>&-
	answer=$(cat $TMPFILE)

	case $answer in
		1) vncinfodialog;;
		2) startserver;;
		3) killfromlist;;
		4) setpw;;
		5) quit;;
	esac
}

TMPFILE=`mktemp`
VNCINFO=`mktemp`
someinitialchecks

# main program
while true
do
	# run the main menu
	mainmenu
done

Leave a Reply