PseudoServerCommandsImpl.mesa
Copyright © 1984, 1985 by Xerox Corporation. All rights reserved.
Russ Atkinson, March 5, 1985 6:06:26 pm PST
DIRECTORY
Commander USING [CommandProc, Register],
CommandTool USING [ArgumentVector, Failed, Parse],
FSPseudoServers USING [GetPseudoServers, PseudoServerList, PseudoServerRep, SetPseudoServers],
IO USING [PutFR, PutRope, STREAM],
Rope USING [Equal, Fetch, Length, ROPE],
UserProfile USING [Token];
PseudoServerCommandsImpl: CEDAR PROGRAM
IMPORTS
Commander, CommandTool, IO, FSPseudoServers, Rope, UserProfile
= BEGIN
LORA: TYPE = LIST OF REF ANY;
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
PseudoServerAddCommand: Commander.CommandProc = {
[cmd: Handle] RETURNS [result: REFNIL, msg: ROPENIL]
CommandObject = [in, out, err: STREAM, commandLine, command: ROPE, ...]
argv: CommandTool.ArgumentVector ← CommandTool.Parse[cmd: cmd
! CommandTool.Failed => {msg ← errorMsg; GO TO failed}];
ProcessSwitches: PROC [arg: ROPE] = {
sense: BOOLTRUE;
direction: {up, down} ← down;
FOR index: INT IN [0..Rope.Length[arg]) DO
SELECT Rope.Fetch[arg, index] FROM
'~ => {sense ← NOT sense; LOOP};
'r, 'R => rec.avoidCheck ← sense;
ENDCASE;
sense ← TRUE;
ENDLOOP;
};
which: {server, writer, reader} ← server;
rec: FSPseudoServers.PseudoServerRep ← [NIL, FALSE, NIL, NIL];
serverList: FSPseudoServers.PseudoServerList ← FSPseudoServers.GetPseudoServers[];
ProcessSwitches[UserProfile.Token["PseudoServerAddCommand.DefaultSwitches"]];
FOR i: NAT IN [1..argv.argc) DO
arg: ROPE = argv[i];
IF Rope.Length[arg] = 0 THEN LOOP;
IF Rope.Fetch[arg, 0] = '- THEN {
switches for the remaining arguments
ProcessSwitches[arg];
LOOP;
};
Now the argument is assumed to be a file pattern.
SELECT which FROM
server => {
rec.server ← arg;
which ← writer;
};
writer => {
rec.write ← arg;
which ← reader;
};
ENDCASE => {
add the new reader to the end of the list
new: LIST OF ROPELIST[arg];
old: LIST OF ROPE ← rec.read;
IF old = NIL
THEN rec.read ← new
ELSE {
DO
IF old.rest = NIL THEN {old.rest ← new; EXIT};
old ← old.rest;
ENDLOOP;
};
};
ENDLOOP;
IF rec.server = NIL THEN {
We insist that there be a server
msg ← "Usage: server writer readers ...";
GO TO failed;
};
FOR each: FSPseudoServers.PseudoServerList ← serverList, each.rest WHILE each # NIL DO
IF Rope.Equal[each.first.server, rec.server, FALSE] THEN {
each.first ← rec;
IF rec.write = NIL AND rec.read = NIL THEN {
We are really deleting this translation
each.first.server ← NIL;
msg ← IO.PutFR["'%g' deleted from pseudo server list.", [rope[rec.server]]];
RETURN;
};
each.first ← rec;
msg ← IO.PutFR["'%g' updated in pseudo server list.", [rope[rec.server]]];
RETURN;
};
ENDLOOP;
The item is completely new, so add it at the front
IF rec.write = NIL AND rec.read = NIL
THEN {
msg ← IO.PutFR["'%g' not in pseudo server list.", [rope[rec.server]]];
}
ELSE {
FSPseudoServers.SetPseudoServers[CONS[rec, serverList]];
msg ← IO.PutFR["'%g' added to pseudo server list.", [rope[rec.server]]];
};
EXITS
failed => {result ← $Failure};
};
PseudoServerPrintCommand: Commander.CommandProc = {
[cmd: Handle] RETURNS [result: REFNIL, msg: ROPENIL]
CommandObject = [in, out, err: STREAM, commandLine, command: ROPE, ...]
serverList: FSPseudoServers.PseudoServerList ← FSPseudoServers.GetPseudoServers[];
out: STREAM = cmd.out;
PutName: PROC [name: ROPE] = {
IO.PutRope[out, " "];
IF Rope.Length[name] = 0
THEN IO.PutRope[out, "$"]
ELSE IO.PutRope[out, name];
};
FOR each: FSPseudoServers.PseudoServerList ← serverList, each.rest WHILE each # NIL DO
IF each.first.server = NIL THEN LOOP;
IO.PutRope[out, " "];
PutName[each.first.server];
IF each.first.avoidCheck THEN PutName[" -r"];
PutName[each.first.write];
FOR readers: LIST OF ROPE ← each.first.read, readers.rest WHILE readers # NIL DO
PutName[readers.first];
ENDLOOP;
IO.PutRope[out, "\n"];
ENDLOOP;
};
docAdd: ROPE = "add pseudo-server translation\n\t-r: assume replicated files (avoid remote check)";
docPrint: ROPE = "print pseudo-server translations";
Commander.Register[key: "///Commands/PSAdd", proc: PseudoServerAddCommand, doc: docAdd];
Commander.Register[key: "///Commands/PseudoServerAdd", proc: PseudoServerAddCommand, doc: docAdd];
Commander.Register[key: "///Commands/PSPrint", proc: PseudoServerPrintCommand, doc: docPrint];
Commander.Register[key: "///Commands/PseudoServerPrint", proc: PseudoServerPrintCommand, doc: docPrint];
END.