home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
pub
/
rt11pascal
/
rtkerm.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
2020-01-01
|
10KB
|
402 lines
PROGRAM Kermit(input,output);
LABEL
9999; { used only to simulate a "halt" instruction }
CONST
{ standard file descriptors. subscripts in open, etc. }
STDIN = 1; { these are not to be changed }
STDOUT = 2;
STDERR = 3;
DL11LINE = 4;
BINARYFILE = 5;
{ other io-related stuff }
IOERROR = 0; { status values for open files }
IOAVAIL = 1;
IOREAD = 2;
IOWRITE = 3;
IOLINE = 4;
MAXOPEN = 7; { maximum number of open files }
MAXCMD = 10; { maximun number of arguments }
{ universal manifest constants }
ENDFILE = MaxInt; { Cannot be -1 }
ENDSTR = 256; { Cannot be 0 }
MAXSTR = 100; { longest possible string }
CONLENGTH = 20; { length of constant string }
BLKSIZE = 512; { Block Size for files }
{ ascii character set in decimal }
{ used by KERMIT }
NULLCHAR = 0;
SOH = 1; { SOH }
BACKSPACE = 8;
TAB = 9;
NEWLINE = 10; { LF }
CR = 13; { CR }
BLANK = 32;
SHARP = 35; { # }
AMPER = 38; { & }
PERIOD = 46; { . }
COLON = 58; { : }
LESS = 60; { < }
GREATER = 62; { > }
QUESTION = 63; { ? }
DEL = 127; { rubout }
{ Constants for KERMIT }
DEFTRY = 5; { default for number of retries }
DEFITRY = 15; { default for number of retries on init }
DEFTIMEOUT = 12; { default time out }
MAXPACK = 94; { max is 94 ~ - ' ' }
DEFDELAY = 5; { delay before sending first init }
NUMPARAM = 7; { number of parameters in init packet }
DEFQUOTE = SHARP; { default quote character }
DEFPAD = 0; { default number OF padding chars }
DEFPADCHAR = 0; { default padding character }
DEF8CHAR = AMPER; { default 8 Bit Quote Character }
{ packet types }
TYPEB = 66; { ord('B') }
TYPED = 68; { ord('D') }
TYPEE = 69; { ord('E') }
TYPEF = 70; { ord('F') }
TYPEN = 78; { ord('N') }
TYPES = 83; { ord('S') }
TYPET = 84; { ord('T') }
TYPEY = 89; { ord('Y') }
TYPEZ = 90; { ord('Z') }
{ Command parser constants }
SMALLSIZE = 13;
LARGESIZE = 80;
MINPACKETSIZE = 10;
MAXPACKETSIZE = 94;
oON = 21;
oOFF = 22;
oEVEN = 31;
oODD = 32;
oNONE = 33;
TYPE
character = -128..MaxInt; { byte-sized. ascii + other stuff }
string = array [1..MAXSTR] of character;
string100 = PACKED ARRAY[1..MAXSTR] of char;
cstring = PACKED ARRAY [1..CONLENGTH] OF char;
filedesc = IOERROR..MAXOPEN;
ioblock = record { to keep track of open files }
filevar : text;
mode : -IOWRITE..IOLINE;
end;
block = array[1..BLKSIZE] of char;
binfile = file of block;
{ Data Types for Kermit }
Packet = RECORD
mark : character; { SOH character }
count: character; { # of bytes following this field }
seq : character; { sequence number modulo 64 }
ptype: character; { d,y,n,s,b,f,z,e,t packet type }
data : string; { the actual data }
{ chksum is last validchar in data array }
{ eol is added, not considered part of packet proper }
END;
Command = (Transmit,Receive,SetParm,Connect,Invalid,Alldone);
KermitStates = (FileData,Init,Break,FileHeader,EOFile,Complete,Abort);
EOLtype = (LineFeed,CrLf,JustCr);
Stats = real;
Ppack = ^Packet;
InType = (nothing,CRin,abortnow);
TypeOfBinary = (NotSupported,FullBinary,Quoted);
{ Parser defined types }
string13 = packed array [1..SMALLSIZE] of char;
string80 = packed array [1..LARGESIZE] of char;
VAR
{ for system }
openlist : ARRAY [1..MAXOPEN] OF ioblock; { open files }
redirect : ARRAY [STDIN..STDOUT] OF filedesc;
cmdargs : 0..MAXCMD;
cmdlin : string;
cmdidx : ARRAY [1..MAXCMD] OF 1..MAXSTR;
bfile : binfile;
binbuffer : block;
bptr : integer;
{ Varibles for Kermit }
DiskFile : filedesc; { File being read/written }
SaveState : kermitstates;
NextArg : integer; { next argument to process }
local : boolean; { local/remote flag }
MaxTry : integer;
n : integer; { packet number }
NumTry : integer; { times this packet retried }
OldTry : integer;
Pad : integer; { padding to send }
MyPad : integer; { number of padding characters I need }
PadChar : character;
MyPadChar: character;
RunType : command;
State : kermitstates; { current state of the automaton }
MyTimeOut: integer; { when i want to be timed out }
TheirTimeOut : integer;
Delay : integer;
LineIN,LineOUT : filedesc; { Line to other KERMIT }
SizeRecv, SizeSend : integer;
SendEOL, SendQuote : character;
myEOL,myQuote: character;
QuoteForBinary : character;
BinaryMode : TypeOfBinary;
Def8QuoteMode : character; { default 8 Bit Mode is Y or AMPER
this the one we send when starting transmit }
EOLforFile : EOLtype;
NumSendPacks : integer;
NumRecvPacks : integer;
NumACK : integer;
NumNAK : integer;
NumACKrecv : integer;
NumNAKrecv : integer;
NumBADrecv : integer;
RunTime: integer;
ChInFileSend, ChInPackSend, ChInFileRecv, ChInPackRecv : Stats;
Verbosity: boolean; { true to print verbose messages }
OneWayOnly : boolean; { used for testing }
Debug : boolean;
ThisPacket : Ppack; { current packet being sent }
LastPacket : Ppack; { last packet sent }
CurrentPacket : Ppack; { current packet received }
NextPacket : Ppack; { next packet being received }
InputPacket : Ppack; { save input to do debug }
TimeLeft : integer; { until Time_Out }
{ these are used for the Receive Packet Procedures }
FromConsole : InType; { input from Console during receive }
check: integer; { Checksum }
PacketPtr : integer; { pointer to InputPacket }
dataptr : integer; { pointer to data of Packet }
fld : 0..5; { current fld number }
t : character; { input character }
finished : boolean; { finished packet ? }
restart : boolean; { restart packet ? }
control : boolean; { quoted ? }
ishigh : integer; { shift to put high bit on }
isgood : boolean; { packet is good ? }
invalidConnection : boolean;
{ Parser defined variables }
commandLine, fileSpec : string80;
exitProgram,fileWarning : boolean;
localEcho, sFileSpec, rFileSpec, fileWarn, lSpeed : integer;
debugging, commandLen, fileEol, parity, eightBitQuoting : integer;
oldRunType : command;
{$E+}
PROCEDURE stiphalt; { used by external procedures for halt }
BEGIN
GOTO 9999;
END;
{$E-}
{ initio (RT-11) -- initialize open file list }
PROCEDURE initio;
EXTERNAL;
{ open (RT-11) -- open a file for reading or writing }
FUNCTION Sopen (VAR name : string; omode : integer) : filedesc;
EXTERNAL;
{ close all files on exit }
PROCEDURE closeall;
EXTERNAL;
FUNCTION Exists({ Using } VAR s:string): { Returning } boolean;
EXTERNAL;
{ getarg (RT-11) -- copy n-th command line argument into s }
FUNCTION getarg (n : integer; VAR s : string;
maxs : integer) : boolean;
EXTERNAL;
PROCEDURE PutCS({ Using } x:cstring;
{ Using } s : string;
{ Using } fd:filedesc);
EXTERNAL;
PROCEDURE OpenPort;
EXTERNAL;
PROCEDURE BadVTerminalConnect;
EXTERNAL;
PROCEDURE MakeConnection;
EXTERNAL;
PROCEDURE KermitInit; { initialize various parameters & defaults }
EXTERNAL;
PROCEDURE FinishUp(ok : boolean); { do any End of Program clean up }
EXTERNAL;
PROCEDURE ErrorPack({ Using } c:cstring);
{ output Error packet if necessary -- then exit }
EXTERNAL;
PROCEDURE PutErr({ Using } c:cstring);
{ Print error_messages }
EXTERNAL;
PROCEDURE Verbose({ Using } c:cstring);
EXTERNAL;
PROCEDURE SendSwitch;
EXTERNAL;
PROCEDURE RecvSwitch;
EXTERNAL;
PROCEDURE KermitMain; { Main KERMIT procedure }
VAR
aline : string;
j : integer;
errorOccurred : boolean;
dummy : boolean;
BEGIN
Verbose('KermitMain... ');
errorOccurred := false;
CASE Runtype OF
Receive:
BEGIN { filename is optional here }
IF (rFileSpec = oON)
THEN
BEGIN
dummy := getarg(1,aline,MAXSTR);
IF ((Exists(aline)) AND (local))
THEN
PutCS('Overwriting ',aline,STDERR);
DiskFile := Sopen(aline, -IOWRITE);
IF (DiskFile <= IOERROR)
THEN
BEGIN
PutErr('Cannot Open File ');
errorOccurred := true;
END
ELSE
IF (local)
THEN
PutCS('Receiving File... ',
aline, STDERR);
rFileSpec := oOFF;
END;
IF NOT(errorOccurred)
THEN
RecvSwitch;
END;
Transmit: SendSwitch;
Invalid,
SetParm,
Alldone: { nothing };
END;
{ case }
FinishUp(errorOccurred); { end of program }
END { main KERMIT };
PROCEDURE PromptAndParseUser(VAR exitProgram : boolean;
VAR RunType : command);
EXTERNAL;
BEGIN { of main }
initio;
KermitInit; { initialize }
9999: { Goto for an error_packet }
RunType := Invalid;
WHILE NOT(exitProgram) DO
BEGIN
PromptAndParseUser(exitProgram, RunType);
IF NOT(exitProgram)
THEN
BEGIN
CASE RunType OF
Receive,
Transmit :
IF (NOT local)
THEN
KermitMain
ELSE
IF NOT(invalidConnection)
THEN
KermitMain
ELSE
BadVTerminalConnect;
Connect :
BEGIN
local := true;
OpenPort;
IF NOT(invalidConnection)
THEN
MakeConnection
ELSE
BadVTerminalConnect;
END;
END;
END;
RunType := Invalid;
END;
Closeall;
END.