BridgeSubmitImpl:
CEDAR
PROGRAM
IMPORTS Ascii, BridgeExec, BridgeDriver, CedarProcess, Rope, SymTab, UserCredentials
EXPORTS BridgeSubmit
~ BEGIN
TransferProc: TYPE = BridgeSubmit.TransferProc;
ROPE: TYPE = Rope.ROPE;
magicString: ROPE ← "RBatch\n";
registationTable: SymTab.Ref ← SymTab.Create[];
Registration:
TYPE =
REF RegistrationRec;
RegistrationRec:
TYPE =
RECORD [
session: BridgeExec.Session,
s: IO.STREAM,
id: ROPE,
cmd: ROPE,
wDir: ROPE,
phase1,
phase2: TransferProc,
curPh: Phase
];
Phase: TYPE = {ph1, ph2, finished};
cmdName: ROPE ← "RFTP"; -- temporary until the Vax side is fixed
phasePrompt: ARRAY Phase OF ROPE ← ["-h ", "-H ", "ERR"];
cmdPhase1: ROPE ← Rope.Cat[cmdName, " ", phasePrompt[ph1]];
cmdPhase2: ROPE ← Rope.Cat[cmdName, " ", phasePrompt[ph2]];
retrieveCmd: ROPE ← Rope.Concat[" ;", cmdPhase2];
Register:
PUBLIC
PROC [id, cmd, wDir:
ROPE, phase1, phase2: TransferProc]
RETURNS [msg:
ROPE] ~ {
reg: Registration ←
NEW[RegistrationRec ← [
id: id,
cmd: cmd,
wDir: wDir,
phase1: phase1,
phase2: phase2,
curPh: ph1
]];
[] ← SymTab.Store[registationTable, id, reg];
msg ← ExecuteUnixShell[Rope.Cat[cmdPhase1, id]];
};
Create: BridgeExec.CreateProc ~ {
PROC [s: NetworkStream, args: ROPE, session: Session, clientData: REF] RETURNS [Instance]
found: BOOLEAN;
val: SymTab.Val;
reg: Registration;
id: ROPE ← Rope.Substr[base: args, start: 3]; --bad dependance in RFTP -h
[found, val] ← SymTab.Fetch[registationTable, id];
IF ~found THEN RETURN[NIL];
reg ← NARROW[val];
IF ~Rope.Equal[Rope.Substr[base: args, len: 2], Rope.Substr[base: phasePrompt[reg.curPh], len: 2]] THEN ERROR;
reg.s ← s;
reg.session ← session;
[] ← CedarProcess.Fork[DoTransfer, reg];
RETURN [reg.id] --reg.id is Rope.Equal to id but not =
};
Destroy: BridgeExec.DestroyProc ~ {
PROC [instance: Instance, clientData: REF]
found: BOOLEAN;
val: SymTab.Val;
reg: Registration;
id: ROPE ← NARROW[instance];
[found, val] ← SymTab.Fetch[registationTable, id];
IF ~found THEN RETURN;
reg ← NARROW[val];
IF reg.curPh=finished THEN [] ← SymTab.Delete[registationTable, id];
};
DoTransfer: CedarProcess.ForkableProc ~ {
PROC [data: REF] RETURNS [results: REF ← NIL]
reg: Registration ← NARROW[data];
SELECT reg.curPh
FROM
ph1 => {
msg: ROPE ← reg.phase1[reg.id, reg.wDir, reg.s];
IF msg=NIL THEN [] ← ExecuteUnixShell[Rope.Cat[reg.cmd, retrieveCmd, reg.id]];
reg.curPh ← ph2;
};
ph2 => {
[] ← reg.phase2[reg.id, reg.wDir, reg.s];
reg.curPh ← finished;
};
ENDCASE => ERROR;
kill the instance
BridgeExec.DestroyInstance[reg.session, reg.id, NIL];
};
ExecuteUnixShell:
PUBLIC
PROC [unixCmd:
ROPE]
RETURNS [errmsg:
ROPE] ~ {
completeCmd, name, password: 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];
completeCmd ← Rope.Cat[magicString, unixCmd];
errmsg ← BridgeDriver.StartSession["vaxc", name, password, completeCmd];
};
MyLower: Rope.TranslatorType ~ {
RETURN[Ascii.Lower[old]]};
BridgeExec.Register[cmdName, Create, NIL, Destroy];
END.