home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
pub
/
scripts
/
ckermit
/
remoteaccess
< prev
next >
Wrap
Text File
|
2020-01-01
|
7KB
|
192 lines
#!/usr/local/bin/kermit
; r e m o t e a c c e s s
;
; How to conduct a dialog with a user when Kermit does not have a controlling
; terminal; for example, when Kermit has accepted an incoming Internet ("set
; host *") or modem ("answer") connection, or when a Kermit script is started
; under inetd. This script shows how to handle echoing and rudimentary
; keyboard editing:
;
; . Prints a prompt and waits for a line of text.
; . Ordinary characters echo.
; . Rubout, Delete, or Backspace removes the rightmost character from the line.
; . Ctrl-U removes the current line, if any.
; . Ctrl-R repaints the current line.
; . The prompt is protected.
;
; To make it more interesting, lines are interpreted as commands, validated,
; and executed.
;
; Note that when printing lines to the user's screen, both carriage (\13)
; and linefeed (\10) are included for when there is no terminal driver
; to supply them. In case there IS a terminal driver, the SET INPUT ECHO OFF
; command allows the script to work there too.
;
; F. da Cruz, Columbia University, January 2003
; First make a command keyword table and then sort it for \tablelook().
;
declare \&k[] = exit:5 quit:5 help:2 ?:2 echo:1 send:3 list:4 directory:4
sort &k
; Make an array of help strings keyed on keyword value.
;
dcl \&h[5]
.\&h[1] = ECHO [text] echos its arguments.
.\&h[2] = HELP prints this message; Synonym: "?".
.\&h[3] = SEND filename [as-name] sends the given file under the given name.
.\&h[4] = LIST [filespec] lists files; Synonym: DIRECTORY.
.\&h[5] = EXIT exits; Synonym: QUIT.
; Define command service routines
define DOEXIT { ; Service routine for EXIT command
output "\13\10Bye.\13\10"
sleep 1
exit
}
define DOSEND { ; Service routine for SEND command
if not defined \%1 {
output "Filename required\13\10"
end 1
} else if not exist \%1 {
output "File not found: "\%1"\13\10"
end 1
}
send \%1 \%2
}
define DOLIST { ; Service routine for LIST command
local \&d[] \%i \%f \%m
directory /array:&d \%1 ; Get filenames into array &d[]
output "\13\10"
if not \fdim(&d) {
output "(No files match)\13\10"
} else {
.\%m := 0 ; Quickly get length of longest name
for \%i 1 \fdim(&d) 1 {
.\%m := \fmax(\%m,\flen(\&d[\%i]))
}
incr \%m
for \%i 1 \fdim(&d) 1 { ; Print listing
.\%f := \&d[\%i]
if not readable \%f continue
output " \frpad(\%f,\%m) \flpad(\fsize(\%f),9) \fdate(\%f)\13\10"
}
}
output "\13\10"
}
define DOHELP { ; Service routine for HELP command
local \%i
output "\13\10"
output "Commands are:\13\10\13\10"
for \%i 1 \fdim(&h) 1 {
output " \&h[\%i]\13\10"
}
output "\13\{10}Commands may be abbreviated.\13\10"
output "\13\10"
}
; Command parser and dispatcher
define DOCOMMAND {
if not def \%1 return ; Ignore blank lines
void \fsplit(\%1,&a,\32) ; Split line into words
.\%k := \ftablelook(\&a[1],&k) ; Look up first word
switch \%k { ; Handle lookup error
:-1
output "Command not found: "\&a[1]"\13\10"
output "Type HELP for help\13\10"
continue
:-2
output "Ambiguous: "\&a[1]"\13\10"
output "Type HELP for help\13\10"
continue
}
switch \fword(\&k[\%k],2,:) { ; Dispatch on keyword value
:1 ; ECHO prints its arguments
output "\fjoin(&a[2:])\13\10"
break
:2 ; HELP prints help text
dohelp
break
:3 ; SEND sends a file
dosend \&a[2] \&a[3] ; with an optional as-name
output "\13\10"
break
:4 ; LIST prints a file list
dolist \&a[2]
break
:5 ; QUIT and EXIT quit
doexit
}
}
set case off ; Commands are case-independent
set input echo off ; In case there is a controlling tty
set root . ; Restrict users to this directory tree
define prompt "Command: " ; Define prompt
output "\13\10" ; Start on a new line
output "Type HELP for help.\13\10" ; Greet
; Loop to read lines and pass them to the command interpreter.
; This is where we handle echoing and editing.
while true { ; Outer loop for lines
undef buf ; Line buffer
.\%n = 0 ; Line length
output "\m(prompt)" ; Prompt
set flag off ; Inner loop control
while not flag { ; Inner loop for characters
input -1 ; Get a character
if fail stop 1 INPUT Error ; Make sure we did
.\%c := \v(inchar) ; This is the character
.\%x := \fcode(\%c) ; This is its code
switch \%x { ; switch on its code
:3 ; Ctrl-C
doexit ; Exit immediately
:13 ; Carriage Return
:10 ; or Line Feed
:12 ; or Form Feed
output "\13\10" ; Echo CRLF
set flag on ; Set inner-loop exit flag
docommand "\m(buf)" ; Process the user's command
continue
:8 ; Backspace
:127 ; or Rubout
if not def buf { ; Nothing to delete
output "\7" ; just beep
continue
}
output "\8 \8" ; Erase char from user's screen
decr \%n ; And from line buffer
.buf := \s(buf[1:\%n])
continue
:18 ; Ctrl-R
output "\13\10" ; Refresh line
output "\m(prompt)\m(buf)"
continue
:21 ; Ctrl-U
for \%i 1 \%n 1 { ; Erase line from screen
output "\8 \8"
}
.\%n = 0
undef buf
continue
:9 ; Ctrl-I (Tab)
.\%c := \32 ; Convert to space
.\%x := 32 ; and fall thru.
:default ; Anything else
if > \%x 31 { ; If char is printable
output \%c ; echo it
.buf := \m(buf)\%c ; add it to line buffer
incr \%n ; and count it
} else output "\7" ; Beep for nonprintables
}
}
}