DIRECTORY Basics USING [bytesPerWord, LongNumber, SwapHalves], BasicTime USING [GMT, nullGMT, ToPupTime, Update], CedarProcess USING [Abort, CheckAbort, Fork, ForkableProc, Process], FS USING [ComponentPositions, Error, ExpandName, FileInfo], PupDefs USING [GetHopsToNetwork, GetPupContentsBytes, PupBuffer, PupSocket, PupSocketDestroy, PupSocketMake, ReturnPup, SendErrorPup, veryLongWait], PupTypes USING [fillInPupAddress, Pair, PupAddress, PupSocketID, PupType], Rope USING [Cat, Find, FromRefText, Index, Length, Replace, ROPE, Substr], RuntimeError USING [UNCAUGHT], STPServerFileTranslation USING [FindNamedTranslator, NamedTranslator], STPServerPrivate USING [CurrentVersion, FileName, NameMapDirection, NameMapList], UserProfile USING [CallWhenProfileChanges, ListOfTokens, ProfileChangeReason]; STPServerAuxImpl: CEDAR MONITOR IMPORTS Basics, BasicTime, CedarProcess, FS, PupDefs, Rope, RuntimeError, STPServerPrivate, UserProfile, STPServerFileTranslation EXPORTS STPServerPrivate ~ BEGIN OPEN STPServerPrivate; nameMaps: NameMapList _ NIL; GMT: TYPE ~ BasicTime.GMT; LongNumber: TYPE ~ Basics.LongNumber; ROPE: TYPE ~ Rope.ROPE; LOR: TYPE ~ LIST OF ROPE; BothFromOne: PUBLIC PROC [oneName: ROPE, direction: NameMapDirection] RETURNS [both: FileName] ~ { otherName: ROPE _ oneName; otherLength: INT _ otherName.Length[]; FOR nms: NameMapList _ nameMaps, nms.rest WHILE nms # NIL DO find: ROPE ~ SELECT direction FROM localToRemote => nms.first.local, remoteToLocal => nms.first.remote, ENDCASE => ERROR; repl: ROPE ~ SELECT direction FROM localToRemote => nms.first.remote, remoteToLocal => nms.first.local, ENDCASE => ERROR; start: INT ~ otherName.Find[s2: find, case: FALSE]; cutLength: INT ~ find.Length[]; IF start >= 0 THEN { otherName _ otherName.Replace[start: start, len: cutLength, with: repl]; EXIT; }; ENDLOOP; both _ SELECT direction FROM localToRemote => [local: oneName, remote: otherName], remoteToLocal => [local: otherName, remote: oneName], ENDCASE => ERROR; }; RealName: PROC [remoteName: ROPE] RETURNS [realName: ROPE _ NIL, translated: BOOL _ FALSE] ~ { fullFName: ROPE _ NIL; cp: FS.ComponentPositions; namedTranslator: STPServerFileTranslation.NamedTranslator _ NIL; hostNameLength: INT _ 0; [fullFName, cp] _ FS.ExpandName[remoteName]; namedTranslator _ STPServerFileTranslation.FindNamedTranslator[fullFName, cp.dir.start, cp.dir.length]; IF namedTranslator = NIL OR cp.subDirs.length = 0 THEN RETURN [realName: BothFromOne[remoteName, remoteToLocal].local, translated: FALSE]; hostNameLength _ Rope.Index[s1: fullFName, pos1: cp.subDirs.start, s2: ">"] - cp.subDirs.start; realName _ Rope.Cat["[", Rope.Substr[fullFName, cp.subDirs.start, hostNameLength], "]<", Rope.Substr[fullFName, cp.subDirs.start+hostNameLength+1]]; translated _ TRUE; }; NoteProfile: PROC [reason: UserProfile.ProfileChangeReason] --UserProfile.ChangeProc-- ~ { maps: LOR _ UserProfile.ListOfTokens["STPServer.NameMappings", NIL]; newMaps: NameMapList _ NIL; FOR maps _ maps, maps.rest.rest WHILE maps # NIL AND maps.rest # NIL DO remote: ROPE ~ maps.first; local: ROPE ~ maps.rest.first; newMaps _ CONS[[local: local, remote: remote], newMaps]; ENDLOOP; IF maps # NIL THEN ERROR; nameMaps _ newMaps; }; LookupFileType: PupTypes.PupType = LOOPHOLE[200B]; LookupFileReplyType: PupTypes.PupType = LOOPHOLE[201B]; LookupFileErrorType: PupTypes.PupType = LOOPHOLE[202B]; LookupFileSocket: PupTypes.PupSocketID = [0, 61B]; singleSocket: PupDefs.PupSocket _ NIL; singleProcess: CedarProcess.Process _ NIL; StartSingle: PUBLIC ENTRY PROC = { ENABLE UNWIND => NULL; IF singleProcess = NIL THEN { singleSocket _ PupDefs.PupSocketMake [local: LookupFileSocket, remote: PupTypes.fillInPupAddress, ticks: PupDefs.veryLongWait ]; singleProcess _ CedarProcess.Fork[ SinglePacketListener, NIL, [priority: foreground, usePriority: TRUE]]; }; }; StopSingle: PUBLIC ENTRY PROC = { ENABLE UNWIND => NULL; IF singleProcess # NIL THEN { CedarProcess.Abort[singleProcess]; PupDefs.PupSocketDestroy[singleSocket ! RuntimeError.UNCAUGHT => CONTINUE]; singleSocket _ NIL; }; }; ReplyRecord: TYPE = MACHINE DEPENDENT RECORD[v: CARDINAL, c, l: LongNumber]; ReplyRecordBytes: CARDINAL = SIZE[ReplyRecord]*Basics.bytesPerWord; SinglePacketListener: CedarProcess.ForkableProc = TRUSTED { ENABLE UNWIND => singleProcess _ NIL; text: REF TEXT _ NEW[TEXT[256]]; DO receiver: PupDefs.PupBuffer = singleSocket.get[]; replyType: PupTypes.PupType _ error; replyBytes: CARDINAL _ 0; IF receiver # NIL THEN { addr: PupTypes.PupAddress _ receiver.source; msWait: CARDINAL = 2000+500*MIN[8, PupDefs.GetHopsToNetwork[addr.net]]; IF receiver.pupType = LookupFileType THEN { id: PupTypes.Pair _ receiver.pupID; len: INT _ PupDefs.GetPupContentsBytes[receiver]; IF len IN [1..256] THEN { ENABLE RuntimeError.UNCAUGHT => GO TO dropIt; sLen: NAT _ len; name: ROPE _ NIL; fileLen: INT _ 0; fileDate: GMT _ BasicTime.nullGMT; rPtr: LONG POINTER TO ReplyRecord = LOOPHOLE[@receiver.pupBody]; translated: BOOL _ FALSE; text[0] _ '[; text[1] _ ']; FOR i: NAT IN [0 .. sLen) DO text[i+2] _ receiver.pupChars[i]; ENDLOOP; text.length _ sLen+2; name _ Rope.FromRefText[text]; [name, translated] _ RealName[name]; [fullFName: name, created: fileDate, bytes: fileLen] _ FS.FileInfo[name: name ! FS.Error => { SELECT error.code FROM $nonCedarVolume, $unknownVolume, $unknownFile, $unknownCreatedTime, $illegalName, $patternNotAllowed => replyType _ LookupFileErrorType; ENDCASE => NULL; CONTINUE }; ]; IF fileDate # BasicTime.nullGMT AND fileLen >= 0 THEN { IF translated THEN { fileLen _ (fileLen+999)/1000*1000; fileDate _ BasicTime.Update[fileDate, 1]; }; rPtr.v _ CurrentVersion[name]; rPtr.c _ Basics.SwapHalves[[lc[BasicTime.ToPupTime[fileDate]]]]; rPtr.l _ Basics.SwapHalves[[li[fileLen]]]; replyType _ LookupFileReplyType; replyBytes _ ReplyRecordBytes; }; }; EXITS dropIt => {}; }; receiver.pupType _ replyType; IF replyType = error THEN PupDefs.SendErrorPup[receiver, noProcessPupErrorCode, "Can't lookup file"] ELSE PupDefs.ReturnPup[receiver, replyType, replyBytes]; }; CedarProcess.CheckAbort[singleProcess]; ENDLOOP; }; Init: PROC ~ { UserProfile.CallWhenProfileChanges[NoteProfile]; }; Init[]; END. xSTPServerAuxImpl.mesa Copyright (C) 1984, 1985 Xerox Corporation. All rights reserved. Michael Plass, December 30, 1985 3:02:24 pm PST Jim Gasbarro, March 8, 1985 11:39:14 am PST Russ Atkinson (RRA) June 21, 1985 1:05:20 pm PDT Spreitzer, September 4, 1985 4:56:26 pm PDT Hal Murray December 9, 1985 5:14:47 pm PST Name Mapping Single Packet Protocol Initialization ΚΠ˜code™K™AK™/K™+K™0K™+K™*K™—šΟk ˜ Jšœœ(˜4Jšœ œœ˜2Jšœ œ2˜DJšœœ3˜;Jšœœ‡˜”Jšœ œ<˜JJšœœ2œ ˜JJšœ œœ˜Jšœœ(˜FJšœœ;˜QJšœ œ=˜N—K˜šΠlnœœ˜Kšœ"œV˜Kšœ˜šœœœ˜K˜——™ K˜Kšœœ˜K˜Kšœœ œ˜Kšœ œ˜%Kšœœœ˜š œœœœœ˜K˜—š Οn œœœ œœ˜bKšœ œ ˜Kšœ œ˜&šœ'œœ˜<šœœœ ˜"Kšœ!˜!Kšœ"˜"Kšœœ˜—šœœœ ˜"Kšœ"˜"Kšœ!˜!Kšœœ˜—Kšœœ"œ˜3Kšœ œ˜šœ œ˜KšœH˜HKšœ˜K˜—Kšœ˜—šœœ ˜Kšœ5˜5Kšœ5˜5Kšœœ˜—K˜K˜—šŸœœœœ œœœœ˜^Kšœ œœ˜Kšœœ˜Kšœ<œ˜@Kšœœ˜Kšœœ˜,Kšœg˜gKš œœœœœFœ˜ŠK•StartOfExpansion>[s1: ROPE, pos1: INT _ 0, s2: ROPE, case: BOOL _ TRUE]šœ_˜_Kšœ”˜”Kšœ œ˜K˜K˜—šŸ œœ+Οcœ˜ZKšœœ6œ˜DKšœœ˜š œœœœ œ˜GKšœœ˜Kšœœ˜Kšœ œ*˜8Kšœ˜—Kšœœœœ˜Kšœ˜K˜K˜——™K™Kšœ#œ˜2Kšœ(œ˜7Kšœ(œ˜7Kšœ2˜2K˜Kšœ"œ˜&Kšœ&œ˜*K˜šŸ œœœœ˜"Kšœœœ˜šœœœ˜Kšœ€˜€Kšœ9œ&œ˜iK˜—K˜K˜—šŸ œœœœ˜!Kšœœœ˜šœœœ˜Kšœ"˜"šœ%˜%Kšœœœ˜%—Kšœœ˜K˜—K˜K˜—Kš œ œœ œœœ˜LKšœœœ"˜CK˜šœ2œ˜;Kšœœœ˜%Icode2š œœœœœ˜ š˜Lšœ1˜1Lšœ$˜$Lšœ œ˜šœ œœ˜Lšœ,˜,Lšœœ œ(˜Gšœ#œ˜+Lšœ#˜#Lšœœ)˜1šœœ œ˜Lšœœœœ˜-Lšœœ˜Lšœœœ˜Lšœ œ˜Lšœ œ˜"Lš œœœœœ˜@Lšœ œœ˜Lšœ˜šœœœ ˜Lšœ!˜!Lšœ˜—Lšœ˜Lšœ˜Lšœ$˜$šœ7œ˜Mšœœ ˜šœ ˜Lšœ œw˜ˆLšœœ˜—Lš˜L˜—Lšœ˜—šœœœ˜7šœ œ˜Lšœ"˜"Lšœ)˜)L˜—Lšœ˜Lšœ@˜@Lšœ*˜*Lšœ ˜ Lšœ˜L˜—L˜—Lšœ˜L˜—Lšœ˜šœ˜LšœJ˜J—Lšœ4˜8L˜—Lšœ'˜'Kšœ˜—K˜—K™—™K˜šŸœœ˜Kšœ0˜0Kšœ˜K˜—šœ˜K˜—Kšœ˜—K˜—…—(!p