Metropoli BBS
VIEWER: uymodem.pas MODE: TEXT (LATIN1)
{$I COMPDIR.PAS}

UNIT UYmodem ;
INTERFACE

{$UNDEF VERBOSE}
{$DEFINE ERRORS}

CONST OneK = 1024 ;  { For one kilobyte packet }

TYPE YM_Buffer  = ARRAY[0..OneK-1] OF BYTE ;  { To receive/send packets }


VAR YM_Error : STRING ;
    YM_ErrorNb : WORD ;




FUNCTION  YM_ReceiveFile ( NbPort : BYTE ; DoReplace : BOOLEAN ) : BOOLEAN ;

FUNCTION  YM_SendFile ( NbPort:BYTE;
                        NameFile:STRING;
                        NameRecept:STRING ) : BOOLEAN ;
PROCEDURE YM_CloseBatchSession ( NbPort : BYTE );

IMPLEMENTATION
USES UEZComm , UCRC ;

CONST SOH = 1  ; { 128 bytes packet    }
      STX = 2  ; { 1024 bytes packet   }
      EOT = 4  ; { End of transmission }
      ACK = 6  ; { Acknowledge         }
      NAK = 21 ; { Not-Acknowledge     }

CONST _20_ticks = 20 ;
      _100_ticks = 100 ;


FUNCTION YM_ReceivePacket ( NbPort : BYTE ;
                            Max_Retries : BYTE ;
                            VAR Size : WORD ;
                            VAR NumPacket : BYTE ;
                            VAR Packet : YM_Buffer ;
                            DoCRC : BOOLEAN;
                            WaitsForEOT : BOOLEAN ) : BOOLEAN ;
{ The only case where YM_ReceivePacket = FALSE and YM_ErrorNb = 0
is when:  WaitsForEOT = TRUE
     AND  effectively the first character received is EOT
}


VAR Retry : BYTE ;
    Ch    : BYTE ;
    i : INTEGER ;

    CRC_Cal : WORD ;
    CRC_Rec : WORD ;

    Checksum_Cal : BYTE ;
    Checksum_Rec : BYTE ;

