{$DOUBLE}
{$NOMAIN}

PROGRAM MSINIT; 
 
{
  Description: Initialize a Message Header. 
	 File: [Message]Msinit.pas
       Author: Jim Bostwick
    Last Edit: 20-OCT-1989 01:51:26 
      History: 
    	 20-OCT-1989 -JMB - handle dropped header fields. 
	 18-OCT-1989 -JMB - new integrated message_rec
    	 13-OCT-1989 -JMB - don't truncate node name
	 9-OCT-1989 - JMB - Major happy munging...
	 3-AUG-1989 - JMB - Add $DOUBLE compiler switch
}

{$NOLIST} 
%INCLUDE 'pas$ext:GENERAL.TYP';
%INCLUDE 'pas$ext:MESSAGE.TYP';
%INCLUDE 'pas$ext:MSSIZE.EXT';
%INCLUDE 'pas$ext:GTSK.TYP';
%INCLUDE 'pas$ext:STRING.PKG';
%INCLUDE 'pas$ext:GTSK.EXT';
%INCLUDE 'pas$ext:RLON.EXT';
%INCLUDE 'pas$ext:CATR56.EXT';
{$LIST}

PROCEDURE MSINIT
     (To_Node:ch6; 
      To_Task:ch6; 
      VAR MSG:Message_rec;
      VAR Status: Integer 
	) ; External;
 
{*USER*

FUNCTIONAL DESCRIPTION: 
     
Initializes message header with supplied and default information.
     
FORMAL PARAMETERS: 
.sk .nf     
To_node [read]: Destination node name or empty string (nulls)
To_Task [read]: Destination task name in ASCII
Message [Read/Write]: message (only header area modified)
Stat [write]: output status (1=ok) 	
.f .sk     
     
SIDE EFFECTS:
     
Get-Task called for caller task name. 
RLON called for translation of SYS$NODE (local node name). 
	This becomes Src_node. 
Attempt is made to translate logical of form "MSG$node", where
	<node> is destination node. If the translation succeeds,
	it will return a string of the form "node::task". This 
	then is decomposed into destination node and router(task). 
	The translated node will overwrite the destination node field, 
	with the original destination node being lost. 

	This scheme enables several functions: first, testing
	may be accomplished by defining any node and router
	task - for example, two routers (different names) may be
	running on a single node, and DECNET used for communications. 
	Also, dedicated routers are possible - for example, the 
	destination node could run a router for general uses, and 
	another dedicated to a specific task or set of tasks. 
	In any case, if the translation fails, then router_node is
	set to dest_node. 

If Src_Node = Dest_Node, router is set to Dest_task, 
	enabling direct send to the target task. 

If Msg_Size zero, a call is made to MSSIZE, and the result inserted
	into the msg_size field. 

** User should establish packet id and sub-id BEFORE calling MSINIT ***

If user will be changing message size frequently, the Msg_Auto_size
	bit may be set in Msg_Flags.  This must be done AFTER calling
	MSINIT - as the bit is cleared unconditionally here. 
	Auto_size will call MSGSIZ from MSSEND for each send 
	- with a corresponding loss of performance. 
User will normally manage the text_size field along with id and sub -
	that is, will call MSSIZE after id and/or sub (or gross length
	of chxx fields) have been changed. Use Auto_size only where
	the text size will change with each transmission. 

  }

Procedure msinit;

VAR
    Task_Info: Task_info_rec;	{ GTSK info buffer }
    Loc_node: CH6;		{ name of our node }
    i,siz: Integer;		{ size of logicals }
 
Procedure Router(VAR dest_node:ch6; 
	    	 var rtr_task: RAD56);
VAR
    tnam: ch6;
    logical,equivalent: str20;
    i,dsw,pos, siz: integer; 
    defaul: Boolean; 
    
BEGIN
    defaul := FALSE;
    Sassign(logical,'MSG$');
    Sconcat(logical,dest_node);
    STrunc(logical);
    SClear(equivalent);
    RLON(logical,equivalent,siz);
    IF $DSW = 1
	THEN BEGIN	{ translation succeeded }
	    pos := Ssearch(equivalent,'::',1);
	    if pos = 0 
		then defaul := true	{ bogus logical - use default } 
		else BEGIN		{ extract node, task name }
		    SSubstr(dest_node,equivalent,1,pos-1);
    		    if pos < 7 THEN 
    			for i := pos to 6 do dest_node[i] := ' ';
		    Ssubstr(tnam,equivalent,pos+2,slen(equivalent)-(pos+1));
	    	    CATR56(tnam,rtr_task)	    
		    end
	    end
	ELSE Defaul := TRUE;	{ translation failed - use defaults }
    IF defaul 
    	THEN BEGIN	{ set defaults }
	    IF  Sequal(Dest_Node,msg.Src_Node) 
		THEN rtr_task := msg.Dest_Task
		ELSE CATR56('AMIRTR',rtr_Task)
	    END
    end; { router}

BEGIN
    GTSK(Task_info);	{ Get our task name }
    Status := $DSW;
    IF (Status = 1)	{ got it?}
    THEN
	BEGIN
	RLON('SYS$NODE',msg.Src_Node,siz);  { Get our node name }
        IF siz < 6 
    		then for i := siz+1 to 6 do msg.src_node[i] := ' ';         
        spad(to_node,chr(0),' ');
	Status := $DSW;
	IF (Status = 1)		    { got it?}
	THEN
	    BEGIN
	    CATR56(To_task,msg.Dest_task);
	    msg.Dest_Node := To_Node;
	    Router(msg.dest_node,msg.router);
	    		{ get routing task name, node }
	    msg.Src_Task := Task_info.Name;	{ Copy Task name }
	    msg.Flags := [];	    		{ default flags }
    	    if msg.msg_size = 0 then msg.msg_size := MSSIZE(msg);
	    msg.Protocol := 0
	    END
    	ELSE Writeln('MSINIT - Can''t translate SYS$NODE! HELP!')
	END
    END; {procecure msinit}
