This section gives an overview of how LPRng uses filter programs, and gives a detailed discussion of how the printcap options and filters interact.
Print filters are one of the most powerful tools in BSD-style printer systems.
In general UNIX terms, a filter is a program that takes its input file(s), does something with it, and sends the result to its standard output. Most UNIX utilities are designed as filters. (But since you are a system manager, you should already know that :))
In the context of a BSD-style print spooler (and also LPRng), the term filter refers to a program that processes file while it is being transferred to a printer.
The filter is executed with STDIN reading from the file to be printed STDOUT to the printer device or a temporary file. STDERR (file handle 2) is redirected to a log file, and file handle 3 to an accounting file.
A filter can be as simple as a LF
to CR/LF
translator,
or it can incorporate a complete
accounting system, automatic file type translations,
or even redirect the job to another printing system.
As part of the LPRng project, the following filters are supported. The are many others available for use, but are currently not supported.
The supported filters and other facilities are available from ftp://ftp.astart.com/pub/LPRngOptions used:
if
,
cf
,
df
,
gf
,
nf
,
of
,
rf
,
tf
,
vf
,
Xf
,
Filter programs LPRng has inherited a set of so-called `print formats' from its
BSD ancestor.
The format was used to specify the type of file that was being printed.
The lpd
server
used the print format to select the filter for processing the file.
The default format is f
.
The user can specify the format (i.e., the file type) by giving
the appropriate option to lpr
:
-b
or -l
: Binary (literal) file. No processing should
be done.
The
l
format is recorded as the file format.-c
: cifplot(1) output.-d
: TeX DVI file.-g
: Output from the plot(3X) routines.-n
or -t
: (di)troff output.-p
: Text file that should be pre-processed by the pr
command, and then by the standard text filter.-v
: Benson Varian raster image.Alternatively, one can also use
-Fx
, where x
is the format specifier.
(E.g., -Fc
instead of -c
.)
This last form also allows you to use other
(non-standard) format specifiers.
The filter for format
X
is the value for the
Xf
printcap
option,
with some minor exceptions.
The following
Xf
options have a pre-defined meaning.
if
The f
format filter,
i.e. - for the default
f
format.
All print jobs are passed
through this one, unless another format is selected.cf
Cifplot data filter (for -c
format).df
Filter for DVI files (-d
).gf
Graph data filter (-g
).nf
Ditroff data filter (-n
).of
This filter is used for processing the (optional)
banner at the start and/or end of the print job,
and also for the interjob separators.
See
of filter for details.rf
Filter for Fortran style files (-r
).tf
Troff filter (-t
).vf
(Versatek) raster image filter (-v
).The
of
filter is used to process banners and job separators.
The
of
filter is responsible for performing appropriate
processing of this information and sending to the printer
for action.
While the various file filters are invoked on a once per print file basis,
the
of
filter is invoked on a once per print job basis.
This filter is the first one to be started, and should perform whatever specialized device initialization is needed. It should also do whatever accounting procedure is desired for start of job accounting.
The
of
filter will be given any banner printing or job separation
information for a job.
As part of its operation,
it can detect a specific string,
corresponding to a banner print request,
and generate a banner.
(See the
Job Processing Steps and Printcap Options
for details.)
During operation,
the
lpd
server will send the special
stop sequence of \031\001
to the
of
filter.
The filter must then suspend itself using a
kill -STOP
operation.
The lpd
server will detect that the
of
filter has suspended itself and then
will perform other printing operations.
After the other printing operations have been completed,
the of
will then be sent a
kill -CONT
signal.
This sequence will continue until all information has been printed,
and then the of
filter's STDIN will be closed.
The filter will then perform whatever cleanup operations are needed,
update accounting or other information,
and exit.
Options used:
pr=
pr program for p formatThe -p
format is requires filtering the
the input files by the pr
utility
and then passing the result through the
if
filter.
This is widely regarded as a kludge and may not be supported on your print spooler.
The binary (or literal) format is -l
.
The if
filter
is used to process the file,
and is invoked with the
-c
(c
ancel processing?) flag.
The filter will not modify the file when sending it to the printer, but may apply various setups to the printer.
Options used:
bk_filter_options=
Backwards Compatible Filter optionsbk_of_filter_options=
Backwards Compatible OF Filter optionsbkf
Backwards Compatible Filtersfilter_ld_path=
Filter LD_LIBRARY_PATH environmentfilter_options=
Filter optionsfilter_path=
Filter PATH environmentof_filter_options=
OF Filter optionspass_env=
Environment variables to copy to Filter environmentpl#
line count for pagepw#
column count for pagepx#
pixel width for pagepy#
pixel length for pageA filter (or program) specification in the LPRng printcap database usually has the form:
:option=| [flags] /path [arguments]
:option=[flags] /path [arguments]
The first case is used where the option value can be a string or filter, and the second where a program is always expected. The following procedure is used to run a filter program.
The sequence of operations to run a filter is as follows:
lpr
, lpc
, etc.
If invoked from lpd
, it is run as the
server_user
user
(default daemon
) configuration entry.The alternative to ROOT is to have a setuid ROOT executable. Under NO circumstances should you run a shell script setuid ROOT, with general execute permissions on it.
filter_options
to the program command line.bkf
(Berkeley LPD filter compatible flag) flag are added to the
filter command line.
If bkf
is false the
filter_options
are added for OF filters and
of_filter_options
are added for non-OF filters;
if it is true, then the
bk_filter_options
and bk_of_filter_options
are added for
OF and non-OF filters respectively.
Option | DefaultValue |
filter_options | $C $F $H $J $L $P $Q $R $Z $a $c $d $e $f $h $i $j $k $l $n $p$r $s $w $x $y $-a |
of_filter_options | (same as filter_options ) |
bk_filter_options | $P $w $l $x $y $F $c $L $i $J $C $0n $0h $-a |
bk_of_filter_options | $w $l $x $y |
filter_options
arguments are added.
For print job filters, if the bkf
flag is set,
then the
bk_filter_options
and
bk_of_filter_options
entries are used.
The default bk
filter options are the same as originally used
with the BSD LPR filters.
For the of
filter,
either the of_filter_options
or bk_of_filter_options
arguments will be added.$
letter will be
translated into values from the
print job control file and/or printcap entry.
The letters have the following meaning:
Letter | TranslatedValue |
a | printcap af (accounting file name) |
b | job size (in K bytes) |
c | binary file (l format for print file) |
d | printcap cd or sd entry |
e | print job data file name (currently being processed) |
f | print job original name when spooled for printing (N info from control file) |
h | print job originating host (H info from control file) |
i | indent request (I info from control file) |
j | job number in spool queue |
k | print job control file name |
l | printcap pl (page length) |
m | printcap co |
n | user name (L info from control file) |
p | remote printer (when processing for bounce queue) |
r | remote host (when processing for bounce queue) |
s | printcap sf (status file) |
t | time in common UNIX format |
w | printcap pw (page width) |
x | printcap px (page x dimension) |
y | printcap py (page y dimension) |
F | print file format |
P | printer name |
S | printcap cm (comment field) |
Capital letter | Corresponding line from control file |
{key} | printcap value for key |
Form | TranslatedValue |
$x | '-xvalue' |
$-x | 'value' |
$0x | -x 'value' |
$'x | -x value |
Each entry in quotes is treated as a single value,
as in /bin/sh.
The $'x
does not quote the value.
Combinations of the various flags are allowed. For example,
$-x
would simply substitute the value for x
,
and then pass the whitespace separated components as individual arguments.
This last form is useful for adding in additional flags on the command line.
_
(underscores),
and an argument list suitable for the execve
system call
is formed.
USER | User name (client only) |
LOGNAME | L control file info |
HOME | Home directory (client only) |
LOGDIR | Home directory (client only) |
PATH | filter_path configuration information |
LD_LIBRARY_PATH | filter_ld_path configuration information |
SHELL | /bin/sh |
IFS | " \t" |
TZ | Time zone |
SPOOL_DIR | sd printcap info |
CONTROL_DIR | cd printcap info |
PRINTCAP_ENTRY | printcap info |
CONTROL | control file |
lpr
,
then the environment variables specified by the
pass_env
configuration or printcap option will be
extracted from the environment,
have any metacharacters removed,
and then placed in the environment variable list.
Commonly, the
PGPPASS
,
PGPPASSFD
,
and PGPPATH
are specified./dev/null
.There already exists a large library of ready-to-use filters. Some of them have LPRng-specific versions, which can be found at the LPRng ftp mirror sites.
By convention, most filters are either totally standalone (very rare), or require a set of support files. There are two types of support files: per print queue configuration information and global support information.
Since a print filter will execute with the current directory set to the
spool queue directory,
most filters expect that per print queue configuration information
should be kept in the spool directory.
Most vintage filters insist on having these files hidden
with names such as .setup
.
This can make it difficult for administrators to determine where the
configuration files are.
It is strongly recommended that filters and information
be placed in commonly accessible directories such as
/usr/local/lib/filters
,
and the executables in subdirectories.
This allows the LPRng administrator to set the privileges on these
directories such that only the lpd
process can
access them.
Most of the LPRng supported filters can either be used as a
if
or of
filter.
The filter will examine the format type passed by the -FX
command line argument,
and if it is o
it will perform as an of
filter.
Alternatively,
the filter will check the filename in the pathname by which is was invoked.
If the name has the substring of
in the filename,
then it assumes it is to act as an of
filter.
This allows symbolic links to be made to a common filter executable,
each of which corresponds to the filter name by which it is to be invoked.
When a filter is invoked, it is passed a large number of options, many of which are totally ignored in filter operation. However, for many purposes it is necessary to provide options to the filters to tailor their operation to the particular spool queue needs.
By convention, all LPRng supported filters use the
-Tkey=value[,key=value]
convention for specifying filter configuration option values.
Source code: LPRng Distribution
This filter is distributed as part of the LPRng source code,
and has a very limited functionality.
By default,
it only translates \n
to \r\n
sequences,
and detects the OF Filter Stop sequence when invoked as an OF filter.
-Tcrlf
- suppress \n
to \r\n
translationSource code: LPRng Distribution, ifhp-<em>version</em>.tgz
This filter supports a wide variety of smart printers, or to be more specific, printers which support PostScript, PCL or PJL languages.
As explained in Setting Up Your Printer, you can have a parallel (unidirectional), serial (bidirectional), or network (bidirectional) connection. When using a bidirectional connection, you can sometime obtain or gratuitously receive error and/or status information from the printer.
Some printers will spontaneously generate error messages when printing a job on a bidirectional interface. Usually, though, it it necessary to force the printer to provide status in a reasonable format.
Some printers have the capability of printing either PCL or PostScript; some require special setup commands and some will autosense which type of job is being printed.
If you are printing text, and not using a Page Description Language like PostScript or PCL, then you may want to download a font to the printer. This is especially the case when you are trying to print text files in a non-English font.
Some printers will provide a hardware page counter value when requested; however, the means of requesting differ from model to model.
Sometimes you want to generate a special banner for a particular printer,
and need to put in some dynamic information.
While this can be done by the lpd
server using the
bp
program specification,
it turns out that non-LPRng systems which want to use the ifhp
want to have the same facilities.
Thus, you need to have some way to get the same effect as the bp
option, but at the filter level.
Having done lpd
banner generation and printing,
why not have the filter run an accounting script as well?
At this point, I suspect that the reader is beginning to suspect that making a general purpose filter to support all of these possibilities is difficult. That is incorrect. It is extremely difficult.
However,
the ifhp
filter greatly simplifies this,
as it uses a simple database together with some printer configuration options.
For details,
see the ifhp
documentation for details on using the filter.
For the terminally impatient,
the following is a quick cookbook:
# network connection to jet direct box,
# no banners, HP compatible
lp
:lp=ipaddr%9100
:/usr/local/lib/filters/ifhp
:sh:sf
#
# banner added
#
lp
:bp=/usr/local/lib/filters/pclbanner
:of=/usr/local/lib/filters/ifhp
:if=/usr/local/lib/filters/ifhp
:sf:sb
#
# for a parallel port printer or when you want VERY fast
# throughput, no pagecounts, error messages, etc. The
#
lp
:ifhp=status@
:/usr/local/lib/filters/ifhp -Tstatus@
:sh:sf
If you already have a working setup, with its own specific filter programs, you might want to keep them. Or, you might want to write a set of your own.
See the source code in the LPRng Distribution, FILTERS_LPRng-<version>.tgz files for examples.