#!/bin/csh -f
#
#
#    Main menu script for testing gated
#
#    Print header, if desired
#
echo ""
echo "                      GATED Test Driver"
echo "                Version 2.1 - November 3, 1995"
echo "            Copyright 1994, 1995 Merit Network, Inc."
echo "" 
#
#    Revision History
#
#    11-11-94  JWJ   Created.
#    11-17-94  JWJ   Added more features.
#    11-22-94  JWJ   Added log file save feature.
#    11-29-94  JWJ   Put global variables in separate setup file.
#                    Added shell spawn feature.
#     1-10-95  JWJ   Added "sleep" feature when running tests.
#     1-11-95  JWJ   Save routing tables along with log file.
#     1-13-95  JWJ   Minor bug fix.
#     2-23-95  JWJ   Added prompt for test name, filled in command
#                    to compare actual results with expected.
#     3-1-95   JWJ   Minor bug fix.
#     3-3-95   JWJ   Reworked environment variables.
#     6-28-95  JWJ   Added log file viewing, minor bug fix.
#     6-30-95  JWJ   Added analysis of memory trace calls in log file.
#     8-3-95   JWJ   Removed sleep mode as separate function.
#                    Put in auto compare of route table vs. expected
#                    with sleep duration (renamed to wait duration).
#                    Added function to edit expected results file.
#     8-9-95   JWJ   Added menu print on/off function.
#                    Added ability to put secondary args on choice line.
#                    (Ex: 1 3 6 to set test sequence 3 6)
#     8-11-95  JWJ   Added command line option processing.
#     8-14-95  JWJ   Added "netstat -m" to analyze memory function per request.
#     8-16-95  JWJ   Added synchronization file processing.
#                    Added automatic mode (input from file) processing.
#     8-25-95  JWJ   Removed prompting for test name.  Added extra checks
#                    related to gated running or not.  Added aid to automatic
#                    testing by having program skip to next command if setting
#                    a test sequence and the specified config file does not exist.
#     8-28-95  JWJ   Added code to remove sync file at startup.
#    10-26-95  JWJ   Added -q option to "compare results" call.
#    10-30-95  JWJ   Added process existence check to "kill gated" command.
#    11-1-95   JWJ   Added check for "use/don't use QOS" when calling
#                    expected results script.
#    11-3-95   JWJ   Added "-z" option use for compare script.
#
#
#    Environment variables used:
#
#    gated_work_dir  Directory where the gated.conf, expected.txt,
#                    and gated (or link to) are located.
#
#    gated_test_dir  Directory containing the individual test subdirectories.
#                    If undefined, sets to $gated_work_dir.
#
#    gated_scripts   Directory containing scripts and templates needed
#                    for running this program and the gated config file
#                    generator.
#
#    gated_config_file     Location and name of the config file used
#                          when running gated.
#
#    gated_results_file    Location and name of expected results file
#                          for the current config file.
#
#    gated_default_rt_gw   Gateway for default route.  Used when
#                          reinstalling default route after route
#                          table flush.
#
#    gated_cmp_script      Script which compares routing table
#                          against expected results.
#
#    gated_qos_file        QOS file (used in comparing results)
#
#    gated_mainlog_dir     Location of gated log file
#    gated_locallog_dir    Where to put a copy of log file
#    gated_log_file_name   Log file name
#    gated_sync_dir        Directory for node synchronization
#
#    gated_perl_cmd        Perl executable (dir and file name)
#

#
#    Local variables
#
set proc_id = 0
set NULL="<none>"
set test_name=$NULL
set test_num=($NULL $NULL)
set auto_compare_mode="OFF"
set def_wait_time=90
set mach_type=`arch`
set verbose_mode="OFF"
set synchronize_mode="OFF"
set start_gated="OFF"
set use_qos="ON"
set operating_mode="MANUAL"

#
#    Read variables on support/log file names and locations
#
source $gated_scripts/testg_setup.csh

