1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2
3<html>
4  <head>
5    <meta name="generator" content="HTML Tidy, see www.w3.org">
6    <title>Print Job Filters</title>
7    <meta name="GENERATOR" content=
8    "Modular DocBook HTML Stylesheet Version 1.7">
9    <link rel="HOME" title=" LPRng Reference Manual" href=
10    "index.htm">
11    <link rel="UP" title="Print Spooling Tutorial " href=
12    "tutorial.htm">
13    <link rel="PREVIOUS" title="Job Removal" href="jobremoval.htm">
14    <link rel="NEXT" title=
15    "Job File Format Conversion with Filters" href=
16    "jobfileformatconversion.htm">
17  </head>
18
19  <body class="SECT1" bgcolor="#FFFFFF" text="#000000" link=
20  "#0000FF" vlink="#840084" alink="#0000FF">
21    <div class="NAVHEADER">
22      <table summary="Header navigation table" width="100%" border=
23      "0" cellpadding="0" cellspacing="0">
24        <tr>
25          <th colspan="3" align="center">LPRng Reference Manual: 5
26          Sep 2003 (For LPRng-3.8.22)</th>
27        </tr>
28
29        <tr>
30          <td width="10%" align="left" valign="bottom"><a href=
31          "jobremoval.htm" accesskey="P">Prev</a></td>
32
33          <td width="80%" align="center" valign="bottom">Chapter 4.
34          Print Spooling Tutorial</td>
35
36          <td width="10%" align="right" valign="bottom"><a href=
37          "jobfileformatconversion.htm" accesskey="N">Next</a></td>
38        </tr>
39      </table>
40      <hr align="LEFT" width="100%">
41    </div>
42
43    <div class="SECT1">
44      <h1 class="SECT1"><a name="PRINTJOBFILTERS">4.9. Print Job
45      Filters</a></h1>
46
47      <p>A printer usually understands one or more <span class=
48      "emphasis"><i class="EMPHASIS">Print Job
49      Languages</i></span>. Files sent to this printer must be in
50      one of these languages and have the appropriate <span class=
51      "emphasis"><i class="EMPHASIS">job format</i></span>. The
52      most common Print Job Languages are <a href=
53      "x291.htm#POSTSCRIPT">PostScript</a> and <a href=
54      "x291.htm#PCL">PCL</a>. Text files are PCL with no special
55      PCL control sequences.</p>
56
57      <p>In order for a printer to reliably print a job it needs to
58      be reset to a known configuration and then at the end of job
59      having it flush all of the output to the printing device.
60      This is done by sending it <span class="emphasis"><i class=
61      "EMPHASIS">start of job</i></span> and <span class=
62      "emphasis"><i class="EMPHASIS">end of job</i></span>
63      commands. These commands differ from printer to printer and
64      depend on the print job language as well. Some <span class=
65      "emphasis"><i class="EMPHASIS">vintage</i></span> line
66      printers also have a set of proprietary <span class=
67      "emphasis"><i class="EMPHASIS">escape sequences</i></span>
68      that are used to set up margins, form size, and other
69      printing characteristics. Usually a <span class="emphasis"><i
70      class="EMPHASIS">setup string</i></span> with these escape
71      sequences must be sent to the printer before a file can be
72      printed.</p>
73
74      <p>When sending a job to the printer the print spooler will
75      first process the job using a <span class="emphasis"><i
76      class="EMPHASIS">print job filter</i></span> or <span class=
77      "emphasis"><i class="EMPHASIS">filter</i></span> program.
78      This program reads the job file and then produces output in
79      the format required for the printer.</p>
80
81      <p>When a print job is created the files in the print job are
82      assigned a <span class="emphasis"><i class=
83      "EMPHASIS">format</i></span>. This format was meant as a
84      guide to the print spooler and was to be used to select the
85      filter program for the files in the job. The format was a
86      lower case letter; the <var class="LITERAL">f</var> is the
87      de<var class="LITERAL">f</var>ault format and indicates
88      normal processing and the <var class="LITERAL">l</var> format
89      indicates a literal or binary file. Job files that are
90      flagged as having literal or binary format are usually passed
91      directly to the printer or have at the most a minimal amount
92      of processing. See <a href="printjobformats.htm">Print Job
93      Formats</a> for more information about formats and their use
94      with filters.</p>
95
96      <p>There are two ways to specify filters: the default <var
97      class="LITERAL">:filter=...</var> option and the more
98      specific <var class="LITERAL">Xf=...</var> option. The <var
99      class="LITERAL">X</var> is a lower case letter corresponding
100      to a format. Here is a sample printcap entry with a filter
101      specification:</p>
102
103      <div class="INFORMALEXAMPLE">
104        <a name="AEN2200"></a>
105<pre class="SCREEN">
106    lp:sd=/var/spool/lpd/%P
107      :filter=/usr/local/lib/filters/ifhp
108      :rf=/usr/local/lib/filters/rfilter
109</pre>
110      </div>
111      All jobs with formats other than <var class="LITERAL">r</var>
112      will be processed using the <var class="LITERAL">ifhp</var>
113      program while the jobs with the <var class="LITERAL">r</var>
114      format will be processed using the <var class=
115      "LITERAL">rfilter</var> program.<br>
116      <br>
117
118      <p>We will set up a very simple filter and use it to
119      demonstrate how filtering is done by the <b class=
120      "APPLICATION">lpd</b> print spooler. First, set up the <tt
121      class="FILENAME">/tmp/testf</tt> file as shown below.</p>
122
123      <div class="INFORMALEXAMPLE">
124        <a name="AEN2209"></a>
125<pre class="SCREEN">
126    #!/bin/sh
127    # /tmp/testf - test filter for LPRng
128    PATH=/bin:/usr/bin; export PATH
129    echo TESTF $0 "$@" &gt;&amp;2
130    echo TESTF $0 "$@"
131    echo ENV
132    set
133    echo LEADER
134    /bin/cat
135    echo TRAILER
136    exit 0
137</pre>
138      </div>
139      <br>
140      <br>
141
142      <p>Let us carefully examine the script line by line. The
143      first couple of lines are <span class="emphasis"><i class=
144      "EMPHASIS">boilerplate</i></span>. You should <span class=
145      "emphasis"><i class="EMPHASIS">always</i></span> set the <var
146      class="ENVAR">PATH</var> value in a filter script or use full
147      pathnames for executable programs. This is a good practice as
148      it ensures that only the specified directories will be
149      searched for commands.</p>
150
151      <p>The next lines echo the command line arguments to file
152      descriptor 2 (<acronym class="ACRONYM">STDERR</acronym>) and
153      to <acronym class="ACRONYM">STDOUT</acronym>. We will soon
154      see how this information is displayed by the <b class=
155      "APPLICATION">LPRng</b> software. We then use the <tt class=
156      "COMMAND">set</tt> command to list the shell variables to
157      <acronym class="ACRONYM">STDOUT</acronym>, print <acronym
158      class="ACRONYM">LEADER</acronym> to <acronym class=
159      "ACRONYM">STDOUT</acronym>, copy <acronym class=
160      "ACRONYM">STDIN</acronym> to <acronym class=
161      "ACRONYM">STDOUT</acronym>, and print <acronym class=
162      "ACRONYM">TRAILER</acronym> to <acronym class=
163      "ACRONYM">STDOUT</acronym>. We exit with a zero result
164      code.</p>
165
166      <p>We can test our script, with the results shown below:</p>
167
168      <div class="INFORMALEXAMPLE">
169        <a name="AEN2228"></a>
170<pre class="SCREEN">
171    <samp class="PROMPT">h4: {163} %</samp> <kbd class=
172"USERINPUT">chmod 755 /tmp/testf</kbd>
173    <samp class="PROMPT">h4: {164} %</samp> <kbd class=
174"USERINPUT">echo hi |/tmp/testf -a1</kbd>
175    TESTF /tmp/testf -a1
176    TESTF /tmp/testf -a1
177    ENV
178    USER=papowell
179    HOSTNAME=h4
180    ...
181    PATH=/bin:/usr/bin
182    LEADER
183    hi
184    TRAILER
185</pre>
186      </div>
187      <br>
188      <br>
189
190      <p>Let's now use this filter. Edit the <var class=
191      "LITERAL">lp</var> printcap entry so it has contents
192      indicated below, use <tt class="COMMAND">checkpc -f</tt> to
193      check the printcap, and then use <tt class="COMMAND">lpc
194      reread</tt> to restart the <b class="APPLICATION">lpd</b>
195      server.</p>
196
197      <div class="INFORMALEXAMPLE">
198        <a name="AEN2239"></a>
199<pre class="SCREEN">
200    lp:sd=/var/spool/lpd/%P
201      :force_localhost
202      :lp=/tmp/lp
203      :filter=/tmp/testf
204</pre>
205      </div>
206      <br>
207      <br>
208
209      <p>Execute the following commands to print the <tt class=
210      "FILENAME">/tmp/hi</tt> file and observe the results:</p>
211
212      <div class="INFORMALEXAMPLE">
213        <a name="AEN2243"></a>
214<pre class="SCREEN">
215    <samp class="PROMPT">h4: {165} %</samp> <kbd class=
216"USERINPUT">cp /dev/null /tmp/lp</kbd>
217    <samp class="PROMPT">h4: {166} %</samp> <kbd class=
218"USERINPUT">lpr /tmp/hi</kbd>
219    <samp class="PROMPT">h4: {167} %</samp> <kbd class=
220"USERINPUT">lpq -llll</kbd>
221    Printer: lp@h4
222     Queue: no printable jobs in queue
223     Status: lp@h4.private: job 'papowell@h4+26593' printed at 21:37:21.312
224     Status: job 'papowell@h4+26593' removed at 21:37:21.323
225     Status: subserver pid 26683 starting at 21:39:21.908
226     Status: accounting at start at 21:39:21.908
227     Status: opening device '/tmp/lp' at 21:39:21.909
228     Status: printing job 'papowell@h4+26681' at 21:39:21.909
229     Status: no banner at 21:39:21.909
230     Status: printing data file 'dfA026681h4.private', size 3, \
231        IF filter 'testf' at 21:39:21.909
232     Status: IF filter msg - 'TESTF /tmp/testf -Apapowell@h4+26681 \
233         -CA -D2000-04 -11-21:39:21.877 -Ff -Hh4.private -J/tmp/hi \
234          -Lpapowell -Plp -Qlp -aacct -b3 -d/var/tmp/LPD/lp \
235          -edfA026681h4.private -f/tmp/hi -hh4.private -j026681 \
236          -kcfA026681h4.private -l66 -npapowell -sstatus \
237          -t2000-04-11-21:39:21.000 -w80 -x0 -y0 acct' \
238           at 21:39:21.914
239     Status: IF filter finished at 21:39:22.070
240     Status: printing done 'papowell@h4+26681' at 21:39:22.070
241     Status: accounting at end at 21:39:22.070
242     Status: finished 'papowell@h4+26681', status 'JSUCC' at 21:39:22.070
243     Status: subserver pid 26683 exit status 'JSUCC' at 21:39:22.072
244     Status: lp@h4.private: job 'papowell@h4+26681' printed at 21:39:22.072
245     Status: job 'papowell@h4+26681' removed at 21:39:22.085
246    <samp class="PROMPT">h4: {168} %</samp> <kbd class=
247"USERINPUT">more /tmp/lp</kbd>
248    TESTF /tmp/testf -Apapowell@h4+26681 -CA -D2000-04-11-21:39:21.877 \
249     -Ff -Hh4.private -J/tmp/hi -Lpapowell -Plp -Qlp -aacct -b3 \
250     -d/var/tmp/LPD/lp -edfA026681h4.private -f/tmp/hi -hh4.private \
251     -j026681 -kcfA026681h4.private -l66 -npapowell -sstatus \
252     -t2000-04-11-21:39:21.000 -w80 -x0 -y0 acct
253    ENV
254    USER=papowell
255    LD_LIBRARY_PATH=/lib:/usr/lib:/usr/5lib:/usr/ucblib
256    HOME=/home/papowell
257    PRINTCAP_ENTRY=lp
258     :force_localhost
259     :filter=/tmp/testf
260     :lp=/var/tmp/lp
261     :sd=/var/tmp/LPD/lp
262    
263    PS1=$
264    OPTIND=1
265    PS2=&gt;
266    SPOOL_DIR=/var/tmp/LPD/lp
267    LOGNAME=papowell
268    
269    CONTROL=Hh4.private
270     Ppapowell
271     J/tmp/hi
272     CA
273     Lpapowell
274     Apapowell@h4+15850
275     D2000-04-26-18:13:55.505
276     Qlp
277     N/tmp/hi
278     fdfA015850h4.private
279     UdfA015850h4.private
280    
281    PATH=/bin:/usr/bin
282    SHELL=/bin/sh
283    LOGDIR=/home/papowell
284    IFS=
285    PRINTER=lp
286    LEADER
287    test Test
288    TRAILER
289</pre>
290      </div>
291      <br>
292      <br>
293
294      <p>The <tt class="COMMAND">cp</tt> command clears out the <tt
295      class="FILENAME">/tmp/lp</tt> file we are using as a dummy
296      output device. The <tt class="COMMAND">lpr</tt> command
297      prints the <tt class="FILENAME">/tmp/hi</tt> file and the <tt
298      class="COMMAND">lpq -llll</tt> command shows the status
299      information. The status information now contains the line
300      that the <tt class="COMMAND">testf</tt> script wrote to
301      <acronym class="ACRONYM">STDERR</acronym>. The <b class=
302      "APPLICATION">lpd</b> server captures filter <acronym class=
303      "ACRONYM">STDERR</acronym> messages and puts it them in the
304      spool queue status file.</p>
305
306      <p>As we see from the lpq status, <b class=
307      "APPLICATION">lpd</b> passes a large number of command line
308      options to our filter. These options and their meanings are
309      discussed in detail in <a href="filteroptions.htm">Filter
310      Command Line Options and Environment Variables</a>. We will
311      discuss these in more detail in the next section.</p>
312
313      <p>If we look at the <tt class="FILENAME">/tmp/lp</tt> file,
314      we see the command line options and values of the shell
315      variables. For a full discussion of the environment variables
316      passed to a filter see <a href="filteroptions.htm">Filter
317      Command Line Options and Environment Variables</a>. The more
318      interesting environment variables include the <var class=
319      "ENVAR">PRINTCAP_ENTRY</var> variable, which is a copy of the
320      printcap entry for this printer, and the <var class=
321      "ENVAR">CONTROL</var> variable, which is a copy of the
322      control file for the the print job.</p>
323
324      <div class="SECT2">
325        <h2 class="SECT2"><a name="CONTROLFILES">4.9.1. Control
326        Files and Filter Options</a></h2>
327
328        <p>When you submit a print job the <b class=
329        "APPLICATION">lpd</b> print spooler stores it in the spool
330        queue as two or more files: a <span class="emphasis"><i
331        class="EMPHASIS">control</i></span> file that contains
332        information about the job and the <span class="emphasis"><i
333        class="EMPHASIS">data</i></span> files that contain the
334        information to be printed. Here is sample control file:</p>
335
336        <div class="INFORMALEXAMPLE">
337          <a name="AEN2277"></a>
338<pre class="SCREEN">
339    Hh4.private
340    Ppapowell
341    J/tmp/hi
342    CA
343    Lpapowell
344    Apapowell@h4+15850
345    D2000-04-26-18:13:55.505
346    Qlp
347    N/tmp/hi
348    fdfA015850h4.private
349    UdfA015850h4.private
350</pre>
351        </div>
352        <br>
353        <br>
354
355        <p>Lines starting with upper case letters contain job
356        information such as the user who submitted the job. Lines
357        starting with lower case letters indicate the data file to
358        be printed and the corresponding format. For full details
359        about the exact format of the control file see <a href=
360        "jobfiles.htm">Job Files</a>.</p>
361
362        <p><a href="printjobfilters.htm#FILTEROPTIONSTABLE">Table
363        4-1</a> shows the correspondence between lines in the
364        control file and <b class="APPLICATION">lpr</b> command
365        line options. The <var class="LITERAL">N</var> values are
366        the names of the files that are printed. The <var class=
367        "LITERAL">U</var> indicates a data file is in a job and is
368        present to meet RCF1179 and <span class="emphasis"><i
369        class="EMPHASIS">vintage</i></span> print spooler
370        requirements.</p>
371
372        <div class="TABLE">
373          <a name="FILTEROPTIONSTABLE"></a>
374
375          <p><b>Table 4-1. Filter Options</b></p>
376
377          <table border="1" frame="border" rules="all" class=
378          "CALSTABLE">
379            <col>
380            <col>
381            <col>
382
383            <thead>
384              <tr>
385                <th>Control File</th>
386
387                <th>Filter Option</th>
388
389                <th>Purpose or Value</th>
390              </tr>
391            </thead>
392
393            <tbody>
394              <tr>
395                <td>&nbsp;</td>
396
397                <td><var class="LITERAL">-P</var><span class=
398                "emphasis"><i class=
399                "EMPHASIS">Printer</i></span></td>
400
401                <td>Print queue name - printcap information</td>
402              </tr>
403
404              <tr>
405                <td><span class="emphasis"><i class=
406                "EMPHASIS">H</i></span></td>
407
408                <td><var class="LITERAL">-H</var><span class=
409                "emphasis"><i class="EMPHASIS">Host</i></span></td>
410
411                <td>Host Name</td>
412              </tr>
413
414              <tr>
415                <td><var class="LITERAL">P</var></td>
416
417                <td><var class="LITERAL">-n</var><span class=
418                "emphasis"><i class="EMPHASIS">User</i></span></td>
419
420                <td>User Login Name of job originator</td>
421              </tr>
422
423              <tr>
424                <td><var class="LITERAL">J</var></td>
425
426                <td><var class="LITERAL">-J</var><span class=
427                "emphasis"><i class="EMPHASIS">Job
428                name</i></span></td>
429
430                <td>lpr -J option or file name</td>
431              </tr>
432
433              <tr>
434                <td><var class="LITERAL">C</var></td>
435
436                <td><var class="LITERAL">-C</var><span class=
437                "emphasis"><i class=
438                "EMPHASIS">Class</i></span></td>
439
440                <td>Print class (lpr -C option)</td>
441              </tr>
442
443              <tr>
444                <td><var class="LITERAL">L</var></td>
445
446                <td><var class="LITERAL">-L</var><span class=
447                "emphasis"><i class=
448                "EMPHASIS">Banner</i></span></td>
449
450                <td>Banner page request</td>
451              </tr>
452
453              <tr>
454                <td><var class="LITERAL">A</var></td>
455
456                <td><var class="LITERAL">-A</var><span class=
457                "emphasis"><i class=
458                "EMPHASIS">Jobid</i></span></td>
459
460                <td>Job Id</td>
461              </tr>
462
463              <tr>
464                <td><var class="LITERAL">D</var></td>
465
466                <td><var class="LITERAL">-D</var><span class=
467                "emphasis"><i class="EMPHASIS">Date</i></span></td>
468
469                <td>Date or time information</td>
470              </tr>
471
472              <tr>
473                <td><var class="LITERAL">Q</var></td>
474
475                <td><var class="LITERAL">-Q</var><span class=
476                "emphasis"><i class=
477                "EMPHASIS">Queue</i></span></td>
478
479                <td>Original Print queue job was sent to</td>
480              </tr>
481
482              <tr>
483                <td><var class="LITERAL">N</var></td>
484
485                <td><var class="LITERAL">-N</var><span class=
486                "emphasis"><i class=
487                "EMPHASIS">Filename</i></span></td>
488
489                <td>Filename</td>
490              </tr>
491
492              <tr>
493                <td><var class="LITERAL">f,l,p,...</var></td>
494
495                <td><var class="LITERAL">-F</var><span class=
496                "emphasis"><i class="EMPHASIS">f</i></span></td>
497
498                <td>Datafile format</td>
499              </tr>
500
501              <tr>
502                <td><var class="LITERAL">U</var></td>
503
504                <td>&nbsp;</td>
505
506                <td>Datafile (historical)</td>
507              </tr>
508            </tbody>
509          </table>
510        </div>
511
512        <p>When a print filter processes these jobs the values in
513        the control file are passed on the command line as options
514        starting with upper case letters:</p>
515
516        <div class="INFORMALEXAMPLE">
517          <a name="AEN2378"></a>
518<pre class="SCREEN">
519    /tmp/testf -Apapowell@h4+26681 -CA \
520       -D2000-04-11-21:39:21.877 -Ff -Hh4.private ....
521</pre>
522        </div>
523        Sometimes we want to pass only a small subset of these
524        command line options to a filter or provide them in a
525        specific order in order to be compatible with <span class=
526        "emphasis"><i class="EMPHASIS">legacy</i></span> print
527        filters. <b class="APPLICATION">LPRng</b> provides several
528        different ways to do this and we will explore how to
529        control command line options.<br>
530        <br>
531
532        <p>If the filter entry starts with <var class=
533        "LITERAL">-$</var>, this suppresses the automatic addition
534        of command line options; we can then add our own options to
535        the command line. Modify the printcap entry to have the
536        following form:</p>
537
538        <div class="INFORMALEXAMPLE">
539          <a name="AEN2384"></a>
540<pre class="SCREEN">
541    lp:sd=/var/spool/lpd/%P
542      :force_localhost
543      :lp=/tmp/lp
544      :filter= -$ /tmp/testf '$P' $0P -X$-P ${lp} G\072 or \:
545</pre>
546        </div>
547        <br>
548        <br>
549
550        <p>Lets print our <tt class="FILENAME">/tmp/hi</tt> test
551        file and then look at the <b class="APPLICATION">lpq</b>
552        status:</p>
553
554        <div class="INFORMALEXAMPLE">
555          <a name="AEN2389"></a>
556<pre class="SCREEN">
557    <samp class="PROMPT">h4: {169} %</samp> <kbd class=
558"USERINPUT">cp /dev/null /tmp/lp</kbd>
559    <samp class="PROMPT">h4: {170} %</samp> <kbd class=
560"USERINPUT">lpr /tmp/hi</kbd>
561    <samp class="PROMPT">h4: {171} %</samp> <kbd class=
562"USERINPUT">lpq -llll</kbd>
563    Printer: lp@h4
564     ....
565     Status: IF filter msg - 'TESTF /tmp/testf -Plp -P lp -Xlp \
566        -Ylp /tmp/lp G: or :' at 01:20:21.560
567</pre>
568        </div>
569        <br>
570        <br>
571
572        <p>The <var class="LITERAL">-$</var> suppresses the adding
573        the default literals to the filter command line. You can
574        pass specific options using <var class="LITERAL">$X</var>;
575        if the option has a non-null value then it will be expanded
576        in the following format:</p>
577
578        <div class="INFORMALEXAMPLE">
579          <a name="AEN2400"></a>
580<pre class="SCREEN">
581    Option    Value Expansion
582    $X        -X&lt;value&gt;
583    $'X       -X'&lt;value&gt;'
584    $0X       -X '&lt;value&gt;'
585    $-X       &lt;value&gt;
586    $'-X      '&lt;value&gt;'
587    ${X}      control file X option value
588    $'{X}     control file X option value (in quotes)
589    ${name}   printcap option value if value nonzero length
590    $'{name}  printcap option value if value nonzero length in quotes
591    \nnn      single printable character
592    $*        all options in control file expanded using $X
593</pre>
594        </div>
595        <br>
596        <br>
597
598        <p>Command line options can be grouped and passed as a
599        single argument by enclosing them in single or double
600        quotes. You should be aware that <b class=
601        "APPLICATION">LPRng</b> has an <span class="emphasis"><i
602        class="EMPHASIS">extremely</i></span> primitive way of
603        handling quotes. When the <tt class="COMMAND">/bin/sh
604        -c</tt> parameter is not used, the the command line is
605        broken on spaces and each unit is passed as an individual
606        argument. If the first character after a space is a quote
607        (single or double), the next quote is found, and then
608        entire element is then used as a single parameter.
609        Substitution of <var class="LITERAL">$X</var> parameters is
610        then done. As a special case, when you have a <var class=
611        "LITERAL">$0X</var>, this causes a split and all of the
612        string previous and including the <var class=
613        "LITERAL">-X</var> flag is passed as a single option and
614        all of the option value and following are passed as another
615        option. If the result of the expansion is a zero length
616        parameter then it is removed from the parameter list. When
617        the <tt class="COMMAND">/bin/sh -c</tt> is used the command
618        line is not broken, and all non-empty option values are
619        enclosed in single quotes.</p>
620
621        <p>The <var class="LITERAL">${name}</var> option is used to
622        pass a printcap option value. For example, you can pass the
623        value of the printcap option <var class=
624        "LITERAL">form</var> as shown below. You can experiment
625        with this by using the <tt class="FILENAME">/tmp/testf</tt>
626        filter and printcap shown below.</p>
627
628        <div class="INFORMALEXAMPLE">
629          <a name="AEN2414"></a>
630<pre class="SCREEN">
631    printcap:
632    lp:sd=/var/spool/lpd/%P
633      :force_localhost
634      :lp=/tmp/lp
635      :filter=/tmp/testf -F ${form}
636      :form=payroll
637    
638    <samp class="PROMPT">h4: {172} %</samp> <kbd class=
639"USERINPUT">cp /dev/null /tmp/lp</kbd>
640    <samp class="PROMPT">h4: {173} %</samp> <kbd class=
641"USERINPUT">lpr /tmp/hi</kbd>
642    <samp class="PROMPT">h4: {174} %</samp> <kbd class=
643"USERINPUT">lpq -llll</kbd>
644    Printer: lp@h4
645     ...
646     Status: IF filter msg - 'TESTF /tmp/testf -F payroll' at 09:55:31.276
647     ...
648</pre>
649        </div>
650        <br>
651        <br>
652
653        <p>If we have a <span class="emphasis"><i class=
654        "EMPHASIS">legacy</i></span> print filter that was
655        originally written for the <acronym class=
656        "ACRONYM">BSD</acronym> print spooler, then we may find
657        that it requires a small number of command line options in
658        a very specific order. We can use the <var class=
659        "LITERAL">:bkf</var> (BSD Kompatible Filter or BacKwards
660        compatible Filter) flag to pass suitable options. Modify
661        the printcap entry to have the following form:</p>
662
663        <div class="INFORMALEXAMPLE">
664          <a name="AEN2426"></a>
665<pre class="SCREEN">
666    lp:sd=/var/spool/lpd/%P
667      :force_localhost
668      :lp=/tmp/lp
669      :filter=/tmp/testf
670      :bk
671</pre>
672        </div>
673        <br>
674        <br>
675
676        <p>Lets print our <tt class="FILENAME">/tmp/hi</tt> test
677        file and then look at the <b class="APPLICATION">lpq</b>
678        status:</p>
679
680        <div class="INFORMALEXAMPLE">
681          <a name="AEN2431"></a>
682<pre class="SCREEN">
683    <samp class="PROMPT">h4: {175} %</samp> <kbd class=
684"USERINPUT">cp /dev/null /tmp/lp</kbd>
685    <samp class="PROMPT">h4: {176} %</samp> <kbd class=
686"USERINPUT">lpr /tmp/hi</kbd>
687    <samp class="PROMPT">h4: {177} %</samp> <kbd class=
688"USERINPUT">lpq -llll</kbd>
689    Printer: lp@h4
690     ....
691     Status: IF filter msg - 'TESTF /tmp/testf -Plp -w80 -l66 \
692        -x0 -y0 -Ff -Lpapowell -J/tmp/hi -CA -n papowell \
693        -h h4.private acct' at 08:07:46.583
694</pre>
695        </div>
696        <br>
697        <br>
698
699        <p>Finally, there are times when we would like the print
700        filter to be a simple shell command or to chain several
701        programs together in a simple pipeline. While this is
702        possible using a print filter, you can also do this in the
703        filter specification. If your filter specification starts
704        with a parenthesis (<var class="LITERAL">(</var>) or
705        contains the IO redirection for pipeto (<var class=
706        "LITERAL">|</var>), input redirection (<var class=
707        "LITERAL">&lt;</var>), or output redirection (<var class=
708        "LITERAL">&gt;</var>) then the <b class=
709        "APPLICATION">lpd</b> server will use the <var class=
710        "LITERAL">:shell</var> configuration option value (default
711        <tt class="FILENAME">/bin/sh</tt>) and execute it
712        using:</p>
713
714        <div class="INFORMALEXAMPLE">
715          <a name="AEN2447"></a>
716<pre class="SCREEN">
717    ${shell} -c "( ${if} )"
718</pre>
719        </div>
720        <br>
721        <br>
722
723        <p>If this is done, then no command line options are added
724        to the command. However, expansion of <var class=
725        "LITERAL">$X</var> parameters are still done. Modify the
726        printcap entry to have the following form:</p>
727
728        <div class="INFORMALEXAMPLE">
729          <a name="AEN2451"></a>
730<pre class="SCREEN">
731    lp:sd=/var/spool/lpd/%P
732      :force_localhost
733      :lp=/tmp/lp
734      :filter=(echo "PREAMBLE"; /tmp/testf; echo "APPENDIX")
735</pre>
736        </div>
737        <br>
738        <br>
739
740        <p>Lets print our <tt class="FILENAME">/tmp/hi</tt> test
741        file and then look at the <b class="APPLICATION">lpq</b>
742        status:</p>
743
744        <div class="INFORMALEXAMPLE">
745          <a name="AEN2456"></a>
746<pre class="SCREEN">
747    <samp class="PROMPT">h4: {178} %</samp> <kbd class=
748"USERINPUT">cp /dev/null /tmp/lp</kbd>
749    <samp class="PROMPT">h4: {179} %</samp> <kbd class=
750"USERINPUT">lpr /tmp/hi</kbd>
751    <samp class="PROMPT">h4: {180} %</samp> <kbd class=
752"USERINPUT">lpq -llll</kbd>
753    Printer: lp@h4
754     ....
755     Status: printing data file 'dfA018881h4.private', size 3, \
756       IF filter 'echo' at 09:22:11.476
757     Status: IF filter msg - 'TESTF /tmp/testf' at 09:22:11.510
758     Status: IF filter finished at 09:22:11.514
759</pre>
760        </div>
761        <br>
762        <br>
763
764        <p>If we examine the <tt class="FILENAME">/tmp/lp</tt> file
765        we find:</p>
766
767        <div class="INFORMALEXAMPLE">
768          <a name="AEN2466"></a>
769<pre class="SCREEN">
770    PREAMBLE
771    TESTF /tmp/testf
772    ENV
773    USER=papowell
774    LD_LIBRARY_PATH=/lib:/usr/lib:/usr/5lib:/usr/ucblib
775    ...
776    PRINTER=lp
777    LEADER
778    hi
779    TRAILER
780    APPENDIX
781</pre>
782        </div>
783        <br>
784        <br>
785
786        <p>As we expected, no options were passed on the command
787        line. If the printcap is modified to have the following
788        contents, then you will see:</p>
789
790        <div class="INFORMALEXAMPLE">
791          <a name="AEN2469"></a>
792<pre class="SCREEN">
793    lp:sd=/var/spool/lpd/%P
794      :force_localhost
795      :lp=/tmp/lp
796      :filter=(echo "PREAMBLE"; /tmp/testf $*; echo "APPENDIX")
797    
798    <samp class="PROMPT">h4: {181} %</samp> <kbd class=
799"USERINPUT">lpr /tmp/hi</kbd>
800    <samp class="PROMPT">h4: {182} %</samp> <kbd class=
801"USERINPUT">lpq -llll</kbd>
802    Printer: lp@h4
803     ....
804     Status: IF filter msg - 'TESTF /tmp/testf -Apapowell@h4+18941 \
805       -CA -D2000-04-29-09:27:30.700 -Ff -Hh4.private -J/tmp/hi \
806       -Lpapowell -Plp -Qlp -aacct -b3 -d/var/tmp/LPD/lp \
807       -edfA018941h4.private -f/tmp/hi -hh4.private -j018941 \
808       -kcfA018941h4.private -l66 -npapowell -sstatus \
809       -t2000-04-29-09:27:30.864 -w80 -x0 -y0 acct' at 09:27:30.879
810</pre>
811        </div>
812        <br>
813        <br>
814
815        <p>Using the shell invocation is especially useful when you
816        may have a parameter that has an empty string value, and
817        need to pass this as a command line parameter. Modify the
818        <tt class="FILENAME">/tmp/testf</tt> filter, the printcap,
819        and execute the following commands:</p>
820
821        <div class="INFORMALEXAMPLE">
822          <a name="AEN2477"></a>
823<pre class="SCREEN">
824    printcap:
825      lp:sd=/var/spool/lpd/%P
826        :force_localhost
827        :lp=/tmp/lp
828        :filter=( /tmp/testf -F '${form}' )
829        :form=
830    
831    #!/bin/sh
832    # /tmp/testf - test filter for LPRng
833    PATH=/bin:/usr/bin; export PATH
834    echo TESTF $0 "$@" &gt;&amp;2
835    echo TESTF $0 "$@"
836    while test $# -gt 0 ; do
837      echo "PARM '$1'";
838      shift;
839    done
840    echo LEADER
841    /bin/cat
842    echo TRAILER
843    exit 0
844    
845    <samp class="PROMPT">h4: {183} %</samp> <kbd class=
846"USERINPUT">cp /dev/null /tmp/lp</kbd>
847    <samp class="PROMPT">h4: {184} %</samp> <kbd class=
848"USERINPUT">lpr /tmp/hi</kbd>
849    <samp class="PROMPT">h4: {185} %</samp> <kbd class=
850"USERINPUT">lpq -llll</kbd>
851    Printer: lp@h4
852     ...
853     Status: IF filter msg - 'TESTF /tmp/testf -F' at 09:59:27.365
854    
855    <samp class="PROMPT">h4: {186} %</samp> <kbd class=
856"USERINPUT">more /tmp/lp</kbd>
857    TESTF /tmp/testf -F
858    PARM '-F'
859    PARM ''
860    LEADER
861    hi
862    TRAILER
863</pre>
864        </div>
865        <br>
866        <br>
867
868        <p>As you can see, there are <span class="emphasis"><i
869        class="EMPHASIS">empty</i></span> parameters passed to the
870        filter. This is due to the combination of the <var class=
871        "LITERAL">$'{form}</var> and using the <var class=
872        "LITERAL">:filter=(...)</var> form.</p>
873      </div>
874
875      <div class="SECT2">
876        <h2 class="SECT2"><a name="FILTERENVIRONMENTVARS">4.9.2.
877        Filter Environment Variables</a></h2>
878
879        <p>In this section we will look further at the environment
880        variables passed to the filter. We printed the shell
881        variable values for the filter at the start of the
882        file:</p>
883
884        <div class="INFORMALEXAMPLE">
885          <a name="AEN2494"></a>
886<pre class="SCREEN">
887    <samp class="PROMPT">h4: {187} %</samp> <kbd class=
888"USERINPUT">cat /tmp/lp</kbd>
889    /tmp/testf -Plp -P lp -Xlp -Ylp /tmp/lp G:' at 01:20:21.560
890    ENV
891    CONTROL=Hh4.private
892     Ppapowell
893     J/tmp/hi
894     CA
895     Lpapowell
896     Apapowell@h4+105
897     D2000-04-12-15:27:26.662
898     Qlp
899     N/tmp/hi
900     fdfA105h4.private
901     UdfA105h4.private
902    HOME=/home/daemon
903    LD_LIBRARY_PATH=/lib:/usr/lib:/usr/5lib:/usr/ucblib
904    LOGDIR=/home/daemon
905    LOGNAME=daemon
906    OPTIND=1
907    PATH=/bin:/usr/bin:/usr/local/bin
908    PRINTCAP_ENTRY=lp
909     :force_localhost
910     :filter=/tmp/testf
911     :lp=/tmp/lp
912     :sd=/tmp/LPD/lp
913    PRINTER=lp
914    PS1=$
915    PS2=&gt;
916    SHELL=/bin/sh
917    SPOOL_DIR=/tmp/LPD/lp
918    USER=daemon
919    
920    LEADER
921    hi
922    TRAILER
923</pre>
924        </div>
925        <br>
926        <br>
927
928        <p>The <var class="ENVAR">HOME</var>, <var class=
929        "ENVAR">USER</var>, <var class="ENVAR">SHELL</var>, <var
930        class="ENVAR">PS1</var>, and <var class="ENVAR">PS2</var>
931        variables are usually set by the shell, and are reflect the
932        information for the <acronym class="ACRONYM">UID</acronym>
933        of the user running the shell.</p>
934
935        <p>The <var class="ENVAR">PATH</var> and <var class=
936        "LITERAL">LP_LIBRARY_PATH</var> are set by the <b class=
937        "APPLICATION">lpd</b> server to values specified in the
938        printcap or configuration information. It is recommended
939        that users set these to site specific values if the
940        defaults are not suitable for their sites.</p>
941
942        <p>The <b class="APPLICATION">lpd</b> server sets the <var
943        class="LITERAL">PRINTER</var>, <var class=
944        "LITERAL">PRINTCAP_ENTRY</var>, and <var class=
945        "LITERAL">CONTROL</var> environment variables to the
946        printer name, printcap entry, and control file for the
947        print job. This information is very useful to filters that
948        must make decisions based on values passed to the print
949        server in the control file and which use parameters in the
950        printcap entry to control their actions.</p>
951      </div>
952
953      <div class="SECT2">
954        <h2 class="SECT2"><a name=
955        "USINGCOMMANDLINEANDPRINTCAP">4.9.3. Using Command Line and
956        Printcap Options In Filters</a></h2>
957
958        <p>One of the problems commonly encountered problem in
959        writing a filter is getting the command line values. The
960        UNIX POSIX Standard provides a C Language <code class=
961        "FUNCTION">getopt</code> function that can be used for
962        command line options, and some, but not all shell
963        implementations have a corresponding shell <code class=
964        "FUNCTION">getopt</code> function. Also, many times it
965        would be useful to get the values of the printcap options.
966        These could be used to specify options or operations that
967        are not easily done by passing command lines.</p>
968
969        <ul>
970          <li>
971            <p>Observe that all the command line options are single
972            letters. If we set the shell variables to the
973            corresponding option value, then we could access them
974            by using <var class="LITERAL">$x</var>, where <var
975            class="LITERAL">x</var> is the option letter. There is
976            an exception to this rule, which is the <var class=
977            "LITERAL">-c</var> command line literal, which for
978            various historical and compatibility reasons does not
979            take a value. But if it is present, we might as well
980            assign it the value <var class="LITERAL">1</var>.</p>
981          </li>
982
983          <li>
984            <p>Observe that by convention all printcap options have
985            lowercase names of two or more letters, and that all
986            environment variables have all upper case letters. If
987            we set shell variables with the corresponding printcap
988            entry values, then we can access them using <var class=
989            "LITERAL">$literal</var>. If we need to create a local
990            shell variable for use, we can use <var class=
991            "LITERAL">mIxEd</var> case and not have a conflict.</p>
992          </li>
993        </ul>
994        <br>
995        <br>
996
997        <p>The <var class="LITERAL">decode_args_with_sh</var>
998        script which is in the <acronym class=
999        "ACRONYM">UTILS</acronym> directory of the <b class=
1000        "APPLICATION">LPRng</b> distribution follows these
1001        conventions and sets the appropriate shell variables. We
1002        have also include a bit of code that will extract the
1003        control file control line values and put them into
1004        variables as well.</p>
1005
1006        <p>Save the current <tt class="FILENAME">/tmp/testf</tt>
1007        filter file in <tt class="FILENAME">/tmp/testf.old</tt> and
1008        replace it with the following:</p>
1009
1010        <div class="INFORMALEXAMPLE">
1011          <a name="AEN2537"></a>
1012<pre class="SCREEN">
1013    #!/bin/sh
1014    # this is an example of how to use /bin/sh and LPRng
1015    # to get the command line and printcap option values
1016    # and set shell variables from them
1017    #  Note that we use a couple of variables
1018    #PATH=/bin:/usr/bin
1019    Args=""
1020    vAr=""
1021    vAlue=""
1022    vAls=""
1023    iI=""
1024    Tf=""
1025    Debug=1
1026    if -n $Debug ; then
1027        set &gt;/tmp/before
1028    fi
1029    Args="$@"
1030    if -n $Debug ; then
1031        echo "$@" &gt;&gt;/tmp/before
1032    fi
1033    while expr "$1" : '-.*' &gt;/dev/null ; do
1034      vAr=`expr "$1" : '-\(.\).*'`;
1035      vAlue=`expr "$1" : '-.\(.*\)`;
1036      case "$vAr" in
1037        - ) break;;
1038        c ) c=1;;
1039        [a-zA-Z] )
1040          if test "X$vAlue" = "X" ; then shift; vAlue=$1; fi;
1041          eval $vAr='$vAlue';
1042          #setvar $vAr "$vAlue"
1043          ;;
1044      esac;
1045      shift;
1046    done
1047    
1048    # set shell variables to the printcap options
1049    #  flag   -&gt;  flag=1
1050    #  flag@  -&gt;  flag=0
1051    #  option=value -&gt;  option='value'
1052    #
1053    setpcvals () {
1054        while test "$#" -gt 0 ; do
1055          iI=$1
1056          if expr "$iI" : " *\:" &gt;/dev/null ; then
1057            vAr=`expr "$iI" : " *\:\([^=][^=]*\)=.*"`;
1058            vAlue=`expr "$iI" : " *\:[^=][^=]*=\(.*\)"`;
1059            if test "X$vAr" = "X" ; then
1060              vAr=`expr "$iI" : " *:\(.*\)@"`;
1061              vAlue=0;
1062            fi
1063            if test "X$vAr" = "X" ; then
1064              vAr=`expr "$iI" : " *:\(.*\)"`;
1065              vAlue=1;
1066            fi
1067            if test "X$vAr" != "X" ; then
1068              eval $vAr='$vAlue';
1069              #setvar $vAr "$vAlue"
1070            fi
1071          else
1072            vAr=`expr "$iI" : " *\([^|][^|]*\).*"`;
1073            if test "X$vAr" != "X" ; then
1074              eval Printer="$vAr"
1075            fi
1076          fi;
1077          shift
1078        done
1079    }
1080    
1081    # set shell variables to the printcap options
1082    #  flag   -&gt;  flag=1
1083    #  flag@  -&gt;  flag=0
1084    #  option=value -&gt;  option='value'
1085    #
1086    setcontrolvals () {
1087        while test "$#" -gt 0 ; do
1088          iI=$1
1089          vAr=`expr "$iI" : " *\([A-Z]\).*"`;
1090          vAlue=`expr "$iI" : " *[A-Z]\(.*\)"`;
1091          if test "X$vAr" != "X" ; then
1092            eval $vAr='$vAlue';
1093            #setvar $vAr "$vAlue";
1094          fi;
1095          shift
1096        done
1097    }
1098    
1099    Tf=$IFS
1100    IFS="
1101    "
1102    setpcvals $PRINTCAP_ENTRY
1103    setcontrolvals $CONTROL
1104    IFS=$Tf
1105    
1106    #
1107    # restore argument list
1108    set -- $Args
1109    Args=""
1110    vAr=""
1111    vAlue=""
1112    vAls=""
1113    iI=""
1114    Tf=""
1115    
1116    if test -n "$Debug" ; then
1117        set &gt;/tmp/after
1118        echo "$@" &gt;&gt;/tmp/after
1119        diff /tmp/before /tmp/after
1120    fi
1121    /bin/cat
1122    exit 0
1123</pre>
1124        </div>
1125        <br>
1126        <br>
1127
1128        <p>Lets print our <tt class="FILENAME">/tmp/hi</tt> test
1129        file and then look at the results in <tt class=
1130        "FILENAME">/tmp/lp</tt>:</p>
1131
1132        <div class="INFORMALEXAMPLE">
1133          <a name="AEN2542"></a>
1134<pre class="SCREEN">
1135    <samp class="PROMPT">h4: {188} %</samp> <kbd class=
1136"USERINPUT">cp /dev/null /tmp/lp</kbd>
1137    <samp class="PROMPT">h4: {189} %</samp> <kbd class=
1138"USERINPUT">lpr /tmp/hi</kbd>
1139    <samp class="PROMPT">h4: {190} %</samp> <kbd class=
1140"USERINPUT">more /tmp/lp</kbd>
1141    0a1
1142    &gt; e=dfA021771h4.private
1143    2a4,6
1144    &gt; l=66
1145    &gt; s=status
1146    &gt; L=papowell
1147    10a15,17
1148    &gt; j=021771
1149    &gt; C=A
1150    &gt; J=/tmp/hi
1151    12a20
1152    &gt; a=acct
1153    ...
1154    33a58
1155    &gt; Printer=lp
1156    ...
1157    hi
1158</pre>
1159        </div>
1160        <br>
1161        <br>
1162
1163        <p>As we see from the output, shell variables have the
1164        values of our command line and printcap options. It is left
1165        as an exercise for the reader to add the necessary <var
1166        class="LITERAL">export</var> statements to cause these
1167        values to be exported to subshells. It is <span class=
1168        "emphasis"><i class="EMPHASIS">not</i></span> recommended
1169        that a wholesale export of the shell variables be done, but
1170        only selected ones.</p>
1171
1172        <p>The paranoid and security minded reader will see some
1173        possible security problem with this script. The <var class=
1174        "LITERAL">eval $vAr='$vAlue'</var> command sets the value
1175        of the shell variable <var class="LITERAL">$vAr</var> to
1176        the value <var class="LITERAL">$vAlue</var>. The <var
1177        class="LITERAL">$vAr</var> variable is always taken from
1178        either a single letter or is the name of an option in the
1179        printcap file. Clearly the printcap file must not be
1180        modifiable by users, and should have the same security
1181        considerations as any other system configuration file. The
1182        values of the <var class="LITERAL">$vAlue</var> are taken
1183        directly from the control file, whose contents are under
1184        the control of the originator of the print job request.</p>
1185
1186        <p>For this reason <b class="APPLICATION">LPRng</b> takes
1187        the rather brutal step of <span class="emphasis"><i class=
1188        "EMPHASIS">sanitizing</i></span> the control file. Only
1189        alphanumerics or a character in the list <var class=
1190        "LITERAL">@/:()=,+-%_</var> are used in the control file;
1191        all others replaced by the underscore (<var class=
1192        "LITERAL">_</var>) character. In addition, all filters are
1193        run as the <b class="APPLICATION">lpd</b> user specified in
1194        the <tt class="FILENAME">lpd.conf</tt> configuration
1195        file.</p>
1196
1197        <p>The following is an example of how to extract the same
1198        information in Perl:</p>
1199
1200        <div class="INFORMALEXAMPLE">
1201          <a name="AEN2567"></a>
1202<pre class="SCREEN">
1203    #!/usr/bin/perl
1204    eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
1205        if $running_under_some_shell;
1206                # this emulates #! processing on NIH machines.
1207                # (remove #! line above if indigestible)
1208    
1209    use Getopt::Std;
1210    my(%args,%options);
1211    # get the arguments
1212    getopt(
1213        "a:b:cd:e:f:g:h:i:j:l:m:n:o:p:q:r:s:t:u:v:w:x:y:z:" .
1214        "A:B:C:D:E:F:G:H:I:J:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z:",
1215        \%args );
1216    
1217    # set :key=value  -&gt; $option{$key}=$value
1218    # set :key@       -&gt; $option{$key}="0"
1219    # set :key        -&gt; $option{$key}="1"
1220     map {
1221        if( m/^\s*:([^=]+)=(.*)/ ){
1222         $options{$1}=$2;
1223        } elsif( m/^\s*:([^=]+)\@$/ ){
1224         $options{$1}="0";
1225        } elsif( m/^\s*:([^=]+)/ ){
1226         $options{$1}="1";
1227        } elsif( m/^\s*([^|]+)/ ){
1228         $options{"Printer"}=$1;
1229        }
1230     } split( "\n", $ENV{'PRINTCAP_ENTRY'});
1231    
1232    # get the control file entries
1233     map {
1234        if( m/^\s*([A-Z])(.*)/ ){
1235         $options{$1}=$2;
1236        } elsif( m/^\s*([a-z])/ ){
1237         $options{'Format'}=$1;
1238        }
1239     } split( "\n", $ENV{'CONTROL'});
1240</pre>
1241        </div>
1242        <br>
1243        <br>
1244
1245        <p>The Perl <var class="LITERAL">Getopt::Std</var> routine
1246        parses the command line options and puts their values in
1247        the <var class="LITERAL">%args</var> hash variable where
1248        they can be accessed using <var class=
1249        "LITERAL">$args{'x'}</var>. Similarly, the <var class=
1250        "LITERAL">map</var> and <var class="LITERAL">split</var>
1251        functions process the PRINTCAP_ENTRY and CONTROL
1252        environment variable and set <var class=
1253        "LITERAL">%options</var> with the printcap entry options
1254        and the values from the control file. The <code class=
1255        "FUNCTION">map</code> function could be replaced by a <code
1256        class="FUNCTION">foreach</code> loop, but this is Perl:
1257        <span class="emphasis"><i class="EMPHASIS">There is more
1258        than one way to do it</i></span> and no tutorial would be
1259        complete without at least one mind stretching example that
1260        has the reader reaching for the reference manual.</p>
1261      </div>
1262
1263      <div class="SECT2">
1264        <h2 class="SECT2"><a name="FILTEREXITCODES">4.9.4. Filter
1265        Exit Codes</a></h2>
1266
1267        <p>The <b class="APPLICATION">lpd</b> server uses the exit
1268        code of the filter to determine if the filter was
1269        successful or unsuccessful. The <a href=
1270        "exitcodes.htm">Filter Exit Codes</a> section discusses
1271        these values in detail, but here are the most
1272        important:</p>
1273
1274        <div class="VARIABLELIST">
1275          <dl>
1276            <dt>0 - JSUCC</dt>
1277
1278            <dd>
1279              <p>A JSUCC exit code indicates that the filter was
1280              successful in doing its work.</p>
1281            </dd>
1282
1283            <dt>1 - JFAIL</dt>
1284
1285            <dd>
1286              <p>A JFAIL exit code indicates that the filter was
1287              unsuccessful in doing its work, possibly due to a
1288              transient condition such as out of paper, printer
1289              jam, etc., but an additional attempt might be
1290              successful. Usually the <b class=
1291              "APPLICATION">lpd</b> server will try at most <a
1292              href="abnormalterm.htm">send_try</a> attempts before
1293              giving up.</p>
1294            </dd>
1295
1296            <dt>2 - JABORT</dt>
1297
1298            <dd>
1299              <p>A JABORT exit code indicates that the filter was
1300              unsuccessful in doing its work and has detected a
1301              condition that would make it impossible to print the
1302              job. In addition, the printer may require
1303              administrative attention, and the print queue
1304              operation may need to be suspended until the problem
1305              is rectified.</p>
1306            </dd>
1307
1308            <dt>3 - JREMOVE</dt>
1309
1310            <dd>
1311              <p>The JREMOVE exit code will cause the job to be
1312              removed from the print queue.</p>
1313            </dd>
1314
1315            <dt>6 - JHOLD</dt>
1316
1317            <dd>
1318              <p>The JHOLD exit code will cause the job to be
1319              temporarily prevented from printing until release by
1320              the <tt class="COMMAND">lpc release</tt> command.</p>
1321            </dd>
1322
1323            <dt>Other Values</dt>
1324
1325            <dd>
1326              <p>Usually any other value, including exit due to a
1327              signal, is treated as a JABORT exit, and the same
1328              action is taken.</p>
1329            </dd>
1330          </dl>
1331        </div>
1332        <br>
1333        <br>
1334
1335        <p>It should be obvious that the filter exit code is very
1336        important, and that care needs to be taken to return the
1337        correct value.</p>
1338      </div>
1339
1340      <div class="SECT2">
1341        <h2 class="SECT2"><a name=
1342        "JOBFORMATSANDFILTERSELECTION">4.9.5. Job Formats and
1343        Filter Selection</a></h2>
1344
1345        <p>In the previous sections we discussed how a print filter
1346        was executed and how it could be used. Now we will look at
1347        how the <b class="APPLICATION">lpd</b> spooler chooses a
1348        print filter program. Let us re-examine our example print
1349        job control file:</p>
1350
1351        <div class="INFORMALEXAMPLE">
1352          <a name="AEN2617"></a>
1353<pre class="SCREEN">
1354    Hh4.private
1355    Ppapowell
1356    J/tmp/hi
1357    CA
1358    Lpapowell
1359    Apapowell@h4+105
1360    D2000-04-12-15:27:26.662
1361    Qlp
1362    N/tmp/hi
1363    fdfA105h4.private
1364    UdfA105h4.private
1365</pre>
1366        </div>
1367        <br>
1368        <br>
1369
1370        <p>Each data file for a print job has a name with the
1371        format <var class="LITERAL">df</var><span class=
1372        "emphasis"><i class="EMPHASIS">X</i></span>nnn<tt class=
1373        "FILENAME">h4.private</tt>. The <var class=
1374        "LITERAL">df</var> is used to indicate that the file is a
1375        <span class="emphasis"><i class="EMPHASIS">data
1376        file</i></span>, and the remainder is a unique name for the
1377        file in the job. The <var class="LITERAL">X</var> part of
1378        the name must be an upper or lower case letter, setting a
1379        limit of 52 different files in a single print job.</p>
1380
1381        <p>The <tt class="FILENAME">fdfA105h4.private</tt> line in
1382        the control file specifies that we are to print the job
1383        using the filter for the <var class="LITERAL">f</var>
1384        format; the file printing information consists of the
1385        format assigned to the file and the name of the file. In
1386        the legacy BSD print spoolers, this format was used to
1387        select the print filter to be used. <b class=
1388        "APPLICATION">LPRng</b> has expanded this by providing a
1389        <span class="emphasis"><i class=
1390        "EMPHASIS">default</i></span> filter specification.</p>
1391
1392        <div class="TABLE">
1393          <a name="JOBFORMAT"></a>
1394
1395          <p><b>Table 4-2. Job Formats and Filter Selection</b></p>
1396
1397          <table border="1" frame="border" rules="all" class=
1398          "CALSTABLE">
1399            <col>
1400            <col>
1401            <col>
1402
1403            <thead>
1404              <tr>
1405                <th><b class="APPLICATION">lpr</b> command line
1406                option</th>
1407
1408                <th>Control File Line</th>
1409
1410                <th>Printcap Option For Filter</th>
1411
1412                <th>Filter Command Line</th>
1413              </tr>
1414            </thead>
1415
1416            <tbody>
1417              <tr>
1418                <td>(default)</td>
1419
1420                <td>fdfAnnn</td>
1421
1422                <td>:if=/path</td>
1423
1424                <td>/path -Ff ...</td>
1425              </tr>
1426
1427              <tr>
1428                <td>-b or -l</td>
1429
1430                <td>ldfAnnn</td>
1431
1432                <td>:if=/path</td>
1433
1434                <td>/path ... -Ff -c</td>
1435              </tr>
1436
1437              <tr>
1438                <td>-p</td>
1439
1440                <td>pdfAnnn</td>
1441
1442                <td>:if=/path</td>
1443
1444                <td>pr | format f filter</td>
1445              </tr>
1446
1447              <tr>
1448                <td>-c, -d, -n, -r, -t, -v, -FX</td>
1449
1450                <td>XdfAnnn</td>
1451
1452                <td>:Xf=/path ...</td>
1453
1454                <td>/path -FX</td>
1455              </tr>
1456
1457              <tr>
1458                <td>any format</td>
1459
1460                <td>XdfAnnn</td>
1461
1462                <td>:filter=/path ...</td>
1463
1464                <td>/path -FX</td>
1465              </tr>
1466            </tbody>
1467          </table>
1468        </div>
1469
1470        <p><a href="printjobfilters.htm#JOBFORMAT">Table 4-2</a>
1471        shows the rather baroque relationship between the format
1472        options specified by the <b class="APPLICATION">lpr</b>
1473        command and the way that <b class="APPLICATION">lpd</b>
1474        uses them. The reason for this complexity lies in the
1475        various implementations and variations that occurred during
1476        the development and deployment of the original BSD print
1477        spooling software.</p>
1478
1479        <p>Here is the complete, arcane, and baroque set of rules
1480        that are used to select and print filters. The de<var
1481        class="LITERAL">f</var>ault format used by <b class=
1482        "APPLICATION">lpr</b> is <var class="LITERAL">f</var>;
1483        unless some other format is specified this is used. The <tt
1484        class="COMMAND">lpr -b</tt> and <tt class="COMMAND">lpr
1485        -l</tt> (<var class="LITERAL">b</var>inary and <var class=
1486        "LITERAL">l</var>iteral literals) are a request to <b
1487        class="APPLICATION">lpd</b> to do as little processing as
1488        possible of this file before printing it. <b class=
1489        "APPLICATION">Lpd</b> use the <var class=
1490        "LITERAL">:if</var> filter for formats <var class=
1491        "LITERAL">f</var> and <var class="LITERAL">l</var>; the
1492        <var class="LITERAL">l</var> literal causes the the <var
1493        class="LITERAL">-c</var> filter command line flag to be
1494        used as well. The <tt class="COMMAND">lpr</tt> <var class=
1495        "LITERAL">-c</var>, <var class="LITERAL">-d</var>, <var
1496        class="LITERAL">-n</var>, <var class="LITERAL">-r</var>,
1497        <var class="LITERAL">-t</var>, and <var class=
1498        "LITERAL">-v</var> options cause the corresponding format
1499        to be used, and for <b class="APPLICATION">lpd</b> to use
1500        the filter specified by the printcap option <var class=
1501        "LITERAL">:Xf</var>, where <var class="LITERAL">X</var> is
1502        the specified format.</p>
1503
1504        <p>The <tt class="COMMAND">lpr -p</tt> (<var class=
1505        "LITERAL">p</var>retty-print literal) selects <var class=
1506        "LITERAL">p</var> format, and <b class=
1507        "APPLICATION">lpd</b> is supposed to use the program
1508        specified by the <var class="LITERAL">:pr</var> printcap
1509        option to format the file and then process the output of
1510        this program according to format <var class=
1511        "LITERAL">f</var>. Unpredictable results may occur using
1512        this facility.</p>
1513
1514        <p>the <tt class="COMMAND">lpr -FX</tt> allows you to
1515        explicitly specify format <var class="LITERAL">X</var>
1516        where <var class="LITERAL">X</var> is a lower case letter,
1517        and <b class="APPLICATION">lpd</b> will use the filter
1518        specified by printcap option <var class=
1519        "LITERAL">:Xf</var>, where <var class="LITERAL">X</var> is
1520        the specified format. If there is no <var class=
1521        "LITERAL">:Xf</var> printcap literal value then the
1522        printcap <var class="LITERAL">:filter</var> literal value
1523        will be used as the filter, and if this is undefined then
1524        the file will be passed without processing through to the
1525        printing device.</p>
1526
1527        <p>If a filter is not specified for the format then the
1528        default filter specified by <var class=
1529        "LITERAL">:filter=/path</var> filter is used, and if there
1530        is no default, then the output is sent directly to the
1531        output device.</p>
1532
1533        <p>If the <var class="LITERAL">:fx=</var><span class=
1534        "emphasis"><i class="EMPHASIS">formats</i></span> is
1535        present in a printcap entry, it specifies the formats that
1536        are allowed. For example, <var class=
1537        "LITERAL">:fx=lfv</var> would allow only formats <var
1538        class="LITERAL">l</var>, <var class="LITERAL">f</var>, and
1539        <var class="LITERAL">v</var> to be used on a particular
1540        spool queue.</p>
1541
1542        <p>Some <var class="LITERAL">Xf</var> options have
1543        pre-assigned meanings and cannot be used for filter
1544        selection.</p>
1545
1546        <div class="INFORMALTABLE">
1547          <a name="AEN2723"></a>
1548
1549          <table border="1" class="CALSTABLE">
1550            <col>
1551            <col>
1552
1553            <thead>
1554              <tr>
1555                <th>Printcap Option</th>
1556
1557                <th>Purpose</th>
1558              </tr>
1559            </thead>
1560
1561            <tbody>
1562              <tr>
1563                <td>Printcap Option</td>
1564
1565                <td>Purpose</td>
1566              </tr>
1567
1568              <tr>
1569                <td>:af=/path</td>
1570
1571                <td>Accounting File</td>
1572              </tr>
1573
1574              <tr>
1575                <td>:ff=formfeed</td>
1576
1577                <td>Form Feed String</td>
1578              </tr>
1579
1580              <tr>
1581                <td>:if=/path</td>
1582
1583                <td>filter (l,b,p,f formats)</td>
1584              </tr>
1585
1586              <tr>
1587                <td>:filter=/path</td>
1588
1589                <td>Default filter</td>
1590              </tr>
1591
1592              <tr>
1593                <td>:lf=/path</td>
1594
1595                <td>Log file</td>
1596              </tr>
1597
1598              <tr>
1599                <td>:of=/path</td>
1600
1601                <td>OF filter</td>
1602              </tr>
1603
1604              <tr>
1605                <td>:sf</td>
1606
1607                <td>suppress form feed between job files</td>
1608              </tr>
1609            </tbody>
1610          </table>
1611        </div>
1612
1613        <p>The <var class="LITERAL">:of</var> filter is a special
1614        case and is used for banner printing and accounting
1615        purposes. See <a href="ofdetails.htm">OF Filter</a> for
1616        details.</p>
1617      </div>
1618    </div>
1619
1620    <div class="NAVFOOTER">
1621      <hr align="LEFT" width="100%">
1622
1623      <table summary="Footer navigation table" width="100%" border=
1624      "0" cellpadding="0" cellspacing="0">
1625        <tr>
1626          <td width="33%" align="left" valign="top"><a href=
1627          "jobremoval.htm" accesskey="P">Prev</a></td>
1628
1629          <td width="34%" align="center" valign="top"><a href=
1630          "index.htm" accesskey="H">Home</a></td>
1631
1632          <td width="33%" align="right" valign="top"><a href=
1633          "jobfileformatconversion.htm" accesskey="N">Next</a></td>
1634        </tr>
1635
1636        <tr>
1637          <td width="33%" align="left" valign="top">Job
1638          Removal</td>
1639
1640          <td width="34%" align="center" valign="top"><a href=
1641          "tutorial.htm" accesskey="U">Up</a></td>
1642
1643          <td width="33%" align="right" valign="top">Job File
1644          Format Conversion with Filters</td>
1645        </tr>
1646      </table>
1647    </div>
1648  </body>
1649</html>
1650
1651