#!/bin/ksh

TMPDIR=/tmp/vnc
JUNKFILE1="${TMPDIR}/vnc.junk1"
JUNKFILE2="${TMPDIR}/vnc.junk2"
SESSIONSLIST="${TMPDIR}/vnc.sessions.list"

if [ ! -d ${TMPDIR} ]; then mkdir ${TMPDIR} ; fi
if [ -f ${JUNKFILE1} ]; then rm ${JUNKFILE1}; fi
if [ -f ${JUNKFILE2} ]; then rm ${JUNKFILE2}; fi
if [ -f ${SESSIONSLIST} ]; then rm ${SESSIONSLIST}; fi


REMOTE_WST_LIST="m7ossca1 m7ossca2"    # choices to login to

DMZ_HOST="`hostname`"   # current box
DMZ_PORT=""             # dynamic
PEECEE_PORT=""          # derived from DMZ_PORT
REMOTE_WST=""
VNC_ID=""               # dynamic
typeset -Z2 JUNK_PORT   # xx
REMOTE_PORT=""

integer USER_SESSIONS_COUNT=0
integer SESSION_NUMBER=1


SHORT_VNC_SESSION_NAME=""
VNC_SESSION_NAME=""

function check_remote_wst_loads {
###################################################
#  Find total VNC jobs running on two target boxes
#  Assign value to REMOTE_WST
###################################################

   if ping m7ossca1 -n2 2>&1 >/dev/null
      then
          ca1_load=`remsh m7ossca1 ps -ef|grep Xvnc | grep -v grep | wc -l | awk '{print $1}'`
      else
          ca1_load=20  # if unreachable, high count so it won't be used
      fi

   if ping m7ossca2 -n2 2>&1 >/dev/null
      then
          ca2_load=`remsh m7ossca2 ps -ef|grep Xvnc | grep -v grep | wc -l | awk '{print $1}'`
      else
          ca2_load=20  # if unreachable, high count so it won't be used
      fi
  echo
  echo "Existing VNC Load:"
  echo "  m7ossca1:${ca1_load}"
  echo "  m7ossca2:${ca2_load}"

  if ((${ca1_load}<=${ca2_load}))
  then
       REMOTE_WST="m7ossca1"
  else
       REMOTE_WST="m7ossca2"
  fi
} #check_remote_wst_load

function check_for_existing_sessions {
####################################################
#  check for existing VNC session(s) already running
####################################################

SHORT_VNC_SESSION_NAME=`echo ${VNC_SESSION_NAME} | cut -c 1-4`   #shortened lastname

if [ -f ${JUNKFILE1} ]; then rm ${JUNKFILE1}; fi

 for host in ${REMOTE_WST_LIST}   #currently ossca1 & 2
 do
     if ping $host -n2 2>&1 >/dev/null
     then
         remsh ${host} "ps -eaf|grep Xvnc | grep -v grep"  | awk '{printf ("%s %s %s\n", $9, $11, $12) }'  >> ${SESSIONSLIST}
#         remsh ${host} "ps -eaf|grep Xvnc | grep -i ${SHORT_VNC_SESSION_NAME} | grep -v grep"  | cut -d'Xvnc' -f2 |
#                   awk '{printf ("%s %s %s\n", "'$host'", $2, $4) }'  >> ${SESSIONSLIST}
      else
         continue
      fi
 done

USER_SESSIONS_COUNT=`grep ${SHORT_VNC_SESSION_NAME} ${SESSIONSLIST} | wc -l | awk '{print $1}'`  #total number of sessions on all boxes for User X

((SESSION_NUMBER =  ${USER_SESSIONS_COUNT} + 1 ))

} # check_for_existing_sessions

