<> <> <> 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; <> ROPE: TYPE = Rope.ROPE; <> <<>> <> 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: BOOL_TRUE, print: BOOL_TRUE] = { rName: ROPE_FullLark[larkNum]; IF print THEN Calling["Mode", larkNum, newMode]; NamesGV.GVSetAttribute[rName, $mode, newMode]; <> IF print THEN PrintDetails[rName]; }; Owner: PROC[larkNum, newOwner: ROPE, update: BOOL_TRUE, print: BOOL_TRUE] = { rName: ROPE_FullLark[larkNum]; newOwner _ VoiceUtils.MakeRName[newOwner, rNameDotLark]; IF print THEN Calling["Owner", larkNum, newOwner]; NamesGV.GVSetAttribute[rName, $owner, newOwner]; <> IF print THEN PrintDetails[rName]; }; Configure: PROC[larkNum, instance, mode: ROPE, update: BOOL_TRUE] = { rName: ROPE_FullLark[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: BOOL_TRUE, print: BOOL_TRUE] = { 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_4; 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 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]; <> PrintDetails[rName]; }; SetAttributeTimed: PROC[rName, interval, attributeName, attributeValue: ROPE] = { attribute: ATOM _ VoiceUtils.MakeAtom[attributeName, FALSE]; as: NamesGV.AttributeSeq _ NEW[NamesGV.AttributeSeqRec[2]]; as.length_2; 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]; <> PrintDetails[rName]; }; SetProgram: PROC[larkNum, program: ROPE, update: BOOL_TRUE] = { rName: ROPE _ FullLark[larkNum]; Calling["SetProram", larkNum, program]; NamesGV.GVSetAttribute[rName, $program, program]; <> 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]; <> PrintDetails[rName]; }; Make: PROC[rName, extension, machine, instance, mode, net, host, program: ROPE] = { wsName: ROPE_IF 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]; }; <> 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_cmdStream.GetLineRope[]; IF a3#NIL AND a3.Length[]#0 THEN a3_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_cmdStream.GetLineRope[]; IF a4#NIL AND a4.Length[]#0 THEN a4_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_cmdStream.GetLineRope[]; IF a3#NIL AND a3.Length[]#0 THEN a3_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]; }; <> StartTok: PROC[cmd: Commander.Handle] = { cmdStream _ IO.RIS[cmd.commandLine]; out _ cmd.out; }; Token: PROC[default: ROPE_NIL] RETURNS [r: ROPE _ NIL] = { r _ cmdStream.GetTokenRope[breakProc: IO.IDProc ! IO.EndOfStream => { r_default; CONTINUE;} ].token; }; PrintDetails: PROC[rName: ROPE] = { attributeSeq: NamesGV.AttributeSeq _ NamesGV.GVGetAttributes[rName]; authenticity: ROPE _ SELECT 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: ROPE_NIL] = { res: ROPE_funcName.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; 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#."]; }.