{Whatstuff--common definitions for WHAT and whatserver

  John Fritz 
  MCV Academic Computing
  Medical College of Virignia
  Box 16, MCV Station
  Richmond, VA   23298
  (804) 786-9843
  }

[inherit('mcv:rtl','sys$library:starlet')] module whatStuff;
const
   nodeLen = 15;		{Longest possible node name returned by $getpji}
   shortNodeLen = 6;		{Longest cluster nodename as of VMS version 4  }
   mcvWhat = 'MCV_WHAT_';	{Prefix for lock names			       }
   maxProc = 200;		{Maximum number of processes per node that     }
				{we handle are prepared to handle	       }
   imageLen = 255;		{Maximum length of an image name	       }
type
   {The record type info is used to communicate information between the        }
   {WHATSERVER detached process(es) and the WHAT program		       }

      nodeType = varying[nodeLen] of char;
      shortNodeType = packed array[1..shortNodeLen] of char;
      userType = packed array[1..12] of char;
      info = [aligned(0)] record
         userName:    [aligned(0)] userType;
         node:        [aligned(0)] shortNodeType;
         master_pid:  [aligned(0)] integer;
         sub:         [aligned(0)] char;	{'Y' if a subprocess-'N' if not}
         pid:         [aligned(0)] integer;
         connect:     [aligned(0)] packed array[1..10] of char;
         cpu:         [aligned(0)] packed array[1..9] of char;
         mode:        [aligned(0)] integer;
         terminal:    [aligned(0)] packed array[1..7] of char;
         prcnam:      [aligned(0)] packed array[1..15] of char;
         image:       [aligned(0)] packed array[1..10] of char;
         end;

   {The WHAT program will sort the information passed to it by userName, node, }
   {master_pid and sub. The following types will be used to cast the info      }
   {records so that the concatenation of these fields may be referred to with  }
   {a single field reference, e.g. inf::sortInfo.key. Note that since character}
   {string comparison will be used the bytes of master_pid will not be compared}
   {in the correct order; but we only require that equal master_pid's sort     }
   {together. Putting the master_pid in the key will force processes with the  }
   {same userName, node, and master_pid to appear together, and the sub field  }
   {will ensure that the top-level process appears first.                      }

      keyType = packed array[1..
         size(userType)+			{userName		       }
         size(shortNodeType)+			{node			       }
         size(integer)+				{master_pid		       }
         size(char)				{sub			       }
         ] of char;
      sortInfo = [aligned(0)] record
         key: [aligned(0)] keyType;
         rest: [aligned(0)] packed array[1..size(info)-size(keyType)] of char;
         end;

   {The following types are used to collect a number of info records together  }
   {and pass them between the WHATSERVER process(es) and the WHAT program.     }
   {The WHATSERVER process(es) write out their information to a disk file which}
   {the WHAT program then reads. In order to speed up the reading process, we  }
   {do not write out each record individually, but write all of them out at    }
   {once as a single varying length record. To do this we cast the jpiArray as }
   {a varying length character string using the jpiString type.                }

      jpiArray = array[1..maxProc] of info;
      jpiRecType = record
         jpiLen: $uword;
         jpi: jpiArray;
         end;
      jpiString = varying[size(jpiArray)] of char;

   {This type is used to call system services which require itemlists when     }
   {requesting only one item                                                   }

      oneItem = record
         bufLen,item: $uword;
         bufAddr,retLen,sentinel: unsigned
         end;

   fileSpec = varying[imageLen] of char;

var
   {We use the name of the running image to find out the device and directory  }
   {information. All files used for communications between WHATSERVER and WHAT }
   {are contained in the same directory as the WHATSERVER and WHAT image files }
   {(which MUST be in the same directory!)				       }

      myName: [volatile] fileSpec;
      [initialize,hidden] procedure getMyName;
      var
         request: [static] oneItem := (imageLen,jpi$_imagname,0,0,0);
      begin
         request.bufAddr := (address(myName.body))::unsigned;
         request.retlen  := (address(myName.length))::unsigned;
         $getjpi(itmlst:=request);
         end;
var
   myNode: [volatile] nodeType;			{Node the process is running on}
   [initialize,hidden] procedure getMyNode;
   var
      syiList: [static] oneItem := (nodeLen,syi$_nodeName,0,0,0);
      stat: integer;
   begin
      syiList.bufAddr := (address(myNode.body))::unsigned;
      syiList.retLen := (address(myNode.length))::unsigned;
      stat := $getsyiw(,,,syiList);
      if not odd(stat) then lib$stop(stat);
      end;

end.
