#!/bin/sh # # vncadm # # by Ralph Bogendoerfer (Sun Microsystems) 2009 # # This script is used to administer (list/add/delete) VNC desktops. # Those are then under control of dtlogin, all changes are reboot safe. # # Configuration variables XVNC=/usr/X11/bin/Xvnc RES=1280x1024 CONFIGDIR=/etc/dt/config CONFIGFILE=/etc/dt/config/Xservers DEFAULTCONFIG=/usr/dt/config/Xservers TITLE=`hostname` ROOTHOME=`getent passwd root | cut -d: -f6` VNCPASSWD=/usr/bin/vncpasswd VNCPASSWDFILE=$ROOTHOME/.vnc/passwd usage() { cat << EOF Usage: $0 [Options] { list [] | add | del } DISPLAYS: Either a single display number (e.g. 1) or a range of displays (e.g. 2-4) Options: -r x: Display resolution for displays to add (default: $RES) -t : Title for the displays (default: hostname) -X <Xvnc>: Path to Xvnc binary (default: $XVNC) EOF exit 1 } check_root() { USER=`/usr/ucb/whoami` if [ "root" != "$USER" ]; then echo "ERROR: Must be root to modify displays!" exit 1 fi } process_args() { if [ $# -lt 1 ]; then usage fi while [ $# -gt 0 ] do case $1 in # Resolution -r) if [ -z "$2" ]; then usage else RES=$2 shift 2 fi ;; # X-Server (Xvnc) -X) if [ -z "$2" ]; then usage else XVNC=$2 shift 2 fi ;; # Title -t) if [ -z "$2" ]; then usage else TITLE=`echo $2 | sed -e "s/ /_/g"` shift 2 fi ;; # Add displays add) MODE=ADD if [ -z "$2" ]; then usage else DISPLAYS=$2 shift 2 fi ;; # Delete displays del) MODE=DEL if [ -z "$2" ]; then usage else DISPLAYS=$2 shift 2 fi ;; # List displays list) MODE=LIST if [ -z "$2" ]; then DISPLAYS=0-999999 shift else DISPLAYS=$2 shift 2 fi ;; *) usage exit ;; esac done # Check if the Xvnc server exists and is executable if [ ! -x $XVNC ]; then echo "ERROR: $XVNC is not executable!" exit fi # Parse display specification case $DISPLAYS in *-*) FROMSTR=`echo $DISPLAYS | cut -d- -f1` TOSTR=`echo $DISPLAYS | cut -d- -f2` ;; *) FROMSTR=$DISPLAYS TOSTR=$DISPLAYS ;; esac # Check if displays are numeric FROM=`echo $FROMSTR | awk '{ print int($0) }'` TO=`echo $TOSTR | awk '{ print int($0) }'` if [ $FROM != $FROMSTR -o $TO != $TOSTR ]; then echo "ERROR: Illegal display range $FROMSTR-$TOSTR!" exit 1 fi # Swap FROM and TO if TO is smaller than FROM if [ $TO -lt $FROM ]; then TMP=$FROM FROM=$TO TO=$TMP fi } create_configfiles() { # Create configuration directory if [ ! -d $CONFIGDIR ]; then mkdir -p $CONFIGDIR fi # Create config file and set owner and permissions if [ ! -f $CONFIGFILE ]; then cp $DEFAULTCONFIG $CONFIGFILE chown root:bin $CONFIGFILE chmod 444 $CONFIGFILE fi # Try to create the VNC password file if necessary if [ ! -f $VNCPASSWDFILE ]; then if [ -x $VNCPASSWD ]; then if [ ! -d `dirname $VNCPASSWDFILE` ]; then mkdir -p `dirname $VNCPASSWDFILE` fi echo "Please specify a password for the VNC sessions:" $VNCPASSWD $VNCPASSWDFILE else echo "WARNING: Remember to create the VNC password file $VNCPASSWDFILE!" fi fi } add_displays() { i=$FROM while [ $i -le $TO ]; do PORT=`expr $i + 5900` cat << EOF >> $CONFIGFILE :$i Local local_uid@console root $XVNC :$i -desktop ${TITLE}_\(:$i\) -auth /.Xauthority -geometry $RES -depth 24 -rfbwait 30000 -rfbauth $VNCPASSWDFILE -rfbport $PORT -pn EOF i=`expr $i + 1` done } del_displays() { # If there is no config file there is nothing to do if [ ! -f $CONFIGFILE ]; then return fi ANSWER="y" XSERVERS=`nawk '{ disp=int(substr($1,2,length($1)-1)); if (disp >= from && disp <= to && $5 != xvnc ) { print $5 }}' from=$FROM to=$TO xvnc=$XVNC $CONFIGFILE` if [ -n "$XSERVERS" ]; then echo "WARNING! Not all sessions within the selected range are VNC sessions!" echo "Are you sure you want to delete the selected sessions? (y/n) \c" read ANSWER fi if [ "$ANSWER" = "y" -o "$ANSWER" = "Y" -o "$ANSWER" = "yes" -o "$ANSWER" = "Yes" -o "$ANSWER" = "YES" ]; then nawk '{ disp=int(substr($1,2,length($1)-1)); if (disp < from || disp > to) { print $0 }}' from=$FROM to=$TO $CONFIGFILE > $CONFIGFILE.$$ mv $CONFIGFILE.$$ $CONFIGFILE else exit 1 fi } list_displays() { # If there is no config file there is nothing to do if [ ! -f $CONFIGFILE ]; then echo "No sessions using $XVNC as Xserver found!" exit fi XSERVERS=`nawk '{ disp=int(substr($1,2,length($1)-1)); if (disp >= from && disp <= to && $5 == xvnc ) { print $0 }}' from=$FROM to=$TO xvnc=$XVNC $CONFIGFILE` if [ -z "$XSERVERS" ]; then echo "No sessions using $XVNC as Xserver found!" exit fi printf "Display Title Resolution Port\n" echo "===============================================================" echo "$XSERVERS" | while read DISP A1 A2 USER CMD do set -- $CMD while [ $# -gt 0 ]; do case $1 in -geometry) GEO=$2; shift;; -desktop) TITLE=$2; shift;; -rfbport) PORT=$2; shift;; esac shift done printf "%-7s %-30s %-10s %s\n" $DISP $TITLE $GEO $PORT done } restart_dtlogin() { if [ -x /usr/bin/svcs ]; then SVC=`/usr/bin/svcs -H -o STATE cde-login` else SVC="" fi if [ $SVC = "online" ]; then svcadm restart cde-login else if [ -x /etc/init.d/dtlogin ]; then /etc/init.d/dtlogin reset else echo "Unable to restart dtlogin! Please restart manually!" fi fi } cleanup() { # Remove empty configuration file # if [ -f $CONFIGFILE -a -z "`egrep -v '^#|^[ \t]*$' $CONFIGFILE 2> /dev/null`" ]; # Remove configuration file, if identical to default cmp -s $DEFAULTCONFIG $CONFIGFILE if [ $? -eq 0 ]; then rm $CONFIGFILE fi # Try to remove possibly empty configuration directory rmdir $CONFIGDIR > /dev/null 2>&1 } # # Actual processing # process_args $* case $MODE in ADD) check_root create_configfiles # Make sure added displays do not exist first del_displays add_displays restart_dtlogin ;; DEL) check_root del_displays restart_dtlogin ;; LIST) list_displays ;; *) ;; esac cleanup