home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 2
/
ctrom_ii_b.zip
/
ctrom_ii_b
/
PROGRAM
/
PASCAL
/
TPKERMIT
/
RECVFILE.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1987-03-25
|
14KB
|
328 lines
(* +FILE+ RECVFILE.PASMSCPM *)
(* ------------------------------------------------------------ *)
(* BreakACK - Procedure will send a ACK plus a break char *)
(* X or Z . *)
(* ------------------------------------------------------------ *)
PROCEDURE BreakACK (Achar : Char);
BEGIN (* SEND ACK or NAK *)
OutDataCount := 1 ;
OUTSEQ := OUTSEQ + 1 ;
IF OUTSEQ >= 64 then OUTSEQ := 0;
OUTPACKETTYPE := ord('Y');
SendData[1] := Ord(Achar);
SENDPACKET ;
END ; (* SEND ACK or NAK *)
(* ------------------------------------------------------------ *)
(* RenameDup- Procedure will check to see if a file is *)
(* already present if it is it returns a new *)
(* name modified with &. *)
(* Note : this procedure is maybe called recursively. *)
(* ------------------------------------------------------------ *)
PROCEDURE RenameDup(var MyFile:comstring);
BEGIN (* RenameDup *)
If Firstfile(MyFile,MyFile) then
Begin (* change name of file *)
Insert ('&',Myfile,Pos('.',Myfile));
if Pos('.',Myfile) > 9 then
Delete(Myfile,Pos('&',Myfile)-1,1);
RenameDup(Myfile);
End ; (* change name of file *)
END ; (* RenameDup *)
(* **************************************************************** *)
(* RECVFILE - This routine handles the Receiving of a file from *)
(* the Main frame computer. *)
(* *)
(* **************************************************************** *)
PROCEDURE RECVFILE (var InParms : comstring);
VAR
Bit8 : BYTE ;
Lastseqnum : INTEGER ;
Receiving,ReplaceFile : BOOLEAN ;
Retries,PacketCount,
CharCount,i,j : INTEGER ;
Filenames,FileName,
Myfiles,Myfile,Astring : ComString ;
ErrorMsg : ComString ;
FileComing : TEXT ;
Label Gotinit;
(* ------------------------------------------------------------ *)
(* SENDNAK - Procedure of RECVFILE, will check the number of *)
(* RETRIES , if it is greater than 0 it will send a *)
(* call SendPacketType('N') which send a NAK packet *)
(* and decrements the RETRIES by 1. *)
(* Side Effect - RETRIES is decremented by 1. *)
(* STATE is set to A if no more retries. *)
(* - RetryCount is incremented *)
(* ------------------------------------------------------------ *)
PROCEDURE SENDNAK ;
BEGIN (* SEND NAK *)
RetryCount := RetryCount + 1;
IF RETRIES > 0 then
BEGIN (* Ask for a retransmission *)
SendPacketType('N');
RETRIES := RETRIES - 1 ;
END (* Ask for a retransmission *)
else
STATE := A ;
END ; (* SEND NAK *)
BEGIN (* ------- RECVFILE procedure ------- *)
WRITELN (' RECEIVE file command . ',InParms);
Packetcount := 0 ;
ReplaceFile := false ;
Lastseqnum := 0 ;
(* Scan Parameter string *)
FileNames := GETTOKEN(InParms);
MyFiles := FileNames ;
Astring := Uppercase(GetToken(Inparms));
If Astring = 'AS' then
if length(InParms) > 0 then
Begin (* get AS name *)
MyFiles := GetToken(Inparms);
Astring := Uppercase(GetToken(Inparms));
If Pos(Astring,' REPLACE') = 2 then ReplaceFile := True
else InParms := Astring + InParms;
End (* get AS name *)
else MyFiles := FileNames
else
If Pos(Astring,' REPLACE') = 2 then ReplaceFile := True
else InParms := Astring + InParms ;
If FileNames <> '' then
Begin (* Send a R type packet requesting the file *)
OutDataCount := length(Filenames);
OutSeq := 0 ;
OutPacketType := ord('R');
For i := 1 to length(Filenames) do
SendData[i] := Ord(FileNames[i]) ;
WaitXon := false ;
SendPacket ;
End (* Send a R type packet requesting the file *)
else
WaitXon := XonXoff ;
STATE := R ;
RECEIVING := TRUE ;
BreakState := NoBreak ;
RETRIES := 10 ; (* Up to 10 retries allowed. *)
RetryCount := 0 ;
clrscr ;
GotoXY(10,4) ;
Write('Number of Data Packets Received = ');
GotoXY(10,5) ;
Write('Number of Nak responses sent = ');
WHILE RECEIVING DO CASE STATE OF
(* R ------ Initial receive State ------- *)
(* Valid received msg type : S *)
R : BEGIN (* Initial Receive State *)
If InPacketType =Ord('S') then goto Gotinit;
IF (NOT RECVPACKET) OR (INPACKETTYPE=Ord('N')) then SENDNAK
else
Gotinit:
(* Get a packet *)
IF INPACKETTYPE = Ord('S') then
BEGIN (* Got INIT packet *)
GetInitPacket ; (* Get Init parameters *)
(* Reply with ACK and init parameters *)
OutPacketType := Ord('Y');
PutInitPacket ;
SENDPACKET ;
STATE := RF ;
END (* Got INIT packet *)
else
BEGIN (* Not init packet *)
STATE := A ; (* ABORT if not INIT packet *)
ABORT := NOT_S ;
END ; (* Not init packet *)
END ; (* Initial Receive State *)
(* RF ----- Receive Filename State ------- *)
(* Valid received msg type : S,Z,F,B *)
RF: IF (NOT RECVPACKET) OR (INPACKETTYPE=Ord('N')) then SENDNAK
else
(* Get a packet *)
IF INPACKETTYPE = Ord('S') then STATE:=R else
IF INPACKETTYPE = Ord('Z') then SendPacketType('N') else
IF INPACKETTYPE = Ord('B') then STATE:=C else
IF INPACKETTYPE = Ord('F') then
BEGIN (* Got file header *)
For i := 1 to InDataCount do
FileName[i] := Chr(RecvData[i]) ;
FileName[0] := Chr(InDataCount) ;
If Filenames = '' then
Myfile := Filename
else
If NewAsfile(Filenames,Filename,MyFiles,Myfile) then;
GotoXY(10,2);
If ReplaceFile then (* write over old file *)
else ReNameDup(Myfile);
Writeln('Receiving file ',Filename,' as ',Myfile,
' ');
Assign(FileComing,Prefixof(Filenames)+MyFile);
STATE := RD ;
If not ForPrinter then
Begin {$I-}
REWRITE(FileComing);
If IOresult <> 0 then
Begin (* IO error *)
Writeln(' Directory Full ');
STATE := A ;
SendPacketType('N');
End ; (* IO error *)
End ; {$I+}
SendPacketType('Y');
END (* Got file header *)
else
BEGIN (* Not S,F,B,Z packet *)
STATE := A ; (* ABORT if not a S,F,B,Z type packet *)
ABORT := NOT_SFBZ ;
END ; (* Not S,F,B,Z packet *)
(* RD ----- Receive Data State ------- *)
(* Valid received msg type : D,Z *)
RD: IF (NOT RECVPACKET) OR (INPACKETTYPE=Ord('N')) then SENDNAK
else
If lastseqnum = inseq then SendPacketType('Y')
else
BEGIN (* Got a good packet *)
lastseqnum := inseq ;
IF INPACKETTYPE = Ord('D') then
BEGIN (* Receive data *)
(* WRITELN ('RECEIVE data '); *)
PacketCount := PacketCount + 1 ;
GotoXY(44,4) ; Write (PacketCount);
GotoXY(44,5) ; Writeln(RetryCount);
I := 1 ;
WHILE I <= InDataCount DO
BEGIN (* Write Data to file *)
IF RecvData[I] = RepChar then
BEGIN (* Repeat char *)
I := I+1 ;
charcount := RecvData[I] - 32 ;
I := I + 1 ;
For j := 1 to charcount - 1 do
If ForPrinter then Write(LST,Chr(RecvData[i]))
else
Begin {$I-}
Write(FileComing,Chr(RecvData[i]));
If IOresult <> 0 then
Begin (* IO error *)
Writeln(' Disk is Full or file too large');
STATE := A ;
SendPacketType('N');
End ; (* IO error *)
End ; {$I+}
END ; (* Repeat char *)
IF RecvData[I] = Bit8Quote then
BEGIN (* 8TH BIT QUOTING *)
I := I+1 ;
BIT8 := $80 ;
END (* 8TH BIT QUOTING *)
else
BIT8 := 0 ;
IF RecvData[I] = CntrlQuote then
BEGIN (* CONTROL character *)
I := I+1 ;
IF RecvData[I] = $3F then (* Make it a del *)
RecvData[I] := $7F
else
IF RecvData[I] >= 64 then (* Make it a control *)
RecvData[I] := RecvData[I] - 64 ;
END ; (* CONTROL character *)
RecvData[I] := RecvData[I] + BIT8 ;
If ForPrinter then Write(LST,Chr(RecvData[i]))
else
Begin {$I-}
Write(FileComing,Chr(RecvData[i]));
If IOresult <> 0 then
Begin (* IO error *)
Writeln(' Disk is Full or file too large');
STATE := A ;
SendPacketType('N');
End ; (* IO error *)
End ; {$I+}
I := I + 1 ;
END ; (* Write Data to File *)
Case Breakstate of
NoBreak : SendPacketType('Y');
BC : RECEIVING:=false ;
BE : SendPacketType('N') ;
BX : BreakAck('X') ;
BZ : BreakAck('Z') ;
End; (* Case BreakState *)
If Breakstate <> NoBreak then
Writeln('Receiving file ',Filename,' as ',Myfile,' Interrupted');
If BreakState = BX then Breakstate := NoBreak ;
END (* Receive data *)
else
IF INPACKETTYPE = Ord('F') then
BEGIN (* repeat *)
OutSeq := OutSeq - 1 ;
SendPacketType('Y') ;
END (* repeat *)
else
IF INPACKETTYPE = Ord('Z') then
BEGIN (* End of Incoming File *)
If not ForPrinter then
Begin {$I-}
CLOSE(FileComing);
If IOresult <> 0 then
Begin (* IO error *)
Writeln(' Disk is Full or file too large');
End ; (* IO error *)
End ; {$I+}
STATE := RF ;
SendPacketType('Y');
END (* End of Incoming File *)
else
BEGIN (* Not D,Z packet *)
STATE := A; (* ABORT - Type not D,Z, *)
ABORT := NOT_DZ ;
END ; (* Not D,Z packet *)
END ; (* Got a good packet *)
(* C ----- COMPLETED State ------- *)
C: BEGIN (* COMPLETED Receiving *)
SendPacketType('Y');
If BreakState = NoBreak then
Writeln ('Receiving files completed OK.')
else
Writeln('Receiving Files terminated by manual interruption');
RECEIVING := FALSE ;
END ; (* COMPLETED Receiving *)
(* A ----- A B O R T State ------- *)
A: BEGIN (* Abort Sending *)
{$I-}
CLOSE(FileComing);
If IOresult <> 0 then
Writeln(' Unable to close file, is DISK FULL ');
{$I+}
WRITELN ('RECEIVEing files ABORTED');
RECEIVING := FALSE ;
(* SEND ERROR packet *)
OutSeq := 0 ;
ErrorMsg :=' RECVfile abort' ;
OutDataCount := length(ErrorMsg) ;
For i := 1 to length(ErrorMsg) do
SendData[i] := Ord(ErrorMsg[i]) ;
OutPacketType := Ord('E');
SENDPACKET ;
END ; (* Abort Sending *)
END ; (* CASE of STATE *)
END ; (* ------- RECVFILE procedure -------*)