function find_remote_port {
###############################################################
#  From initial menu, choice was made to start new VNC session
#  REMOTE_WST was already defined by  check_remote_wst_loads
#  Need to capture 1st unused port on remote_wst.  
################################# ###############################

#  New session - find next available VNC session - the port will be 59xx

  # Login to remote_wst, start VNC session letting VNC pick next available port
     remsh ${REMOTE_WST} "vncserver " > ${JUNKFILE1} 2>&1

  # Capture session number
  # junkfile1 contains
  #  New 'm7ossca2:2 (root)' desktop is m7ossca2:2

    VNC_ID=`grep New  ${JUNKFILE1} | awk '{print $NF}' | cut -d':' -f2`
    JUNK_PORT=`grep New  ${JUNKFILE1} | awk '{print $NF}' | cut -d':' -f2`  # need zero fill for tunnel
    REMOTE_PORT="59${JUNK_PORT}"       

   # Have next available port.  Hope nobody grabs it b4 we can use it.
     remsh ${REMOTE_WST} vncserver -kill :${VNC_ID}  > /dev/null 2>&1

    # Clean up the stuff that might cause it to fail
    remsh ${REMOTE_WST} "if [ -f /usr/spool/sockets/X11/${VNC_ID} ]; then rm /usr/spool/sockets/X11/${VNC_ID} ; fi"
    remsh ${REMOTE_WST} "if [ -f /tmp/.X11-unix/X/${VNC_ID} ]; then rm /tmp/.X11-unix/X/${VNC_ID} ; fi"
    remsh ${REMOTE_WST} "if [ -f .vnc/*:${VNC_ID}.log ]; then rm .vnc/*:${VNC_ID}.log ; fi"

   # doesn't quite work
#    echo "vnc_id: $VNC_ID"
#    if [[ $VNC_ID = @([1-9]) ]]; then  ((VNC_ID = "x$VNC_ID")) ; fi
#     echo "modified: $VNC_ID"

} #  find_remote_port

function find_dmz_port {
#################################################
# Get next unused port on gateway box (DMZ_HOST)
# This is needed for whatever u want to do
#################################################

tra1_PORTS="01 02  04 05 06 07 08 09"
tra2_PORTS="21 22 23 24 25 26 27 28 29"
#tra2_PORTS="11 12 13 14 15 16 17 18 19"

    # find 1st unused port on DMZ_HOST
    # different port ranges for tra1 and tra2

    if [[ ${DMZ_HOST} = "m7sstra1" ]]; then LOCAL_PORTS="${tra1_PORTS}"; fi
    if [[ ${DMZ_HOST} = "m7sstra2" ]]; then LOCAL_PORTS="${tra2_PORTS}"; fi

    # capture ports already in use
    netstat -a  |  grep *.59 | awk '{print $4}' | sort|  sed -e s/\*\.59// > ${JUNKFILE1}
    #  *.5902

     for port in ${LOCAL_PORTS}    # look 4 1st unused port
     do
         count=`grep ${port} ${JUNKFILE1} | wc -l | awk '{print $1}'`
         if (( ${count} > 0 ))          # port in use.  Check next port
         then
               continue
         else
               DMZ_PORT="59${port}"   #  This is next avail port
               PEECEE_PORT=${port}    # for localhost:xx
               break
         fi
    done
} #find_dmz_port


function old_check_for_existing_sessions {
## check for existing VNC session(s) already running

integer SESSIONS_COUNT=0

if [ -f ${JUNKFILE1} ]; then rm ${JUNKFILE1}; fi

 for host in ${REMOTE_WST_LIST}
 do
     if ping $host -n2 2>&1 >/dev/null
     then
         remsh ${host} "ps -eaf|grep Xvnc | grep -i ${SHORT_VNC_SESSION_NAME} | grep -v grep"  | cut -d'Xvnc' -f2 |
                   awk '{printf ("%s %s %s\n", "'$host'", $2, $4) }'  >> ${JUNKFILE1}
      else
         continue
      fi
 done

      # junk1
      #  m7ossca1 :6 metzger_1
      #  m7ossca1 :5 metzger
      #  m7ossca2 :1 metzger

 SESSIONS_COUNT=`wc -l ${JUNKFILE1} | awk '{print $1}'`  #total number of sessions on all boxes for User X

 if (( ${SESSIONS_COUNT}>0 ))
 then
      echo
      echo "You have ${SESSIONS_COUNT} existing VNC sessions."
      echo "--------------------------------- "
      cat ${JUNKFILE1} | awk '{printf ("  %s%s named %s\n", $1, $2, $3)}'
      echo

      CURRENT_SESSION_NUMBER=`head -1  ${JUNKFILE1} | awk '{print $2}' | sed -e s/://g `
      TMPHOST=`head -1  ${JUNKFILE1} | awk '{print $1}'`

      echo "Would you like to: "
      echo "------------------ "
      print "1) Create new tunnel for existing ${TMPHOST}:${CURRENT_SESSION_NUMBER} session"
      print "2) Kill existing VNC session ${TMPHOST}:${CURRENT_SESSION_NUMBER}"
      print "3) Kill existing VNC session ${TMPHOST}:${CURRENT_SESSION_NUMBER}, and start a new session."
      print "4) Start a new VNC session on ${REMOTE_WST}."
      print "0) Bail out."

      print -n "\nChoice: "; read reply
      case ${reply} in
           1)  print "Create new tunnel for existing ${TMPHOST}:${CURRENT_SESSION_NUMBER} session"
               REMOTE_WST="${TMPHOST}" 
