201 lines
5.8 KiB
Plaintext
201 lines
5.8 KiB
Plaintext
{$X+,V-,B-,I-}
|
|
program Fget; { Listening Process / receiver / Slave }
|
|
|
|
{ Testprogram for the nwPEP unit / NwTP 0.6 API. (c) 1993,1995, R.Spronk }
|
|
|
|
{$DEFINE noTRACE}
|
|
|
|
uses crt,nwMisc,nwIPX,nwPEP;
|
|
|
|
Var ListenECB :Tecb; { used to listen for packets }
|
|
ListenPepHdr :TpepHeader;
|
|
|
|
SendECB :Tecb; { used to send acknowledgements }
|
|
SendPepHdr :TpepHeader;
|
|
|
|
IOsocket :word;
|
|
DataBuffer :array[1..546] of byte;
|
|
SendDataBuffer:byte;
|
|
|
|
PacketReceived :Boolean;
|
|
LastTransactionID:LongInt;
|
|
|
|
NewStack:array[1..8192] of word; { !! used by ESR }
|
|
StackBottom:word; { !! used by ESR }
|
|
|
|
Procedure CheckError(err:boolean; errNbr:word);
|
|
begin
|
|
if err
|
|
then begin
|
|
CASE errNbr of
|
|
$0100:writeln('IPX needs to be installed.');
|
|
$0101:writeln('ERROR: Connection not established. A Timeout occured');
|
|
$0102:writeln('ERROR: The transfer is aborted; A timeout occured.');
|
|
$0108:writeln('Transfer aborted.');
|
|
$0300:writeln('The supplied path doesn'' exist / no write rights in directory.');
|
|
$0301:writeln('Error writing to file / no write rights in directory.');
|
|
$10FE:writeln('Error opening socket: Socket Table Is Full.');
|
|
$10FF:writeln('Error opening socket: Socket is already open.');
|
|
else writeln('Unspecified error.');
|
|
end; {case}
|
|
IPXcloseSocket(IOsocket);
|
|
halt(1);
|
|
end;
|
|
end;
|
|
|
|
Function TimeOut(t1,t2:word;n:byte):boolean;
|
|
{ ticks t2 - ticks t1 > n seconds ? }
|
|
Var lt1,lt2:LongInt;
|
|
begin
|
|
lt2:=t2;
|
|
if t1>t2 then lt2:=lt2+$FFFF;
|
|
TimeOut:=(lt2-t1)>(n*18);
|
|
end;
|
|
|
|
{$F+}
|
|
Procedure ListenAndAckHandler;
|
|
begin
|
|
If (ListenECB.CompletionCode<>0)
|
|
or (ListenPepHdr.IPXhdr.packetType<>PEP_PACKET_TYPE)
|
|
or (ListenPepHdr.clienttype<>$EA)
|
|
or (ListenPepHdr.TransactionID<LastTransactionID) { discard dupe old packet }
|
|
then IPXlistenForPacket(ListenECB)
|
|
else begin
|
|
PacketReceived:=(ListenPepHdr.transactionID>LastTransactionID); { new packet received }
|
|
|
|
{ Acknowledge new packets and duplicates of the latest packet, }
|
|
{ as the original acknowledgement may have been lost. }
|
|
LastTransactionID:=ListenPepHdr.TransactionID;
|
|
|
|
{ Setup acknowledgement ECB and PEPheader, and send it. }
|
|
if SendECB.InUseFlag=0
|
|
then begin
|
|
ListenPepHdr.IPXhdr.source.socket:=swap(ListenPepHdr.IPXhdr.source.socket);
|
|
{ socket is hi-lo in IPX/PEPHeaders. SetupSendECB expects lo-hi }
|
|
PEPsetupSendECB(NIL,IOsocket,ListenPepHdr.IPXhdr.source,
|
|
@SendDataBuffer,0,
|
|
SendPepHdr,SendECB);
|
|
SendPepHdr.TransactionId:=LastTransactionID;
|
|
SendPepHdr.ClientType:=$EA;
|
|
IPXsendPacket(SendECB);
|
|
end;
|
|
end;
|
|
end;
|
|
{$F-}
|
|
|
|
{$F+}
|
|
Procedure ListenAndAckESR; assembler;
|
|
asm
|
|
mov dx, seg stackbottom
|
|
mov ds, dx
|
|
|
|
mov dx,ss { setup of a new local stack }
|
|
mov bx,sp { ss:sp copied to dx:bx}
|
|
mov ax,ds
|
|
mov ss,ax
|
|
mov sp,offset stackbottom
|
|
push dx { push old ss:sp on new stack }
|
|
push bx
|
|
CALL ListenAndAckHandler
|
|
pop bx { restore ss:sp from new stack }
|
|
pop dx
|
|
mov sp,bx
|
|
mov ss,dx
|
|
end;
|
|
{$F-}
|
|
|
|
Var ticks,ticks2 :word;
|
|
FileName:string;
|
|
FileSize:LongInt;
|
|
DirName:string;
|
|
f:file;
|
|
BytesToWrite,BytesWritten:word;
|
|
|
|
begin
|
|
IpxInitialize;
|
|
CheckError(nwIPX.result>0,$100);
|
|
|
|
If (pos('?',ParamStr(1))>0) or (paramcount>1)
|
|
then begin
|
|
writeln('Usage: FGET <directory>');
|
|
writeln('-The File sent by FSEND on another workstation');
|
|
writeln('will be copied to the supplied directory.');
|
|
halt(1);
|
|
end;
|
|
If paramcount=1
|
|
then DirName:=ParamStr(1)
|
|
else DirName:='.';
|
|
|
|
IF NOT (DirName[ord(dirName[0])] IN [':','\'])
|
|
then DirName:=DirName+'\';
|
|
assign(f,DirName+'temp.$$$');
|
|
rewrite(f,1);
|
|
CheckError(IOresult<>0,$0300);
|
|
close(f);
|
|
|
|
IOSocket:=$5678;
|
|
IPXopenSocket(IOsocket,SHORT_LIVED_SOCKET);
|
|
CheckError(nwIPX.result>0,$1000+nwIPX.result);
|
|
|
|
{ Setup of ECB and PepHeader, start listening for incoming packets. }
|
|
LastTransactionID:=0;
|
|
PacketReceived:=False;
|
|
PEPSetupListenECB(Addr(ListenAndAckESR),IOsocket,@DataBuffer,546,
|
|
ListenPepHdr,ListenECB);
|
|
IPXListenForPacket(ListenECB);
|
|
writeln('Waiting for FSEND to start sending.. (any key to abort)');
|
|
|
|
IPXGetIntervalMarker(ticks);
|
|
REPEAT
|
|
IPXrelinquishControl;
|
|
IPXGetIntervalMarker(ticks2);
|
|
CheckError(TimeOut(ticks,ticks2,130),$101);{ error if a timeout occurred }
|
|
CheckError(Keypressed,$108);
|
|
UNTIL PacketReceived;
|
|
|
|
writeln('Handshaking.. Initiating transfer process.');
|
|
{$IFDEF TRACE}
|
|
writeln('Received PacketID:',LastTransactionID);
|
|
{$ENDIF}
|
|
|
|
{ do something with DataBuffer: the data that was just received. }
|
|
{ the first packet contains the filename and filesize }
|
|
Move(DataBuffer[1],FileName[0],15);
|
|
Move(DataBuffer[16],FileSize,4);
|
|
writeln('Receiving file ',FileName,', size: ',FileSize);
|
|
|
|
assign(f,DirName+filename);
|
|
rewrite(f,1);
|
|
BytesToWrite:=512;
|
|
|
|
REPEAT { Listen for remaining packets }
|
|
Packetreceived:=false;
|
|
|
|
While SendECB.InuseFlag<>0
|
|
do IPXrelinquishControl;
|
|
|
|
IPXListenForPacket(ListenECB);
|
|
IPXGetIntervalMarker(ticks);
|
|
Repeat
|
|
IPXrelinquishControl;
|
|
IPXGetIntervalMarker(ticks2);
|
|
CheckError(TimeOut(ticks,ticks2,10),$102); { error if Timeout occurred }
|
|
CheckError(Keypressed,$108);
|
|
until PacketReceived;
|
|
{$IFDEF TRACE}
|
|
writeln('Received packet#:',LastTransactionID);
|
|
{$ENDIF}
|
|
|
|
{ Write DataBuffer to disk. }
|
|
IF FileSize<512
|
|
then BytesToWrite:=FileSize;
|
|
BlockWrite(f,DataBuffer,BytesToWrite,BytesWritten);
|
|
CheckError(BytesToWrite<>BytesWritten,$0301);
|
|
|
|
FileSize:=FileSize-512;
|
|
UNTIL (FileSize<=0); { entire file received }
|
|
|
|
writeln('Transfer complete.');
|
|
IPXcloseSocket(IOsocket);
|
|
close(f);
|
|
end. |