LABEL Bad_Packet ;
BEGIN
     YM_ErrorNb := 0 ;
     Retry := 0 ;
     WHILE ( Retry <> Max_Retries ) DO
      BEGIN
         IF NOT ( PortReadTicks ( NbPort , _100_ticks , Ch ) ) THEN
           BEGIN
                YM_ErrorNb := 10 ;
                YM_Error := 'Time out' ;
                {$IFDEF ERRORS}
                WriteLn( 'Receiving Packet: Error; TimeOut first byte.');
                {$ENDIF}
                Inc ( Retry ) ;
                Continue ;
           END;

         IF WaitsForEOT AND (Ch=EOT) THEN
          BEGIN YM_ErrorNb := 0 ; { No error !! }
                YM_ReceivePacket := FALSE ;
                Exit ;
          END;

         CASE Ch OF
           STX : Size := 1024 ;
           SOH : Size :=  128 ;
           ELSE
            BEGIN YM_ErrorNb := 11 ;
                  YM_Error := 'Bad synchro character' ; GOTO Bad_Packet ;
            END;
         END;

         {$IFDEF VERBOSE}
         WriteLn('Receiving Packet; first byte OK: ', Ch:3 );
         {$ENDIF}

         IF NOT ( PortReadTicks ( NbPort , _20_ticks , Ch ) ) THEN
           BEGIN YM_ErrorNb := 12 ;
                 YM_Error := 'Time out' ; GOTO Bad_Packet ;
           END;

         IF ( Ch <> NumPacket ) THEN
           IF (NumPacket > 0) AND (Ch = NumPacket-1) THEN
            BEGIN { Maybe the ACK was not correctly transmitted, so
                    the sender sends this packet another time }
                  { For synchro with the main handler, we set NumPacket=Ch }
                  NumPacket := Ch ;
            END
           ELSE
            BEGIN YM_ErrorNb := 13 ;
                  YM_Error := 'Bad packet number' ; GOTO Bad_Packet ;
            END;

         {$IFDEF VERBOSE}
         WriteLn('Receiving Packet; Packet num OK: ', NumPacket:3 );
         {$ENDIF}

         IF NOT ( PortReadTicks ( NbPort , _20_ticks , Ch ) ) THEN
           BEGIN YM_ErrorNb := 14 ;
                 YM_Error := 'Time out' ; GOTO Bad_Packet ;
           END;
         IF ( Ch <> $FF - NumPacket ) THEN
           BEGIN YM_ErrorNb := 15 ;
                 YM_Error := 'Bad 1-complement packet number' ; GOTO Bad_Packet ;
           END;

         {$IFDEF VERBOSE}
         WriteLn('Receiving Packet; 1-complement Packet num OK: ', Ch:3 );
         {$ENDIF}

         CRC_Cal := 0 ;
         Checksum_Cal := 0 ;
         FOR i := 0 TO Size - 1 DO
           BEGIN
                IF NOT ( PortReadTicks (NbPort,_20_ticks,Packet[i]) ) THEN
                   BEGIN YM_ErrorNb := 16 ;
                         YM_Error := 'Time out' ; GOTO Bad_Packet ;
                   END;
                {$IFDEF VERBOSE}
                IF (i MOD 64) = 0 THEN Write('.');
                {$ENDIF}

                CRC_Cal := UpdCRCfast ( Packet[ i ] , CRC_Cal );
                Inc(Checksum_Cal,Packet[i]);
           END;

         {$IFDEF VERBOSE}
         WriteLn ;
         WriteLn( 'Receiving Packet; all data bytes are here.');
         {$ENDIF}

         IF NOT ( PortReadTicks ( NbPort , _20_ticks , Ch ) ) THEN
           BEGIN YM_ErrorNb := 17 ;
                 YM_Error := 'Time out' ; GOTO Bad_Packet ;
           END;


         IF DoCrc THEN
          BEGIN
           { Checks with the CRC }
           CRC_Rec := Ch SHL 8 ;
           IF NOT ( PortReadTicks ( NbPort , _20_ticks , Ch ) ) THEN
             BEGIN YM_ErrorNb := 18 ;
                   YM_Error := 'Time out' ; GOTO Bad_Packet ;
             END;
           CRC_Rec := CRC_Rec OR Ch ;

           {$IFDEF VERBOSE}
           WriteLn( 'Receiving Packet; CRC reception OK.');
           {$ENDIF}

           IF ( CRC_Cal <> CRC_Rec ) THEN
             BEGIN YM_ErrorNb := 19 ;
                   {$IFDEF VERBOSE}
                   WriteLn( 'My CRC :        ' , CRC_Cal:5 );
                   WriteLn( 'Sender''s CRC : ' , CRC_Rec:5 );
                   {$ENDIF}
                   YM_Error := 'Bad CRC' ; GOTO Bad_Packet ;
             END;
          END
         ELSE
          BEGIN
           { Checks with the checksum }
           {$IFDEF VERBOSE}
           WriteLn( 'Receiving Packet; checksum reception OK.');
           {$ENDIF}
           Checksum_Rec := Ch ;
           IF ( Checksum_Cal <> Checksum_Rec ) THEN
             BEGIN YM_ErrorNb := 20 ;
                   YM_Error := 'Bad checksum' ; GOTO Bad_Packet ;
             END;
          END;

         {$IFDEF VERBOSE}
         WriteLn( 'Receiving Packet; sending ACK.');
         {$ENDIF}
         PortWrite ( NbPort , ACK ) ;
         YM_ReceivePacket := TRUE ;
         Exit ;

    Bad_Packet :
         { Waits for the line to clear }
         {$IFDEF ERRORS}
         WriteLn( 'Receiving Packet; error:clearing line.');
         {$ENDIF}
         PortClearLineTicks ( NbPort, _20_ticks );

         { Now write NAK }
         PortWrite ( NbPort , NAK ) ;

         {$IFDEF ERRORS}
         WriteLn ( 'Error: ' , YM_Error:3  );
         {$ENDIF}
         Inc ( Retry ) ;
         {$IFDEF ERRORS}
         WriteLn ('Retry Nø ' , Retry:2 );
         {$ENDIF}
      END;
      YM_ReceivePacket := FALSE ;
END;


FUNCTION YM_ReceiveFile ( NbPort : BYTE ; DoReplace : BOOLEAN ) : BOOLEAN ;
CONST DecimalDigits : STRING = '0123456789' ;

