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 "$@" >&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=> 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> </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> </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<value> 583 $'X -X'<value>' 584 $0X -X '<value>' 585 $-X <value> 586 $'-X '<value>' 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"><</var>), or output redirection (<var class= 708 "LITERAL">></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 "$@" >&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=> 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 >/tmp/before 1028 fi 1029 Args="$@" 1030 if -n $Debug ; then 1031 echo "$@" >>/tmp/before 1032 fi 1033 while expr "$1" : '-.*' >/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 -> flag=1 1050 # flag@ -> flag=0 1051 # option=value -> option='value' 1052 # 1053 setpcvals () { 1054 while test "$#" -gt 0 ; do 1055 iI=$1 1056 if expr "$iI" : " *\:" >/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 -> flag=1 1083 # flag@ -> flag=0 1084 # option=value -> 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 >/tmp/after 1118 echo "$@" >>/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 > e=dfA021771h4.private 1143 2a4,6 1144 > l=66 1145 > s=status 1146 > L=papowell 1147 10a15,17 1148 > j=021771 1149 > C=A 1150 > J=/tmp/hi 1151 12a20 1152 > a=acct 1153 ... 1154 33a58 1155 > 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 -> $option{$key}=$value 1218 # set :key@ -> $option{$key}="0" 1219 # set :key -> $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