#   Get the root hostname of the machine we are on
#   ('hostname -s' not standard on all machines)
hostname | $gated_perl_cmd -e 'split("\\.",<STDIN>); print "@_[0]\n";' >/tmp/test.tmp
set host=`cat /tmp/test.tmp`

#   Set synchronization file name
set sync_file_name=$gated_sync_dir/$host.lock

#
#    Process command line options
#
set print_usage="OFF"
set argc=$#argv
set i=1
while ( $i <= $argc )
   switch ( $argv[$i] )
      case "-t":
         # Make sure another argument follows
         if ( $i == $argc ) then
           echo "   *** ERROR - no test name specified"
           set print_usage="ON"
         else
           @ i = $i + 1
           set test_name=$argv[$i]
         endif
         breaksw

      case "-s":
         # Make sure two more arguments follow.
         if ( $i + 2 > $argc ) then
           echo "   *** ERROR - must supply both sequence and test number"
           set print_usage="ON"
         else
           @ i = $i + 1
           set test_num[1]=$argv[$i]
           @ i = $i + 1
           set test_num[2]=$argv[$i]
         endif

         # Warn user if no test name specified.
         if ( "$test_name" == "$NULL" ) then
           echo "     *** WARNING - sequence set, but test name not specified"
         endif
         breaksw

      case "-a":
         set operating_mode="AUTOMATIC"
         echo ""
         echo "     --- Operating in AUTOMATIC mode (no menu printed)"
         breaksw

      case "-g":
         set start_gated="ON"
         breaksw

      case "-Q":
         set use_qos="OFF"
         breaksw

      case "-v":
         set verbose_mode="ON"
         echo ""
         echo "     --- Verbose mode turned on"
         breaksw

      case "-h":
         echo "Usage: `basename $0` [-a] [-g] [-h] [-Q] [-v] [-t <test set name>] [-s <sequence> <test #>]"
         echo ""
         echo "Gated test driver options:"
         echo "   -a      Tells driver to use AUTO mode - input from file rather than terminal"
         echo "             NOTE: this is cosmetic only: use '<' on command line to specify file"
         echo "   -g      Start gated when starting driver"
         echo "   -h      Print this help list"
         echo "   -Q      Do not use QOS table when comparing expected results"
         echo "   -s      Set sequence and test number on startup"
         echo "   -t      Set test name on startup"
         echo "   -v      Set verbose mode (prints more information while running)"
         exit
         breaksw

      default:
         echo "   *** Unknown option $argv[$i]"
         set print_usage="ON"
         breaksw
   endsw
@ i = $i + 1
end

if ( $print_usage == "ON" ) then
   echo "Usage: `basename $0` [-a] [-g] [-h] [-Q] [-v] [-t <test set name>] [-s <sequence> <test #>]"
   echo "       The "-h" option will explain all the options."
   exit 1
endif
#

#
#    Prompt for test name to use
#
#if ("$test_name" == "$NULL" ) then
#   echo ""
#   echo -n "Please enter the name of the test you will be using: "
#   set resp=$<
#   if ( "$resp" != "" ) then
#      set test_name=$resp
#   endif
#endif

if ( ! $?gated_work_dir ) then
   set gated_work_dir="."
   echo '   *** WARNING:  $gated_work_dir not set, using current directory'
endif

if ( ! $?gated_scripts ) then
   echo '   *** WARNING:  $gated_scripts not set, using current directory'
   set gated_scripts ="."
endif

if ( ! $?gated_test_dir ) then
   set gated_test_dir=$gated_work_dir
endif

if ("$test_name" == "$NULL" ) then
   set working_test_dir = "."
else
   set working_test_dir = $gated_test_dir/$test_name
endif

if ( $verbose_mode == "ON" ) then
   echo ""
   echo '     --- gated working directory set to "'"$gated_work_dir"'"'
   echo '         gated script directory set to  "'"$gated_test_dir"'"'
   echo '         gated test directory set to    "'"$gated_scripts"'"'
   echo ""
endif

#
#    Print test name, sequence, and test number
#
echo "     --- Test name: $test_name    Sequence: $test_num[1]    Test #: $test_num[2]"

