DIRECTORY CedarNSPrint, CedarNSPrintRpcControl, CedarNSPrintUtilsRpcControl, Commander USING [CommandProc, Register], CommandTool USING [ArgumentVector, Failed, Parse], IO USING [PutRope, STREAM], Process USING [CheckForAbort], Rope USING [Fetch, Flatten, Length, ROPE], RPC USING [ImportFailed, ShortROPE], UserProfile USING [Token]; AgentStub: CEDAR PROGRAM IMPORTS CedarNSPrint, CedarNSPrintRpcControl, CedarNSPrintUtilsRpcControl, Commander, CommandTool, IO, Process, Rope, RPC, UserProfile = BEGIN ROPE: TYPE = Rope.ROPE; ShortROPE: TYPE = RPC.ShortROPE; STREAM: TYPE = IO.STREAM; Print: PROCEDURE[agent: ShortROPE, printServer: ROPE, master: ROPE, log: STREAM] = { noBind: BOOLEAN _ FALSE; longStringServerName: ROPE; interpressMaster: ROPE; serverNSAddress: CedarNSPrint.SystemElement; chUsed: BOOLEAN; printRequestID: CedarNSPrint.RequestID; CedarNSPrintRpcControl.ImportInterface[[NIL, agent] ! RPC.ImportFailed => { noBind _ TRUE; IO.PutRope[log, "CedarNSPrintRpcControl.ImportInterface from "]; IO.PutRope[log, agent]; IO.PutRope[log, " failed: "]; SELECT why FROM communications => IO.PutRope[log, "communications"]; badInstance => IO.PutRope[log, "badInstance"]; badVersion => IO.PutRope[log, "badVersion"]; wrongVersion => IO.PutRope[log, "wrongVersion"]; unbound => IO.PutRope[log, "unbound"]; stubProtocol => IO.PutRope[log, "stubProtocol"]; ENDCASE => IO.PutRope[log, "??"]; IO.PutRope[log, ".\n"]; CONTINUE; }]; IF noBind THEN RETURN; CedarNSPrintUtilsRpcControl.ImportInterface[[NIL, agent] ! RPC.ImportFailed => { noBind _ TRUE; IO.PutRope[log, "CedarNSPrintUtilsRpcControl.ImportInterface from "]; IO.PutRope[log, agent]; IO.PutRope[log, " failed: "]; SELECT why FROM communications => IO.PutRope[log, "communications"]; badInstance => IO.PutRope[log, "badInstance"]; badVersion => IO.PutRope[log, "badVersion"]; wrongVersion => IO.PutRope[log, "wrongVersion"]; unbound => IO.PutRope[log, "unbound"]; stubProtocol => IO.PutRope[log, "stubProtocol"]; ENDCASE => IO.PutRope[log, "??"]; IO.PutRope[log, ".\n"]; CONTINUE; }]; IF noBind THEN RETURN; longStringServerName _ Rope.Flatten[printServer]; interpressMaster _ Rope.Flatten[master]; IO.PutRope[log, "Trying to contact Clearinghouse: "]; TRUSTED{[serverNSAddress, chUsed] _ CedarNSPrint.AddressTranslationStringToNetworkAddress[name: LOOPHOLE[longStringServerName, LONG STRING]]}; IF chUsed THEN IO.PutRope[log, "went to server.\n"] ELSE IO.PutRope[log, "local cache hit.\n"]; IO.PutRope[log, "Trying to Print:"]; TRUSTED{printRequestID _ CedarNSPrint.Print[master: LOOPHOLE[interpressMaster, LONG STRING], printAttributes: NIL, printOptions: NIL, systemElement: serverNSAddress]}; IO.PutRope[log, " all"]; TRUSTED{CedarNSPrintRpcControl.UnimportInterface[]}; TRUSTED{CedarNSPrintUtilsRpcControl.UnimportInterface[]}; IO.PutRope[log, " done.\n"]; }; IPPrintCommandProc: Commander.CommandProc = { out: STREAM = cmd.out; switches: PACKED ARRAY CHAR['a..'z] OF BOOL _ ALL[FALSE]; agent: ShortROPE _ UserProfile.Token["IPPrint.PrintAgent"]; printServer: ROPE _ UserProfile.Token["IPPrint.PrintServer"]; master: ROPE _ UserProfile.Token["IPPrint.PrintScratch"]; nada: BOOL _ TRUE; ProcessSwitches: PROC [arg: ROPE] = { sense: BOOL _ TRUE; FOR index: INT IN [0..Rope.Length[arg]) DO char: CHAR _ Rope.Fetch[arg, index]; SELECT char FROM '- => LOOP; '~ => {sense _ NOT sense; LOOP}; IN ['a..'z] => switches[char] _ sense; IN ['A..'Z] => switches[char + ('a-'A)] _ sense; ENDCASE; sense _ TRUE; ENDLOOP; }; ProcessArgument: PROC [arg: ROPE] = { argsProcessed _ argsProcessed + 1; Process.CheckForAbort[]; IF switches['a] THEN {switches['a] _ FALSE; agent _ arg; RETURN}; IF switches['s] THEN {switches['s] _ FALSE; printServer _ arg; RETURN}; master _ arg; Print[agent, printServer, master, out]; }; argsProcessed: NAT _ 0; argv: CommandTool.ArgumentVector _ CommandTool.Parse[cmd: cmd, starExpand: FALSE ! CommandTool.Failed => {msg _ errorMsg; GO TO failed}]; ProcessSwitches[UserProfile.Token["IPPrint.DefaultSwitches"]]; FOR i: NAT IN [1..argv.argc) DO arg: ROPE = argv[i]; Process.CheckForAbort[]; IF Rope.Length[arg] = 0 THEN LOOP; IF Rope.Fetch[arg, 0] = '- THEN { ProcessSwitches[arg]; LOOP; }; ProcessArgument[arg]; ENDLOOP; EXITS failed => {result _ $Failure}; }; doc: ROPE = "IPPrint -- print an interpress master.\nUSAGE: IPPrint ...\nSwitches: -a: -s: <8044 Print Server>"; Commander.Register[ key: "///Commands/IPPrint", proc: IPPrintCommandProc, doc: doc, clientData: NIL, interpreted: TRUE ]; END... ~AgentStub.Mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Bill Jackson June 25, 1985 3:37:50 am PDT Bob Hagmann June 24, 1985 4:30:29 pm PDT BJackson, June 24, 1985 6:40:18 pm PDT Be sure that you've got these guys going... Run CedarNSPrintRpcClientImpl.bcd Run CedarNSPrintUtilsRpcClientImpl.bcd And if you'd rather just so some interpretor based debugging: _ CedarNSPrintRpcControl.ImportInterface[[NIL, "Thunderbird"]] _ CedarNSPrintUtilsRpcControl.ImportInterface[[NIL, "Thunderbird"]] _ &host _ Rope.Flatten["Papermate:PARC:Xerox"] _ &addr _ CedarNSPrint.AddressTranslationStringToNetworkAddress[name: LOOPHOLE[&host]] _ &file _ Rope.Flatten["[Cherry]Print.scratch$"] _ CedarNSPrint.Print[master: LOOPHOLE[&file], printAttributes: NIL, printOptions: NIL, systemElement: LOOPHOLE[&addr]] [cmd: Handle] RETURNS [result: REF _ NIL, msg: ROPE _ NIL] CommandObject = [in, out, err: STREAM, commandLine, command: ROPE, ...] It is a good idea to periodically check for a process abort request. This should be done whenever a clean point has been reached and some significant processing (1 second, 1 file or 1 phase) has taken place. It is cheap enough to do fairly often. USAGE: Print[-a: agent, -s: printServer, file1, file2, ..., filen]; # of arguments processed When parsing the command line, be prepared for failure. The error is reported to the user Allows the user to specify personal defaults for the switches via the user's profile. Each argument can either be a switch specification or a genuine argument to be processed. The first argument (argv[0]) is not examined, because by convention it is the name of the command as given by the user. It is a good idea to periodically check for a process abort request. Ignore null arguments (it is not easy to generate them, even). This argument sets switches for the remaining patterns. By convention, switches are normally "sticky", in that they stay set until explicitly changed. Perform whatever processing is necessary for a normal argument. key is the name of the command. Registering the command under the "///Commands/" directory indicates that this command should be globally known and useful. If no directory is given, the command is registered under the current working directory, which is the proper place for more specific commands. proc is called to execute the command. doc gives the brief documentation for the command. This should be as brief as possible to remind the user of the function and options. clientData is passed to the command through cmd.procData.clientData. This is useful when various commands are registered with the same procedure, since the clientData can be used to tell the invocations apart. interpreted indicates whether or not the arguments should be scanned for special characters. The default is TRUE, which implies that I/O redicrection characters should be interpreted by the CommandTool. ʘcodešœ™Kšœ<™˜@Kšœ˜Kšœ˜šœ˜Kšœœ ˜4Kšœœ˜.Kšœœ˜,Kšœœ˜0Kšœ œ˜&Kšœœ˜0Kšœœ˜!—Kšœ˜Kšœ˜ K˜——Kšœœœ˜K˜šœ-œ ˜:šœ˜K˜Kšœ œ˜KšœC˜EKšœ˜Kšœ˜šœ˜Kšœœ ˜4Kšœœ˜.Kšœœ˜,Kšœœ˜0Kšœ œ˜&Kšœœ˜0Kšœœ˜!—Kšœ˜Kšœ˜ K˜——Kšœœœ˜K˜Kšœ1˜1Kšœ(˜(Kšœ3˜5K˜KšœYœœœ˜ŽK˜Kšœœœ"˜4Kšœœ$˜+K˜Kšœ"˜$K˜Kš œ-œœœœœ#˜§K˜Kšœ˜K™Kšœ-˜4Kšœ2˜9K˜Kšœ˜K˜—K˜šœ-˜-š œœ œœœœ™:Kšœœœ™G—Kšœœ ˜Kšœ œœœ œœœœ˜9Kšœ;˜;Kšœ œ,˜=Kšœœ-˜9Kšœ œ˜K˜šŸœœœ˜%Kšœœœ˜šœœœ˜*Kšœœ˜$šœ˜Kšœœ˜ Kšœœœ˜ Kšœ$˜&Kšœ.˜0Kšœ˜—Kšœœ˜ Kšœ˜—K˜—K˜šŸœœœ˜%Kšœ"˜"˜Kšœø™ø—K˜Kšœœœœ˜AKšœœœœ˜GKšœ ˜ K˜Kšœ'˜'K˜KšœC™CKšœ˜—K˜šœœ˜Kšœ™—•StartOfExpansionI[cmd: Commander.Handle, starExpand: BOOL _ FALSE, switchChar: CHAR]šœK˜PKšœ)œœ ˜8KšœZ™ZK˜—šœ>˜>KšœU™U—K˜šœœœ˜KšœÒ™ÒKšœœ ˜˜KšœD™D—šœœœ˜"Kšœ>™>—šœœ˜!Kšœ—™—Kšœ˜Kšœ˜Kšœ˜—šœ˜Kšœ?™?—Kšœ˜K˜—š˜Kšœ˜—K˜K˜—Kšœœ´˜½K˜–x[key: ROPE, proc: Commander.CommandProc, doc: ROPE _ NIL, clientData: REF ANY _ NIL, interpreted: BOOL _ TRUE]šœ˜šœ˜KšÏoœ©™¬—šœ˜Kš œ"™&—šœ ˜ Kš œ„™‡—šœ œ˜Kš  œÈ™Ò—šœ ˜Kš  œbœœœB™Ë—Kšœ˜—K˜K˜Kšœ˜K˜K˜K˜—…—ò%Š