GVNames.mesa: Client access to the R-Server database
Copyright © 1985 by Xerox Corporation. All rights reserved.
Andrew Birrell June 22, 1983 5:58 pm
Levin, September 22, 1983 10:25 am
DIRECTORY
GVBasics USING[ Connect, GVString, oldestTime, Password, MakeKey, Remark, RName, Timestamp ],
Rope USING[ ROPE ];
GVNames: CEDAR DEFINITIONS IMPORTS GVBasics = BEGIN OPEN Rope;
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
Password: TYPE = GVBasics.Password;
Timestamp: TYPE = GVBasics.Timestamp;
oldestTime: Timestamp = GVBasics.oldestTime;
"RLists" are sequences of R-Names returned from the server
RName: TYPE = GVBasics.RName;
RListHandle: TYPE = LIST OF RName;
"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: Timestamp,
count: INT ],
individual => [ sites: RListHandle,
stamp: Timestamp,
count: INT ],
notFound => NULL,
protocolError => NULL,
wrongServer => NULL,
allDown => NULL,
ENDCASE ];
Expand: PROC[name: RName, oldStamp: Timestamp ← oldestTime, reporter: ReporterProc ← NIL] 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: Timestamp,
count: INT ],
individual => NULL,
notFound => NULL,
protocolError => NULL,
wrongServer => NULL,
allDown => NULL,
ENDCASE ];
GetMembers: PROC[name: RName, oldStamp: Timestamp ← oldestTime] RETURNS[ MemberInfo ] = INLINE { RETURN[ GetList[name, oldStamp, members] ] };
GetOwners: PROC[name: RName, oldStamp: Timestamp ← oldestTime] RETURNS[ MemberInfo ] = INLINE { RETURN[ GetList[name, oldStamp, owners] ] };
GetFriends: PROC[name: RName, oldStamp: Timestamp ← oldestTime] RETURNS[ MemberInfo ] = INLINE { RETURN[ GetList[name, oldStamp, friends] ] };
GetList: PROC[name: RName, oldStamp: Timestamp, list: ListType, reporter: ReporterProc ← NIL] 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: RName, oldStamp: Timestamp ← oldestTime, reporter: ReporterProc ← NIL] RETURNS[ StampInfo ];
"GetConnect" returns the connect-site for an individual. The connect-site is either an NLS name or a net-address.
ConnectInfo: TYPE = NameType[group..allDown];
GetConnect: PROC[name: RName, reporter: ReporterProc ← NIL] RETURNS[ info: ConnectInfo, connect: GVBasics.Connect ];
"GetRemark" returns the remark for a group. The remark is a human readable string..
RemarkInfo: TYPE = NameType[group..allDown];
GetRemark: PROC[name: RName, reporter: ReporterProc ← NIL] RETURNS[ info: RemarkInfo, remark: GVBasics.Remark ];
"GetEntry" is mainly for use by Maintain. It returns the entire contents of a database entry. Consult a wizard before using GetEntry
GetEntryInfo: TYPE = RECORD[
name: RName,
stamp: Timestamp,
body: SELECT type: * FROM
group => [
remark: GVBasics.Remark,
remarkStamp: Timestamp,
members: GetEntryList,
owners: GetEntryList,
friends: GetEntryList],
individual => [
password: Password,
passwordStamp: Timestamp,
connect: GVBasics.Connect,
connectStamp: Timestamp,
forward: GetEntryList,
sites: GetEntryList],
notFound => NULL,
dead => NULL,
ENDCASE ];
GetEntryList: TYPE = RECORD[
current: RListHandle,
currentStamps: LIST OF Timestamp,
deleted: RListHandle,
deletedStamps: LIST OF Timestamp];
GetEntry: PRIVATE PROC[name: RName, reporter: ReporterProc ← NIL] RETURNS[rc: NameType[group..allDown], info: REF GetEntryInfo];
"Authenticate" checks a user name and password.
AuthenticateInfo: TYPE = NameType[group..badPwd];
Authenticate: PROC[name: RName, password: ROPE] RETURNS[ AuthenticateInfo ] = INLINE { RETURN[ AuthenticateKey[name, GVBasics.MakeKey[password]] ] };
AuthenticateKey: PROC[name: RName, key: Password, reporter: ReporterProc ← NIL] RETURNS[ AuthenticateInfo ];
AuthenticatedGetEntry: PROC [user: RName ← NIL, password: Password ← [,,,], name: RName, reporter: GVNames.ReporterProc ← NIL] RETURNS [rc: GVNames.NameType[group..allDown], info: REF GVNames.GetEntryInfo];
Access control primitives
Membership: TYPE = { yes, no, notGroup, allDown };
IsMemberDirect: PROC[name: RName, member: RName] RETURNS[ Membership ] = INLINE {
RETURN[IsInList[name, member, direct, self, members]] };
IsOwnerDirect: PROC[name: RName, owner: RName] RETURNS[ Membership ] = INLINE {
RETURN[IsInList[name, owner, direct, self, owners]] };
IsFriendDirect: PROC[name: RName, friend: RName] RETURNS[ Membership ] = INLINE {
RETURN[IsInList[name, friend, direct, self, friends]] };
IsMemberClosure: PROC[name: RName, member: RName] RETURNS[ Membership ] = INLINE {
RETURN[IsInList[name, member, closure, self, members]] };
IsOwnerClosure: PROC[name: RName, owner: RName] RETURNS[ Membership ] = INLINE {
RETURN[IsInList[name, owner, closure, self, owners]] };
IsFriendClosure:PROC[name: RName, friend: RName] RETURNS[ Membership ] = INLINE {
RETURN[IsInList[name, friend, closure, self, friends]] };
IsMemberUpArrow:PROC[name: RName, member: RName] RETURNS[ Membership ] = INLINE {
RETURN[IsInList[name, member, upArrow, self, members]] };
IsOwnerUpArrow: PROC[name: RName, owner: RName] RETURNS[ Membership ] = INLINE {
RETURN[IsInList[name, owner, upArrow, self, owners]] };
IsFriendUpArrow:PROC[name: RName, friend: RName] RETURNS[ Membership ] = INLINE {
RETURN[IsInList[name, friend, upArrow, self, friends]] };
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: RName, member: RName, level: MembershipLevel, grade: MembershipGrade, acl: ListType, reporter: ReporterProc ← NIL] RETURNS[Membership];
Updates
Creation and Deletion
CreateIndividual: PROC[user: RName, password: Password, individual: RName, newPwd: Password ] RETURNS[Outcome] = INLINE { RETURN[ Update[user, password, CreateIndividual, individual, NIL, newPwd] ] };
DeleteIndividual: PROC[user: RName, password: Password, individual: RName] RETURNS[Outcome] = INLINE { RETURN[ Update[user, password, DeleteIndividual, individual] ] };
CreateGroup: PROC[user: RName, password: Password, group: RName] RETURNS[Outcome] = INLINE {
RETURN[ Update[user, password, CreateGroup, group] ] };
DeleteGroup: PROC[user: RName, password: Password, group: RName] RETURNS[Outcome] = INLINE {
RETURN[ Update[user, password, DeleteGroup, group] ] };
Updates to single-valued components
SetPassword: PROC[user: RName, password: Password, individual: RName, newPwd: Password] RETURNS[Outcome] = INLINE {
RETURN[ Update[user, password, ChangePassword, individual, NIL, newPwd] ] };
SetConnect: PROC[user: RName, password: Password, individual: RName, connect: GVBasics.Connect] RETURNS[Outcome] = INLINE {
RETURN[ Update[user, password, ChangeConnect, individual, connect] ] };
SetRemark: PROC[user: RName, password: Password, group: RName, remark: GVBasics.Remark] RETURNS[Outcome] = INLINE {
RETURN[ Update[user, password, ChangeRemark, group, remark] ] };
Adding to list-valued components
AddMailbox: PROC[user: RName, password: Password, individual: RName, site: RName] RETURNS[Outcome] = INLINE {
RETURN[ Update[user, password, AddMailBox, individual, site] ] };
AddForward: PROC[user: RName, password: Password, individual: RName, dest: RName] RETURNS[Outcome] = INLINE {
RETURN[ Update[user, password, AddForward, individual, dest] ] };
AddMember: PROC[user: RName, password: Password, group: RName, member: RName] RETURNS[Outcome] = INLINE {
RETURN[ Update[user, password, AddMember, group, member] ] };
AddOwner: PROC[user: RName, password: Password, group: RName, owner: RName] RETURNS[Outcome] = INLINE {
RETURN[ Update[user, password, AddOwner, group, owner] ] };
AddFriend: PROC[user: RName, password: Password, group: RName, friend: RName] RETURNS[Outcome] = INLINE {
RETURN[ Update[user, password, AddFriend, group, friend] ] };
Removing from list-valued components --
RemoveMailbox: PROC[user: RName, password: Password, individual: RName, site: RName] RETURNS[Outcome] = INLINE {
RETURN[ Update[user, password, DeleteMailBox, individual, site] ] };
RemoveForward: PROC[user: RName, password: Password, individual: RName, dest: RName] RETURNS[Outcome] = INLINE {
RETURN[ Update[user, password, DeleteForward, individual, dest] ] };
RemoveMember: PROC[user: RName, password: Password, group: RName, member: RName] RETURNS[Outcome] = INLINE {
RETURN[ Update[user, password, DeleteMember, group, member] ] };
RemoveOwner: PROC[user: RName, password: Password, group: RName, owner: RName] RETURNS[Outcome] = INLINE {
RETURN[ Update[user, password, DeleteOwner, group, owner] ] };
RemoveFriend: PROC[user: RName, password: Password, group: RName, friend: RName] RETURNS[Outcome] = INLINE {
RETURN[ Update[user, password, DeleteFriend, group, friend] ] };
Update: PROC[
user: RName,
password: Password,
op: RSOperation,
target: RName,
value: GVBasics.GVString ← NIL,
newPwd: Password ← NULL,
list: RListHandle ← NIL,
reporter: ReporterProc ← NIL]
RETURNS[Outcome];
RSOperation: TYPE = MACHINE DEPENDENT {
NoOp(0),
Enquiries (also 60..69)
Expand(1),
ReadMembers(2),
ReadOwners(3),
ReadFriends(4),
ReadEntry(5),
CheckStamp(6),
ReadConnect(7),
ReadRemark(8),
Authenticate(9),
Updates
CreateRegistry(10), -- not implemented
DeleteRegistry(11), -- not implemented
CreateIndividual(12),
DeleteIndividual(13),
CreateGroup(14),
DeleteGroup(15),
ChangePassword(16),
ChangeConnect(17),
ChangeRemark(18),
AddMember(19),
AddMailBox(20),
AddForward(21),
AddOwner(22),
AddFriend(23),
DeleteMember(24),
DeleteMailBox(25),
DeleteForward(26),
DeleteOwner(27),
DeleteFriend(28),
AddSelf(29),
DeleteSelf(30),
AddListOfMembers(31),
NewName(32),
IdentifyCaller(33),--internal to GVNamesImpl
IsMemberDirect(40), -- archaic
IsOwnerDirect(41), -- archaic
IsFriendDirect(42), -- archaic
IsMemberClosure(43), -- archaic
IsOwnerClosure(44), -- archaic
IsFriendClosure(45), -- archaic
IsInList(46),
60..69 reserved for more enquiries
ReadMailboxes(60), -- not implemented
(255)
};
"ReporterProc" is primarily to allow Maintain to report progress to its user. Consult a wizard before using this facility.
ReporterProc: TYPE = PROC[ROPE];
"SetServer" provides a server hint, primarily used by Maintain. Consult a wizard before using this facility.
SetServerInfo: TYPE = { badName, allDown, noRoute, ok };
SetServer: PROC[ROPE] RETURNS[ SetServerInfo ];
END.