#
#  If test sequence and number are set, copy over the config file.
#
if ( ("$test_name" != "$NULL") && ("$test_num[1]" != "$NULL") ) then
   #   Copy the gated configuration file of user's choice into working area.
   set cfg_filename="gated.conf.$test_name.$host.$test_num[1].$test_num[2]"
   set res_filename="expected.$test_name.$host.$test_num[1].$test_num[2]"
   if ( $verbose_mode == "ON" ) then
      echo "         The configuration file name is     $working_test_dir/$cfg_filename"
      echo "         The expected results file name is  $res_filename"
   endif     
   if ( ! -e $working_test_dir/$cfg_filename ) then
      echo "     *** Configuration file does not exist, ignoring request"
      set test_num[1]=$NULL
      set test_num[2]=$NULL
   else
      cp $working_test_dir/$cfg_filename $gated_config_file
   endif
   if ( ! -e $working_test_dir/$res_filename ) then
      echo "     *** WARNING: expected results file does not exist"
   else
      cp $working_test_dir/$res_filename $gated_results_file
   endif
endif

#
#    Clear this node's entry in the synhronization directory
#
rm -f $gated_sync_dir/$sync_file_name
if ( $verbose_mode == "ON" ) then
   echo ""
   echo "     --- Synchronization file cleared"
endif     

#
#    Test to see if gated is running
#
if ( `ps -auxw | grep "gated " | grep -c -v grep` ) then
   set proc_line = `ps -auxw | grep "gated " | grep -v grep`
   set proc_id = $proc_line[2]
   echo ""
   echo "     --- gated is running, process ID = $proc_id"
else
   if ( $start_gated == "ON" ) then
      $gated_work_dir/gated -f $gated_config_file
      set proc_line = `ps -auxw | grep "gated " | grep -v grep`
      set proc_id = $proc_line[2]
      echo ""
      echo "     --- gated started, process ID = $proc_id"
   else
      echo ""
      echo "     *** gated is not running."
   endif
endif

#
#    Main menu
#
set choice=999
set print_menu="ON"
while ( "$choice" != "0" )
   #  If running in automatic mode, skip the menu entirely
   if ( $operating_mode == "AUTOMATIC" ) then
      goto ENTER_CHOICE
   endif

   if ( $print_menu == "ON" ) then
      echo ""
      echo "                   Main Menu"
      echo "                   ---------"
      echo "1)  Select a test sequence (1t = display current test)"
      echo "2)  Check gated status"
      echo "3)  Start gated (3c = test current config file only)"
      echo "4)  Kill gated"
      echo "5)  Review the net status (5m = pipe to more)"
      echo "6)  Compare expected test results to routing table"
      echo "7)  Send refresh signal (config file re-read) to gated"
      echo "8)  Flush the routing table"
      echo "9)  Spawn a shell (csh)"
      echo ""
      echo "10) Set the test name"
      echo "11) Edit the configuration file"
      echo "12) Edit the expected results file"
      echo "13) View the gated log file"
      echo "14) Save the gated log and routing tables to local log files"
      echo "15) Analyze memory trace calls in the log file"
      echo ""
      echo "21) Turn on auto comparison - expected results/routing table"
      echo "22) Turn off auto comparison"
      echo "23) Turn on verbose mode (print more informational messages)"
      echo "24) Turn off verbose mode"
      echo "25) Turn on synchronization with other nodes"
      echo "26) Turn off synchronization"
      echo ""
      echo "\!m) Turn off printing of Main Menu"
      echo "m)  Turn on printing of Main Menu"
      echo ""
      echo "0)  Exit this program"
      echo ""
      echo -n "Enter your choice: "
   else
      echo ""
      echo -n "Enter your choice ("m" to print Main Menu): "
   endif
