{$DOUBLE}
Program Init;
 {$nomain}

{ 
  Desc: Initialization routine for AMIRTR
  File:[amirtr]INIT.PAS
  Author: Jim Bostwick 

  Last Edit: 5-APR-1990 02:19:57 

  History:
         28-OCT-1989 -JMB - Add resonable debug code. 
         13-OCT-1989 -JMB - Pad node name to 6 chars with blanks. 
         3-AUG-1989 - JMB - Add $DOUBLE compiler switch


}
 {$Nolist}
 {[a+,b+,l-,k+,r+] Pasmat }
 %INCLUDE 'AMIRTR.PKG';
 %INCLUDE 'SIGNAL.EXT';
 %INCLUDE 'OPNDBG.EXT';

 %INCLUDE 'PAS$EXT:CLEF.EXT';
 %INCLUDE 'PAS$EXT:ALUN.EXT';
 %INCLUDE 'PAS$EXT:TLON.EXT';
 %INCLUDE 'PAS$EXT:RLON.EXT';
 %INCLUDE 'PAS$EXT:SRDA.EXT';
 %INCLUDE 'pas$ext:CATR56.ext';
 %INCLUDE 'pas$ext:CR56TA.ext';
 %INCLUDE 'Pas$ext:GTSK.TYP';
 %INCLUDE 'Pas$ext:GTSK.Ext';

 {$List }
 {*CALL*}


  PROCEDURE Init(VAR Status: integer);
    EXTERNAL;

{*USER*

Initialization routine for AMIRTR. Does normal initialization things.

Status - >= is number of LUNS assigned, < 1 is an error
code. Generally, any negative status is grounds for suicide.

Functions:

        1. Translate "RTR$LOG_FILE" and open the log file. 
           Set up initial debug conditions. 
        2. Assign all net LUNS to device NS: 
        3. Finds out local node name (global MyNode) by translation of 
           logical SYS$NODE. This is a one-time (non-recursive) translation. 
        4. Zero out all statistics, pointers, etc. 
        5. Open the network mailbox. 
        6. Set up Receive Data Notification. 
 }

