-- Transport Mechanism - Registration server maintenance program -- -- [Indigo]<Grapevine>Maintain>Maintainer.mesa -- Andrew Birrell, 18-Jan-82 10:15:30 -- Philip Karlton, 25-Aug-81 10:27:04 DIRECTORY Ascii USING[ CR, DEL ], BodyDefs USING[ maxRNameLength ], GlassDefs USING[ Handle, Listen ], LaurelExecDefs USING[ FlashTypescriptRegion, GetUserCredentials, MakeMenuCommandCallable ], MaintainDefs USING[], MaintainPrivate USING[ AddForward, AddFriend, AddListOfMembers, AddMailbox, AddOwner, BadConnect, BadName, BadRemark, AddMember, CantCheckName, Command, Confirm, CopyName, CreateGroup, CreateIndividual, DeleteGroup, DeleteIndividual, Handle, HandleObject, InitializeNewName, ModifyAllOccurrences, Operate, Parse, ProposeName, ReadWord, RemoveAllMemberships, RemoveForward, RemoveFriend, RemoveMailbox, RemoveMember, RemoveOwner, SetConnect, SetDecimalPassword, SetPassword, SetRemark, SetServer, TypeAllGroups, TypeDetails, TypeEntry, TypeMembers, VerifyAllGroups, VerifyGroup, VerifyName, VerifyOnOff ], Storage USING[ Free, Node, String ], NameInfoDefs USING[ AuthenticateKey ], NameInfoSpecialDefs USING[ CleanUp ], ProtocolDefs USING[ DestroyStream, Failed, Handle, Init, MakeKey, RegServerSpareSocket ], PupDefs USING[ PupPackageDestroy, PupPackageMake], PupStream USING[ StreamClosing ], Runtime USING[ IsBound, GetBcdTime ], Stream USING[ TimeOut ], String USING[ AppendChar, AppendString, InvalidNumber, StringBoundsFault ], Time USING[ Append, Packed, Unpack ]; Maintainer: PROGRAM IMPORTS GlassDefs, LaurelExecDefs, MaintainPrivate, Storage, NameInfoDefs, NameInfoSpecialDefs, ProtocolDefs, PupDefs, PupStream, Runtime, Stream, String, Time EXPORTS MaintainDefs, MaintainPrivate = BEGIN OPEN BodyDefs, MaintainPrivate, ProtocolDefs; Stopping: ERROR = CODE; Quit: PROCEDURE[handle: MaintainPrivate.Handle] = { IF Confirm[handle.glass] THEN ERROR Stopping[] }; Login: PROCEDURE[handle: MaintainPrivate.Handle] = BEGIN OPEN handle, handle.glass; authenticated ← FALSE; glass.WriteChar[Ascii.CR]; ReadWord[glass, "Your Name Please: "L, caller]; FOR i: CARDINAL IN [0..caller.length) DO IF caller[i] = '. THEN EXIT; REPEAT FINISHED => { WriteString[" ... name must include a registry"L]; ERROR Failed[] }; ENDLOOP; glass.WriteChar[Ascii.CR]; IF glass.ReadString["Your Password: "L, callerPwd, pwd] = Ascii.DEL THEN ERROR Del[]; callerKey ← ProtocolDefs.MakeKey[callerPwd]; IF MaintainPrivate.Operate[handle: handle, op: IdentifyCaller, name: caller, key: callerKey ].code = done THEN authenticated ← TRUE; END; TypeVersion: PROC[str: GlassDefs.Handle, version: Time.Packed] = BEGIN time: STRING = [25]; Time.Append[time, Time.Unpack[version]]; str.WriteString["Version of "L]; str.WriteString[time]; str.WriteChar[Ascii.CR]; END; Failed: PUBLIC ERROR = CODE; Del: PUBLIC ERROR = CODE; -- Much of the following is confused by the existence of two variants -- of the Maintain package. The variants supported are: -- "laurel" => Maintain.bcd running inside Laurel -- "server" => running as, or inside, a TelNet server, or inside Cascade variant: { laurel, server } = SELECT TRUE FROM Runtime.IsBound[LaurelExecDefs.FlashTypescriptRegion] => laurel, ENDCASE => server; DoIt: PUBLIC PROCEDURE[str: GlassDefs.Handle, user, userPwd: STRING] = BEGIN OPEN str; handle: MaintainPrivate.Handle = Storage.Node[SIZE[MaintainPrivate.HandleObject]]; FreeHandle: PROC = BEGIN IF handle.str # NIL THEN ProtocolDefs.DestroyStream[handle.str]; Storage.Free[handle.caller]; Storage.Free[handle.callerPwd]; Storage.Free[handle.name]; Storage.Free[handle.individual]; Storage.Free[handle.group]; Storage.Free[handle.dName]; Storage.Free[handle]; END; handle↑ ← [ str: NIL, serverAddr: , addrKnown: FALSE, caller: Storage.String[BodyDefs.maxRNameLength], callerPwd: Storage.String[16], callerKey: , authenticated: FALSE, verifying: TRUE, name: Storage.String[BodyDefs.maxRNameLength], individual: Storage.String[BodyDefs.maxRNameLength], group: Storage.String[BodyDefs.maxRNameLength], dName: Storage.String[BodyDefs.maxRNameLength], glass: str]; IF userPwd # NIL THEN CopyName[from:userPwd, to:handle.callerPwd]; IF user # NIL THEN CopyName[from:user, to:handle.caller]; DoItWithHandle[handle ! UNWIND => FreeHandle[] ]; FreeHandle[]; END; DoItWithHandle: PROC[handle: MaintainPrivate.Handle] = BEGIN OPEN handle.glass; commands: ARRAY [0..33) OF MaintainPrivate.Command ← [ ["Add Forwarding"L, AddForward], ["Add Friend"L, AddFriend], ["Add List of members"L, AddListOfMembers], ["Add Mailbox"L, AddMailbox], ["Add Member"L, AddMember], ["Add Owner"L, AddOwner], ["Create Group"L, CreateGroup], ["Create Individual"L, CreateIndividual], ["Delete Group"L, DeleteGroup], ["Delete Individual"L, DeleteIndividual], ["Initialize New Name"L, InitializeNewName], ["Login"L, Login], ["Modify All Occurrences"L, ModifyAllOccurrences], ["Quit"L, Quit], ["Remove All Memberships"L, RemoveAllMemberships], ["Remove Friend"L, RemoveFriend], ["Remove Forwarding"L, RemoveForward], ["Remove Mailbox"L, RemoveMailbox], ["Remove Member"L, RemoveMember], ["Remove Owner"L, RemoveOwner], ["Set Connect-site"L, SetConnect], ["Set Decimal Password"L, SetDecimalPassword], ["Set Password"L, SetPassword], ["Set Remark"L, SetRemark], ["Set Server"L, SetServer], ["Type All Groups"L, TypeAllGroups], ["Type Details"L, TypeDetails], ["Type Entry"L, TypeEntry], ["Type Members"L, TypeMembers], ["Verify All Groups"L, VerifyAllGroups], ["Verify Group"L, VerifyGroup], ["Verify Name"L, VerifyName], ["Verify on/off", VerifyOnOff] ]; WriteChar[Ascii.CR]; WriteString["Grapevine Registration Server Maintenance Program"L]; WriteChar[Ascii.CR]; IF Runtime.IsBound[Runtime.GetBcdTime] THEN TypeVersion[handle.glass, Runtime.GetBcdTime[]] ELSE { WriteString["Version unknown"L]; WriteChar[Ascii.CR] }; IF variant = laurel THEN SetLocalDefaults[handle]; handle.callerKey ← ProtocolDefs.MakeKey[handle.callerPwd]; CopyName[from:handle.caller, to: handle.dName]; CopyName[from:handle.caller, to: handle.individual]; CopyName[from:handle.caller, to: handle.name]; IF handle.caller.length # 0 AND handle.callerPwd.length # 0 THEN BEGIN WriteString["Login "L]; WriteString[handle.caller]; WriteString[" ... "L]; SendNow[]; IF NameInfoDefs.AuthenticateKey[handle.caller, handle.callerKey] = individual THEN { WriteString["done"L]; handle.authenticated←TRUE }; END; IF NOT handle.authenticated THEN WriteString["You are not logged in yet"L]; WriteChar[Ascii.CR]; DO BEGIN ENABLE -- CONTINUE produces screen flash; RETRY doesn't. BEGIN Del => { Flush[]; WriteString[" XXX"L]; GOTO CloseStream }; String.InvalidNumber => { WriteString[" ... invalid number"L]; CONTINUE }; String.StringBoundsFault => { WriteString[" ... string too long"L]; CONTINUE }; BadRemark => BEGIN WriteString[" ... illegal character in remark"L]; CONTINUE END; BadName => IF handle.verifying THEN BEGIN WriteString[" ... """L]; WriteString[bad]; WriteString[""" is not a valid name."L]; MaintainPrivate.ProposeName[handle, bad, either]; CONTINUE END ELSE { WriteString[" (bad name)"L]; RESUME }; CantCheckName => IF handle.verifying THEN BEGIN WriteString[" ... can't verify name - server down"L]; CONTINUE END ELSE { WriteString[" (can't verify)"L]; RESUME }; BadConnect => IF handle.verifying THEN BEGIN WriteString[" ... not a host name or address"L]; CONTINUE END ELSE { WriteString[" (bad connect)"L]; RESUME }; Stream.TimeOut, PupStream.StreamClosing, ProtocolDefs.Failed => BEGIN WriteString["communication failure - please re-try"L]; IF variant = laurel THEN LaurelExecDefs.FlashTypescriptRegion[]; GOTO CloseStream END; Stopping => EXIT; Failed => CONTINUE -- command produced error message --; END; MaintainPrivate.Parse[handle, DESCRIPTOR[commands], "GV: "L]; EXITS CloseStream => BEGIN SendNow[]; IF handle.str # NIL THEN ProtocolDefs.DestroyStream[handle.str]; handle.str ← NIL; LOOP -- don't flash -- END; END; IF variant = laurel THEN LaurelExecDefs.FlashTypescriptRegion[]; ENDLOOP; WriteChar[Ascii.CR]; END; SetLocalDefaults: PROC[handle: MaintainPrivate.Handle] = BEGIN -- used for variant=laurel-- OPEN handle; registry: STRING = [BodyDefs.maxRNameLength]; LaurelExecDefs.GetUserCredentials[caller, callerPwd, registry]; BEGIN ENABLE String.StringBoundsFault => CONTINUE; String.AppendChar[caller, '.]; String.AppendString[caller, registry]; END; LaurelExecDefs.MakeMenuCommandCallable[newMail]; LaurelExecDefs.MakeMenuCommandCallable[mailFile]; LaurelExecDefs.MakeMenuCommandCallable[display]; LaurelExecDefs.MakeMenuCommandCallable[delete]; LaurelExecDefs.MakeMenuCommandCallable[undelete]; LaurelExecDefs.MakeMenuCommandCallable[moveTo]; LaurelExecDefs.MakeMenuCommandCallable[copy]; END; ListenerWork: PROC[str: GlassDefs.Handle] = { DoIt[str, NIL, NIL] }; PupDefs.PupPackageMake[]; ProtocolDefs.Init[]; IF variant = laurel THEN GlassDefs.Listen[ListenerWork, ProtocolDefs.RegServerSpareSocket]; NameInfoSpecialDefs.CleanUp[]; PupDefs.PupPackageDestroy[]; END.