{$DOUBLE}
Program DoMail;
 {$nomain}

{ 
       Desc: Process Network Mailbox input for AMIRTR
       File: [AMIRTR]DoMail.pas
     Author: Jim Bostwick 
  Last Edit: 5-DEC-1989 23:14:41 
    History:
         3-AUG-1989 - JMB - Add $DOUBLE compiler switch


}
 {$Nolist}
 {[a+,b+,l-,k+,r+] Pasmat }
 %INCLUDE 'AMIRTR.pkg';
 %INCLUDE 'NewLnk.ext';
 %INCLUDE 'SIGNAL.EXT';
 %INCLUDE 'DEBUG.EXT';

 {$List }
 {*CALL*}


  PROCEDURE DoMail;
    EXTERNAL;

{*USER*

Process Network Mailbox input for AMIRTR.  Network data is common to all
active network links. Included are connect requests, interrupt messages, 
and disconnect request/notification. 

The mailbox is flushed each time this routine is called (except on net
abort, when we just quit and let DECNET clean up). 

The Mailbox LUN is known from Net_Mbx_LUN. 
 }

{*WIZARD*

 }


  PROCEDURE DoMail;

    VAR
      quit: Boolean;
      MbxMsg: Str16;
      The_Lun: 0..Max_Links; { the LUN to which net msg belongs }


    BEGIN
      quit := FALSE;
{
Call NTGND repeatedly to flush network mailbox queue.
}
      WITH Link[0] DO
        REPEAT
          NTGND(Mbx_lun, Aux_Efn, Conb, Read_IOSB);
          IF (Read_IOSB.byt[1] = NT_IE_NDA) THEN { The queue is empty }
          ELSE
            CASE Read_IOSB.byt[2] OF
              Nt_NT_CON: NewLnk; { Connect }
              Nt_NT_INT: { Interrupt message }
                BEGIN
                sassign(Read_dat, MbxMsg);
                MbxMsg[0] := chr(Read_IOSB.byt[3]);
                { force proper length }
                The_Lun := Read_IOSB.byt[4];
                Signal(Sig_NTINT, The_Lun, Read_IOSB, MbxMsg)
                END;
{
 Link shutdown is somewhat tricky, in that we have a network read IO pending
at all times. We can't simply trash the link data structures at this point,
without leaving a dangling IO buffer. 

 The solution is to mark the link as shutting down, to prevent further
sends from our end. Later, when DECNET completes (and we get around to 
handling) the Read IO with IE.ABO, we can go ahead and purge the link 
structure. 

All three disconnects (disconnect, user abort, system abort) are handled
the same way here. 
 }
              Nt_NT_DSC, { User synchronous disconnect }
              Nt_NT_ABT, { User abort }
              Nt_NT_ABO: { Network abort }
                BEGIN
                sassign(Read_dat, MbxMsg);
                MbxMsg[0] := chr(Read_IOSB.byt[3]);
                { force proper length }
                The_Lun := Read_IOSB.byt[4];
                Signal(Sig_NTDSC, The_Lun, Read_IOSB, MbxMsg);
                Link[The_Lun].Link_Flags := Link[The_Lun].Link_Flags +
                                            [Link_Shutdown];
                quit := True
                END;
              OTHERWISE Signal(Sig_NTMBX, 0, Read_IOSB, 'Huh?');
              END {Case}
        UNTIL (quit OR (Read_IOSB.byt[1] = NT_IE_NDA))
    END;
