DIRECTORY Args USING [Arg, ArgsGet, Error, NArgs], Commander USING [CommandProc, Register], CommanderOps USING [ArgumentVector, Failed, Parse], FileNames USING [ResolveRelativePath], IO, Process USING [CheckForAbort, Pause, SecondsToTicks], Rope USING [Cat, Concat, Equal, Length, ROPE], PrintingP4V3Aux, SimpleFeedback USING [Append], XNSPrint, XNSPrintExtras; XNSPrintCommandsImpl: CEDAR PROGRAM IMPORTS Args, Commander, CommanderOps, FileNames, IO, PrintingP4V3Aux, Process, Rope, SimpleFeedback, XNSPrint, XNSPrintExtras ~ { OPEN PrintingAux: PrintingP4V3Aux; ROPE: TYPE ~ Rope.ROPE; FaxIPMaster: ROPE ~ "FaxIPMaster"; faxdoc: ROPE ~ " [-t -c -h -0 -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 -0 leave plex unspecified\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 ~ " [-0 -1 -2 -a -b -s -c -h -f -l -m -medium ]\nTransmit a master to an XNS based printer.\nSwitches:\n -0 leave plex unspecified\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\n -medium paper size, e.g., -medium usLetter or -medium ([width~229, length~279])"; 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.PutFL[out, " Service: [%g]\n Spooler: %g, Formatter: %g, Printer: %g\n Media: ", LIST[ 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, defaultPlex, oneSided, twoSided, first, last, pages: Args.Arg; FixUpPhone: PROC [in: ROPE] RETURNS [out: ROPE ฌ NIL] ~ { out ฌ IO.PutFR1["//%g//", IO.rope[in]]; }; IF Args.NArgs[cmd] = 0 THEN RETURN[$Failure, faxusage]; [name, phone, copies, host, defaultPlex, oneSided, twoSided, first, last, pages] ฌ Args.ArgsGet[cmd, "%s-t%s-c%i-h%s-0%b-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 defaultPlex.ok AND defaultPlex.bool THEN XNSPrintExtras.SetPlex[context, $default]; IF twoSided.ok AND twoSided.bool THEN XNSPrintExtras.SetPlex[context, $simplex]; IF oneSided.ok AND oneSided.bool THEN XNSPrintExtras.SetPlex[context, $duplex]; 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, defaultPlex, oneSided, twoSided, first, last, pages, colorCorr, grayBal, message, stapled, medium: 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, defaultPlex, oneSided, twoSided, first, last, pages, colorCorr, grayBal, message, stapled, medium] ฌ Args.ArgsGet[cmd, "%s-c%i-h%s-0%b-1%b-2%b-f%i-l%i-p%i-a%b-b%b-m%s-s%b-medium%s" ! 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; XNSPrintExtras.SetPlex[context, $default]; IF twoSided.ok AND twoSided.bool THEN XNSPrintExtras.SetPlex[context, $duplex]; IF oneSided.ok AND oneSided.bool THEN XNSPrintExtras.SetPlex[context, $simplex]; 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 XNSPrintExtras.SetStapling[context, $stapled]; IF medium.ok THEN { [] ฌ XNSPrint.GetPrinterProperties[context.printerName]; -- This loads the media list with all the sizes this printer knows about. IF XNSPrint.GetPaperDimensions[medium.rope].width = 0 THEN { CommanderOps.Failed[Rope.Cat["Unknown medium: ", medium.rope, "; use GetPrintProperties to list the known media for this printer"]]; }; context.mediumHint ฌ medium.rope; }; 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[]; NoteContext[context]; 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}; }; NoteContext: PROC [c: XNSPrint.Context] = { IF c = NIL THEN ERROR; }; 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.PutF1[out, IF (tail = m) THEN "[ [%g]" ELSE ", [%g]", IO.rope[tail.first]]; ENDLOOP; IO.PutRope[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[]; }. š XNSPrintCommandsImpl.mesa Copyright ำ 1985, 1986, 1987, 1989, 1990, 1992 by Xerox Corporation. All rights reserved. Russ Atkinson, June 5, 1993 7:35 pm PDT 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, April 7, 1992 4:54 pm PDT Michael Plass, June 2, 1993 3:31 pm 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. RRA: A great place to plant a breakpoint! Helper Procs Initialization สa•NewlineDelimiter –(cedarcode) style™codešœ™Kšœ ฯeœO™ZK™'K™/K™#K™-K™,K™-K™$K™)K™(K™#K™'K˜—šฯk ˜ Kšœžœ˜(Kšœ žœ˜(Kšœ žœ!˜3Kšœ žœ˜&Kšžœ˜Kšœžœ(˜5Kšœžœžœ˜.Kšœ˜Kšœžœ ˜K˜ K˜K˜—šฯnœžœž˜#Kšžœ+žœN˜‚KšžœŸ œ˜"Kšžœžœžœ˜headšฯz™Kšะbn œžœก œ˜"Kšฯbœžœฤ˜ะKšขœžœ&ขœ˜˜MKšข œžœ)ข œ˜EK˜KšŸœžœ˜0KšขœžœD˜QKšข œžœ-ขœ˜EK˜Kšก œžœ˜$Kšขœžœก˜ฎKšข œžœ'ขœ˜?—š ™šŸœ˜1šžœ˜Kšœ)žœžœ ˜8Kšœ:žœžœ ˜IKšœ˜—Kšœžœ˜K˜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]˜AKšœž œ ˜K˜šŸ œžœžœ˜"Kšœ žœ˜Kšœ˜K˜"K˜K˜3šžœX˜ZKšžœžœ˜Kšžœ:˜˜@KšžœA˜CKšœ˜—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˜Yš Ÿ œžœžœžœžœžœ˜9Kšœžœžœ ˜'Kšœ˜—Kšžœžœžœ ขœ˜7Kšœคžœžœ˜ถKšžœžœžœžœ$˜9K˜K˜!K˜Kšžœ žœ ˜1Kšžœ žœ!˜0Kšžœ žœ*˜:Kšžœžœžœ+˜VKšžœ žœžœ+˜PKšžœ žœžœ*˜OKšžœ žœ˜/Kšžœ žœ˜,Kšžœ žœ0˜@K˜K˜5Kšœฯc#˜:šžœ ˜"Kšžœ˜Kšžœ˜Kšœ˜—Kšœ˜Kšœ5Ÿœ˜>šžœ4˜6Kšžœ!˜#Kšžœ8˜:Kšœ˜—šž˜K˜—K˜K˜—šŸœ˜)šžœ˜Kšœ:žœžœ ˜IKšœ˜—Kšœ˜Kšœ˜Kš œžœžœžœžœ˜,Kšœž œ ˜K˜€K˜šžœžœžœ˜K˜(Kšžœžœžœ˜4K˜—K˜Kšžœžœžœ ข œ˜8Kšœเžœžœ˜๒Kšžœžœžœžœ$˜9K˜K˜!Kšžœ žœ ˜1Kšžœ žœ!˜0K˜*Kšžœ žœžœ*˜OKšžœ žœžœ+˜PKšžœ žœ˜/Kšžœ žœ˜,Kšžœ žœ0˜@Kšžœ žœ ˜2Kšžœ žœžœ/˜Ršžœ žœ˜Kšœ9ฃI˜‚šžœ4žœ˜šœ˜š žœžœžœ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˜—šŸ œžœ˜+K™)Kšžœžœžœžœ˜K˜——š  ™ šŸœ ˜'KšœžœJ˜Tšœžœžœ)˜7Kšžœ˜Kšžœ ˜ Kšœ˜—šžœž˜%Kšœ˜šœ˜Kšœ<˜šžœ%žœ žœž˜?Kš žœ žœ žœ žœ žœ˜NKšžœ˜—Kšžœ˜Kšœ˜K˜—Kšฯy˜š ะny คะkyค ฆค ฆคฆค˜9Kšฆค,˜2Kšค˜K˜—š ฅคฆค ฆค ฆคฆค˜>šฆค ฆ˜šค ˜ Kšฆค˜Kšค˜—šฆค˜ šฆค˜Kšฆคฆค˜Kšฆคฆค6˜A—Kšค˜——Kšค˜K˜—šฅ คฆคฆคœคฆค ฆคฆค ฆค˜RKšคฆค˜ Kšคฆคœค˜(Kšคฆคœค)˜?Kšคฆค˜ Kšคฆค˜K˜Kšคœคฆค˜3Kšคœค˜$Kšคœค/˜5šฆคฆค˜$Kšคœค8˜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™—K˜—…—0B