ENTER_CHOICE:
   set resp_list=$<
   set resp_list=($resp_list)
   if ( $#resp_list == 0 ) then
      continue
   else
      set choice=$resp_list[1]
   endif

   switch ( "$choice" )
      case "1":
         # If user supplied two args with choice "1", (e.g. 1 3 6)
         # use those two args, else prompt user
         if ( $#resp_list >= 3 ) then
            set test_num=($resp_list[2] $resp_list[3])
         else
            if ( $#resp_list != 1 ) then
               echo "     *** Illegal input, please try again"
               breaksw
            endif

            # Prompt user to enter test numbers
            set valid = 0
            while ( ! $valid )
               echo ""
               echo -n "Enter sequence <space> test: "
               set resp=$<
               if ( "$resp" == "" ) then
                  break
               endif

               set resp=($resp)
               if ( $#resp != 2 ) then
                  echo "     *** Illegal input, hit <CR> to quit"
               else
                  set test_num=($resp)
                  set valid = 1
               endif
            end
         endif

         if ( "$test_num[1]" != "$NULL" ) then
            echo ""
            echo "     --- Test name: $test_name    Sequence: $test_num[1]    Test #: $test_num[2]"

            #   Copy the gated configuration file of user's choice into working area.
            set cfg_filename="gated.conf.$test_name.$host.$test_num[1].$test_num[2]"
            set res_filename="expected.$test_name.$host.$test_num[1].$test_num[2]"
            if ( $verbose_mode == "ON" ) then
               echo "         The configuration file name is     $working_test_dir/$cfg_filename"
               echo "         The expected results file name is  $res_filename"
            endif     

            #   If the configuration file does not exist, ignore and go on.
            if ( ! -e $working_test_dir/$cfg_filename ) then
               echo "     *** Configuration file does not exist, ignoring request"
               breaksw
            else
               cp $working_test_dir/$cfg_filename $gated_config_file
            endif
            if ( ! -e $working_test_dir/$res_filename ) then
               echo "     *** WARNING: expected results file does not exist"
            else
               cp $working_test_dir/$res_filename $gated_results_file
            endif

            #
            #   Synchronize and send hangup signal if gated is running.
            #
            if ( $proc_id != 0 ) then
               #   Synchronize with peers, if turned on
               if ( $synchronize_mode == "ON" ) then
                  #   Unlock node for synchronization
                  if ( $synchronize_mode == "ON" ) then
                     echo "$test_num[1] $test_num[2]" >$sync_file_name
                  endif

                  #  Check the other nodes
                  set node_list=( $gated_sync_files )
                  set first_time="yes"
                  while ( "$node_list" != "" )
                     set temp_list=""
                     foreach node ( $node_list )
                        set node_lock_file=$gated_sync_dir/$node.lock
                        if ( ! -e $node_lock_file ) then
                           set temp_list=($temp_list $node)  # node is not running yet
                           continue
                        endif
                        set resp=(`cat $node_lock_file`)
                        #  If it reads while another node is writing (it happens),
                        #  ignore and wait.
                        if ( $#resp < 2 ) then
                           set temp_list=($temp_list $node)
                           continue
                        endif
                        if ( $test_num[1] == $resp[1] && $test_num[2] == $resp[2] ) then
                           if ( $verbose_mode == "ON" ) then
                              echo "Synchronized with $node"
                           endif
                        else
                           set temp_list=($temp_list $node)  # node is not at that test
                        endif
                     end    # foreach loop
                     set node_list=( $temp_list )
                     if ( "$node_list" != "" ) then
                        if ( $first_time == "yes" ) then
                           echo "Waiting to synchronize with $node_list ..."
                           set first_time="no"
                        endif
                        sleep 2
                     endif
                  end    # while loop
               endif   # synchronize code handling

               #   If gated has crashed, and we are in automatic mode, exit the program.
               if ( ! (`ps -auxw | grep "gated " | grep -c -v grep`) ) then
                  if ( $operating_mode == "AUTOMATIC" ) then
                     echo "*** gated has stopped running, terminating program."
                     exit 1
                  else
                     echo "***"
                     echo "***  WARNING \!\!\!\!   GATED HAS STOPPED RUNNING \!\!\!\!\!"
                     echo "***"
                     set proc_id = 0
                     breaksw
                  endif
               endif

#
#  TEMPORARY
#
#  If this is px, put in an additional 10 second delay before hangup signal.
#
#if ( "$host" == "px" ) then
#   echo -n "Sleeping additional 10 seconds..."
#   sleep 10
#   echo "done"
#endif

               #   Send a "hangup" signal to gated.  This will cause it to
               #   re-read the configuration file.
               if ( $verbose_mode == "ON" ) then
                  echo "         Sending refresh signal (kill -HUP) to gated process ID $proc_id"
               else
                  echo "         Sending refresh signal to gated"
               endif
               kill -HUP $proc_id

               #   If auto compare is on, wait for specified duration
               #   then compare routing table against expected results
               if ( "$auto_compare_mode" == "ON" ) then
                  if ( $wait_duration > 0 ) then
                     echo -n "         Waiting for $wait_duration seconds ... "
                     sleep $wait_duration
                     echo "done"
                  endif
               endif
               echo "         Comparing routing table against expected results..."
               if ( "$use_qos" == "ON" ) then
                  $gated_cmp_script -z -q  $gated_qos_file $gated_results_file
               else
                  $gated_cmp_script -z $gated_results_file
               endif

               #   Reset for synchronization
               if ( $synchronize_mode == "ON" ) then
                  rm -f $sync_file_name
               endif
            endif   # if gated is running
         endif     # if test numbers are specified
         breaksw

      case "1t":
         echo "     --- Test name: $test_name    Sequence: $test_num[1]    Test #: $test_num[2]"
         breaksw

      case "2":
         if ( `ps -auxw | grep "gated " | grep -c -v grep` ) then
            set proc_line = `ps -auxw | grep "gated " | grep -v grep`
            set proc_id = $proc_line[2]
            echo ""
            echo "     --- gated is running, process ID = $proc_id"
         else
            echo ""
            echo "     *** gated is not running."
            set proc_id = 0
         endif
         breaksw

      case "3":
         if ( `ps -auxw | grep "gated " | grep -c -v grep` ) then
            set proc_line = `ps -auxw | grep "gated " | grep -v grep`
            set proc_id = $proc_line[2]
            echo ""
            echo "     *** gated is already running, process ID = $proc_id"
         else
            $gated_work_dir/gated -f $gated_config_file

            # Allow time for the process to register
            sleep 2

            set proc_line = `ps -auxw | grep "gated " | grep -v grep`
            set proc_id = $proc_line[2]
            echo ""
            echo "     --- gated started, process ID = $proc_id"
         endif
         breaksw

      case "3c":
         $gated_work_dir/gated -N -c -f $gated_config_file
         breaksw

      case "4":
         if ( `ps -auxw | grep "gated " | grep -c -v grep` ) then
            set proc_line = `ps -auxw | grep "gated " | grep -v grep`
            set proc_id = $proc_line[2]
            kill -9 $proc_id
            echo ""
            echo "     --- gated process $proc_id killed."
            set proc_id = 0
         else
            echo ""
            echo "     *** No gated process to kill."
         endif
         breaksw

      case "5":
         netstat -rn
         breaksw

      case "5m":
         netstat -rn | more
         breaksw

      case "6":
         if ( "$use_qos" == "ON" ) then
            $gated_cmp_script -z -q  $gated_qos_file $gated_results_file
         else
            $gated_cmp_script -z $gated_results_file
         endif
         breaksw

      case "7":
         if ( `ps -auxw | grep "gated " | grep -c -v grep` ) then
            set proc_line = `ps -auxw | grep "gated " | grep -v grep`
            set proc_id = $proc_line[2]
            kill -HUP $proc_id
            echo "     --- Hangup signal sent to gated process ID $proc_id"
         else
            echo "     *** gated is not running."
            set proc_id = 0
         endif
         breaksw

      case "8":
         echo ""
         echo "     --- Flushing routing table..."
         if ( $mach_type == "sun4" ) then
            route -f
         else
            route flush
         endif

         if ( $mach_type == "sun4" ) then
            route add default $gated_default_rt_gw 1
         else
            route add default $gated_default_rt_gw
         endif
         echo "         Default route added, gateway $gated_default_rt_gw"
         breaksw

      case "9":
         /bin/csh -f
         breaksw

      case "10":
         echo "     --- Current test name is $test_name"
         echo ""
         if ( $#resp_list >= 2 ) then
            set resp=$resp_list[2]
         else
            echo -n "Enter new test name (<CR> to leave alone): "
            set resp=$<
         endif
         if ( "$resp" != "" ) then
            set test_name=$resp
            set working_test_dir = $gated_test_dir/$test_name
            echo "     --- New work dir is $working_test_dir"
            echo "     --- New test name is $test_name"
         endif
         breaksw

      case "11":
         vi $gated_config_file
         breaksw

      case "12":
         vi $gated_results_file
         breaksw

      case "13":
         view $gated_mainlog_dir/$gated_log_file_name
         breaksw

      case "14":
         if ( "$test_num[1]" == "$NULL" ) then
            echo "     *** No test sequence currently defined"
         else
            set datenum = `date +"%m%d"`
            set seq = $test_num[1]
            set num = $test_num[2]
            set from_file = $gated_mainlog_dir/$gated_log_file_name
            set to_file   = $gated_locallog_dir/$gated_log_file_name.$datenum.$seq.$num
            #
            #  I'd like to check the status of "cp" here, like the man page
            #  says I can, but the BSDI coders apparently didn't read their
            #  own specs.  (returns null in any situation)
            cp $from_file $to_file
            echo "     --- $from_file"
            echo "              copied to"
            echo "         $to_file"
            #
            # Now save an image of the routing tables.
            set to_file = $gated_locallog_dir/netstat.$datenum.$seq.$num
            netstat -rn >$to_file
            echo ""
            echo "     --- routing tables copied to $to_file"
         endif
         breaksw

      case "15":
         netstat -m
         echo ""
         if ( $verbose_mode == "on" ) then
            echo "     --- Now searching log file for MEM_TRACE calls""
            echo ""
         endif
         $gated_scripts/analyze_memory.csh
         breaksw

      case "21":
         set auto_compare_mode="ON"
         if ( $#resp_list >= 2 ) then
            set resp=$resp_list[2]
         else
            echo ""
            echo -n "Enter wait duration (<CR>=$def_wait_time): "
            set resp=$<
         endif
         if ( "$resp" == "" ) then
            set wait_duration=$def_wait_time
         else
            set wait_duration=$resp
         endif
         echo ""
         echo "     --- Automatic comparison mode turned ON"
         echo "         Wait of $wait_duration seconds between signal and comparison"
         breaksw

      case "22":
         set auto_compare_mode="OFF"
         echo ""
         echo "     --- Automatic comparison mode turned OFF"
         breaksw

      case "23":
         set verbose_mode="ON"
         echo ""
         echo "     --- Verbose mode turned ON"
         breaksw

      case "24":
         set verbose_mode="OFF"
         echo ""
         echo "     --- Verbose mode turned OFF"
         breaksw

      case "25":
         set synchronize_mode="ON"
         if ( $#resp_list >= 2 ) then
            set resp=( $resp_list[2-] )
         else
            echo -n "Enter node names to synchronize with: "
            set resp=$<
         endif
         set gated_sync_files=( $resp )
         echo ""
         echo "     --- Synchronization mode turned ON"
         if ( $verbose_mode == "ON" ) then
            echo "         Sync directory: $gated_sync_dir"
         endif
         echo "         Nodes are: $gated_sync_files"
         breaksw

      case "26":
         set synchronize_mode="OFF"
         rm -f $sync_file_name
         echo ""
         echo "     --- Synchronization mode turned OFF"
         breaksw

      case "!m":
         set print_menu="OFF"
         breaksw

      case "m":
         set print_menu="ON"
         breaksw

      case "#":
         # comment (probably in an auto test script) - ignore
         breaksw

      case "0":
         breaksw

      default:
         echo "     *** Illegal input, please try again"
         breaksw
   endsw
end
#