#               REMOTE_PORT="590${CURRENT_SESSION_NUMBER}"    #enhancement opport
#               VNC_ID="${CURRENT_SESSION_NUMBER}"
               CREATE_NEW_VNC="no" ;;

           2)  # kill existing sesson and bail
                remsh ${TMPHOST} "vncserver -kill :${CURRENT_SESSION_NUMBER}"
                remsh ${TMPHOST} "rm .vnc/*:${CURRENT_SESSION_NUMBER}.*"
# add if here
                remsh ${TMPHOST} "rm /tmp/.X11-unix/X${CURRENT_SESSION_NUMBER}"
               remsh ${TMPHOST} "rm /usr/spool/sockets/X11/${CURRENT_SESSION_NUMBER}"
                exit 0 ;;

           3)  # kill existing session, and let script create new tunnel & vnc session as normal
               print "killing ${TMPHOST}:${CURRENT_SESSION_NUMBER}"
               remsh ${TMPHOST} "vncserver -kill :${CURRENT_SESSION_NUMBER}"
               remsh ${TMPHOST} "rm .vnc/*:${CURRENT_SESSION_NUMBER}.*"
               CREATE_NEW_VNC="yes" ;;

           4)  # Create 2nd vnc session and tunnel
               ((SESSION_NUMBER =  ${SESSIONS_COUNT} + 1 ))
                CREATE_NEW_VNC="yes" ;;

             *) print "Bailing out."
                exit 0 ;;
        esac
    fi
} #check_for_existing_sessions


function create_new_vnc_session {
################################################################
# Using variables collected, create new vnc session, and tunnel
################################################################

#  VNC session and new tunnel
      echo "remote_wst:  ${REMOTE_WST}"
      echo "remote_port: ${REMOTE_PORT}"
      echo "vnc_id:    ${VNC_ID}"
      echo "session_name: ${VNC_SESSION_NAME}.${SESSION_NUMBER}"
      echo "dmz_host: ${DMZ_HOST}"
      echo "dmz_port: ${DMZ_PORT}"
      echo "peecee_port: ${PEECEE_PORT}"


      REMOTE_WST_IP=`grep ${REMOTE_WST} /etc/hosts | cut -d" " -f 1`
      echo "\n       Starting session on ${REMOTE_WST}:${VNC_ID}   named ${VNC_SESSION_NAME}.${SESSION_NUMBER}"
      echo "\n       Your Existing Sessions Include:\n"
      grep ${SHORT_VNC_SESSION_NAME} ${SESSIONSLIST}
      echo " "

  remsh ${REMOTE_WST} "vncserver :${VNC_ID} -name '${VNC_SESSION_NAME}.${SESSION_NUMBER}  ${REMOTE_WST} (${REMOTE_WST_IP}) Xvnc:${VNC_ID}' > /dev/null 2>&1  "  


    # Start SSH tunnel and listen for VNC on REMOTE end
     echo "        To access use localhost:${PEECEE_PORT}  (exit when through)\n\n "

     # -q Quiet; don't display any warning messages.
     # -g Allow remote hosts to connect to forwarded ports.
     # -A Enable authentication agent forwarding.
     # -X Enable X11 connection forwarding.
     # -v Verbose; display verbose debugging messages.
     # -t Tty; allocate a tty even if command is given.
     # -C Enable compression.
     ssh -gAXt  -L ${DMZ_PORT}:${REMOTE_WST}:${REMOTE_PORT} -R ${REMOTE_PORT}:${DMZ_HOST}:${DMZ_PORT} root@${REMOTE_WST} 

} # create_new_vnc_session 

