DIRECTORY Args USING [Arg, ArgsGet, Error, NArgs], Commander USING [CommandProc, Register], CommanderOps USING [ArgumentVector, Failed, Parse], FileNames USING [ResolveRelativePath], IO USING [bool, PutF, PutFR, rope, STREAM], Process USING [CheckForAbort, Pause, SecondsToTicks], Rope USING [Concat, Equal, Length, ROPE], PrintingP4V3Aux, SimpleFeedback USING [Append], XNSPrint; XNSPrintCommandsImpl: CEDAR PROGRAM IMPORTS Args, Commander, CommanderOps, FileNames, IO, PrintingP4V3Aux, Process, Rope, SimpleFeedback, XNSPrint ~ { OPEN PrintingAux: PrintingP4V3Aux; ROPE: TYPE ~ Rope.ROPE; FaxIPMaster: ROPE ~ "FaxIPMaster"; faxdoc: ROPE ~ " [-t -c -h -1 -2 -f -l ]\nSend a master through an XNS based server to a remote FAX machine.\nSwitches:\n -t FAX phone number\n -c print multiple copies\n -h print thru service\n -1 print one-sided\n -2 print two-sided\n -f \n -l "; faxusage: ROPE ~ Rope.Concat["Usage: FaxIPMaster ", faxdoc]; GetPrintStatus: ROPE = "GetPrintStatus"; statusdoc: ROPE = "{Printer}*\nFind out the status of an XNS based printer."; statususage: ROPE = Rope.Concat["Usage: GetPrintStatus ", statusdoc]; GetPrintProperties: ROPE = "GetPrintProperties"; propdoc: ROPE = "{Printer}*\nFind out the properties of an XNS based printer.\n"; propusage: ROPE = Rope.Concat["Usage: GetPrintProperties ", propdoc]; SendIPMaster: ROPE ~ "SendIPMaster"; senddoc: ROPE ~ " [-1 -2 -a -b -s -c -h -f -l -m ]\nTransmit a master to an XNS based printer.\nSwitches:\n -1 print one-sided\n -2 print two-sided\n -a correct color (Lamming-Rhodes; includes -b)\n -b balance grays\n -s staple output\n -c print multiple copies\n -f \n -h print on that service\n -l -m include parameter (possibly quoted) in printer message field"; sendusage: ROPE ~ Rope.Concat["Usage: SendIPMaster ", senddoc]; GetPrintPropertiesProc: Commander.CommandProc ~ { ENABLE { CommanderOps.Failed => { msg _ errorMsg; GO TO Failed }; XNSPrint.Error => { msg _ Sensible[problem, explanation]; GO TO Failed }; }; argsProcessed: NAT _ 0; argv: CommanderOps.ArgumentVector _ CommanderOps.Parse[cmd: cmd]; out: IO.STREAM ~ cmd.out; CheckProperties: PROC [arg: ROPE] ~ { service: ROPE; properties: XNSPrint.Properties; argsProcessed _ argsProcessed + 1; Process.CheckForAbort[]; [service, properties] _ XNSPrint.GetPrinterProperties[arg]; IO.PutF[out, " Service: [%g]\n Staple: %g, TwoSided: %g\n Media: ", IO.rope[service], IO.bool[properties.staple], IO.bool[properties.twoSided] ]; IF ( properties.media # NIL ) THEN DisplayMediaList[out, properties.media]; }; FOR i: NAT IN [1..argv.argc) DO printerName: ROPE ~ argv[i]; Process.CheckForAbort[]; IF (Rope.Length[printerName] = 0) THEN LOOP; CheckProperties[printerName]; ENDLOOP; SELECT argsProcessed FROM 0 => { context: XNSPrint.Context; context _ XNSPrint.GetDefaults[]; IF (context.printerName = NIL) THEN msg _ propusage ELSE CheckProperties[context.printerName]; }; ENDCASE => { NULL }; EXITS Failed => {result _ $Failure}; }; GetPrintStatusProc: Commander.CommandProc ~ { ENABLE { CommanderOps.Failed => { msg _ errorMsg; GO TO Failed }; XNSPrint.Error => { msg _ Sensible[problem, explanation]; GO TO Failed }; }; argsProcessed: NAT _ 0; argv: CommanderOps.ArgumentVector _ CommanderOps.Parse[cmd: cmd]; out: IO.STREAM ~ cmd.out; CheckPrinter: PROC [arg: ROPE] = { service: ROPE; status: XNSPrint.PrinterStatus; argsProcessed _ argsProcessed + 1; Process.CheckForAbort[]; [service, status] _ XNSPrint.GetPrinterStatus[arg]; IO.PutF[out, " Service: [%g]\n Spooler: %g, Formatter: %g, Printer: %g\n Media: ", IO.rope[service], IO.rope[PrintingAux.ExposeSpoolerStatus[status.spooler, 0]], IO.rope[PrintingAux.ExposeFormatterStatus[status.formatter, 0]], IO.rope[PrintingAux.ExposeMarkingEngineStatus[status.printer, 0]] ]; IF ( status.media # NIL ) THEN DisplayMediaList[out, status.media]; }; FOR i: NAT IN [1..argv.argc) DO printerName: ROPE ~ argv[i]; Process.CheckForAbort[]; IF (Rope.Length[printerName] = 0) THEN LOOP; CheckPrinter[printerName]; ENDLOOP; SELECT argsProcessed FROM 0 => { context: XNSPrint.Context; context _ XNSPrint.GetDefaults[]; IF (context.printerName = NIL) THEN msg _ statususage ELSE CheckPrinter[context.printerName]; }; ENDCASE => NULL; EXITS Failed => {result _ $Failure}; }; FaxMasterProc: Commander.CommandProc ~ { ENABLE { XNSPrint.Error => { msg _ Sensible[problem, explanation]; GO TO Failed }; }; context: XNSPrint.Context; request: XNSPrint.PrintRequest; ok: BOOL _ TRUE; fullFName, exp: ROPE _ NIL; out: IO.STREAM ~ cmd.out; name, phone, copies, host, oneSided, twoSided, first, last, pages: Args.Arg; FixUpPhone: PROC [in: ROPE] RETURNS [out: ROPE _ NIL] ~ { out _ IO.PutFR["//%g//", IO.rope[in]]; }; IF Args.NArgs[cmd] = 0 THEN RETURN[$Failure, faxusage]; [name, phone, copies, host, oneSided, twoSided, first, last, pages] _ Args.ArgsGet[cmd, "%s-t%s-c%i-h%s-1%b-2%b-f%i-l%i-p%i" ! Args.Error => {ok _ FALSE; CONTINUE}]; IF NOT ok THEN RETURN[$Failure, "Command syntax error."]; context _ XNSPrint.GetDefaults[]; IF copies.ok THEN context.copyCount _ copies.int; IF host.ok THEN context.printerName _ host.rope; IF phone.ok THEN context.message _ FixUpPhone[phone.rope]; IF twoSided.ok AND twoSided.bool THEN context.twoSided _ TRUE; IF oneSided.ok AND oneSided.bool THEN context.twoSided _ FALSE; IF first.ok THEN context.pageFirst _ first.int; IF last.ok THEN context.pageLast _ last.int; IF pages.ok THEN context.pageLast _ context.pageFirst+pages.int; name.rope _ FileNames.ResolveRelativePath[name.rope]; fullFName _ name.rope; -- FixUpFilename[name.rope, FALSE]; IO.PutF[out, " Sending %s to %s", IO.rope[fullFName], IO.rope[context.printerName] ]; Process.CheckForAbort[]; request _ XNSPrint.PrintFromFile[name.rope, context, AllDone]; IO.PutF[out, "\n Service: [%g]\n RequestID: %g\n", IO.rope[request.distinguishedName], IO.rope[PrintingAux.ExposeRequestID[request.requestID, 0]] ]; EXITS Failed => {result _ $Failure}; }; SendMasterProc: Commander.CommandProc ~ { ENABLE { XNSPrint.Error => { msg _ Sensible[problem, explanation]; GO TO Failed }; }; context: XNSPrint.Context; request: XNSPrint.PrintRequest; ok: BOOL _ TRUE; fullFName, exp: ROPE _ NIL; out: IO.STREAM ~ cmd.out; name, copies, host, oneSided, twoSided, first, last, pages, colorCorr, grayBal, message, stapled: Args.Arg; IF ( FALSE ) THEN { [result, msg] _ GetPrintStatusProc[cmd]; IF ( result = $Failure ) THEN RETURN[$Failure, msg]; }; IF Args.NArgs[cmd] = 0 THEN RETURN[$Failure, sendusage]; [name, copies, host, oneSided, twoSided, first, last, pages, colorCorr, grayBal, message, stapled] _ Args.ArgsGet[cmd, "%s-c%i-h%s-1%b-2%b-f%i-l%i-p%i-a%b-b%b-m%s-s%b" ! Args.Error => {ok _ FALSE; CONTINUE}]; IF NOT ok THEN RETURN[$Failure, "Command syntax error."]; context _ XNSPrint.GetDefaults[]; context.stapled _ FALSE; IF copies.ok THEN context.copyCount _ copies.int; IF host.ok THEN context.printerName _ host.rope; IF twoSided.ok AND twoSided.bool THEN context.twoSided _ TRUE; IF oneSided.ok AND oneSided.bool THEN context.twoSided _ FALSE; IF first.ok THEN context.pageFirst _ first.int; IF last.ok THEN context.pageLast _ last.int; IF pages.ok THEN context.pageLast _ context.pageFirst+pages.int; IF message.ok THEN context.message _ message.rope; IF stapled.ok AND stapled.bool THEN context.stapled _ TRUE; IF grayBal.ok THEN context.message _ context.message.Concat["GrayBalanceThisMaster: TRUE\n"]; IF colorCorr.ok THEN context.message _ context.message.Concat["ColorCorrectThisMaster: TRUE\n"]; name.rope _ FileNames.ResolveRelativePath[name.rope]; fullFName _ name.rope; -- FixUpFilename[name.rope, FALSE]; IO.PutF[out, " Sending %s to %s", IO.rope[fullFName], IO.rope[context.printerName] ]; Process.CheckForAbort[]; request _ XNSPrint.PrintFromFile[name.rope, context, AllDone ! XNSPrint.Error => { IF problem=serviceRetry OR (problem=service AND Rope.Equal[s1: explanation, s2: "Spooling Queue Full"]) OR (problem=connection AND Rope.Equal[s1: explanation, s2: "communication failure"]) THEN { Process.CheckForAbort[]; Process.Pause[Process.SecondsToTicks[5]]; IO.PutF[stream: out, format: " ... %lRETRY%l", v1: [rope["k"]], v2: [rope["K"]]]; RETRY; } }]; IO.PutF[out, "\n Service: [%g]\n RequestID: %g\n", IO.rope[request.distinguishedName], IO.rope[PrintingAux.ExposeRequestID[request.requestID, 0]] ]; EXITS Failed => {result _ $Failure}; }; AllDone: XNSPrint.StatusChangedProc ~ { name: ROPE _ PrintingAux.ExposeInterpressMasterStatus[request.lastStatus.status, 0]; msg: ROPE _ IO.PutFR["print request: %g, status: (%g)", IO.rope[request.fileName], IO.rope[name] ]; SELECT request.lastStatus.status FROM pending, inProgress => { SimpleFeedback.Append[$XNSPrintingUI, oneLiner, $info, msg]; }; completed, completedWithWarning, unknown, rejected, aborted, canceled, held => { SimpleFeedback.Append[$XNSPrintingUI, oneLiner, $info, msg]; XNSPrint.UnRegisterPrintRequest[request]; }; ENDCASE => { NULL }; }; DisplayMediaList: PROC [out: IO.STREAM, m: XNSPrint.Media] ~ { FOR tail: XNSPrint.Media _ m, tail.rest WHILE ( tail # NIL ) DO IO.PutF[out, IF (tail = m) THEN "[ [%g]" ELSE ", [%g]", IO.rope[tail.first]]; ENDLOOP; IO.PutF[out, " ]\n"]; }; << FSErrorMsg: PROC [error: FS.ErrorDesc] RETURNS [ROPE] ~ { RETURN[Rope.Concat[FSErrorMsgBrief[error], "\n"]]; }; FSErrorMsgBrief: PROC [error: FS.ErrorDesc] RETURNS [ROPE] ~ { SELECT error.group FROM lock => { RETURN[" -- locked!"]; }; ENDCASE => { IF (error.code = $unknownFile) THEN RETURN [" -- not found!"] ELSE RETURN[Rope.Concat["\n -- FS.Error: ", error.explanation]]; }; }; FixUpFilename: PROC [name: ROPE _ NIL, copyFrom: BOOL] RETURNS [newName: ROPE] ~ { body: ROPE; platformHost: ROPE _ ThisMachine.Name[]; platformVolume: ROPE _ File.GetVolumeName[File.SystemVolume[]]; prefix: ROPE; cp: FS.ComponentPositions; [fullFName: newName, cp: cp] _ FS.ExpandName[name]; prefix _ Rope.Substr[newName, 0, 4]; body _ Rope.Substr[newName, 4, Rope.Length[newName]]; IF Rope.Equal[prefix, "[]<>"] THEN { newName _ Rope.Cat["[", platformHost, "]<", platformVolume, ">"]; newName _ Rope.Cat[newName, body]; } ELSE newName _ Rope.Cat[ "[", IF copyFrom THEN FSPseudoServers.TranslateForRead[Rope.Substr[newName, cp.server.start, cp.server.length]].first ELSE FSPseudoServers.TranslateForWrite[Rope.Substr[newName, cp.server.start, cp.server.length]], "]<", Rope.Substr[newName, cp.dir.start, Rope.Length[newName]]]; }; >> Sensible: PROC [problem: XNSPrint.Problem, explanation: ROPE] RETURNS [msg: ROPE] ~ { PROBLEM: ARRAY XNSPrint.Problem OF ROPE ~ ["connection", "file", "name", "protocol", "service", "serviceRetry", "stream", "unknown"]; p: ROPE ~ PROBLEM[problem]; msg _ IO.PutFR["XNSPrint.Error(%g): %g", IO.rope[p], IO.rope[explanation]]; }; Init: PROC ~ { Commander.Register[FaxIPMaster, FaxMasterProc, faxdoc]; Commander.Register[GetPrintProperties, GetPrintPropertiesProc, propdoc]; Commander.Register[GetPrintStatus, GetPrintStatusProc, statusdoc]; Commander.Register[SendIPMaster, SendMasterProc, senddoc]; }; Init[]; }. LXNSPrintCommandsImpl.mesa Copyright ำ 1985, 1986, 1987, 1989, 1990 by Xerox Corporation. All rights reserved. Russ Atkinson, April 2, 1985 4:22:08 pm PST Bill Jackson (bj) April 24, 1990 5:08:27 pm PDT Demers, June 6, 1986 3:09:39 pm PDT Tim Diebert: November 27, 1987 8:54:48 am PST Eric Nickell, October 8, 1987 2:58:13 pm PDT Rick Beach, November 28, 1987 12:54:13 pm PST gbb February 15, 1989 5:57:50 pm PST Dave Rumph, March 13, 1990 6:32:47 pm PST Swinehart, April 20, 1990 3:36:40 pm PDT Willie-s, September 10, 1991 11:58 am PDT Commander Constants Commander Procs Note: colorCorr currently is a hack to be able to switch it on and off during research. Once it will work, the switch will disappear and servers will always perform color correction. Giordano Beretta November 4, 1988 10:08:19 am PST. Helper Procs Initialization ส ๚˜codešœ™KšœT™TKšœ+™+K™/K™#K™-K™,K™-K™$K™)K™(K™)K˜—šฯk ˜ Kšœœ˜(Kšœ œ˜(Kšœ œ!˜3Kšœ œ˜&Kšœœœ˜+Kšœœ(˜5Kšœœœ˜)Kšœ˜Kšœœ ˜Kšœ ˜ K˜—šฯnœœ˜#Kšœ+œ>˜rKšœž œ˜"Kšœœœ˜headšฯz™Kšะbn œœ  œ˜"Kšฯbœœข˜ฎKšกœœ&กœ˜˜MKšก œœ)ก œ˜EK˜Kšžœœ˜0KšกœœD˜QKšก œœ-กœ˜EK˜Kš  œœ˜$KšกœœŽ˜›Kšก œœ'กœ˜?—šŸ™šžœ˜1šœ˜Kšœ)œœ ˜8Kšœ:œœ ˜IKšœ˜—Kšœœ˜KšœA˜AKšœ œ ˜K˜šžœœœ˜%Kšœ œ˜Kšœ ˜ Kšœ"˜"K˜Kšœ;˜;šœH˜JKšœ˜Kšœ˜Kšœ˜Kšœ˜—Kšœœœ)˜KKšœ˜K˜—šœœœ˜Kšœ œ ˜K˜Kšœ œœ˜,Kšœ˜Kšœ˜K˜—šœ˜šœ˜Kšœ˜Kšœ!˜!šœœ˜Kšœก ˜Kšœ&˜*—K˜—Kšœœ˜—š˜Kšœ˜—K˜K˜—šžœ˜-šœ˜Kšœ)œœ ˜8Kšœ:œœ ˜IKšœ˜—Kšœœ˜K•StartOfExpansionI[cmd: Commander.Handle, starExpand: BOOL _ FALSE, switchChar: CHAR]šœA˜AKšœ œ ˜K˜šž œœœ˜"Kšœ œ˜Kšœ˜Kšœ"˜"K˜Kšœ3˜3šœW˜YKšœ˜Kšœ:˜˜@Kšœ?˜AKšœ˜—Kšœœœ%˜CK˜K˜—šœœœ˜Kšœ œ ˜K˜Kšœ œœ˜,Kšœ˜Kšœ˜K˜—šœ˜šœ˜Kšœ˜Kšœ!˜!šœœ˜Kšœก ˜Kšœ#˜'—K˜—Kšœœ˜—š˜Kšœ˜—K˜K˜—šž œ˜(šœ˜Kšœ:œœ ˜IKšœ˜—Kšœ˜Kšœ˜Kš œœœœœ˜,Kšœ œ ˜K˜Lš ž œœœœœœ˜9Kšœœœ ˜&Kšœ˜—Kšœœœ กœ˜7Kšœ“œœ˜ฅKšœœœœ$˜9K˜Kšœ!˜!K˜Kšœ œ ˜1Kšœ œ!˜0Kšœ œ*˜:Kšœ œœœ˜>Kšœ œœœ˜?Kšœ œ˜/Kšœ œ˜,Kšœ œ0˜@K˜Kšœ5˜5Kšœฯc#˜:šœ ˜"Kšœ˜Kšœ˜Kšœ˜—Kšœ˜Kšœ5žœ˜>šœ4˜6Kšœ!˜#Kšœ8˜:Kšœ˜—š˜Kšœ˜—K˜K˜—šžœ˜)šœ˜Kšœ:œœ ˜IKšœ˜—Kšœ˜Kšœ˜Kš œœœœœ˜,Kšœ œ ˜K˜kK˜šœœœ˜Kšœ(˜(Kšœœœ˜4K˜—K˜Kšœœœ ก œ˜8Kšœพœœ˜ะKšœœœœ$˜9K˜Kšœ!˜!Kšœœ˜K˜Kšœ œ ˜1Kšœ œ!˜0Kšœ œœœ˜>Kšœ œœœ˜?Kšœ œ˜/Kšœ œ˜,Kšœ œ0˜@Kšœ œ ˜2Kšœ œœœ˜;Kšœ œK˜]šœœL˜`Kšœ้™้—K˜Kšœ5˜5Kšœข#˜:šœ ˜"Kšœ˜Kšœ˜Kšœ˜—Kšœ˜–-[s1: ROPE, s2: ROPE, case: BOOL _ TRUE]šœ>˜>šœ˜š œœœ9œœ;œ˜รK˜K˜)K–ฏ[stream: STREAM, format: ROPE _ NIL, v1: IO.Value _ [null[]], v2: IO.Value _ [null[]], v3: IO.Value _ [null[]], v4: IO.Value _ [null[]], v5: IO.Value _ [null[]]]šœO˜QKšœ˜Kšœ˜—Kšœ˜—K˜—šœ4˜6Kšœ!˜#Kšœ8˜:Kšœ˜—š˜Kšœ˜—K˜——šŸ ™ šžœ ˜'KšœœJ˜Tšœœœ)˜7Jšœ˜Jšœ ˜ Jšœ˜—šœ˜%Kšœ˜šœ˜Jšœ<˜šœ%œ œ˜?Kš œ œ œ œ œ˜MKšœ˜—Kšœ˜Kšœ˜K˜—Kšœ˜š ž œœ œ œœ˜9Kšœ,˜2Kšœ˜K˜—š žœœ œ œœ˜>šœ ˜šœ ˜ Kšœ˜Kšœ˜—šœ˜ šœ˜Kšœœ˜Kšœœ6˜A—Kšœ˜——Kšœ˜K˜—šž œœœœ œœ œ˜RKšœœ˜ Kšœœ˜(Kšœœ+˜?Kšœœ˜ Kšœœ˜K˜Kšœœ˜3Kšœ$˜$Kšœ5˜5šœœ˜$KšœA˜AKšœ"˜"Kšœ˜—šœ˜Kšœ˜šœ ˜Kšœ_˜_—š˜Kšœ[˜[—Kšœ˜Kšœ:˜:—K˜K˜K˜—š žœœ*œœœ˜UKšœœœœ^˜…Kšœœœ ˜Kšœœ!œ œ˜KK˜——šŸ™šžœœ˜Kšœก œž œฯoกœ˜7Kšœกœกœฃกœ˜HKšœกœกœก œ˜BKšœก œกœฃกœ˜:K˜K˜——K˜Kšœ˜K˜—šœ˜K™—J˜—…—,b=จ