#!/bin/sh

#
#  Trivial Netcat + Dialog console client.
#

# Steve
# --
# $Id: argo-dialog,v 1.10 2006/03/06 13:12:06 steve Exp $
#

#
#  Defaults
#
HOST=
PORT=20203
USER=
PASSWORD=
VERBOSE=


#
# Instance we're working on.
#
INSTANCE=

#
#
#  Parse the command line to see if we can get the default
# username + password + hostname + port to connect to.
#
#  -h hostname
#  -P password
#  -S port
#  -u username
#  -v verbose

while getopts 'h:p:S:u:v' option 
  do
  
  case $option in
      v)
	  VERBOSE=1
	  ;;
      h)	
	  HOST="$OPTARG"
	  ;;
      p)	
	  PASSWORD="$OPTARG"
	  ;;
      S)
	  PORT="$OPTARG"
	  ;;
      u)
	  USER="$OPTARG"
	  ;;
  esac
done



#
# stopMachine
#
#   Connect to the server and stop the given machine
#
stopMachine()
{
    nc ${HOST} ${PORT} >/dev/null <<EOF
auth ${USER} ${PASSWORD}
stop $1
exit
EOF

    dialog --msgbox "$1 stopped" 10 20

    # 
    # TODO Look for an error message.
    #
}


#
# startMachine
#
#   Connect to the server and start the given machine
#
startMachine()
{
    nc ${HOST} ${PORT} >/dev/null <<EOF
auth ${USER} ${PASSWORD}
start $1
exit
EOF

    dialog --msgbox "$1 started" 10 20

    # 
    # TODO Look for an error message.
    #
}


#
# unpauseMachine
#
#   Connect to the server and unpause the given machine
#
unpauseMachine()
{
    nc ${HOST} ${PORT} >/dev/null <<EOF
auth ${USER} ${PASSWORD}
unpause $1
exit
EOF

    dialog --msgbox "$1 unpaused" 10 20

    # 
    # TODO Look for an error message.
    #
}


#
# pauseMachine
#
#   Connect to the server and pause the given machine
#
pauseMachine()
{
    nc ${HOST} ${PORT} >/dev/null <<EOF
auth ${USER} ${PASSWORD}
pause $1
exit
EOF

    dialog --msgbox "$1 paused" 10 20

    # 
    # TODO Look for an error message.
    #
}


#
# machineInfo
#
#   Connect to the server and view the information about a given host.
#
machineInfo()
{
    #
    #  Make a temporary file.
    #
    TMPFILE=`mktemp /tmp/info.XXXXXX` || exit 1

    nc ${HOST} ${PORT} > ${TMPFILE} <<EOF
auth ${USER} ${PASSWORD}
info $1
exit
EOF

    output=`cat ${TMPFILE} | grep ':'`
    dialog --msgbox "${output}" 15 60

    #
    #  Remove the temporary file.
    #
    if [ -e ${TMPFILE} ]; then
	rm -f ${TMPFILE}
    fi

    # 
    # TODO Look for an error message.
    #
}



#
# machineUptime
#
#   Connect to the server and view the uptime for a given host.
#
machineUptime()
{
    #
    #  Make a temporary file.
    #
    TMPFILE=`mktemp /tmp/uptime.XXXXXX` || exit 1

    nc ${HOST} ${PORT} > ${TMPFILE} <<EOF
auth ${USER} ${PASSWORD}
uptime $1
exit
EOF

    output=`cat ${TMPFILE} | grep ':'`
    dialog --msgbox "${output}" 15 60

    #
    #  Remove the temporary file.
    #
    if [ -e ${TMPFILE} ]; then
	rm -f ${TMPFILE}
    fi

    # 
    # TODO Look for an error message.
    #
}




