home *** CD-ROM | disk | FTP | other *** search
- { 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;
-
-