DIRECTORY XNSCHName, Rope, AlpInstance, AlpineEnvironment, AlpineEnvironmentP2201V1, XNS, XNSCH, XNSAuth, AlpineP2202V1, AlpInstanceCourier, AuthenticationP14V2, UserCredentials, CrRPC, RPC, Booting; AlpInstanceCourierImpl: CEDAR MONITOR IMPORTS XNSCHName, Rope, CrRPC, XNSCH, XNSAuth, AlpineP2202V1, RPC, UserCredentials, Booting EXPORTS AlpInstance ~ BEGIN OPEN AE: AlpineEnvironment, AlpI: AlpInstance; objectCache: LIST OF CacheRec _ NIL; CacheRec: TYPE = RECORD [ object: AlpI.Handle _ NIL, caller: AE.Principal _ NIL ]; FindObjectInCache: INTERNAL PROCEDURE[fileStore: AE.FileStore, caller: AE.Principal, key: RPC.EncryptionKey, pwd: Rope.ROPE, identity: XNSAuth.Identity] RETURNS[handle: AlpI.Handle _ NIL] = BEGIN fileStoreName: XNSCHName.Name; connectionProblem: AlpineP2202V1.ConnectionProblem; authenticationProblem: AuthenticationP14V2.Problem; crReason: CrRPC.ErrorReason; realFileStore: Rope.ROPE _ fileStore; alpinePos: INT _ Rope.FindBackward[s1: fileStore, s2: ".alpine", case: FALSE]; IF fileStore.Length[] - alpinePos = 7 THEN realFileStore _ fileStore.Substr[len: alpinePos]; fileStoreName _ XNSCHName.NameFromRope[realFileStore]; realFileStore _ XNSCHName.RopeFromName[fileStoreName]; FOR list: LIST OF CacheRec _ objectCache, list.rest UNTIL list = NIL DO IF Rope.Equal[list.first.object.fileStore, fileStore, FALSE] THEN BEGIN IF Rope.Equal[list.first.caller, caller, FALSE] AND (key = list.first.object.key) THEN RETURN[list.first.object]; END; ENDLOOP; handle _ NEW[AlpI.Object _ [ trans: NIL, file: NIL, owner: NIL, volume: NIL, otherInterfaces: NIL, conversation: NIL, key: key, fileStore: fileStore]]; { ENABLE { AlpineP2202V1.ConnectionError => {connectionProblem _ problem; GOTO connection}; AlpineP2202V1.AuthenticationError => { authenticationProblem _ problem; GOTO auth }; CrRPC.Error => SELECT errorReason FROM unknown, unknownClass, argsError, resultsError, bulkDataError, notImplemented, unknownOperation, notServerHandle, notClientHandle, addressInappropriateForClass, other => REJECT; ENDCASE => { crReason _ errorReason; GOTO rpcErr}; }; serverAddress: REF XNS.Address ~ NEW[XNS.Address _ XNSCH.LookupAddressFromRope[realFileStore].address]; courierHandle: CrRPC.Handle ~ CrRPC.CreateClientHandle[$SPP, serverAddress]; authenticatedConversation: XNSAuth.Conversation ~ XNSAuth.Initiate[identity, fileStoreName]; credentials: XNSAuth.Credentials ~ XNSAuth.GetCredentials[authenticatedConversation]; verifier: XNSAuth.Verifier _ XNSAuth.GetNextVerifier[authenticatedConversation]; session: AlpineP2202V1.Session; [session, verifier] _ AlpineP2202V1.Logon[courierHandle, fileStoreName, credentials, [caller, pwd], verifier]; handle.otherInterfaces _ LIST[NEW[AlpInstanceCourier.InstanceObject _ [ , courierHandle, authenticatedConversation, credentials, session]]]; EXITS connection => ERROR RPC.ImportFailed[communications]; auth => ERROR RPC.AuthenticateFailed[badCaller]; -- no appropriate reason available. rpcErr => SELECT crReason FROM rejectedNoSuchProgram => ERROR RPC.ImportFailed[unbound]; rejectedNoSuchVersion, rejectedNoSuchProcedure => ERROR RPC.ImportFailed[wrongVersion]; communicationFailure, remoteClose, cantConnectToRemote => ERROR RPC.ImportFailed[communications]; courierVersionMismatch, rejectedInvalidArgument, rejectedUnspecified, remoteError, protocolError => ERROR RPC.ImportFailed[stubProtocol]; ENDCASE => ERROR; }; objectCache _ CONS[ [handle, caller], objectCache]; END; Create: PUBLIC ENTRY PROC [fileStore: AE.FileStore, caller: AE.Principal, key: RPC.EncryptionKey] RETURNS [handle: AlpI.Handle] ~ { ENABLE UNWIND => NULL; identity: XNSAuth.Identity; psw: Rope.ROPE; BEGIN [caller, psw] _ UserCredentials.Get[]; TRUSTED BEGIN key _ RPC.MakeKey[psw]; END; END; identity _ UserCredentials.GetIdentity[]; handle _ FindObjectInCache[fileStore, caller, key, psw, identity]; }; AlpRollbackProcedure: ENTRY Booting.RollbackProc = -- TYPE = PROC[clientData: REF ANY]; BEGIN ENABLE { UNWIND => NULL }; objectCache _ NIL; END; TRUSTED { Booting.RegisterProcs[c: , r: AlpRollbackProcedure]; }; END. "AlpInstanceCourierImpl.mesa Carl Hauser, November 11, 1987 6:43:24 pm PST Remove any .alpine from the name -- backward compatibility hack First, get a three part name for the fileStore (completing the domain and organization) subsequently, use the Rope version of the fully qualified name This is a terrible abuse of AlpInstance.Objects; for Courier we don't need trans, file, owner, and volume because we are never doing a local import. On the other hand, we need a place to hang our Courier handle and conversation so we'll use otherInterfaces in a stylized way. IF caller = NIL THEN have to ignore caller for now because can't make an RPC password out of a key. Change the Alpine interface so it takes a key instead of a password and this can change back. non system-fatal errors: none. Κ©˜šœ™Icode™-—J™šΟk ˜ Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜K˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜Kšœ˜Kšœ˜K˜—K˜Kšœ ˜%KšœU˜\Kšœ ˜šœ˜K˜—Kšœœ'˜.K˜Kšœ œœ œ˜$šœ œœ˜Kšœ˜Kšœœ ˜K˜—˜K˜—š Οnœœ œ œœ˜YKšœœœœ˜cš˜Kšœ˜Kšœ3˜3Kšœ3˜3Kšœ˜Kšœœ ˜%K™?Kšœ œ9œ˜NKšœ$œ2˜\K™WKšœ6˜6K™>Kšœ6˜6š œœœ"œ˜Gšœ4œœ˜GKš œ'œœœœ˜rKšœ˜——Kšœ˜šœ œ˜K™•Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜Kšœœ˜K˜ K˜—˜šœ˜Kšœ?œ ˜PKšœ<œœ˜Tšœœ˜&Kšœͺœ˜±Kšœœ ˜2—Kšœ˜—Kš œœœ œœ œ/˜gKšœL˜LKšœ\˜\KšœU˜UKšœP˜PK˜Kšœn˜nKšœœœk˜Œš˜Kšœœ"˜5Kšœœœ!Οc#˜Ušœ œ œ˜Kšœœœ˜:Kšœ2œœ˜YKšœ:œœ˜bKšœdœœ˜‰Kšœœ˜——K˜—Kšœœ!˜3—šœ˜K˜K˜——š žœœœœ œœ˜NKšœœ˜4Kšœœœ˜K˜Kšœ œ˜šœ œ™K™­šœ˜K˜&Kšœœœœ˜*Kšœ˜——Kšœ)˜)KšœB˜BK˜K˜—šœœŸ$˜WKšœ™Kšœ™š˜šœ˜Jšœ˜J˜—Kšœœ˜—šœ˜K˜K˜——Kšœœ8˜AK˜K˜Kšœ˜—…—ϊΕ