-- 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.