home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
pub
/
rt11pascal
/
rtrecv.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
2020-01-01
|
8KB
|
422 lines
{ This the ReceiveSwitch Overlay }
PROCEDURE GetFile({ Using } data:string);
{ create file from fileheader packet }
CONST { used for GetFile }
FLEN1 = 7; { Position of "." in file name }
FLEN2 = 10; { Max length of file name }
TEMPFILE = 'TEMP.K '; { Mask for temp file }
VAR
p,strend: integer;
temp : string;
BEGIN
WITH CurrentPacket^ DO
BEGIN
IF DiskFile = IOERROR { check if we already have a file }
THEN
BEGIN
IF Verbosity
THEN
PutCS('Creating file ... ',data,STDERR);
{ check position of '.' -- truncate if bad }
p := index(data,PERIOD);
IF (p > FLEN1 )
THEN
BEGIN
data[FLEN1] := PERIOD;
scopy(data,p+1,temp,1);
scopy(temp,1,data,FLEN1+1);
END;
{ check Max length }
IF length(data) > FLEN2
THEN
data[FLEN2 +1] := ENDSTR;
IF (Exists(data) AND (fileWarn = oON))
THEN
BEGIN
IF local
THEN
PutCS('File already exists ',data,STDERR);
CtoS(TEMPFILE,data);
strend := 0;
REPEAT
strend := strend +1;
UNTIL (data[strend] = BLANK);
strend := itoc(n,data,strend);
IF local
THEN
PutCS('Creating ... ',data,STDERR);
END;
DiskFile := Sopen(data,-IOWRITE);
END;
IF (Diskfile <= IOERROR)
THEN
ErrorPack('Cannot create file ');
END;
END;
PROCEDURE ReceiveInit;
{ receive init packet }
{ respond with ACK and our parameters }
BEGIN
IF NumTry > MaxTry
THEN
BEGIN
State := Abort;
PutErr('Cannot receive init ');
END
ELSE
BEGIN
Verbose ( 'Receiving Init ');
NumTry := NumTry+1;
IF RecvPacket
AND (CurrentPacket^.ptype = TYPES)
THEN
BEGIN
WITH CurrentPacket^ DO
BEGIN
n := seq;
DeCodeParm(data);
END;
{ now send mine }
WITH ThisPacket^ DO
BEGIN
count := NUMPARAM;
seq := n;
Ptype := TYPEY;
EnCodeParm(data);
END;
SendPacket;
NumACK := NumACK+1;
State := FileHeader;
OldTry := NumTry;
NumTry := 0;
MaxTry := DEFTRY; { use regular default now }
n := (n+1) MOD 64
END
ELSE
BEGIN
IF Debug
THEN
PutCln('Received Bad init ',STDERR);
SendNAK(n);
END;
END;
END;
PROCEDURE DataToFile; { output to file }
VAR
len,i : integer;
temp : string;
BEGIN
WITH CurrentPacket^ DO
BEGIN
len := length(data);
AddTo(ChInFileRecv ,len);
CASE EOLforFile OF
LineFeed: putstr(data,DiskFile);
CrLf:
BEGIN { don't output CR }
FOR i:=1 TO len DO
IF data[i] <> CR
THEN
putcf(data[i],DiskFile);
END;
JustCR:
BEGIN { change CR to NEWLINE }
FOR i:=1 TO len DO
IF data[i]=CR
THEN
data[i]:=NEWLINE;
putstr(data,DiskFile);
END;
END;
{ case }
END;
END;
PROCEDURE Dodata; { Process Data packet }
BEGIN
WITH CurrentPacket^ DO
BEGIN
IF seq = ((n + 63) MOD 64)
THEN
BEGIN { data last one }
IF OldTry>MaxTry
{ number of tries? }
THEN
BEGIN
State := Abort;
PutErr('Old data - Too many ');
END
ELSE
BEGIN
SendACK(seq);
NumTry := 0;
END;
END
ELSE
BEGIN { data - this one }
IF (n<>seq)
THEN
SendNAK(n)
ELSE
BEGIN
DataToFile;
SendACK(n); { ACK }
OldTry := NumTry;
NumTry := 0;
n := (n+1) MOD 64;
END;
END;
END;
END;
PROCEDURE DoFileLast; { Process File Packet }
BEGIN { File header - last one }
IF OldTry > MaxTry { tries ? }
THEN
BEGIN
State := Abort;
PutErr('Old file - Too many ');
END
ELSE
BEGIN
OldTry := OldTry+1;
WITH CurrentPacket^ DO
BEGIN
IF seq = ((n + 63) MOD 64)
{ packet number }
THEN
BEGIN { send ACK }
SendACK(seq);
NumTry := 0
END
ELSE
BEGIN
SendNAK(n); { NAK }
END;
END;
END;
END;
PROCEDURE DoEOF; { Process EOF packet }
BEGIN { EOF - this one }
IF CurrentPacket^.seq<>n { packet number ? }
THEN
SendNAK(n) { NAK }
ELSE
BEGIN { send ACK }
Sclose(DiskFile); { close file }
SendACK(n);
DiskFile := IOERROR;
OldTry := NumTry;
NumTry := 0;
n := (n+1) MOD 64; { next packet }
State := FileHeader; { change state }
END;
END;
PROCEDURE ReceiveData; { Receive data packets }
VAR
strend: integer;
good : boolean;
BEGIN
IF NumTry > MaxTry { check number of tries }
THEN
BEGIN
State := Abort;
IF local
THEN
PutCN('Recv data -Too many ',n,STDERR);
END
ELSE
BEGIN
NumTry := NumTry+1; { increase number of tries }
good := RecvPacket; { get packet }
WITH CurrentPacket^ DO
BEGIN
IF Verbosity
THEN
PutCN('Receiving (Data) ',CurrentPacket^.seq,STDERR);
IF ((ptype = TYPED) OR (ptype=TYPEZ)
OR (ptype=TYPEF)) AND good { check type }
THEN
CASE ptype OF
TYPED: DoData;
TYPEF: DoFileLast;
TYPEZ: DoEOF;
END { case }
ELSE
BEGIN
IF Debug
THEN
PutCln('Expected data pack ',STDERR);
SendNAK(n);
END;
END;
END;
END;
PROCEDURE DoBreak; { Process Break packet }
BEGIN { Break transmission }
IF CurrentPacket^.seq<>n { packet number ? }
THEN
SendNAK(n) { NAK }
ELSE
BEGIN { send ACK }
SendACK(n) ;
State := Complete { change state }
END
END;
PROCEDURE DoFile; { Process file packet }
BEGIN { File Header }
WITH CurrentPacket^ DO
BEGIN
IF seq<>n { packet number ? }
THEN
SendNAK(n) { NAK }
ELSE
BEGIN { send ACK }
AddTo(ChInFileRecv, length(data));
GetFile(data); { get file name }
SendACK(n);
OldTry := NumTry;
NumTry := 0;
n := (n+1) MOD 64; { next packet }
State := FileData; { change state }
END;
END;
END;
PROCEDURE DoEOFLast; { Process EOF Packet }
BEGIN { End Of File Last One}
IF OldTry > MaxTry { tries ? }
THEN
BEGIN
State := Abort;
PutErr('Old EOF - Too many ');
END
ELSE
BEGIN
OldTry := OldTry+1;
WITH CurrentPacket^ DO
BEGIN
IF seq =((n + 63 ) MOD 64)
{ packet number }
THEN
BEGIN { send ACK }
SendACK(seq);
Numtry := 0
END
ELSE
BEGIN
SendNAK(n); { NAK }
END
END;
END;
END;
PROCEDURE DoInitLast;
BEGIN { Init Packet - last one }
IF OldTry> DEFITRY { number of tries? }
THEN
BEGIN
State := Abort;
PutErr('Old init - Too many ');
END
ELSE
BEGIN
OldTry := OldTry+1;
IF CurrentPacket^.seq = ((n + 63) MOD 64)
{ packet number }
THEN
BEGIN { send ACK }
WITH ThisPacket^ DO
BEGIN
count := NUMPARAM;
seq := CurrentPacket^.seq;
ptype := TYPEY;
EnCodeParm(data);
END;
SendPacket;
NumACK := NumACK+1;
NumTry := 0;
END
ELSE
BEGIN
SendNAK(n); { NAK }
END;
END;
END;
PROCEDURE ReceiveFile; { receive file packet }
VAR
good: boolean;
BEGIN
IF NumTry > MaxTry { check number of tries }
THEN
BEGIN
State := Abort;
PutErr('Recv file - Too many');
END
ELSE
BEGIN
NumTry := NumTry+1; { increase number of tries }
good := RecvPacket; { get packet }
WITH CurrentPacket^ DO
BEGIN
IF Verbosity
THEN
PutCN('Receiving (File) ',seq,STDERR);
IF ((ptype = TYPES) OR (ptype=TYPEZ)
OR (ptype=TYPEF) OR (ptype=TYPEB)) { check type }
AND good
THEN
CASE ptype OF
TYPES: DoInitLast;
TYPEZ: DoEOFLast;
TYPEF: DoFile;
TYPEB: DoBreak;
END { case }
ELSE
BEGIN
IF Debug
THEN
PutCln('Expected File Pack ',STDERR);
SendNAK(n);
END;
END;
END;
END;
{$E+}
PROCEDURE RecvSwitch; { this procedure is the main receive routine }
BEGIN
StartRun;
REPEAT
CASE State OF
FileData: ReceiveData;
Init: ReceiveInit;
Break: { nothing };
FileHeader: ReceiveFile;
EOFile: { nothing };
Complete: { nothing };
Abort: { nothing };
END;
{ case }
UNTIL (State = Abort ) OR ( State = Complete );
END;