#!/usr/bin/kermit +
#
# Script gethpconfig - Get and save configuration of HP switch.
# Requires C-Kermit 9.0 or later to filter out escape sequences.
#
# Give this file execute permission and change the first line
# to indicate the full path of the C-Kermit executable followed by " +".
#
# Arguments:
#  1. Name of file containing list of devices
#  2. Access password for switches
#
# To make debugging and progress messages come out, set the environment
# variable DEBUG to (say) 1:
#
#  DEBUG=1 gethpconfig /somepath/devicefilename secretpassword
#
# Change the following command to indicate the directory where the
# the device list file is and where the logs are to be created.
#
define directory /hplogs

############################################################################
#
# Everything from here down should be site independent...

assign myname \fbasename(\v(cmdfile))   # Name of this file (without path)

define errquit {                        # Fatal error handler
    if not def \%1 def \%1 Unspecified error
    if open connection close connection
    exit 1 "FATAL [\m(myname)] - \%1"
}
if llt "\v(version)" "900000" errquit "C-Kermit 9.0 or later required"

# To enable debug messages define an environment variable DEBUG; e.g.:
# DEBUG=1 gethpconfig filename password
#
if def \$(DEBUG) set debug message on   # environment variable DEBUG defined.

message Checking network...
check network
if fail errquit "This version of Kermit does not support network connections"

message \m(myname) parameters: 0=\%0  1=\%1  2=\%2
# 0=Script Name
# 1=List of switches, or any CLI device category.
# 2=Password.

define usage exit 1 "Usage: \m(myname) devicelistfile password"
if not def \%1 usage

# Prompt for password if not given on command line

while not def \%2 {
    askq /echo:* \%2 "Password: "
}
cd \m(directory)                        # Change to the right directory
if fail errquit "\m(directory): \v(errstring)"

# Try to open the specified device list file.
# If it can't be opened, quit right here.
#
assign infile \fcontents(\%1)           # Global copy of input file name
assign passwd \fcontents(\%2)           # and password

fopen /read \%c \m(infile)		# Open the list of devices
if fail errquit {Device list file \m(infile): \v(errstring)}

log cx ./GetSwitchConfig.cx.out         # Create connection log

set telopt start-tls refuse             # Do not use START_TLS option
set telopt authentication refuse        # Do not use AUTH option
set telopt encrypt refuse refuse        # Do not use ENCRYPT option
if debug set telnet debug on		# Show telnet negotiations if debugging

set exit on-disconnect off              # Don't exit if connection broken
set exit warning off                    # Don't give connection warning on exit

set session-log text                    # Filter escape sequences from log
set input buffer-length 16384           # Increase input buffer size

# Display most recent record from the devicelist file (only when debugging)
#
define displayRecord {
    echo ....................Device Name:  \m(deviceName)
    echo ....................Device Brand: \m(deviceBrand)
    echo ....................Device Make:  \m(deviceMake)
    echo ....................Device IP:    \m(deviceIP);
}

define n 0                              # Record (switch) counter

# Read a record from the devicelist file.
# There are four lines in the file per device.
#   1: Device name (appears in device's console prompt)
#   2: Manufacturer (info only)
#   3: Device Model
#   4: IP address
#   5: Blank line (end of record) or EOF: end of file
#
define readFileRecord {
    if \f_eof(\%c) {
        message \m(infile): EOF... \m(n) records processed.
        fclose \%c
        exit 0
    }
    fread /line \%c deviceName
    if fail errquit {\m(infile): Bad Device Name}
    fread /line \%c deviceBrand
    if fail errquit {\m(infile): Bad Device Brand}
    fread /line \%c deviceMake
    if fail errquit {\m(infile): Bad Device Make}
    fread /line \%c deviceIP
    if fail errquit {\m(infile): Bad DeviceIP}
    fread /line \%c blankLine
    if fail errquit {\m(infile): Bad blankLine}
    increment n
    if debug displayRecord
}
# commSession does the actual communication and logging.

define commSession {
    lineout   # Force a new line, even if switch flags password error.
    input 5 Password:
    if success {
        message Sending... \m(passwd)
        lineout \m(passwd)
        input 4 "\m(deviceName)# "
        if fail end 1 "Timeout [1]"
        message Asking for no page...
        lineout no page
        message Asking for configs...
        input 4 "\m(deviceName)# "
        if fail end 1 "Timeout [2]"
        message Setting session... \m(deviceName)
        lineout show config
        input 10 "Startup configuration:" # Wait for heading

        # Start logging now - this way we only see the 'show config' output

        assign logname ./output/\m(deviceName).pre_cfg
        log session \m(logname) new
        if fail errquit "Session log: \m(deviceName).pre_cfg: \v(errstring)"
        input 20 "\m(deviceName)# "
        if fail end 1 "Timeout [3]"
        close session                   # Close session log now
        lineout exit                    # exit from CLI
        input 4 "\m(deviceName)> "
        if fail end 1 "Timeout [4]"
        lineout exit
        input 4 "Do you want to log out [y/n]? "
        if fail { hangup, end 0 }       # Don't worry if this fails
        lineout y
    }
}
while 1 {
    readFileRecord                      # Read info record for switch
    message "Connecting to host \m(deviceName) at \m(deviceIP)..."
    set host \m(deviceIP) 23 /telnet    # Connect to switch console
    if fail {                           # On failure try the next one
        echo "WARNING - \v(lastcommand): Connection failed"
        continue
    }
    commSession                         # Success - get the config
    if fail {                           # On failure warn and try next
        local newname
        .newname := \freplace(\m(logname),pre_cf,CHECK_ME)
        echo "WARNING: Session \m(deviceName) did not end normally."
        xecho "Renaming \m(deviceName) to \m(newname)..."
        if open session close session   # Close session log if still open.
        rename \m(logname) \m(newname)	# Rename the log
        if fail { echo " [FAILED]" } else { echo " [OK]" }
    }
}
exit 0					# 0 = success

# The following are for the EMACS text editor used to compose this script.
# They are executed by EMACS but for the script itself they are comments.

# Local Variables:
# comment-column:40
# comment-start:"# "
# End:
