{$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.TransactionIDLastTransactionID); { 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 '); 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.