DIRECTORY BasicTime USING [GMT, Now, nullGMT], Commander USING [CommandProc, Handle, Register], CommanderOps USING [NextArgument], DFUtilities USING [DateToRope], FileNames USING [StripVersionNumber], FS USING [Copy, defaultStreamOptions, EnumerateForInfo, Error, GetInfo, InfoProc, OpenFileFromStream, StreamOpen, StreamOptions], IO, Process USING [CheckForAbort], Rope; ChangePseudoServersImpl: CEDAR PROGRAM IMPORTS BasicTime, Commander, CommanderOps, DFUtilities, FileNames, FS, IO, Process, Rope = BEGIN GMT: TYPE = BasicTime.GMT; ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; PairList: TYPE = LIST OF Pair; Pair: TYPE = RECORD[oldPS, newPS: ROPE]; FileEntry: TYPE = REF FileEntryRep; FileEntryRep: TYPE = RECORD [ name: ROPE, localName: ROPE, oldDate: GMT, newDate: GMT ¬ BasicTime.nullGMT, state: FileEntryState ¬ init ]; FileEntryState: TYPE = {init, fetching, editing, unchanged, changed, done}; doc: ROPE = "dirToChange oldPS newPS {oldPS1 newPS1}* changed oldPS to newPS in df files on dirToChange "; maxRetries: NAT ¬ 10; retrySeconds: NAT ¬ 20; DoIt: PROC [out: STREAM, dirToChange: ROPE, changeList: PairList] = { dfList: LIST OF FileEntry ¬ NIL; errorsEncountered: BOOL ¬ FALSE; CheckFile: PROC [entry: FileEntry] = { ENABLE FS.Error => GOTO failed; srcStream: STREAM ¬ NIL; retriedCount: NAT ¬ 0; openName: ROPE ¬ NIL; streamOptions: FS.StreamOptions ¬ FS.defaultStreamOptions; streamOptions[tiogaRead] ¬ FALSE; Process.CheckForAbort[]; entry.state ¬ fetching; entry.localName ¬ "/tmp/ChangePS.temp$"; [] ¬ FS.Copy[from: entry.name, to: entry.localName, wantedCreatedTime: entry.oldDate]; entry.state ¬ editing; CheckForEdit[out, entry, changeList]; IF entry.state = unchanged THEN RETURN; [] ¬ FS.Copy[from: entry.localName, to: entry.name]; -- should do it all entry.state ¬ done; out.PutF1["Changed %g\n", [rope[entry.name]] ]; EXITS failed => { errorsEncountered ¬ TRUE }; }; EachDfFile: FS.InfoProc = { dstDate: GMT ¬ BasicTime.nullGMT; doTheEnumerate: BOOL ¬ FALSE; this: FileEntry ¬ NEW[FileEntryRep ¬ [name: FileNames.StripVersionNumber[fullFName], oldDate: created ] ]; Process.CheckForAbort[]; dfList ¬ CONS[this, dfList]; numDFFiles ¬ numDFFiles + 1; continue ¬ TRUE; }; filesChanged: INT ¬ 0; numDFFiles: INT ¬ 0; out.PutF["Changing df files on %g from using %g to using %g", [rope[dirToChange]], [rope[changeList.first.oldPS]], [rope[changeList.first.newPS]] ]; FOR pL: PairList ¬ changeList.rest, pL.rest UNTIL pL = NIL DO out.PutF[" & from using %g to using %g", [rope[pL.first.oldPS]], [rope[pL.first.newPS]] ]; ENDLOOP; out.PutChar['\n] ; out.PutF1["{Enumerating df Files at %g}\n", [time[BasicTime.Now[]]] ]; FS.EnumerateForInfo[Rope.Concat[dirToChange, "*.df!H"], EachDfFile]; out.PutF1["{Editing & storing files at %g}\n", [time[BasicTime.Now[]]] ]; FOR entryList: LIST OF FileEntry ¬ dfList, entryList.rest WHILE entryList # NIL DO CheckFile[entryList.first]; ENDLOOP; out.PutF1["{Done at %g}\n", [time[BasicTime.Now[]]] ]; out.PutF1["Files edited and rewritten: %g\n\n", [integer[filesChanged]] ]; }; CheckForEdit: PROC[out: STREAM, entry: FileEntry, changeList: PairList] = { strm: STREAM ¬ FS.StreamOpen[entry.localName, $read]; this: ROPE ¬ strm.GetRope[]; strm.Close[]; entry.state ¬ unchanged; FOR pL: PairList ¬ changeList, pL.rest UNTIL pL = NIL DO where: INT ¬ 0; oldPS: ROPE = pL.first.oldPS; newPS: ROPE = pL.first.newPS; oldLen: INT = oldPS.Length[]; newLen: INT ¬ newPS.Length[]; DO found: INT ¬ Rope.Find[this, pL.first.oldPS, where, FALSE]; IF found = -1 THEN EXIT; this ¬ Rope.Replace[base: this, start: found, len: oldLen, with: newPS]; where ¬ found + newLen; entry.state ¬ changed; ENDLOOP; ENDLOOP; IF entry.state = unchanged THEN { this ¬ NIL; RETURN }; BEGIN dateRope: ROPE = DFUtilities.DateToRope[[format: explicit, gmt: entry.oldDate]]; found: INT ¬ Rope.Find[this, dateRope, 0, FALSE]; IF found = -1 THEN { out.PutF["\n *** Date %g not found in %g, skipping this file ***\n", [rope[dateRope]], [rope[entry.name]] ]; entry.state ¬ unchanged; this ¬ NIL; RETURN; }; strm ¬ FS.StreamOpen[entry.localName, $create]; entry.newDate ¬ FS.GetInfo[FS.OpenFileFromStream[strm]].created; IF found # -1 THEN this ¬ Rope.Replace[base: this, start: found, len: dateRope.Length[], with: DFUtilities.DateToRope[[explicit, entry.newDate]] ]; END; strm.PutRope[this]; strm.Close[]; this ¬ NIL; -- for good measure }; ShowEntry: PROC [out: STREAM, entry: FileEntry] = { IO.PutF[out, "[name: %g, oldDate: %g, newDate: %g, state: ", [rope[entry.name]], [time[entry.oldDate]], [time[entry.newDate]] ]; SELECT entry.state FROM init => IO.PutRope[out, "init]\n"]; fetching => IO.PutRope[out, "fetching]\n"]; editing => IO.PutRope[out, "editing]\n"]; unchanged => IO.PutRope[out, "unchanged]\n"]; changed => IO.PutRope[out, "changed]\n"]; done => IO.PutRope[out, "done]\n"]; ENDCASE; }; ChangeCommandProc: Commander.CommandProc = { out: STREAM = cmd.out; pairList: PairList ¬ NIL; pairListTail: PairList ¬ NIL; dirToChange: ROPE ¬ CommanderOps.NextArgument[cmd]; IF dirToChange = NIL THEN { msg ¬ "No dirToChange given.\n"; RETURN; }; DO new: PairList; newPS: ROPE; oldPS: ROPE ¬ CommanderOps.NextArgument[cmd]; IF oldPS = NIL THEN EXIT; newPS ¬ CommanderOps.NextArgument[cmd]; IF newPS = NIL THEN { msg ¬ "Unmatched old/newPS pair.\n"; RETURN; }; new ¬ LIST[[oldPS, newPS]]; IF pairListTail = NIL THEN pairListTail ¬ pairList ¬ new ELSE pairListTail.rest ¬ new; ENDLOOP; IF pairList = NIL THEN {msg ¬ "No old/newPS pairs given.\n"; RETURN}; DoIt[cmd.out, dirToChange, pairList]; }; Commander.Register[ key: "ChangePseudoServers", proc: ChangeCommandProc, doc: doc ]; END. ά ChangePseudoServersImpl.mesa Copyright Σ 1988, 1991, 1992 by Xerox Corporation. All rights reserved. Willie-Sue, November 25, 1988 11:57:34 am PST Willie-s, January 23, 1992 2:19 pm PST Taken from TrickleChargeSeverImpl ChangePseudoServers switches dirToChange oldPS newPS changes all the df files in dirToChange from using oldPS to using newPS. Types NoDate: SIGNAL[msg: ROPE] = CODE; full path name without version ///temp/ChangePS.temp$ plus version number date of old df file date of new df file indicates the state of the file (obvious) Documentation Example ChangePseudoServers [NewCedar10.0] [NewCedar10.0] [Cedar10.0] All occurrences of [NewCedar10.0] were replaced by [Cedar10.0]. Option variables # of times to retry connectionRejected from STP # of seconds between retry attemps Command Procedures Force the transfers to happen on raw files [fullFName: ROPE, attachedTo: ROPE, created: GMT, bytes: INT, keep: CARDINAL] RETURNS [continue: BOOL] The mainline of DoIt Phase1, build up data base. Don't move any files. Phase2, move files. Don't change the entries (except for the 'moved' field). IF found = -1 THEN { out.PutF["\n *** Date %g not found in %g, checking ***\n", [rope[dateRope]], [rope[entry.name]] ]; entry.state _ unchanged; SIGNAL NoDate[entry.name]; IF entry.state = unchanged THEN { this _ NIL; RETURN}; }; [cmd: Handle] RETURNS [result: REF _ NIL, msg: ROPE _ NIL] CommandObject = [in, out, err: STREAM, commandLine, command: ROPE, ...] Initialization Κ U–(cedarcode) style•NewlineDelimiter ™codešœ™Kšœ Οeœ=™HK™-K™&—˜K™!K™šœ4™4KšœH™H—K˜—šΟk ˜ Kšœ žœžœ˜$Kšœ žœ!˜0Kšœ žœ˜"Kšœ žœ˜Kšœ žœ˜%Kšžœžœy˜Kšžœ˜Kšœžœ˜Kšœ˜—K˜šΠlnœžœž˜&Kšžœ=žœžœ˜YKšœž˜—head™Kšžœžœ žœ˜Kšžœžœžœ˜Kšžœžœžœžœ˜K˜Kšœžœžœžœ™!Kšœ žœžœžœ˜Kšœžœžœžœ˜(K˜Kšœ žœžœ˜#šœžœžœ˜šœžœ˜ K™—šœ žœ˜K™*—šœ žœ˜ K™—šœ žœ˜!K™—˜K™)—K˜—Kšœžœ7˜K—™ Kšœžœd˜mhead2™šΟoœ0™CKšœ?™?K™——K˜—šœ™šœ žœ˜Kšœ/™/—šœžœ˜Kšœ"™"——™šΟnœžœžœžœ˜EKšœžœžœ žœ˜ Kšœžœžœ˜ K•StartOfExpansion> -- [data: RedBlackTree.UserData] RETURNS [stop: BOOL _ FALSE]˜š‘ œžœ˜&Kšžœžœ žœ˜Kšœ žœžœ˜Kšœžœ˜Kšœ žœžœ˜Kšœžœžœ˜:šœžœ˜!Kšœ*™*—Kšœ˜K˜K˜(KšœžœO˜VK˜Kšœ%˜%Kšžœžœžœ˜'Kšœžœ.Οc˜HK˜K˜/Kšžœ!žœ˜-K˜K˜—–j -- [fullFName: ROPE, attachedTo: ROPE, created: GMT, bytes: INT, keep: CARDINAL] RETURNS [continue: BOOL]šΟb œžœ ˜KšΠckf™fKšœ žœ˜!Kšœžœžœ˜KšœžœU˜jKšœ˜Kšœ žœ˜K˜Kšœ žœ˜K˜—K˜K™Kšœžœ˜Kšœ žœ˜K˜šœ”˜”K˜šžœ)žœžœž˜=KšœZ˜ZKšžœ˜—Kšœ˜—K™Kšœ2™2KšœF˜FKšžœB˜DK˜KšœM™MKšœI˜Iš žœ žœžœ$žœ žœž˜RK˜Kšžœ˜—Kšœ6˜6K˜JK˜K˜—š‘ œžœžœ-˜KKšœžœžœ$˜5Kšœžœ˜Kšœ ˜ K˜šžœ$žœžœž˜8Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜šž˜Kšœžœ*žœ˜;Kšžœ žœžœ˜K˜HK˜K˜Kšžœ˜—Kšžœ˜—Kšžœžœ žœžœ˜7šž˜Kšœ žœB˜PKšœžœ žœ˜1šžœ žœ™K™bKšœ™Kšžœ™Kšžœžœ žœžœ™6K™—šžœ žœ˜K˜lK˜Kšœžœ˜ Kšžœ˜K˜—Kšœžœ&˜/Kšœžœ žœ#˜@Kšžœ žœ˜“Kšžœ˜—Kšœ˜K˜ Kšœžœ’˜K˜K˜—š‘ œžœžœ˜3Kšžœ~˜€šžœ ž˜Kšœžœ˜#Kšœ žœ˜+Kšœ žœ˜)Kšœ žœ˜-Kšœ žœ˜)Kšœžœ˜#Kšžœ˜—K˜K˜—š‘œ˜,š œžœ žœžœžœžœ™:Kšœžœžœ™G—Kšœžœ ˜Kšœžœ˜Kšœžœ˜K˜Kšœ žœ"˜3šžœžœžœ˜K˜ Kšžœ˜K˜K˜—šž˜K˜Kšœžœ˜ Kšœžœ"˜-Kšžœ žœžœžœ˜K˜'šžœ žœžœ˜K˜$Kšžœ˜K˜—Kšœžœ˜šžœžœž˜Kšœžœ˜;—Kšžœ˜K˜—šžœ žœžœ'žœ˜EK˜—Kšœ%˜%K˜——–x[key: ROPE, proc: Commander.CommandProc, doc: ROPE _ NIL, clientData: REF ANY _ NIL, interpreted: BOOL _ TRUE]™šœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜——K˜Kšžœ˜K˜K™—…—%9