-- Registration Server - Defs for operations on a registry.
-- [Ibis]<Grapevine>Pilot>RegServerDefs.mesa

-- HGM, 13-Nov-84  1:53:58
-- J. Dion, September 8, 1979
-- Andrew Birrell  27-Oct-82 15:48:41 
-- Brenda Hankins	14-Aug-84 16:16:46	(Klamath update)

DIRECTORY
  BodyDefs USING [oldestTime, RName, Timestamp],
  HeapDefs USING [ObjectNumber, ReaderHandle, WriterHandle],
  ProtocolDefs USING [
    Connect, Password, Remark, ReturnCode, RNameType, RSOperation],
  RegBTreeDefs USING [RegistryObject];

RegServerDefs: DEFINITIONS =

  BEGIN

  -- Module that handles incoming connections - Registration:

  RegistrationInit: PROCEDURE;
  RegistrationLocal: PROCEDURE;
  RegistrationAll: PROCEDURE;

  -- Module for generating RS-internal mail for updates - RegMail:

  RegMailInit: PROCEDURE;
  RegMailEnableUpdates: PROCEDURE;


  CreateIndividual: PROCEDURE [
    name: BodyDefs.RName, password: ProtocolDefs.Password]
    RETURNS [ProtocolDefs.ReturnCode];
  -- creates a new individual entry with no mailbox sites

  DeleteIndividual: PROCEDURE [name: BodyDefs.RName]
    RETURNS [ProtocolDefs.ReturnCode];
  -- deletes an individual entry.

  CreateGroup: PROCEDURE [name, caller: BodyDefs.RName]
    RETURNS [ProtocolDefs.ReturnCode];
  -- creates a new group entry with no members and a single
  -- maintainer, the creator.

  DeleteGroup: PROCEDURE [name: BodyDefs.RName] RETURNS [ProtocolDefs.ReturnCode];
  -- deletes a group if caller has sufficient privilege.

  CreateRegistry: PROCEDURE [entry, caller: BodyDefs.RName]
    RETURNS [ProtocolDefs.ReturnCode];
  -- creates a new registry.

  DeleteRegistry: PROCEDURE [entry: BodyDefs.RName]
    RETURNS [ProtocolDefs.ReturnCode];
  -- deletes a registry (must it be empty?).

  ChangePassword: PROCEDURE [entry: BodyDefs.RName, pw: ProtocolDefs.Password]
    RETURNS [ProtocolDefs.ReturnCode];
  -- changes the password of an individual.

  ChangeConnect: PROCEDURE [entry: BodyDefs.RName, connect: ProtocolDefs.Connect]
    RETURNS [ProtocolDefs.ReturnCode];
  -- changes the connect-site of an individual.

  ChangeRemark: PROCEDURE [entry: BodyDefs.RName, remark: ProtocolDefs.Remark]
    RETURNS [ProtocolDefs.ReturnCode];
  -- changes the remark for a group.

  AddMailbox: PROCEDURE [name, entry: BodyDefs.RName]
    RETURNS [ProtocolDefs.ReturnCode];
  -- adds a mailbox to an individual.

  DeleteMailbox: PROCEDURE [name, entry: BodyDefs.RName]
    RETURNS [ProtocolDefs.ReturnCode];
  -- Deletes a mailbox from an individual.

  AddForward: PROCEDURE [name, entry: BodyDefs.RName]
    RETURNS [ProtocolDefs.ReturnCode];
  -- adds a forwarding for an individual.

  DeleteForward: PROCEDURE [name, entry: BodyDefs.RName]
    RETURNS [ProtocolDefs.ReturnCode];
  -- Deletes forwarding from an individual.

  AddMember: PROCEDURE [name, entry: BodyDefs.RName]
    RETURNS [ProtocolDefs.ReturnCode];
  -- adds a member to a group.

  DeleteMember: PROCEDURE [name, entry: BodyDefs.RName]
    RETURNS [ProtocolDefs.ReturnCode];
  -- Deletes a member from a group.

  AddOwner: PROCEDURE [name, entry: BodyDefs.RName]
    RETURNS [ProtocolDefs.ReturnCode];
  -- adds an owner to a group.

  DeleteOwner: PROCEDURE [name, entry: BodyDefs.RName]
    RETURNS [ProtocolDefs.ReturnCode];
  -- Deletes an owner from a group.

  AddFriend: PROCEDURE [name, entry: BodyDefs.RName]
    RETURNS [ProtocolDefs.ReturnCode];
  -- adds a member to the "friends" acl of a group.

  DeleteFriend: PROCEDURE [name, entry: BodyDefs.RName]
    RETURNS [ProtocolDefs.ReturnCode];
  -- Deletes a member from the "friends" acl of a group.

  AddListOfMembers: PROC [name: BodyDefs.RName, reader: HeapDefs.ReaderHandle]
    RETURNS [ProtocolDefs.ReturnCode];
  -- "reader" is sublist containing desired R-Names --

  NewName: PROC [new, old: BodyDefs.RName] RETURNS [ProtocolDefs.ReturnCode];

  UpdateSublist: PROCEDURE [
    name, element: BodyDefs.RName, op: ProtocolDefs.RSOperation,
    prevStamp: BodyDefs.Timestamp ← BodyDefs.oldestTime]
    RETURNS [rc: ProtocolDefs.ReturnCode, regLocal: BOOLEAN ← TRUE];
  -- Update a sublist of entry;  inform other R-Servers iff "prevStamp=oldestTime" --

  Update: PROCEDURE [object: HeapDefs.ObjectNumber];
  -- updates a registry entry with the heap object 'object'
  -- which is a possibly more recent version of the entry. The result
  -- which replaces the entry is constructed by merging the old and new
  -- versions on the basis of the timestamps of their components.

  CheckRName: PROCEDURE [
    entry: BodyDefs.RName, stamp: POINTER TO BodyDefs.Timestamp]
    RETURNS [ProtocolDefs.ReturnCode];
  -- checks whether the R-Name is known --

  Read: PROCEDURE [entry: BodyDefs.RName]
    RETURNS [
      reader: HeapDefs.ReaderHandle, rc: ProtocolDefs.ReturnCode,
      components, password: CARDINAL];
  -- returns a reader for the entire registry entry for the
  -- group or individual --

  Expand: PROCEDURE [entry: BodyDefs.RName, stamp: POINTER TO BodyDefs.Timestamp]
    RETURNS [HeapDefs.ReaderHandle, ProtocolDefs.ReturnCode];
  -- returns a reader for the member list of a group or the
  -- mailbox list for an individual.

  ReadMembers: PROCEDURE [
    entry: BodyDefs.RName, stamp: POINTER TO BodyDefs.Timestamp]
    RETURNS [HeapDefs.ReaderHandle, ProtocolDefs.ReturnCode];
  -- returns a reader for the member list of a group.

  ReadOwners: PROCEDURE [
    entry: BodyDefs.RName, stamp: POINTER TO BodyDefs.Timestamp]
    RETURNS [HeapDefs.ReaderHandle, ProtocolDefs.ReturnCode];
  -- returns a reader for the "owners list of a group

  ReadFriends: PROCEDURE [
    entry: BodyDefs.RName, stamp: POINTER TO BodyDefs.Timestamp]
    RETURNS [HeapDefs.ReaderHandle, ProtocolDefs.ReturnCode];
  -- returns a reader for the "friends" list of a group

  ReadRegistryMembers: PROCEDURE [
    entry: BodyDefs.RName, stamp: POINTER TO BodyDefs.Timestamp]
    RETURNS [HeapDefs.ReaderHandle, ProtocolDefs.ReturnCode];
  -- returns a reader for the member list of a group's registry.

  ReadRegistryOwners: PROCEDURE [
    entry: BodyDefs.RName, stamp: POINTER TO BodyDefs.Timestamp]
    RETURNS [HeapDefs.ReaderHandle, ProtocolDefs.ReturnCode];
  -- returns a reader for the "owners" list of a group's registry

  ReadRegistryFriends: PROCEDURE [
    entry: BodyDefs.RName, stamp: POINTER TO BodyDefs.Timestamp]
    RETURNS [HeapDefs.ReaderHandle, ProtocolDefs.ReturnCode];
  -- returns a reader for the "friends" list of a group's registry

  ReadPassword: PROCEDURE [entry: BodyDefs.RName]
    RETURNS [ProtocolDefs.Password, ProtocolDefs.ReturnCode];
  -- returns the password of an individual.

  ReadConnect: PROCEDURE [entry: BodyDefs.RName, connect: ProtocolDefs.Connect]
    RETURNS [ProtocolDefs.ReturnCode];
  -- returns the connect-site of an individual.

  ReadRemark: PROCEDURE [entry: BodyDefs.RName, remark: ProtocolDefs.Remark]
    RETURNS [ProtocolDefs.ReturnCode];



  -- Access control operations --

  Membership: TYPE = {yes, no, badList --includes WrongServer-- };

  MembershipGrade: TYPE = MACHINE DEPENDENT{self(0), registry(1)};
  MembershipAcl: TYPE = MACHINE DEPENDENT{members(0), owners(1), friends(2)};
  MembershipLevel: TYPE = MACHINE DEPENDENT{direct(0), closure(1), upArrow(2)};
  -- direct looks only in the specified list --
  -- upArrow is closure by following names of form "foo↑.reg" --
  -- closure is general closure operation --
  -- self looks in the specified group, registry looks in its registry --
  -- members, owners, friends look in the appropriate sub-list --

  IsInList: PROCEDURE [
    entry: BodyDefs.RName, member: BodyDefs.RName, level: MembershipLevel,
    grade: MembershipGrade, acl: MembershipAcl]
    RETURNS [membership: Membership, rc: ProtocolDefs.ReturnCode];
  -- general "IsMember" function --

  IsMember: PROCEDURE [
    entry: BodyDefs.RName, member: BodyDefs.RName, level: MembershipLevel]
    RETURNS [membership: Membership, rc: ProtocolDefs.ReturnCode] = INLINE {
    [membership, rc] ← IsInList[entry, member, level, self, members]};

  IsOwner: PROCEDURE [
    entry: BodyDefs.RName, member: BodyDefs.RName, level: MembershipLevel]
    RETURNS [membership: Membership, rc: ProtocolDefs.ReturnCode] = INLINE {
    [membership, rc] ← IsInList[entry, member, level, self, owners]};

  IsFriend: PROCEDURE [
    entry: BodyDefs.RName, member: BodyDefs.RName, level: MembershipLevel]
    RETURNS [membership: Membership, rc: ProtocolDefs.ReturnCode] = INLINE {
    [membership, rc] ← IsInList[entry, member, level, self, friends]};



  MailUpdate: PROC [
    entry: BodyDefs.RName, stamp: BodyDefs.Timestamp, element: BodyDefs.RName,
    op: ProtocolDefs.RSOperation, rsMailObj: HeapDefs.ObjectNumber];
  -- sends entry to other R-Servers then frees object --

  ReadMail: PROC;
  -- infinite loop reading R-Server internal mail --

  ConsiderPurging: PROC [RegBTreeDefs.RegistryObject, BodyDefs.Timestamp]
    RETURNS [BOOLEAN];
  -- says whether entry may be worth purging --

  ReallyPurge: PROC [
    BodyDefs.RName, RegBTreeDefs.RegistryObject, BodyDefs.Timestamp]
    RETURNS [BOOLEAN, HeapDefs.WriterHandle];
  -- purges old deleted info from entry. Returns writer on new entry;
  -- Doesn't change the timestamp --

  -- enumeration for registry removal in RegAccess --

  EnumeratedMembers: PROC [name: BodyDefs.RName, type: ProtocolDefs.RNameType]
    RETURNS [reader: HeapDefs.ReaderHandle];

  END.