function connect_to_existing_session {
##############################################
#  Create list of all sessions for all machines
#  Let user select session to connect to
#  Create new tunnel to existing VNC session
##############################################

# List existing sessions
if [ -f ${JUNKFILE1} ]; then rm ${JUNKFILE1}; fi

 for hostname in ${REMOTE_WST_LIST}   #currently ossca1 & 2
 do
     if ping $hostname -n1 2>&1 >/dev/null
     then
            count=`remsh ${hostname}  ps -ef |grep desktop | grep -v grep | wc -l | awk '{print $1}'`
            if ((${count} > 0))  # a vnc session is running
            then
                  remsh ${hostname}  "ps -ef |grep desktop | grep -v grep" | 
                   awk 'BEGIN {FS = "Xvnc"};{ print $2}' | awk '{printf ("%s %s %s\n", "'$hostname'", $1, $3)}' >> ${JUNKFILE1}
            fi
      else
            continue
      fi
 done

#        numb   box       session_id   session_name
#        ----  --------   ----------   -------------
#        1)     m7ossca1      :5         metzger.1
#        2)     m7ossca1      :1         callan.1
#        3)     m7ossca1      :3         stuart
#        4)     m7ossca1      :2         liclarkd.1
#        5)     m7ossca1      :4         levy.1
#        6)     m7ossca2      :5         dubois.1
#        7)     m7ossca2      :2         m7ossca2:2
#        8)     m7ossca2      :3         m7ossca2:3

      echo 
      echo
      awk 'BEGIN { print "\tnumb   box       session_id   session_name"
                   print "\t----  --------   ----------   -------------"
                 }
                 {printf ("\t%s)     %-12s  %-6s     %-14s\n",NR , $1, $2, $3)
           }'  ${JUNKFILE1}  

print -n "\n\n      Which existing session (1-`wc -l ${JUNKFILE1} | awk '{print $1}'`) do you wish to connect to?  "
read choice

   awk 'NR == "'$choice'" { print $0 }' ${JUNKFILE1} |  read REMOTE_WST JUNKID junk

REMOTE_PORT=`echo $JUNKID | sed -e 's/:/590/'`

} #connet_to_existing_session 

function create_tunnel {
####################################
# Connect tunnel to existing session
####################################

#  Just a new tunnel
#      echo "remote_wst:  ${REMOTE_WST}"
#      echo "remote_port: ${REMOTE_PORT}"
#      echo "dmz_host: ${DMZ_HOST}"
#      echo "dmz_port: ${DMZ_PORT}"
#      echo "peecee_port: ${PEECEE_PORT}"


  # Start SSH tunnel and listen for VNC on REMOTE end
     echo "\n\n       To access ${REMOTE_WST}:${REMOTE_PORT} use localhost:${PEECEE_PORT} (exit when through) "
     echo
     echo

     # -q Quiet; don't display any warning messages.
     # -g Allow remote hosts to connect to forwarded ports.
     # -A Enable authentication agent forwarding.
     # -X Enable X11 connection forwarding.
     # -v Verbose; display verbose debugging messages.
     # -t Tty; allocate a tty even if command is given.
     # -C Enable compression.
     ssh -gAXt  -L ${DMZ_PORT}:${REMOTE_WST}:${REMOTE_PORT} -R ${REMOTE_PORT}:${DMZ_HOST}:${DMZ_PORT} root@${REMOTE_WST}

}  #create_tunnel


