GVLarkImpl.mesa
Last modified by D. Swinehart, July 18, 1986 1:16:59 pm PDT
Last Edited by: Pier, May 10, 1984 1:08:21 pm PDT
DIRECTORY
BasicTime USING [ Now, ToNSTime, Update],
Commander USING [CommandProc, Handle, Register],
Convert USING [ IntFromRope, RopeFromCard ],
IO,
VoiceUtils USING [ MakeAtom, MakeRName ],
NamesGV USING [ AttributeSeq, AttributeSeqRec, GVGetAttribute, GVGetAttributes, GVGetAttributeSeq, GVIsAuthenticated, GVSetAttribute, GVSetAttributeSeq, --GVUpdate, -- GVFlushCache, GVSaveCache, GVRestoreCache, GVUpdateAll ],
Rope USING [ Cat, Equal, Length, ROPE, Substr ],
UserProfile USING [ Token ]
;
GVLarkImpl: CEDAR PROGRAM
IMPORTS
BasicTime,
Commander,
Convert,
IO,
VoiceUtils,
NamesGV,
Rope,
UserProfile = {
OPEN IO;
Copies
ROPE: TYPE = Rope.ROPE;
Action routines
We don't do updates automatically these days. To really affect Grapevine requires issuing the GVUpdate command (registered by NamesAndLog.bcd) manually. It will write all dirty entries, so use the flush operation judiciously.
UpdateAll: PROC[] = {
Calling["UpdateAll"];
NamesGV.GVUpdateAll[];
};
FlushAll: PROC[] = {
Calling["FlushAll"];
NamesGV.GVFlushCache[];
};
SaveAll: PROC[] = {
Calling["FlushAll"];
NamesGV.GVSaveCache[];
};
RestoreAll: PROC[] = {
Calling["FlushAll"];
NamesGV.GVRestoreCache[];
};
LarkDetails: PROC[larkName: ROPE] = {
Calling["DetailsOfLark#", larkName];
DoDetails[FullLark[larkName]];
};
Details: PROC[rName: ROPE] = {
rName ← VoiceUtils.MakeRName[rName, rName];
Calling["Details", rName];
DoDetails[rName];
};
DoDetails: PROC[rName: ROPE] = {
SELECT NamesGV.GVIsAuthenticated[rName] FROM
unknown, nonexistent => out.PutF["Couldn't find %s\n", rope[rName]];
ENDCASE => PrintDetails[rName];
};
Mode: PROC[larkNum, newMode: ROPE, update: BOOLTRUE, print: BOOLTRUE] = {
rName: ROPE𡤏ullLark[larkNum];
IF print THEN Calling["Mode", larkNum, newMode];
NamesGV.GVSetAttribute[rName, $mode, newMode];
IF update THEN NamesGV.GVUpdate[rName];
IF print THEN PrintDetails[rName];
};
Owner: PROC[larkNum, newOwner: ROPE, update: BOOLTRUE, print: BOOLTRUE] = {
rName: ROPE𡤏ullLark[larkNum];
newOwner ← VoiceUtils.MakeRName[newOwner, rNameDotLark];
IF print THEN Calling["Owner", larkNum, newOwner];
NamesGV.GVSetAttribute[rName, $owner, newOwner];
IF update THEN NamesGV.GVUpdate[rName];
IF print THEN PrintDetails[rName];
};
Configure: PROC[larkNum, instance, mode: ROPE, update: BOOLTRUE] = {
rName: ROPE𡤏ullLark[larkNum];
Calling["Configure", larkNum, instance, mode];
Instance[larkNum, instance, update, FALSE];
Mode[larkNum, mode, update, FALSE];
IF NamesGV.GVGetAttribute[rName, $owner, NIL] = NIL THEN
-- For LarkTest when testing virgin Lark
Owner[larkNum, instance, update, FALSE];
PrintDetails[rName];
};
Instance: PROC[larkNum, newInstance: ROPE, update: BOOLTRUE, print: BOOLTRUE] = {
aSeq: NamesGV.AttributeSeq;
rName: ROPE ← FullLark[larkNum];
newInstance ← VoiceUtils.MakeRName[newInstance, rName];
IF print THEN Calling["Instance", larkNum, newInstance];
aSeq ← NamesGV.GVGetAttributeSeq[rName, $interface];
IF aSeq=NIL THEN aSeq ← NEW[NamesGV.AttributeSeqRec[4]];
aSeq.length𡤄
IF aSeq[0].attributeValue=NIL THEN aSeq[0] ← [,"LarkSmarts.Lark"];
aSeq[1] ← [,newInstance];
IF aSeq[2].attributeValue=NIL THEN aSeq[2] ← [,"1"];
IF aSeq[3].attributeValue=NIL THEN aSeq[3] ← [,"0"];
NamesGV.GVSetAttributeSeq[rName, $interface, aSeq];
IF update THEN NamesGV.GVUpdate[rName];
IF print THEN PrintDetails[rName];
};
SetAttribute: PROC[rName, attributeName, attributeValue: ROPE] = {
attribute: ATOM ← VoiceUtils.MakeAtom[attributeName, FALSE];
rName ← VoiceUtils.MakeRName[rName, nameDotLark];
Calling["SetAttribute", rName, attributeName, attributeValue];
NamesGV.GVSetAttribute[rName, attribute, attributeValue];
NamesGV.GVUpdate[rName];
PrintDetails[rName];
};
SetAttributeTimed: PROC[rName, interval, attributeName, attributeValue: ROPE] = {
attribute: ATOM ← VoiceUtils.MakeAtom[attributeName, FALSE];
as: NamesGV.AttributeSeq ← NEW[NamesGV.AttributeSeqRec[2]];
as.length𡤂
as[1] ← [$unspec, attributeValue];
as[0] ← [$timed, Convert.RopeFromCard[
BasicTime.ToNSTime[BasicTime.Update[BasicTime.Now[], Convert.IntFromRope[interval]]]]];
rName ← VoiceUtils.MakeRName[rName, nameDotLark];
Calling["SetAttribute (timed)", rName, interval, attributeName, attributeValue];
NamesGV.GVSetAttributeSeq[rName, attribute, as];
NamesGV.GVUpdate[rName];
PrintDetails[rName];
};
SetProgram: PROC[larkNum, program: ROPE, update: BOOLTRUE] = {
rName: ROPE ← FullLark[larkNum];
Calling["SetProram", larkNum, program];
NamesGV.GVSetAttribute[rName, $program, program];
IF update THEN NamesGV.GVUpdate[rName];
PrintDetails[rName];
};
SetTune: PROC[rName, doTune, tune: ROPE] = {
len: INT ← tune.Length[];
rName ← VoiceUtils.MakeRName[rName, rNameDotLark];
Calling["Tune", rName, doTune, tune];
NamesGV.GVSetAttribute[rName, $dotune, doTune];
NamesGV.GVSetAttribute[rName, $ringtune, tune];
NamesGV.GVUpdate[rName];
PrintDetails[rName];
};
Make: PROC[rName, extension, machine, instance, mode, net, host, program: ROPE] = {
wsName: ROPEIF net=NIL THEN NIL ELSE net.Cat["#",host,"#"];
wsRName: ROPE;
fullUserName: ROPE←VoiceUtils.MakeRName[rName, rNameDotLark];
larkName: ROPE ← FullLark[machine];
Calling["Make", rName, extension, machine, instance, mode, net, host];
Instance[machine, instance, FALSE];
Mode[machine, mode, FALSE];
NamesGV.GVSetAttribute[larkName, $owner, fullUserName];
IF program#NIL THEN NamesGV.GVSetAttribute[larkName, $program, program];
PrintDetails[larkName];
NamesGV.GVSetAttribute[fullUserName, $larkhost, Rope.Cat["173#", machine, "#"]];
NamesGV.GVSetAttribute[fullUserName, $extension, extension];
PrintDetails[fullUserName];
IF wsName#NIL THEN {
wsRName ← VoiceUtils.MakeRName[wsName, nameDotLark];
NamesGV.GVSetAttribute[wsRName, $owner, rName];
};
NamesGV.GVSetAttribute[fullUserName, $workstationhost, wsName];
IF wsName#NIL THEN PrintDetails[wsRName];
};
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[]]; };
UpdateAllCommand: Commander.CommandProc = TRUSTED { UpdateAll[]; };
FlushAllCommand: Commander.CommandProc = TRUSTED { FlushAll[]; };
SaveCommand: Commander.CommandProc = TRUSTED { SaveAll[]; };
RestoreCommand: Commander.CommandProc = TRUSTED { RestoreAll[]; };
LarkCommand: Commander.CommandProc = TRUSTED {
StartTok[cmd];
LarkDetails[Token[]]; };
MakeCommand: Commander.CommandProc = TRUSTED {
rName, extension, machine, instance, mode, net, host, program: 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[];
program ← Token[];
Make[rName, extension, machine, instance, mode, net, host, program]; };
InstanceCommand: Commander.CommandProc = TRUSTED {
a1, a2: ROPE;
StartTok[cmd];
a1←Token[];
a2←Token[];
Instance[a1, a2];
};
DoProgramCommand: Commander.CommandProc = TRUSTED {
a1, a2: ROPE;
StartTok[cmd];
a1←Token[];
a2←Token[];
SetProgram[a1, a2];
};
ModeCommand: Commander.CommandProc = TRUSTED {
a1, a2: ROPE;
StartTok[cmd];
a1←Token[];
a2←Token[];
Mode[a1, a2]; };
OwnerCommand: Commander.CommandProc = TRUSTED {
a1, a2: ROPE;
StartTok[cmd];
a1←Token[];
a2←Token[];
Owner[a1, a2]; };
OperateCommand: Commander.CommandProc = TRUSTED {
a1, a2: ROPE;
StartTok[cmd];
a1←Token[];
a2←Token[UserProfile.Token[key: "ThrushClientServerInstance", default: "Strowger.lark"]];
Configure[a1, a2, "O"];
};
DebugCommand: Commander.CommandProc = TRUSTED {
a1, a2: ROPE;
StartTok[cmd];
a1←Token[];
a2←Token[UserProfile.Token[key: "LarktestInstance", default: "Einstein.lark"]];
Configure[a1, a2, "D"];
};
AttributeCommand: Commander.CommandProc = TRUSTED {
a1, a2, a3: ROPE;
StartTok[cmd];
a1←Token[];
a2←Token[];
a3𡤌mdStream.GetLineRope[];
IF a3#NIL AND a3.Length[]#0 THEN a3�.Substr[start: 1] ELSE a3←NIL;
SetAttribute[a1, a2, a3]; };
TimedAttributeCommand: Commander.CommandProc = TRUSTED {
a1, a2, a3, a4: ROPE;
StartTok[cmd];
a1←Token[];
a2←Token[];
a3←Token[];
a4𡤌mdStream.GetLineRope[];
IF a4#NIL AND a4.Length[]#0 THEN a4�.Substr[start: 1] ELSE a4←NIL;
SetAttributeTimed[a1, a2, a3, a4];
};
TuneCommand: Commander.CommandProc = TRUSTED {
a1, a2, a3: ROPE;
StartTok[cmd];
a1←Token[];
a2←Token[];
a3𡤌mdStream.GetLineRope[];
IF a3#NIL AND a3.Length[]#0 THEN a3�.Substr[start: 1] ELSE a3←NIL;
SetTune[a1, a2, a3];
};
DoTuneCommand: Commander.CommandProc = TRUSTED {
a1, a2: ROPE;
StartTok[cmd];
a1←Token[];
a2←Token[];
SetAttribute[a1.Cat[".lark"], "dotune", a2]; };
Utilities
StartTok: PROC[cmd: Commander.Handle] = {
cmdStream ← IO.RIS[cmd.commandLine];
out ← cmd.out;
};
Token: PROC[default: ROPENIL] RETURNS [r: ROPENIL] = { r ← cmdStream.GetTokenRope[breakProc: IO.IDProc ! IO.EndOfStream => {
r�ult; CONTINUE;}
].token; };
PrintDetails: PROC[rName: ROPE] = {
attributeSeq: NamesGV.AttributeSeq ← NamesGV.GVGetAttributes[rName];
authenticity: ROPESELECT NamesGV.GVIsAuthenticated[rName] FROM
$authentic => " (authentic)",
$bogus => " (bogus)",
$perhaps => "",
ENDCASE => " (??)";
out.PutF["rName: %s%s\n", rope[rName], rope[authenticity]];
IF attributeSeq#NIL THEN FOR i: INT IN [0..attributeSeq.length) DO
out.PutF[" %s: %s\n",
atom[attributeSeq[i].attributeName],
rope[attributeSeq[i].attributeValue] ];
ENDLOOP;
out.PutChar['\n];
};
FullLark: PROC[larkName: ROPE] RETURNS [fullName: ROPE] = {
RETURN[Rope.Cat["173#", larkName, "#.lark"]];
};
Calling: PROC[funcName, a, b, c, d, e, f, g: ROPENIL] = {
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];
};
Initialization
cmdStream: IO.STREAM;
out: IO.STREAM;
Commander.Register["GVDetails", DetailsCommand, "Print RName details\nPrints attribute fields of fully-specified RName"];
Commander.Register["GVLark", LarkCommand, "Print details for Lark\nPrints attribute 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 attribute fields for Lark operation. Use none for 3 333 to avoid associating a workstation with the Lark."];
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#."];
Commander.Register["GVMode", ModeCommand, "Set Operational Mode\nGVMode 100 O sets the mode field of RName 173#100#.lark to O."];
Commander.Register["GVOwner", OwnerCommand, "Set Lark Owner\nGVOwner 100 fiddle.pa.lark sets the owner field of RName 173#100#.lark to fiddle.pa.lark."];
Commander.Register["GVOperate", OperateCommand, "Make Lark Operational\nGVOperate 155 [Strowger.lark] does GVInstance and GVMode to make lark 155 available as an Etherphone. Leaving out the last argument defaults to the user profile entry ThrushClientServerInstance"];
Commander.Register["GVDebug", DebugCommand, "Configure Lark for debugging\nGVDebug 155 [Strowger.lark] does GVInstance and GVMode to put Lark 155 in debug mode tuned to a debug server. Leaving out the last argument defaults to the user profile entry LarkTestInstance"];
Commander.Register["GVAttribute", AttributeCommand, "Set attribute field\nGVAttribute 173#104#.lark interface LarkSmarts.Lark, Strowger.Lark, 1, 0\n sets the interface attribute of the specified RName as specified."];
Commander.Register["GVTimed", TimedAttributeCommand, "Set attribute field temporarily\nGVTimed SoAndSo.pa.lark 40 interface LarkSmarts.Lark, Strowger.Lark, 1, 0\n changes the interface attribute of the specified RName as specified, for the next 40 seconds."];
Commander.Register["GVSave", SaveCommand, "Make GV cache entries permanent"];
Commander.Register["GVRestore", RestoreCommand, "Obtain most-recently saved cache (saved on server file system!)"];
Commander.Register["GVUpdateAll", UpdateAllCommand, "Write all dirty cache entries\nWhen you issue a change request, it is stored in the cache but not written to GV until you issue this command."];
Commander.Register["GVFlushAll", FlushAllCommand, "Forget all cached Rnames. This will cancel any changes that have been made since the last GVFlushAll or GVUpdateAll."];
Commander.Register["GVTune", TuneCommand, "GVTune Swinehart.pa TRUE TuneString (rest of line!) sets the tune to be used, and does 'GVDoTune TRUE'."];
Commander.Register["GVDoTune", DoTuneCommand, "GVDoTune Swinehart.pa TRUE indicates that ring tune replaces standard ringing; false reverts."];
Commander.Register["GVProgram", DoProgramCommand, "Set program field\nGVProgram 100 LarkA makes LarkA.obj the program for Lark numbered 173#100#."];
}.