<> <> <> <> <> <> <<[cyan]EcadOps>EcadOps.mesa>> <<[cyan]EcadOps>EcadOpsImpl.mesa>> <<[Cyan]SpiceOps>SpiceCDCmds.mesa>> <<>> DIRECTORY Ascii, BridgeFTPOps USING [StoreFile, RetrieveFile], BridgeSubmit USING [TransferProc, Register], BridgeDriver, CedarProcess, Commander, RemoteAlgebra, FS, FSExtras, FSBackdoor, IO, Rope, SymTab USING [Ref, Create, Fetch, Store, Delete], TerminalIO, UserCredentials, TiogaMenuOps, ThisMachine; RemoteAlgebraImpl: CEDAR MONITOR <> IMPORTS Ascii, BridgeDriver, CedarProcess, FS, FSExtras, FSBackdoor, IO, Rope, UserCredentials, ThisMachine, BridgeFTPOps, BridgeSubmit, SymTab, TerminalIO EXPORTS RemoteAlgebra ~ BEGIN ROPE: TYPE = Rope.ROPE; waitingProcess: CedarProcess.Process; stop: BOOL _ FALSE; criterion: ROPE _ "*.SUM!*"; globalOutputStream: IO.STREAM; lock: BOOLEAN _ FALSE; <> AlgebraCmd: Commander.CommandProc ~ { <> <> fileName: ROPE _ NIL; ropeStream: IO.STREAM _ IO.RIS[cmd.commandLine]; IF lock THEN { msg _ "\nWait for the previous Remote Algebra to finish !\nJob not sent.\n"; RETURN; }; lock _ TRUE; fileName _ FSExpandFromStream[ropeStream]; <> < CONTINUE].token;>> msg _ ExecuteRemoteAlgebra[fileName]; IF msg#NIL THEN lock _ FALSE; -- n.b. releases the lock if error from BridgeDriver.StartSession }; ExecuteRemoteAlgebra: PUBLIC PROC [fileName: ROPE] RETURNS [errmsg: ROPE] ~ { <> magicString: ROPE _ "RBatch\ncd /user/csl/arnon; csh .login; cd /user/csl/arnon/Sturgis; /user/csl/arnon/Sturgis/algebra "; name, password, machine, algebraCmd: ROPE; [name, password] _ UserCredentials.Get[]; name _ Rope.Substr[name, 0, Rope.Index[name, 0, "."]]; -- get rid of the ".pa" name _ Rope.Translate[base: name, translator: MyLower]; machine _ Rope.Cat[ThisMachine.Name[], " "]; <> <> <> algebraCmd _ Rope.Cat[magicString, machine, PrepareFFName[fileName] ]; errmsg _ BridgeDriver.StartSession["vaxc", name, password, algebraCmd]; }; <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<[name, password] _ UserCredentials.Get[];>> <> <> <> <> <> <> <> <> <> <> <> <<};>> <> <> <<};>> <<>> MyLower: Rope.TranslatorType ~ {RETURN[Ascii.Lower[old]]}; StartWatching: PUBLIC PROC ~ { IF waitingProcess=NIL OR CedarProcess.GetStatus[waitingProcess]#busy THEN waitingProcess _ CedarProcess.Fork[WaitForListings, criterion]; }; <> FSExpandFromStream: PROC [s: IO.STREAM] RETURNS [fullFName: ROPE] ~ { fName: ROPE; index: INT; fName _ IO.GetTokenRope[s, IO.IDProc ! IO.EndOfStream => CONTINUE].token; index _ Rope.Find[fName, ".inData", 0, FALSE]; IF index#-1 THEN fName _ Rope.Substr[fName, 0, index]; -- toss ".inData" if present fullFName _ FS.ExpandName[fName].fullFName; }; StripExtension: PROC [inName: ROPE, extension: ROPE] RETURNS [fName: ROPE] ~ { index: INT; index _ Rope.Find[inName, extension, 0, FALSE]; IF index#-1 THEN fName _ Rope.Substr[inName, 0, index]; -- toss extension if present <> }; PrepareFFName: PROC [fullFName: ROPE] RETURNS [arg: ROPE] ~ { arg _ Rope.Cat["\"", fullFName, "\" "]; }; WaitForListings: CedarProcess.ForkableProc ~ { <> matchCriterion: ROPE _ NARROW[data]; event: REF READONLY FSBackdoor.CreateEvent _ NIL; UNTIL stop DO event _ FSBackdoor.NextCreateEvent[event]; <> <> <> <<};>> IF Rope.Match[pattern: matchCriterion, object: event.fName, case: FALSE] THEN { globalOutputStream _ FS.StreamOpen[event.fName, $read]; lock _ FALSE; }; ENDLOOP; }; <> msgStream: IO.STREAM _ TerminalIO.TOS[]; keyTable: SymTab.Ref _ SymTab.Create[]; Key: TYPE = REF KeyRec; KeyRec: TYPE = RECORD [ msg: ROPE, locked: BOOL _ TRUE, unlocked: CONDITION ]; Waiting: PUBLIC ERROR = CODE; SAC2PolynomialBinaryOp: PUBLIC PROC [varSeq, firstArg, secondArg: ROPE] RETURNS [result: IO.STREAM] ~ { errmsg: ROPE; intialScript: ROPE _ RopeFromFile["SACScript"]; fileName: ROPE _ "SACIn"; outputFileName: ROPE; out: IO.STREAM _ FS.StreamOpen[fileName: fileName, accessOptions: $create, wDir: FSExtras.GetWDir[] ]; -- also could use CommandTool.FileNames interface; in any event, FSExtras.GetWDir seems to just be returning /// as WD, i.e. trivial effect. Probably result of call not coming from a Commander.CommandProc finalScript: ROPE _ intialScript; position: INT _ -1; position _ Rope.Find[finalScript, "#v"]; finalScript _ Rope.Replace[base: finalScript, start: position, len: Rope.Length["#v"], with: varSeq]; position _ Rope.Find[finalScript, "#1"]; finalScript _ Rope.Replace[base: finalScript, start: position, len: Rope.Length["#1"], with: firstArg]; position _ Rope.Find[finalScript, "#2"]; finalScript _ Rope.Replace[base: finalScript, start: position, len: Rope.Length["#2"], with: secondArg]; out.PutRope[finalScript]; out.Close[]; [outputFileName, errmsg] _ DoRemoteAlgebra["SAC"]; IF errmsg#NIL THEN ERROR Waiting; globalOutputStream _ FS.StreamOpen[outputFileName, $read]; RETURN[globalOutputStream]; }; Store: BridgeSubmit.TransferProc ~ { <> localName : ROPE _ Rope.Cat[wDir, id, "In"]; remoteDir: ROPE _ RopeFromFile[Rope.Cat[id, "Directory"] ]; remoteName: ROPE _ Rope.Cat[remoteDir, id, "In"]; msg _ BridgeFTPOps.StoreFile[s, remoteName, localName, msgStream]; IF msg#NIL THEN { OK[id, msg]; RETURN[msg]}; }; <<>> Retrieve: BridgeSubmit.TransferProc ~ { <> localName : ROPE _ Rope.Cat[wDir, id, "Out"]; remoteDir: ROPE _ RopeFromFile[Rope.Cat[id, "Directory"] ]; remoteName: ROPE _ Rope.Cat[remoteDir, id, "Out"]; msg _ BridgeFTPOps.RetrieveFile[s, remoteName, localName, msgStream]; IF msg#NIL THEN { OK[id, msg]; RETURN[msg]}; OK[id, NIL]; }; RopeFromFile: PROC [filename: ROPE] RETURNS [ROPE] ~ { stream: IO.STREAM _ FS.StreamOpen[filename, $read]; rope: ROPE _ ""; c: CHAR _ stream.GetChar[]; -- toss first newline WHILE NOT stream.EndOf[] DO c _ stream.GetChar[]; IF ~stream.EndOf[] THEN rope _ rope.Cat[Rope.FromChar[c] ]; ENDLOOP; -- toss last newline RETURN[rope]; }; host: ROPE _ "parcvax:parc:xerox"; DoRemoteAlgebra: PUBLIC PROC [id: ROPE, waitUntilDone: BOOLEAN _ TRUE] RETURNS [outputFileName: ROPE, msg: ROPE] ~ { <> line: ROPE _ RopeFromFile[Rope.Cat[id, "Line"] ]; wDir: ROPE _ FSExtras.GetWDir[]; key: Key _ GetKey[id]; outputFileName _ Rope.Cat[wDir, id, "Out"]; IF key=NIL THEN RETURN[outputFileName, Rope.Cat["Remotealgebra -> The rope: '", id, "' is already in use"]]; msg _ BridgeSubmit.Register[host, id, line, wDir, Store, Retrieve, "~", NIL, NIL]; IF msg=NIL AND waitUntilDone THEN msg _ WaitForOk[key]; RETURN[outputFileName, msg]; }; GetKey: PROC [id: ROPE] RETURNS[key: Key] ~ { IF SymTab.Fetch[keyTable, id].found THEN RETURN [NIL]; key _ NEW[KeyRec]; [] _ SymTab.Store[keyTable, id, key]; }; WaitForOk: ENTRY PROC [key: Key] RETURNS [msg: ROPE] ~ { ENABLE UNWIND => NULL; WHILE key.locked DO WAIT key.unlocked ENDLOOP; RETURN [key.msg]; }; OK: PROC [id, msg: ROPE] ~ { key: Key _ NARROW[SymTab.Fetch[keyTable, id].val]; IF key=NIL THEN RETURN; [] _ SymTab.Delete[keyTable, id]; key.msg _ msg; Unlock[key]; }; Unlock: ENTRY PROC [key: Key] ~ { ENABLE UNWIND => NULL; key.locked _ FALSE; BROADCAST key.unlocked; }; <> <> <> <> <<>> TerminalIO.PutRope["Begin TerminalIO\n"]; <<>> END.