-- Transport mechanism: Maintain: error messages
-- [Juniper]<Grapevine>Maintain>MaintainErrors.mesa
-- Andrew Birrell 14-Jan-82 9:37:23
DIRECTORY
BodyDefs USING[ maxRNameLength, RName ],
MaintainPrivate USING[ Failed, Handle, ProposalType ],
NameInfoDefs USING[ CheckStamp, StampInfo ],
ProtocolDefs USING[ ReturnCode, RSOperation ],
String USING[ AppendChar, AppendString, LowerCase,
StringBoundsFault ];
MaintainErrors: PROGRAM
IMPORTS MaintainPrivate, NameInfoDefs, String
EXPORTS MaintainPrivate =
BEGIN
TypeRC: PUBLIC PROC[handle: MaintainPrivate.Handle,
op: ProtocolDefs.RSOperation,
rc: ProtocolDefs.ReturnCode,
name: BodyDefs.RName,
value: STRING] =
BEGIN
OPEN handle.glass;
SELECT rc.code FROM
done => WriteString["done"L];
outOfDate =>
WriteString["out-of-date: consult LaurelSupport.pa"L];
NotAllowed =>
WriteString["You don't have permission to do that. Consult your local Grapevine administrator"L];
BadOperation =>
WriteString["bad-operation: consult LaurelSupport.pa"L];
BadProtocol =>
WriteString["bad-protocol: consult LaurelSupport.pa"L];
BadRName =>
BEGIN
WriteChar['"]; WriteString[name];
IF op = CreateIndividual OR op = CreateGroup OR op = NewName
THEN SELECT rc.type FROM
group =>
WriteString[""" is an existing group"L];
individual =>
WriteString[""" is an existing individual"L];
dead =>
WriteString[""" has recently been deleted - can't recreate it yet. Consult LaurelSupport.pa if necessary."L];
notFound =>
WriteString[""" does not have a valid registry"L];
ENDCASE => ERROR
ELSE BEGIN
wanted: MaintainPrivate.ProposalType;
WriteString[""" is not a valid "L];
SELECT op FROM
ReadConnect, Authenticate, DeleteIndividual,
ChangePassword, ChangeConnect, AddMailBox, AddForward,
DeleteMailBox, DeleteForward, IdentifyCaller =>
{ WriteString["individual."L]; wanted ← individual };
ReadMembers, ReadOwners, ReadFriends, ReadRemark,
DeleteGroup, ChangeRemark, AddMember, AddOwner,
AddFriend, DeleteMember, DeleteOwner, DeleteFriend,
AddSelf, DeleteSelf, AddListOfMembers =>
{ wanted ← group; WriteString["group."L] };
ENDCASE => { wanted ← either; WriteString["name."L] };
IF rc.type = notFound THEN ProposeName[handle, name, wanted];
END;
END;
BadPassword =>
WriteString["incorrect password."L];
WrongServer =>
WriteString["wrong-server: consult LaurelSupport.pa."L];
AllDown =>
WriteString["couldn't contact needed server. Try later."L];
noChange =>
BEGIN
Val: PROC[s: STRING] =
{ WriteChar['"]; WriteString[value]; WriteString[""" is "L];
WriteString[s]; WriteString[" of """L]; WriteString[name];
WriteChar['"] };
SELECT op FROM
AddMember =>
Val["already a member"L];
AddMailBox =>
Val["already a mailbox-site"L];
AddForward =>
Val["already a forwardee"L];
AddOwner =>
Val["already an owner"L];
AddFriend =>
Val["already a friend"L];
DeleteMember =>
Val["not a member"L];
DeleteMailBox =>
Val["not a mailbox-site"L];
DeleteForward =>
Val["not a forwardee"L];
DeleteOwner =>
Val["not an owner"L];
DeleteFriend =>
Val["not a friend"L];
AddSelf =>
WriteString["you're already a member of that group."L];
DeleteSelf =>
WriteString["you're not a member of that group."L];
ENDCASE =>
WriteString["no-change: consult LaurelSupport.pa."L];
END;
ENDCASE =>
WriteString["bad return-code: consult LaurelSupport.pa."L];
IF rc.code # done THEN ERROR MaintainPrivate.Failed[];
END;
ProposeName: PUBLIC PROC[handle: MaintainPrivate.Handle,
name: BodyDefs.RName,
wanted: MaintainPrivate.ProposalType] =
BEGIN
OPEN handle.glass;
dotDL: BOOLEAN ← FALSE;
IF name.length = 0 THEN RETURN;
IF name[0] = '. OR name[0] = '↑ THEN RETURN;
IF name[0] = '@
THEN { WriteString[" ""Maintain"" doesn't handle ""@"" distribution lists."L]; RETURN };
IF wanted = either
THEN FOR i: CARDINAL IN [0..name.length)
DO IF name[i] = '↑ THEN wanted ← group; ENDLOOP;
IF name.length >= 3
AND name[name.length-3] = '.
AND String.LowerCase[name[name.length-2]] = 'd
AND String.LowerCase[name[name.length-1]] = 'l
THEN BEGIN
dotDL ← TRUE;
IF wanted = either THEN wanted ← group;
END;
BEGIN
ENABLE String.StringBoundsFault => CONTINUE;
newName: BodyDefs.RName = [BodyDefs.maxRNameLength];
dot: BOOLEAN;
GenerateName: PROC[group: BOOLEAN] RETURNS[ok: BOOLEAN] =
BEGIN
newName.length ← 0;
dot ← FALSE;
FOR j: CARDINAL IN [0..name.length)
DO IF name[j] = '.
THEN BEGIN
IF dotDL THEN EXIT;
dot ← TRUE;
IF group THEN String.AppendChar[newName, '↑];
END;
IF name[j] # '↑ THEN String.AppendChar[newName, name[j]];
ENDLOOP;
IF NOT dot
THEN BEGIN
IF group THEN String.AppendChar[newName, '↑];
FOR k: CARDINAL DECREASING
IN [0..handle.caller.length)
DO IF handle.caller[k] = '.
THEN BEGIN
FOR x: CARDINAL IN [k..handle.caller.length)
DO String.AppendChar[newName, handle.caller[x]] ENDLOOP;
EXIT
END;
ENDLOOP;
END;
BEGIN
info: NameInfoDefs.StampInfo = NameInfoDefs.CheckStamp[newName];
IF (ok ← SELECT info FROM
notFound => FALSE,
allDown => FALSE,
individual => NOT group,
group => group,
ENDCASE => ERROR)
THEN BEGIN
WriteString[" """L];
WriteString[newName];
WriteString[""" is a valid "];
WriteString[IF group THEN "group."L ELSE "individual."L];
name.length ← 0; String.AppendString[name, newName];
END;
END;
END;
proposed: BOOLEAN ← FALSE;
IF wanted # individual AND GenerateName[TRUE] THEN proposed ← TRUE;
IF wanted # group AND GenerateName[FALSE] THEN proposed ← TRUE;
IF NOT proposed AND NOT dot
THEN BEGIN
WriteString[" Names should be of the form ""firstPart.Registry"""L];
IF wanted # individual
THEN WriteString[" or ""firstPart↑.Registry"""L];
WriteChar['.];
END;
END;
END;
END.