-- Transport mechanism:  Client reading of R-Server database

-- [Indigo]<Grapevine>MS>NameInfoDefs.mesa

-- Andrew Birrell  August 27, 1982 3:00 pm

DIRECTORY

  BodyDefs USING [Connect, oldestTime, Password, Remark, RName, Timestamp];

NameInfoDefs: DEFINITIONS =

  BEGIN

  Outcome: TYPE = {  -- possible outcomes of RS operations --
    noChange,  -- updates and timestamped enquiries --
    group, individual, notFound,  -- any --
    protocolError, wrongServer, allDown,  -- any --
    badPwd,  -- authentication and updates --
    outOfDate, notAllowed  -- updates --
    };

  NameType: TYPE = Outcome [noChange..badPwd];  -- outcomes for enquiries --



  -- "RLists" are sequences of R-Names returned from the server --

  RListHandle: TYPE [SIZE[POINTER]];

  Enumerate: PROC [
    list: RListHandle, work: PROC [BodyDefs.RName] RETURNS [done: BOOLEAN]];

  Close: PROC [list: RListHandle];




  -- "Expand" returns mailbox site names for individuals, membership list
  -- for groups. If the old stamp is still current, returns "noChange".  Will
  -- not return "noChange" if the old stamp is defaulted. --

  ExpandInfo: TYPE = RECORD [
    SELECT type: NameType [noChange..allDown] FROM
    noChange => NULL,
    group => [members: RListHandle, stamp: BodyDefs.Timestamp],
    individual => [sites: RListHandle, stamp: BodyDefs.Timestamp],
    notFound => NULL,
    protocolError => NULL,
    wrongServer => NULL,
    allDown => NULL,
    ENDCASE];

  Expand: PROC [
    name: BodyDefs.RName, oldStamp: BodyDefs.Timestamp ← BodyDefs.oldestTime]
    RETURNS [ExpandInfo];



  -- "GetMembers" returns the membership list for a group. If the old stamp
  -- is still current, returns "noChange".  Will not return "noChange" if
  -- the old stamp is defaulted. --

  MemberInfo: TYPE = RECORD [
    SELECT type: NameType [noChange..allDown] FROM
    noChange => NULL,
    group => [members: RListHandle, stamp: BodyDefs.Timestamp],
    individual => NULL,
    notFound => NULL,
    protocolError => NULL,
    wrongServer => NULL,
    allDown => NULL,
    ENDCASE];

  GetMembers: PROC [
    name: BodyDefs.RName, oldStamp: BodyDefs.Timestamp ← BodyDefs.oldestTime]
    RETURNS [MemberInfo];

  GetOwners: PROC [
    name: BodyDefs.RName, oldStamp: BodyDefs.Timestamp ← BodyDefs.oldestTime]
    RETURNS [MemberInfo];

  GetFriends: PROC [
    name: BodyDefs.RName, oldStamp: BodyDefs.Timestamp ← BodyDefs.oldestTime]
    RETURNS [MemberInfo];



  -- "CheckStamp" performs basic name validation, also telling the caller the
  -- name type. If the old stamp is still current, returns "noChange".  Will
  -- not return "noChange" if the old stamp is defaulted. --

  StampInfo: TYPE = NameType [noChange..allDown];

  CheckStamp: PROC [
    name: BodyDefs.RName, oldStamp: BodyDefs.Timestamp ← BodyDefs.oldestTime]
    RETURNS [StampInfo];



  -- "GetConnect" returns the connect-site for an individual.  "connect" is
  -- undisturbed if the result is not "individual".  The connect-site is
  -- either an NLS name or a net-address.  "connect.maxlength" should equal
  -- "BodyDefs.maxConnectLength". --

  ConnectInfo: TYPE = NameType [group..allDown];

  GetConnect: PROC [name: BodyDefs.RName, connect: BodyDefs.Connect]
    RETURNS [ConnectInfo];




  -- "GetRemark" returns the remark for a group.  "remark" is
  -- undisturbed if the result is not "group".  The remark is a human readable
  -- string.  "remark.maxlength" should equal "BodyDefs.maxRemarkLength". --

  RemarkInfo: TYPE = NameType [group..allDown];

  GetRemark: PROC [name: BodyDefs.RName, remark: BodyDefs.Remark]
    RETURNS [RemarkInfo];



  -- "Authenticate" checks a user name and password. --

  AuthenticateInfo: TYPE = NameType [group..badPwd];

  Authenticate: PROC [name: BodyDefs.RName, password: STRING]
    RETURNS [AuthenticateInfo];

  AuthenticateKey: PROC [name: BodyDefs.RName, key: BodyDefs.Password]
    RETURNS [AuthenticateInfo];



  -- Access control primitives --

  Membership: TYPE = {yes, no, notGroup, allDown};
  MembershipLevel: TYPE = MACHINE DEPENDENT{direct(0), closure(1), upArrow(2)};
  MembershipGrade: TYPE = MACHINE DEPENDENT{self(0), registry(1)};
  ListType: TYPE = MACHINE DEPENDENT{members(0), owners(1), friends(2)};

  IsInList: PROC [
    name: BodyDefs.RName, member: BodyDefs.RName, level: MembershipLevel,
    grade: MembershipGrade, acl: ListType] RETURNS [Membership];

  IsMemberDirect: PROC [name: BodyDefs.RName, member: BodyDefs.RName]
    RETURNS [Membership] = INLINE {
    RETURN[IsInList[name, member, direct, self, members]]};

  IsOwnerDirect: PROC [name: BodyDefs.RName, owner: BodyDefs.RName]
    RETURNS [Membership] = INLINE {
    RETURN[IsInList[name, owner, direct, self, owners]]};

  IsFriendDirect: PROC [name: BodyDefs.RName, friend: BodyDefs.RName]
    RETURNS [Membership] = INLINE {
    RETURN[IsInList[name, friend, direct, self, friends]]};

  IsMemberClosure: PROC [name: BodyDefs.RName, member: BodyDefs.RName]
    RETURNS [Membership] = INLINE {
    RETURN[IsInList[name, member, closure, self, members]]};

  IsOwnerClosure: PROC [name: BodyDefs.RName, owner: BodyDefs.RName]
    RETURNS [Membership] = INLINE {
    RETURN[IsInList[name, owner, closure, self, owners]]};

  IsFriendClosure: PROC [name: BodyDefs.RName, friend: BodyDefs.RName]
    RETURNS [Membership] = INLINE {
    RETURN[IsInList[name, friend, closure, self, friends]]};

  IsMemberUpArrow: PROC [name: BodyDefs.RName, member: BodyDefs.RName]
    RETURNS [Membership] = INLINE {
    RETURN[IsInList[name, member, upArrow, self, members]]};

  IsOwnerUpArrow: PROC [name: BodyDefs.RName, owner: BodyDefs.RName]
    RETURNS [Membership] = INLINE {
    RETURN[IsInList[name, owner, upArrow, self, owners]]};

  IsFriendUpArrow: PROC [name: BodyDefs.RName, friend: BodyDefs.RName]
    RETURNS [Membership] = INLINE {
    RETURN[IsInList[name, friend, upArrow, self, friends]]};


  END.