{*WIZARD*

 }


  PROCEDURE Init;

    LABEL
      999; { the error-out spot }

    VAR
      L, I, len, pos: integer;
      Fubar: Boolean;
      Asc_Task: ch6; { task name in ASCII }
      Log_File_name: CH30; { big name! }
      Hold_logical: Str30; { for logical equivalences }
      Tsk_info: Task_info_rec;


    BEGIN
      Fubar := TRUE; { Assume the worst...}
      Status := 0;
      IOSB.Int[1] := 0;
      IOSB.Int[2] := 0;
      Null_IOSB.Int[1] := 0;
      Null_IOSB.Int[2] := 0;
      	{ build trademark for this invocation of this task }
	Tlon('SYS$NODE',trademark,len);	{ find out node name }
        Sconcat(trademark,'::');	
	Gtsk(tsk_Info);		     { find out about self }
	cr56ta(Tsk_info.Name,Asc_Task);  { make it printable }
        MyName := Tsk_info.name; 	{ save RAD50 task name }
	sconcat(trademark,Asc_task);
	schconcat(trademark,'>');

      { 1. Translate logfile name, open logfile.  }

      RLON('RTR$LOG_FILE', Log_File_name, len); { recursively translate }
      IF (($DSW <> 1) OR (len = 0)) THEN
        BEGIN
        Status := - 4;
        Writeln(' %RTR-F-INIT,  can''t figure out RTR$LOG_FILE - exiting.');
        GOTO 999
        END;
      Rewrite(Log_File, Log_File_name);

      { 1a. Set up initial debug conditions. }
      Debugging := False;
      Debug_flags := [];
      Debug_level := 1;
      SClear(Debug_File_name);
      OpnDbg(Debug_File_name);
      RLON('RTR$DEBUG_FILE', Debug_File_name, len);
{ 
    We can also do debug output via messages. (Recursive errors 
    notwithstanding).
 }
      RLON('RTR$Debug_msg', Hold_logical, len);
      IF ($DSW = 1) AND (len > 0) THEN
        BEGIN
        Debugging := TRUE;
        Debug_to_msg := TRUE;
        pos := SSearch(Hold_logical, '::', 1);
        SSubstr(Debug_node, Hold_logical, 1, pos - 1);
        SSubstr(Debug_task, Hold_logical, pos + 2, (len - pos - 2));
        END
      ELSE Debug_to_msg := False;

      IF Debugging THEN Debug_level := 2; { A hack for now }

      { 2. Assign all net LUNS to device NS:  }

      Alun(Mbx_LUN, 'NS', 0);
      IF $DSW <> 1 THEN
        BEGIN
        Status := - 4;
        SIGNAL( - 1, Mbx_LUN, IOSB, 'INIT: can''t assign Mbx_LUN');
        GOTO 999
        END;

      I := Lo_Net_LUN + 1;
      WHILE (I <= (Lo_Net_LUN + Max_Links)) DO
        BEGIN
        Alun(I, 'NS', 0);
        IF $DSW <> 1 THEN
          BEGIN
          Status := - 4;
          SIGNAL( - 1, I, IOSB, 'INIT: can''t assign net LUN (lun #)');
          GOTO 999 { quit while behind }
          END; { $DSW }
        I := I + 1
        END; { while }

      { 3. Finds out local node name (global MyNode) }

      TLON('SYS$NODE', MyNode, len); { translate sys$node }
      IF (($DSW <> 1) OR (len = 0) OR (len > 6)) THEN
        BEGIN
        Status := - 4;
        SIGNAL( - 3, len, IOSB, 'INIT:  can''t figure out MyNode');
        GOTO 999
        END;
      FOR I := len + 1 TO 6 DO MyNode[I] := ' '; { pad out node name }

      { 4. Zero out all statistics, pointers, etc. }

      CLEF(Net_EFN); { clear activity flag }
      IF $DSW < 0 THEN
        BEGIN
        Status := - 4;
        SIGNAL( - 4, ORD(Net_EFN), IOSB, 'INIT: can''t clear Net_EFN');
        GOTO 999
        END;

      I := Lo_Net_LUN;
      FOR L := 0 TO Max_Links DO
        WITH Link[L] DO
          BEGIN
          LUN := I;
          I := I + 1;
          Read_IOSB.Int[1] := 0;
          Read_IOSB.Int[2] := 0;
          SClear(node);
          SClear(Read_Dat);
          Active := False;
          Link_Flags := [];
          WITH Stats DO
            BEGIN
            Last_Activity := 0;
            Reads := 0.0;
            Writes := 0.0;
            Connects := 0
            END { with stats }
          END; { for }

{ 5. Open the network mailbox, and set up activity notification. 
     Call NTOPN to get a network LUN and start DECNET.
     This is required first network call (other than possibly NTCONB)
     in any network task. 

     The number of active network links is limited to Max_Links. In a 
     future release, this can be removed (=0), and a LRU algorithm used
     to knock down one link when another is requested (and Max_Links are
     already in use). This version simply tells DECNET to reject (trans-
     parently) any connect requests over Max_Links. 
 }

      NtOpn(Mbx_LUN, Aux_EFN, Max_Links, 0, IOSB);
      IF (($DSW <> 1) OR (IOSB.Int[1] <> 1)) THEN
        BEGIN
        Status := - 4;
        SIGNAL( - 3, Mbx_LUN, IOSB, 'INIT: can''t open network');
        GOTO 999
        END;

{
 Call NTSPA to set up net que notification.
 NTSPA sets up an internal (hidden) AST service routine which
 sets Net_EFN whenever new traffic appears in the net mailbox. 
 }
      NtSPA(Mbx_LUN, Net_EFN, IOSB);
      IF (($DSW <> 1) OR (IOSB.Int[1] <> 1)) THEN
        BEGIN
        Status := - 4;
        SIGNAL( - 5, Mbx_LUN, IOSB, 'INIT: can''t set up mailbox AST');
        GOTO 999
        END;

      { 6. Set up Receive Data Notification.  }

      SRDA(Net_EFN);
      IF ($DSW <> 1) THEN
        BEGIN
        Status := - 4;
        SIGNAL( - 6, 0, IOSB, 'INIT: can''t set up receive data AST');
        GOTO 999
        END;

      { Whew! We made it through. }

      Status := Max_Links + 1; { Show LUNS assigned }
      Fubar := False;

    999: { ref label }
      IF NOT (Fubar) THEN
        SIGNAL(Sig_INITFIN, Status, Null_IOSB, 'Whew! (Luns Assigned)')
      ELSE SIGNAL(Sig_NOTINIT, Status, Null_IOSB, 'Poof!');
    END; { init }