#
# promptForMissingOptions
#
#   If we don't have all the options we require setup then we'll prompt
# for them with the Dialog file.
#
promptForMissingOptions() 
{
    #
    #  Make a temporary file.
    #
    TMPFILE=`mktemp /tmp/prompt.XXXXXX` || exit 1


    #
    #  If we don't have a hostname, read it.
    #
    if [ ! -n "${HOST}" ]; then
	dialog --inputbox "Connect to" 10 40 2>${TMPFILE}
	HOST=`cat ${TMPFILE}`
    fi

    #
    #  If the user chose 'Cancel' then exit.
    #
    if [ ! -n "${HOST}" ]; then
	if [ -e ${TMPFILE} ]; then
	    rm -f ${TMPFILE}
	fi

	exit
    fi

    #
    #  If we don't have a port, read it.
    #
    if [ ! -n "${PORT}" ]; then
	dialog --inputbox "Port:" 10 40 2>${TMPFILE}
	PORT=`cat ${TMPFILE}`
    fi

    
    #  If the user chose 'Cancel' then exit.
    #
    if [ ! -n "${PORT}" ]; then
	if [ -e ${TMPFILE} ]; then
	    rm -f ${TMPFILE}
	fi

	exit
    fi

    #
    #  If we don't have a username, read it.
    #
    if [ ! -n "${USER}" ]; then
	dialog --inputbox "Username" 10 40 2>${TMPFILE}
	USER=`cat ${TMPFILE}`
    fi

    #
    #  If the user chose 'Cancel' then exit.
    #
    if [ ! -n "${USER}" ]; then
	if [ -e ${TMPFILE} ]; then
	    rm -f ${TMPFILE}
	fi

	exit
    fi

    #
    #  If we don't have a password, read it.
    #
    if [ ! -n "${PASSWORD}" ]; then
	dialog --insecure --passwordbox "Password" 10 40 2>${TMPFILE}
	PASSWORD=`cat ${TMPFILE}`
    fi

    #
    #  If the user chose 'Cancel' then exit.
    #
    if [ ! -n "${PASSWORD}" ]; then
	if [ -e ${TMPFILE} ]; then
	    rm -f ${TMPFILE}
	fi

	exit
    fi

    #
    #  Remove the temporary file.
    #
    if [ -e ${TMPFILE} ]; then
	rm -f ${TMPFILE}
    fi
}


#
# doLogin
#
#   Connect to the server and do the login.
#
doLogin() 
{
    #
    #  Make a temporary login file.
    #
    TMPFILE=`mktemp /tmp/login.XXXXXX` || exit 1

    #
    # Make the connection.
    #
    nc ${HOST} ${PORT}  2>${TMPFILE} >${TMPFILE} <<EOF
auth ${USER} ${PASSWORD}
exit
EOF

    if grep 400 ${TMPFILE} >/dev/null ; then
	echo "Login failed"
    fi
    if grep refused ${TMPFILE} >/dev/null ; then
	echo "Connection Refused"
    fi

    #
    #  Remove the temporary file.
    # 
    if [ -e ${TMPFILE} ]; then
	rm -f ${TMPFILE}
    fi

}


#
# getState
#
#  Get the state of a given host.  'Running', 'Off', 'Paused', etc.
#
#  This is used for the listing of the instances.
#
getState()
{
    #
    #  Make a temporary file.
    #
    TMPFILE=`mktemp /tmp/info.XXXXXX` || exit 1

    nc ${HOST} ${PORT} > ${TMPFILE} <<EOF
auth ${USER} ${PASSWORD}
info $1
exit
EOF

    output=`cat ${TMPFILE} | grep 'State:' | awk -F: '{print $2}'`

    echo ${output}

    #
    #  Remove the temporary file.
    #
    if [ -e ${TMPFILE} ]; then
	rm -f ${TMPFILE}
    fi

    # 
    # TODO Look for an error message.
    #

}