VAR PacketSize : WORD ;
    PacketBuff : YM_Buffer ;

    Retry : BYTE ;
    LastPacket : BYTE ;
    ExpectedPacket : BYTE ;

    Index : WORD ;
    NameFile : STRING ;
    SizeFile : LONGINT ;

    tmp : WORD ;

    ResFile : FILE ;

    ReceivedBytes : LONGINT ;
    ToWrite : WORD ;

    DoCRC : BOOLEAN ;

    FUNCTION FileExists(FileName: String): BOOLEAN;
    VAR  F: FILE;
    BEGIN
         {$I-}
         Assign(F, FileName);
         FileMode := 0;  { Set file access to read only }
         Reset(F);
         Close(F);
         {$I+}
         FileExists := (IOResult = 0) and (FileName <> '');
    END;  { FileExists }


    PROCEDURE GetNewName ;
    VAR Nam , Ext : STRING ;
        Ind : BYTE ;
        Finished : BOOLEAN ;
        Count : LONGINT ;
        NbStr : STRING ;
        TmpName : STRING ;
    BEGIN Ind := 1 ;
          WHILE ( Ind <= Length(NameFile) ) AND ( NameFile[Ind]<>'.' )
          DO Inc(Ind);

          Nam := Copy(NameFile,1,Ind-1);
          Ext := Copy(NameFile,Ind,Length(NameFile)-Ind+1);

          Count := 0 ;
          Finished := FALSE ;
          WHILE Not(Finished) DO
           BEGIN Str( Count , NbStr );
                 TmpName := Nam ;
                 WHILE Length(TmpName) < 8 DO TmpName := TmpName + '0' ;
                 FOR Ind := 1 TO Length(NbStr) DO
                   TmpName[8-Length(NbStr)+ Ind] := NbStr[Ind] ;

                 { Checks if the file exists ... }
                 TmpName := TmpName + Ext ;
                 Finished := NOT FileExists( TmpName);
                 Inc(Count);
           END;

          NameFile := TmpName ;
          WriteLn (' Changing to /' , NameFile , '/.' );
    END;

LABEL Handshake_OK ;
BEGIN
     YM_ErrorNb := 0 ; { No error at the beginning }
     ExpectedPacket := 0 ;  { We expect the first packet }

     { Try 5 times with the CRC('C') handshake }
     DoCRC := TRUE ;
     Retry := 0 ;
     WHILE ( Retry < 5 ) DO
      BEGIN
           {$IFDEF VERBOSE}
           WriteLn('Rec File: Sending C; Retry Nø' , Retry );
           {$ENDIF}
           PortWrite ( NbPort , Ord('C') ) ;
           IF YM_ReceivePacket( NbPort,1,
                                PacketSize,ExpectedPacket,
                                PacketBuff,DoCRC,FALSE)
           THEN Goto Handshake_OK ;
           Inc ( Retry ) ;
      END;
     { Now we try with the checksum handshake (NAK) 5 times }
     DoCRC := FALSE ;
     Retry := 0 ;
     WHILE ( Retry < 5 ) DO
      BEGIN
           {$IFDEF VERBOSE}
           WriteLn('Rec File: Sending NAK; Retry Nø' , Retry );
           {$ENDIF}
           PortWrite ( NbPort , NAK ) ;
           IF YM_ReceivePacket( NbPort,1,
                                PacketSize,ExpectedPacket,
                                PacketBuff,DoCRC,FALSE)
           THEN Goto Handshake_OK ;
           Inc ( Retry ) ;
      END;
     { We abort the reception of the file ... }
     YM_ErrorNb := 1 ;
     YM_ReceiveFile := FALSE ; Exit ;

