TWOpsImpl.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Christian Le Cocq, August 18, 1987 1:07:14 pm PDT
Sends and retrieves files to a remote Unix host where TimberWolf is installed.
DIRECTORY
BridgeFTPOps USING [StoreFile, RetrieveFile],
BridgeSubmit USING [TransferProc, Register],
FSExtras USING [GetWDir],
IO USING [STREAM],
Rope USING [ROPE, Cat],
SymTab USING [Ref, Create, Fetch, Store, Delete],
TerminalIO USING [PutRope, TOS],
TWOps;
TWOpsImpl: CEDAR MONITOR
IMPORTS BridgeFTPOps, BridgeSubmit, FSExtras, Rope, SymTab, TerminalIO
EXPORTS TWOps
~ BEGIN
ROPE: TYPE ~ Rope.ROPE;
host: ROPE ← "Velantia";
remoteDir: ROPE ← "/usr/guest/";
twCmd: ROPE ← "/usr/guest/timberwolf/TimberWolfSC ";
nInExt: NAT = 4;
inExt: ARRAY [0..nInExt) OF ROPE ← [".cel", ".net", ".blk", ".par"];
nOutExt: NAT = 3;
outExt: ARRAY [0..nOutExt) OF ROPE ← [".out", ".pl1", ".pl2"];
msgStream: IO.STREAM ← TerminalIO.TOS[];
keyTable: SymTab.Ref ← SymTab.Create[];
Key: TYPE = REF KeyRec;
KeyRec: TYPE = RECORD [
msg: ROPE,
locked: BOOLTRUE,
unlocked: CONDITION
];
Store: BridgeSubmit.TransferProc ~ {
PROC [id, wDir: ROPE, s: IO.STREAM] RETURNS [msg: ROPE]
FOR i: NAT IN [0..nInExt) DO
localName : ROPE ← Rope.Cat[wDir, id, inExt[i]];
remoteName: ROPE ← Rope.Cat[remoteDir, id, inExt[i]];
msg ← BridgeFTPOps.StoreFile[s, remoteName, localName, msgStream];
IF msg#NIL THEN { OK[id, msg]; RETURN[msg]};
ENDLOOP;
};
Retrieve: BridgeSubmit.TransferProc ~ {
PROC [id, wDir: ROPE, s: IO.STREAM] RETURNS [msg: ROPE]
FOR i: NAT IN [0..nOutExt) DO
localName : ROPE ← Rope.Cat[wDir, id, outExt[i]];
remoteName: ROPE ← Rope.Cat[remoteDir, id, outExt[i]];
msg ← BridgeFTPOps.RetrieveFile[s, remoteName, localName, msgStream];
IF msg#NIL THEN { OK[id, msg]; RETURN[msg]};
ENDLOOP;
OK[id, NIL];
};
TWIt: PUBLIC PROC [id: ROPE, waitUntilDone: BOOLEANFALSE] RETURNS [msg: ROPE] ~ {
Description of the procedure.
wDir: ROPE ← FSExtras.GetWDir[];
key: Key ← GetKey[id];
cmd: ROPE ← Rope.Cat[twCmd, id];
IF key=NIL THEN RETURN[Rope.Cat["TWOps -> The rope: '", id, "' is already in use"]];
msg ← BridgeSubmit.Register[host, id, cmd, wDir, Store, Retrieve, NIL, NIL, remoteDir];
IF msg=NIL AND waitUntilDone THEN msg ← WaitForOk[key];
};
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["TWOps loaded\n"];
END.