{ 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;