Handshake_OK:
     {$IFDEF VERBOSE}
     WriteLn('Rec File: Sender answered');
     {$ENDIF}
     { We try to get sensible information from the first packet }
      { First, get the name }
      NameFile := '' ;
      Index := 0 ;
      WHILE (Index < PacketSize) AND (PacketBuff[Index] <> 0) DO
        BEGIN NameFile:=NameFile+Chr(PacketBuff[Index]); Inc(Index);
        END;

      IF Index = 0 THEN
        BEGIN { Null name : that is the normal end of the batch session }
              { That is not an error !! }
              WriteLn('End of batch session');
              YM_ReceiveFile := FALSE ; Exit ;
        END;

      IF Index = PacketSize THEN
        BEGIN { We could not find the end of the name ...}
              YM_ErrorNb := 2 ;
              YM_ReceiveFile := FALSE ; Exit ;
        END;
      { Now, get the size (in bytes) }
      Inc(Index); { To skip the null char }
      SizeFile := 0 ;
      WHILE (Index < PacketSize) AND NOT(PacketBuff[Index] IN [Ord(' '),0])
      DO BEGIN SizeFile := SizeFile * 10 ;
               tmp := Pos( Chr(PacketBuff[Index]) , DecimalDigits );
               IF tmp = 0 THEN
                 BEGIN YM_ErrorNb := 3 ;
                       YM_ReceiveFile := FALSE ; Exit ;
                 END;
               Inc(SizeFile, tmp-1 );
               Inc(Index);
         END;

      { We don't use the other fields in the packet 0 (date,attribs,mode) }

     { Now we open the file }
     WriteLn('Receiving /' , NameFile , '/ ( ' , SizeFile ,' bytes).');

     IF FileExists ( NameFile ) AND NOT DoReplace THEN
      BEGIN WriteLn ('/', NameFile ,'/ already exists !!' );
            GetNewName ;
      END;

     Assign( ResFile , NameFile );
     Rewrite ( ResFile , 1 ) ;
     IF IOResult <> 0 THEN
      BEGIN WriteLn ('Unable to create /' , NameFile ,'/.' );
            YM_ReceiveFile := FALSE ; Exit ;
      END;

     { And signal the sender we're ready }
     IF DoCRC THEN PortWrite( NbPort, Ord('C') )
              ELSE PortWrite( NbPort, NAK );

     ReceivedBytes := 0 ;
     WHILE ReceivedBytes < SizeFile DO
      BEGIN
       LastPacket := ExpectedPacket ;
       Inc(ExpectedPacket);
       IF NOT YM_ReceivePacket( NbPort,10,
                                PacketSize,ExpectedPacket,
                                PacketBuff,DoCRC,FALSE)
       THEN
          BEGIN
               Close ( ResFile ) ;
               YM_ReceiveFile := FALSE ; Exit ;
          END;

       IF ExpectedPacket = LastPacket +1 THEN
         BEGIN
          IF ( ReceivedBytes+PacketSize > SizeFile )
          THEN ToWrite := SizeFile - ReceivedBytes
          ELSE ToWrite := PacketSize ;
          BlockWrite ( ResFile , PacketBuff , ToWrite , tmp ) ;
          IF IOResult <> 0 THEN
           BEGIN WriteLn ('Unable to write block !' );
                 Close ( ResFile ) ;
                 YM_ReceiveFile := FALSE ; Exit ;
           END;

          Inc ( ReceivedBytes , ToWrite ) ;
          WriteLn( ReceivedBytes ,' bytes have been successfully received.( '
                    , (100* ReceivedBytes) / SizeFile :4:1 , '% )' );
         END
       ELSE ;
         { The sender should have resent a packet we already received without
           any error ( for example, the ACK was garbaged ), so do nothing }
      END;
     Close(ResFile);

     { If the last ACK sent to the sender was not correctly transmitted,
     then the sender resends the last packet.  Here we can either get
     the EOT, or get the last packet. }

     Retry := 0 ;
     REPEAT
       WHILE YM_ReceivePacket( NbPort,1,
                               PacketSize,ExpectedPacket,
                               PacketBuff,DoCRC,TRUE)
       DO ;
       Inc(Retry);
       IF Retry > 9 THEN
        BEGIN
         YM_ErrorNb := 4 ;
         YM_ReceiveFile := FALSE ; Exit ;
        END;

     UNTIL YM_ErrorNb=0;
     PortWrite(NbPort,ACK);
     YM_ReceiveFile := TRUE ;
END;

{-----------------------------------------------------------------}
FUNCTION YM_SendPacket ( NbPort : BYTE ;
                         Size : INTEGER ;
                         NumPacket : BYTE ;
                         Packet : YM_Buffer ;
                         DoCRC : BOOLEAN ) : BOOLEAN ;

VAR Retry : BYTE ;
    Index : WORD ;

    CRC_Cal : WORD ;
    Checksum_Cal : BYTE ;

    Answer : BYTE ;

BEGIN
     Retry := 0 ;
     WHILE ( Retry < 10 ) DO
      BEGIN
           CASE Size OF
            128  : PortWrite ( NbPort , SOH ) ;
            1024 : PortWrite ( NbPort , STX ) ;
            ELSE
             BEGIN WriteLn('Internal Error' );
                   Halt(1);
             END;
           END;

           {$IFDEF VERBOSE}
           WriteLn( 'Sending Packet:', NumPacket);
           {$ENDIF}

           PortWrite ( NbPort , NumPacket ) ;
           PortWrite ( NbPort , $FF - NumPacket ) ;

           {$IFDEF VERBOSE}
           WriteLn( 'Sending Packet: Sending data');
           {$ENDIF}
           CRC_Cal := 0 ;
           Checksum_Cal := 0 ;
           FOR Index := 0 TO Pred(Size) DO
               BEGIN
                    PortWrite ( NbPort , Packet[Index] ) ;
                    {$IFDEF VERBOSE}
                    IF (Index MOD 64) = 0 THEN Write('.');
                    {$ENDIF}

                    CRC_Cal := UpdCRCfast ( Packet[ Index ] , CRC_Cal );
                    Inc( Checksum_Cal, Packet[Index] );
               END;

           {$IFDEF VERBOSE}
           WriteLn;
           {$ENDIF}

           IF DoCRC THEN
            BEGIN {$IFDEF VERBOSE}
                  WriteLn('Sending Packet: Sending CRC');
                  {$ENDIF}
                  PortWrite ( NbPort , CRC_Cal SHR 8 ) ;
                  PortWrite ( NbPort , CRC_Cal AND $FF ) ;
            END
           ELSE
            BEGIN {$IFDEF VERBOSE}
                  WriteLn('Sending Packet: Sending checksum');
                  {$ENDIF}
                  PortWrite ( NbPort , Checksum_Cal ) ;
            END;

           IF PortReadTicks ( NbPort , _100_ticks , Answer ) THEN
              CASE Answer OF
               ACK : BEGIN {$IFDEF VERBOSE}
                           WriteLn('Sending Packet: Receiver acknowledged');
                           {$ENDIF}
                           YM_SendPacket := TRUE ; Exit ;
                     END;
               NAK : BEGIN {$IFDEF VERBOSE}
                           WriteLn('Sending Packet: !! Receiver sent NAK !!');
                           {$ENDIF}
                     END;
               {$IFDEF VERBOSE}
               ELSE WriteLn('Sending Packet: !! Receiver sent :',Answer,' !!');
               {$ENDIF}
              END;

           {$IFDEF ERRORS}
           WriteLn('Sending Packet: Error , retry' , Retry);
           {$ENDIF}
           Inc ( Retry ) ;
      END;
     YM_SendPacket := FALSE ;
END;

FUNCTION YM_SendFile ( NbPort : BYTE ;NameFile:STRING ; NameRecept:STRING)
                       : BOOLEAN ;
VAR Retry : WORD ;
    Connect : BYTE ;
    DoCRC : BOOLEAN ;

    PacketBuff : YM_Buffer ;
    PacketSize : WORD ;
    Index : WORD ;

    SrcFile : FILE ;
    SizeFile : LONGINT ;
    TmpString : STRING ;

    CurrPacket : BYTE ;

    BytesRead : WORD ;
    BytesSent : LONGINT ;

BEGIN CurrPacket := 0 ;

      Retry := 0 ;
      { We try to get a character, with 10 retries }
      {$IFDEF VERBOSE}
      WriteLn('Sending File: trying to connect' );
      {$ENDIF}
      WHILE NOT PortReadTicks ( NbPort , _100_ticks , Connect ) DO
       BEGIN Inc(Retry);
             IF Retry > 9 THEN
                BEGIN {$IFDEF ERRORS}
                      WriteLn('Sending File: Error no answer' );
                      {$ENDIF}
                      YM_SendFile := FALSE ; Exit ;
                END;
       END;

      {$IFDEF VERBOSE}
      WriteLn('#1:Receiver answered with ' , Connect );
      {$ENDIF}

      CASE Connect OF
         Ord('C') : DoCRC := TRUE ;
         NAK      : DoCRC := FALSE ;
         ELSE
          BEGIN { Bad connect character : 'C' or NAK expected }
                {$IFDEF ERRORS}
                WriteLn('Sending File: Error ; ''C'' or NAK expected' );
                {$ENDIF}
                YM_SendFile := FALSE ; Exit ;
          END;
      END;

      IF Length(NameRecept) = 0
      THEN WriteLn ('End of batch session.' )
      ELSE WriteLn ('Sending file ' , NameFile , ' as ' , NameRecept ,'.');

      IF DoCRC THEN WriteLn( 'Using 16 bit CRC to detect errors')
               ELSE WriteLn( 'Using checksum to detect errors');

      { We now prepare the first packet }
       { First clear the packet }
       FillChar ( PacketBuff , 128 , 0 );
       { We check if that is the end of the batch session }
       IF Length(NameRecept) > 0 THEN
        BEGIN
           { Now write the name }
           Move ( NameRecept[1] , PacketBuff[0] ,Length(NameRecept) );
           Index := Length(NameRecept)+1 ;
           { Now write the size ... }
           Assign( SrcFile, NameFile );
           Reset(SrcFile,1);
           IF IOResult <> 0 THEN
            BEGIN WriteLn ('Unable to open /' , NameFile ,'/.' );
                  YM_SendFile := FALSE ; Exit ;
            END;

           SizeFile := FileSize(SrcFile);
           Str( SizeFile , TmpString );
           Move ( TmpString[1] , PacketBuff[Index] , Length(TmpString) );
        END;
       { The first packet is ready }

       {$IFDEF VERBOSE}
       WriteLn('Sending File: Sending packet #0' );
       {$ENDIF}
       IF NOT YM_SendPacket (  NbPort ,
                               128 ,       { Use a small packet }
                               CurrPacket ,
                               PacketBuff ,
                               DoCRC )
       THEN
        BEGIN YM_SendFile := FALSE ; Exit ;
        END;

       IF Length(NameRecept) = 0 THEN
        BEGIN { End of batch session }
              YM_SendFile := TRUE ; Exit ;
        END;

      { Here we wait for a character, either 'C' or ACK , 10 retries }
      {$IFDEF VERBOSE}
      WriteLn('Sending File: Waiting for receiver' );
      {$ENDIF}
      Retry := 0 ;
      WHILE NOT PortReadTicks ( NbPort , _100_ticks , Connect ) DO
       BEGIN Inc(Retry);
             IF Retry > 9 THEN
                BEGIN {$IFDEF ERRORS}
                      WriteLn('Sending File: Error; No answer' );
                      {$ENDIF}
                      YM_SendFile := FALSE ; Exit ;
                END;
       END;

      {$IFDEF VERBOSE}
      WriteLn('#2:Receiver answered with ' , Connect );
      {$ENDIF}

      CASE Connect OF
         Ord('C') : ;  { OK }
         NAK      : ;  { OK }
         ELSE
          BEGIN { Bad connect character : 'C' or NAK expected }
                {$IFDEF ERRORS}
                WriteLn('Sending File: Error; ''C'' or NAK expected' );
                {$ENDIF}
                YM_SendFile := FALSE ; Exit ;
          END;
      END;

      { So here we will send the file itself }
      BytesSent := 0 ;
      REPEAT
        FillChar ( PacketBuff , 1024 , 0 );

        BlockRead ( SrcFile , PacketBuff , 1024 , BytesRead ) ;
        IF IOResult <> 0 THEN
            BEGIN WriteLn ('Unable to read a block from /' , NameFile ,'/.' );
                  YM_SendFile := FALSE ; Exit ;
            END;


        IF BytesRead > 0 THEN
         BEGIN
           Inc(CurrPacket);
           IF NOT YM_SendPacket (  NbPort ,
                                   1024 ,       { Use a big packet }
                                   CurrPacket ,
                                   PacketBuff ,
                                   DoCRC )
           THEN
            BEGIN YM_SendFile := FALSE ; Exit ;
            END;

           Inc(BytesSent, BytesRead );
           WriteLn( BytesSent ,' bytes have been successfully sent.( ',
                    (100.0*BytesSent)/SizeFile :4:1 , ' %)' );
         END;

      UNTIL BytesRead <> 1024 ;

      Close(SrcFile);

      { And now, send EOT and wait for ACK }
      Retry := 0 ;
      WHILE Retry < 9 DO
       BEGIN
         PortWrite ( NbPort , EOT );
         IF PortReadTicks ( NbPort , _100_ticks , Connect ) AND (Connect=ACK)
         THEN BEGIN {$IFDEF VERBOSE}
                    WriteLn('Sending File: Receiver aknowledged EOT.' );
                    {$ENDIF}
                    YM_SendFile := TRUE ; Exit ;
              END;
         Inc(Retry);
         {$IFDEF ERRORS}
         WriteLn('Sending File: Sending EOT , retry # ' , retry );
         {$ENDIF}
       END;
      YM_SendFile := FALSE ;
END;


PROCEDURE YM_CloseBatchSession ( NbPort : BYTE );
BEGIN YM_SendFile ( NbPort , '', '' );
END;

END.
[ RETURN TO DIRECTORY ]