function kill_vnc_session {
##############################################
#  Create list of all sessions for all machines
#  Let user select session to kill
##############################################

# List existing sessions
if [ -f ${JUNKFILE1} ]; then rm ${JUNKFILE1}; fi

 for hostname in ${REMOTE_WST_LIST}   #currently ossca1 & 2
 do
     if ping $hostname -n1 2>&1 >/dev/null
     then
            count=`remsh ${hostname}  ps -ef |grep desktop | grep -v grep | wc -l | awk '{print $1}'`
            if ((${count} > 0))  # a vnc session is running
            then
                  remsh ${hostname}  "ps -ef |grep desktop | grep -v grep" | 
                   awk 'BEGIN {FS = "Xvnc"};{ print $2}' | awk '{printf ("%s %s %s\n", "'$hostname'", $1, $3)}' >> ${JUNKFILE1}
            fi
      else
         continue
      fi
 done

#        numb   box       session_id   session_name
#        ----  --------   ----------   -------------
#        1)     m7ossca1      :5         metzger.1

      echo 
      echo
      awk 'BEGIN { print "\tnumb   box       session_id   session_name"
                   print "\t----  --------   ----------   -------------"
                 }
                 {printf ("\t%s)     %-12s  %-6s     %-14s\n",NR , $1, $2, $3)
           }'  ${JUNKFILE1}  

print -n "\n\n      Which session (1-`wc -l ${JUNKFILE1} | awk '{print $1}'`) do you wish to kill? (CNTL-C if none) "
read choice

   awk 'NR == "'$choice'" { print $0 }' ${JUNKFILE1} |  read REMOTE_WST VNC_ID junk

    remsh  ${REMOTE_WST} "vncserver -kill ${VNC_ID}"

    # Clean up the stuff that might cause it to fail next time
    remsh ${REMOTE_WST} "if [ -f /usr/spool/sockets/X11/${VNC_ID} ]; then rm /usr/spool/sockets/X11/${VNC_ID} ; fi"
    remsh ${REMOTE_WST} "if [ -f /tmp/.X11-unix/X/${VNC_ID} ]; then rm /tmp/.X11-unix/X/${VNC_ID} ; fi"
    remsh ${REMOTE_WST} "if [ -f .vnc/*:${VNC_ID}.log ]; then rm .vnc/*:${VNC_ID}.log ; fi"

} # kill_vnc_session



#############################
# runit
#############################

#if (($# == 0))
#then
#     echo "Useage:  script [your lastname]"
#     exit 1
#else
##   for name in $*

clear
   print -n "\n\n
              Select a Task \n
        1) Start a new VNC session.
        2) Connect to an existing session
        3) Kill existing VNC session
        4) Bail out  \n
      choice (1-4):   "
        read  answer

    case $answer in
         1) # start a new sesstion
            print -n "LastName? : "
            read name
#            if ((name == " ")); then echo "no blanks allowed"; exit 1; fi

            VNC_SESSION_NAME=${name}

           check_remote_wst_loads;
               #check current load.  determine REMOTE_WST

           check_for_existing_sessions 
               # count number of existing sessions
               # USER_SESSIONS_COUNT
               # SESSION_NUMBER 

           find_remote_port
               # determine VNC_ID 
               # REMOTE_PORT="590${VNC_ID}"
                  
           find_dmz_port 
               # 1st avail port on DMZ box
               # DMZ_PORT="59${port}"  
               # PEECEE_PORT=${port}    # for localhost:xx

           create_new_vnc_session 
               # create new VNC session and new tunnel
           ;;
         2) # connect to existing session

            connect_to_existing_session 
               # create list of existing sessions for all users (SESSIONSLIST)
               # provide menu - which to reconnect to
               # determine REMOTE_HOST and REMOTE_PORT

            find_dmz_port
               # 1st avail port on DMZ box
               # DMZ_PORT="59${port}"  
               # PEECEE_PORT=${port}    # for localhost:xx

            create_tunnel

           ;;
         3) # kill any existing session
             kill_vnc_session
           ;;
         *) print "     See Ya." 
            exit 1 ;;
    esac


   if [ -f ${JUNKFILE1} ]; then rm ${JUNKFILE1}; fi
   if [ -f ${JUNKFILE2} ]; then rm ${JUNKFILE2}; fi


