#!/opt/local/bin/kermit +
;
; a u t o s s h
;
; Illustration of scripted SSH session using C-Kermit 8.0 or K95 2.0.
; Also illustrates client/server features such as client query of server
; variables and sending e-mail containing a script-composed text body
; through the server.
;
; In Unix, adjust the top line to point to your C-Kermit 8.0 executable.
;
; F. da Cruz, Columbia University Kermit Project, July 2002.
;
; Command-line parameters:
;  1. Hostname or address
;  2. Username on host
;  3. Name of file to send
;  4. Directory on host in which to store the file
;  5. Email address for status report.
;
; Parameters not supplied are prompted for.
;
; The following version-check works with older Kermit versions.
;
define badversion {
    echo Sorry - C-Kermit 8.0 or K95 2.0 or later required.
    exit 1
}
if not equal "\v(program)" "C-Kermit" badversion
if LLT \v(version) 800200 badversion

; From here down we make free use of C-Kermit 8.0 / K95 2.0 features.

define ERRQUIT {			; Macro to exit appropriately
    if kerbang exit 1 \%1	        ; If Kerbang script, exit all the way.
    stop 1 \%1				; Otherwise return to Kermit prompt.
}
while not def \%1 {			; If hostname/address not supplied
    ask \%1 { Host: }			; prompt for one until we get it.
    if > \fsplit(\%1,,,.) 1 {		; Allow only one "word" here
        echo Just the address please.	; (no TCP port number).
        undef \%1
    }
}
if not def \%2 {			; If username not supplied
    ask \%2 { User [\v(user)]: }	; Prompt for one, but default
    if not def \%2 assign \%2 \v(user)	; to local user ID.
}					; 
; Note: if you have key files the following step can and should be skipped.

if not def \%3 {			; If password not supplied
    askq \%3 { Password: }		; Prompt for one.
}

; As a sample, let's suppose we want to access a Unix host, upload a file
; to a certain directory, and then send mail to somebody when it's uploaded.
; Accept these items from the command line and prompt for any that are missing.
;
while not def filename {		; If filename not supplied
    ask filename { File: }		; Prompt for one.
    if not def filename continue
    if not readable \m(filename) {
        echo \m(filename): not found or not readable	
        continue
    }
}
.filename := \fcontents(\%3)

; Note: \fcontents() is used to avoid over-evaluating DOS pathnames that
; contain backslashes.

while not def \%4 {                     ; Target directory for uploading
    ask \%4 { Target directory: }
}
.directory := \fcontents(\%4)

while not def \%5 {                     ; Email address for upload report
    ask \%5 { Email address for report: }
}
.address := \fcontents(\%5)

;;; log session session.log             ; Uncomment to log the host session
set input echo off                      ; Change to ON to watch the session

echo Making SSH connection to \%1 as user \%2...

; Bypass network directory lookup to avoid finding an entry of that name that
; specifies a different connection method.
;
set network directory ""

; In Unix, we make the connection through a pseudoterminal to the external SSH
; client, which prompts you for the host password unless you have the
; appropriate public and private keys installed for SSH.  The only way to
; avoid the password prompt is to install the needed keys.
;
; If you are running this script in Unix and it fails, it is most likely due
; to a peculiarity of the underlying PTY driver.  Try changing "set host /pty"
; to "set host /pipe" below.
;
if k-95 {                                ; K-95 has SSH built in
    set host /network:ssh /user:\%2 /password:\%3 \%1
} else {                                 ; C-Kermit uses external SSH client
    set host /pty ssh -e none -l \%2 \%1
}
if fail errquit {Can't open SSH connection to \%1.}
echo Connected to \%1.

; At this point we have a connection to the host.  Everything from here
; here down is specific to the host's prompts, commands, and applications,
; and of course, what you want to do once you have a connection.
;
; In this example we start the host's Kermit server and use it.  The method
; used to start the server depends on the host allowing typeahead and there
; being no interactive non-shell prompt prior to login (adjust as necessary,
; e.g. to respond to prompts and/or wait for a specific shell prompt).  It
; also assumes a relatively up-to-date C-Kermit version is installed on the
; host as "kermit" in your PATH.
;
set xfer display brief                  ; No fancy screen stuff
set exit warning off                    ; Exit without asking
lineout kermit -x                       ; Start Kermit server
input 20 "READY TO SERVE..."            ; Wait for server's ready message
if fail stop 1 Server didn't start      ; Check
remote cd \m(directory)                 ; CD to download directory on server
if fail stop 1 REMOTE CD \m(directory) failure

query kermit directory                  ; Get full remote directory path
if success .directory := \v(query)

set flag off                            ; For remembering transfer status
send \m(filename)                       ; Upload the file
if success set flag on                  ; Remember file-transfer status

; Send a report by e-mail through the server.  This illustrates not only
; how to send email but also how to have the message body in memory rather
; than in a file by creating a small array containing the lines of the
; message.
;
declare \&a[4]                          ; Declare a 4-element array
.\&a[1] := File: \fpath(\m(filename))   ; Full pathname of source file
.\&a[2] := Size: \fsize(\m(filename))   ; Size of source file
.\&a[3] := To directory: \m(directory)  ; Target directory
if flag {                               ; Status
    .\&a[4] := Status: Success
} else {
    .\&a[4] := Status: Failure \v(xfermsg)
}
send /mail:\m(address) /array:a /text /subject:"Upload status"

; Shut down the server and close the connection

bye
exit \v(status)