#
# chooseMachine
#
#  List the available machines, in a menu, and return the one
# selected.
#
chooseMachine()
{
    #
    #  Make a temporary login file.
    #
    TMPFILE=`mktemp /tmp/list.XXXXXX` || exit 1

    
    nc ${HOST} ${PORT} >${TMPFILE} <<EOF
auth ${USER} ${PASSWORD}
list available
exit
EOF

    #
    #  Find the number of instances.
    #
    count=`grep -v '\(200\|300\|400\)' ${TMPFILE} | wc -l`
    step=`expr 100 / $count`

    #
    #
    # Now find the instances.
    #
    instance=''
    item=0
    for i in $(grep -v '\(200\|300\|400\)' ${TMPFILE}) ; do
        state=`getState $i`
	item=`expr $item + 1`
	instance="$instance $i $state"
	
	expr $step \* $item | dialog --gauge "Determining State of available Xen instances" 12 60  100

    done

     #
     # Select an instance.
    dialog --menu "Select Xen instance" 12 60 8 ${instance} 2>${TMPFILE}

    INSTANCE=`cat ${TMPFILE}`

    #
    #  If the user chose 'Cancel' then exit.
    #
    if [ ! -n "${INSTANCE}" ]; then

	#
	# Remove the temporary file, then exit.
	#
	if [ -e ${TMPFILE} ]; then
	    rm -f ${TMPFILE}
	fi

	exit
    fi

    #
    # Remove the temporary file
    # 
    if [ -e ${TMPFILE} ]; then
	rm -f ${TMPFILE}
    fi
}


#
# doOperation
#
#  Choose an operation, and apply it to the chosen host.
#
#
doOperation ()
{
    #
    #  Make a temporary selection file.
    #
    TMPFILE=`mktemp /tmp/select.XXXXXX` || exit 1

    dialog --menu "Select operation for ${INSTANCE}" 12 60 8 uptime 'Show Uptime' info 'Show information' pause "Pause Instance" unpause "Unpause Instance" start "Start instance" stop "Shutdown instance" 2>${TMPFILE}

    OPERATION=`cat ${TMPFILE}`

    #
    #  Remove the temporary file.
    #
    if [ -e ${TMPFILE} ]; then
	rm -f ${TMPFILE}
    fi

    if [ ! -n "${OPERATION}" ]; then
	echo "Exiting"
	exit
    fi

    case "${OPERATION}" in
	info)
	    echo "Info: ${INSTANCE}"
	    machineInfo ${INSTANCE}
	    ;;
	uptime)
	    echo "Uptime ${INSTANCE}"
	    machineUptime ${INSTANCE}
	    ;;
	pause)
	    echo "Pause: ${INSTANCE}"
	    pauseMachine ${INSTANCE}
	    ;;
	unpause)
	    echo "Unpause: ${INSTANCE}"
	    unpauseMachine ${INSTANCE}
	    ;;
	start)
	    echo "Start: ${INSTANCE}"
	    startMachine ${INSTANCE}
	    ;;
	stop)
	    echo "Stop: ${INSTANCE}"
	    stopMachine ${INSTANCE}
	    ;;
	*)
	    echo "Aborting"
	    exit
	    ;;
    esac
    
}






#####
#
#  Start of the main script.
#
#####



#
#  If we're running verbosely dump the conenction details.
#
if [ -n "$VERBOSE" ]; then 

    echo "Hostname: $HOST"
    echo "Port    : $PORT"
    echo "Username: $USER"
    echo "Password: $PASSWORD"
fi


#
#  Now that we have optionally parsed the command line let make sure
# we have all the options we need.
#
promptForMissingOptions



#
#  Now that we have all the options login.
#
#
l=`doLogin`
if [ -n "${l}" ]; then
    dialog --msgbox "Error\n${l}" 10 20
fi


#
# Mail loop
#
while true;
  do
  
  # Select an instance.
  chooseMachine

  # Choose and apply an operation.
  doOperation  ${INSTANCE}

done;

