DIRECTORY
Commander USING [CommandProc, Handle, Register],
IO,
Names USING [ GetGVDetails, GVDetails, Results, SetGVDetails, WaitForGV ],
Rope USING [ Cat, Equal, Fetch, ROPE ]
;
Action routines
LarkDetails:
PROC[larkName:
ROPE] = {
Calling["DetailsOfLark#", larkName];
DoDetails[FullLark[larkName]];
};
Details:
PROC[rName:
ROPE] = {
Calling["Details", rName];
DoDetails[rName];
};
DoDetails:
PROC[rName:
ROPE] = {
details: GVDetails;
results: Results;
[results, details] ← Names.GetGVDetails[rName, error];
IF results=ok THEN PrintDetails[details];
};
Create:
PROC[rName, password:
ROPE] = {
Does Individual exist already?
details: GVDetails;
results: Results;
Calling["Create", rName, password];
[results, details] ← Names.GetGVDetails[rName, create];
IF results=ok THEN PrintDetails[details];
};
Mode:
PROC[larkNum, newMode:
ROPE] = {
details: GVDetails;
results: Results;
Calling["Mode", larkNum, newMode];
[results, details] ← Names.GetGVDetails[FullLark[larkNum], error];
IF results#ok THEN RETURN;
details.mode ← newMode.Fetch[0];
details.larkSpec ← TRUE;
Names.SetGVDetails[details];
PrintDetails[details];
};
Tune:
PROC[larkNum, newTune:
ROPE] = {
details: GVDetails;
results: Results;
Calling["Tune", larkNum, newTune];
[results, details] ← Names.GetGVDetails[FullLark[larkNum], error];
IF results#ok THEN RETURN;
details.ringTune ← newTune;
details.larkSpec ← TRUE;
Names.SetGVDetails[details];
PrintDetails[details];
};
Instance:
PROC[larkNum, newInstance:
ROPE] = {
details: GVDetails;
results: Results;
Calling["Instance", larkNum, newInstance];
[results, details] ← Names.GetGVDetails[FullLark[larkNum], error];
IF results#ok THEN RETURN;
details.instance ← newInstance.Cat[".lark"];
details.larkSpec ← TRUE;
Names.SetGVDetails[details];
PrintDetails[details];
};
Owner:
PROC[larkNum, newOwner:
ROPE] = {
Calling["Owner", larkNum, newOwner];
DoConnect[FullLark[larkNum], newOwner];
};
Connect:
PROC[rName, newConnect:
ROPE] = {
Calling["Connect", rName, newConnect];
DoConnect[rName, newConnect];
};
DoConnect:
PROC[rName, newConnect:
ROPE] = {
details: GVDetails;
results: Results;
[results, details] ← Names.GetGVDetails[rName, error];
IF results#ok THEN RETURN;
details.connect ← newConnect;
Names.SetGVDetails[details];
PrintDetails[details];
};
Make:
PROC[rName, extension, machine, instance, mode, net, host:
ROPE] = {
larkDetails, rnameDetails, wsDetails: GVDetails;
results: Results;
wsName: ROPE←IF net=NIL THEN NIL ELSE net.Cat["#",host,"#.Lark"];
fullName: ROPE←rName.Cat[".Lark"];
Calling["Make", rName, extension, machine, instance, mode, net, host];
[results, larkDetails] ← Names.GetGVDetails[FullLark[machine], create];
IF results#ok THEN RETURN;
[results, rnameDetails] ← Names.GetGVDetails[fullName, create];
IF results#ok THEN RETURN;
IF wsName#NIL THEN [results, wsDetails] ← Names.GetGVDetails[wsName, create];
IF results#ok THEN RETURN;
larkDetails.instance ← instance.Cat[".Lark"];
larkDetails.mode ← mode.Fetch[0];
larkDetails.connect ← fullName;
larkDetails.larkSpec ← TRUE;
rnameDetails.connect ← Rope.Cat["173#", machine, "#"];
rnameDetails.telephoneExtension ← extension;
rnameDetails.userSpec ← TRUE;
Names.SetGVDetails[larkDetails];
PrintDetails[larkDetails];
Names.SetGVDetails[rnameDetails];
PrintDetails[rnameDetails];
IF wsDetails=NIL THEN RETURN;
wsDetails.connect←rName;
Names.SetGVDetails[wsDetails];
PrintDetails[wsDetails];
};
Command Procs
SemiTok: IO.BreakProc = TRUSTED {RETURN[IF char='; THEN break ELSE other]; };
CommaTok: IO.BreakProc = TRUSTED {RETURN[IF char=', THEN break ELSE other]; };
DetailsCommand: Commander.CommandProc =
TRUSTED {
StartTok[cmd];
Details[Token[]]; };
LarkCommand: Commander.CommandProc =
TRUSTED {
StartTok[cmd];
LarkDetails[Token[]]; };
MakeCommand: Commander.CommandProc =
TRUSTED {
rName, extension, machine, instance, mode, net, host: ROPE;
StartTok[cmd];
rName←Token[];
extension←Token[];
machine←Token[];
instance←Token[];
mode ← Token[];
net←Token[];
IF net.Equal["none"] THEN net←NIL ELSE host←Token[];
Make[rName, extension, machine, instance, mode, net, host]; };
CreateCommand: Commander.CommandProc =
TRUSTED {
a1, a2: ROPE;
StartTok[cmd];
a1←Token[];
a2←Token[];
[]𡤌reate[a1, a2]; };
InstanceCommand: Commander.CommandProc =
TRUSTED {
a1, a2: ROPE;
StartTok[cmd];
a1←Token[];
a2←Token[];
Instance[a1, a2]; };
OwnerCommand: Commander.CommandProc =
TRUSTED {
a1, a2: ROPE;
StartTok[cmd];
a1←Token[];
a2←Token[];
Owner[a1, a2]; };
ConnectCommand: Commander.CommandProc =
TRUSTED {
a1, a2: ROPE;
StartTok[cmd];
a1←Token[];
a2←Token[];
Connect[a1, a2]; };
ModeCommand: Commander.CommandProc =
TRUSTED {
a1, a2: ROPE;
StartTok[cmd];
a1←Token[];
a2←Token[];
Mode[a1, a2]; };
TuneCommand: Commander.CommandProc =
TRUSTED {
a1, a2: ROPE;
StartTok[cmd];
a1←Token[];
a2←Token[];
Tune[a1, a2]; };
WaitCommand: Commander.CommandProc =
TRUSTED {
Names.WaitForGV[]; };
Utilities
StartTok:
PROC[cmd: Commander.Handle] = {
cmdStream ← IO.RIS[cmd.commandLine];
out ← cmd.out;
};
Token: PROC RETURNS [r: ROPE ← NIL] = { r ← cmdStream.GetTokenRope[breakProc: IO.IDProc ! IO.EndOfStream => CONTINUE;].token; };
PrintDetails:
PROC[details: GVDetails] = {
out.PutF["%s: %s, %s\n",
rope[details.rName], rope[details.connect], rope[details.forward]];
};
FullLark:
PROC[larkName:
ROPE]
RETURNS [fullName:
ROPE] = {
RETURN[Rope.Cat["173#", larkName, "#.lark"]];
};
Calling:
PROC[funcName, a, b, c, d, e, f, g:
ROPE←
NIL] = {
res: ROPE𡤏uncName.Cat["[", a];
IF b#NIL THEN res←res.Cat[", ", b];
IF c#NIL THEN res←res.Cat[", ", c];
IF d#NIL THEN res←res.Cat[", ", d];
IF e#NIL THEN res←res.Cat[", ", e];
IF f#NIL THEN res←res.Cat[", ", f];
IF g#NIL THEN res←res.Cat[", ", g];
res←res.Cat["]\n "];
out.PutRope[res];
};
cmdStream: IO.STREAM;
Commander.Register["GVDetails", DetailsCommand, "Print RName details\nPrints connect and forwarding fields of fully-specified RName"];
Commander.Register["GVLark", LarkCommand, "Print details for Lark\nPrints connect and forwarding fields, given string for octal representation of a Lark's host ID; network 173B assumed."];
Commander.Register["GVMake", MakeCommand, "Update data base for Lark and user\nGVMake Swinehart.pa 4473 104 Morley O 3 333 sets Swinehart.pa.lark and 173#104#.lark and 3#333#.lark (creating if necessary) to contain all necessary fields for Lark operation. Use none for 3 333 to avoid associating a workstation with the Lark."];
Commander.Register["GVCreate", CreateCommand, "Create RName\nGVCreate Swinehart.pa.lark mflflx creates the specified rName with the specified password"];
Commander.Register["GVInstance", InstanceCommand, "Set instance field\nGVInstance 100 Morley makes Morley.Lark the instance for the type LarkSmarts.Lark for Lark numbered 173#100#. If there's no forwarding field, also sets defaults for the development mode and the program to run."];
Commander.Register["GVOwner", OwnerCommand, "Set Lark connect field\nGVOwner 100 Swinehart.pa.lark sets the connect field of RName 173#100#.lark to Swinehart.pa.lark."];
Commander.Register["GVConnect", ConnectCommand, "Set Connect field\nGVConnect Swinehart.pa.lark 173#100# sets the connect field of RName Swinehart.pa.lark to 173#100#."];
Commander.Register["GVMode", ModeCommand, "Set Operational Mode\nGVMode 100 O sets the mode field of RName 173#100#.lark to O."];
Commander.Register["GVWait", WaitCommand, "Wait for all Grapevine operations to terminate."];
Commander.Register["GVTune", TuneCommand, "Set ringing tune to the PlayTune on command line. Tune should be in double quotes\n GVTune 101 \"cdefgab>c\" sets the ringing tune of RName 173#101#.lark to a C major scale."];
}.
Edited on August 30, 1983 9:16 am, by Swinehart
Upgrade for use by real world; Cedar, use Commander, and use Names update functions; no need to make it a monitor, since Names implementation provides all needed protection.
changes to: DIRECTORY, GVLarkImpl, Results, DetailsCommand, LarkCommand, MakeCommand, CreateCommand, InstanceCommand, OwnerCommand, ConnectCommand, ModeCommand, StartTok