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 does processing on a file that is submitted to the printer. As such, it is a specific example of the general class of programs called `filters'.
Usually the filter is executed with STDIN reading from the file to be printed or program generating the output and STDOUT to the printer device. 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 (the example used before),
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. See the associated documentation for details.
Options 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 originally used
to specify the type of file that was being printed. The
lpd
daemon
would use the print format to select the required
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.-r
: Text with FORTRAN carriage control characters in the
first column. (Used to be the -f
option.)-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 implemented by sending the file through
the program
specified by the pr
printcap utility (default is /bin/pr
),
and passing the result to the normal
:if
filter.
The binary (or literal) format
is indicated by format type
-l
.
The if
filter
is used to process the file,
and is invoked with the
-c
(c
ancel processing?) flag.
Much of the flexibility of the LPRng software is obtained from the ability to control the details of each step of job processing. The following section details each step in the processing of a job, and explains the printcap options used to control each operation.
Assume the pr
printcap entry has the form:
pr :lp=/dev/lp OR :lp=rp@rm :sd=/var/spool/lpd/pr :lf=log :of=/usr/local/bin/lpf :if=/usr/local/bin/lpf
Assume that we have used the following command to print a set of files.
lpr -Ppr file1 file2
This will create a control file
in the
/var/spool/lpd/pr
directory with the following contents (this is an example -
in practice there may be minor differences between the example
and an actual control file):
Hastart4.astart.com J/tmp/file1 /tmp/file2 CA Lpapowell Ppapowell fdfA002230astart4.astart.com N/tmp/file1 UdfA002230astart4.astart.com fdfB002230astart4.astart.com N/tmp/file2 UdfB002230astart4.astart.com
Options used:
achk
Accounting check at startaf=
Accounting Filear
Remote printer accounting enabledas=
Accounting at startconnect_grace#
Time between jobsconnect_interval#
Connection intervalconnect_timeout#
Connection timeoutcontrol_filter=
Control file filterff
form feedfo
form feed on openla
Local printer accounting enabledld=
leader on open (initialization string)lk
Lock IO devicelp=
IO device pathnamenb
Nonblocking device opennetwork_connect_grace#
Time between jobsof=
of filterretry_econnrefused#
Retry if open failedretry_nolink#
Retry if open failedrm
the remote machine to send the job torp
the remote print queue to send the job torw
device opened RW flagserver_tmp_dir=
temporary directoryserver_tmp_dir
directory.af
exists,
it is opened (af_fd) and the af_fd is passed as file descriptor
3 to all filters.
If the af
value has the form af=|/program
then the program is started and the program STDIN is used as af_fd.
If the af
value has the form af=host%port
,
then a TCP/IP connection to the corresponding port on the remote host
is made and the port used as af_fd.
In the latter two cases, the filter STDIN (file descriptor 0)
is actualy opened read/write, and is used when information is needed
from the accounting filter or remote server.
See
Accounting Printcap Options
for more information on the LPRng accounting support.connect_grace
value is non-zero and the server is opening a device or
network_connect_grace
is non-zero and a network connection
is being made,
the server will pause the specified time.
This is to accommodate devices which need a recovery time between jobs.lp
option is checked to determine the type of IO device.
Format | Meaning |
/pathname | Absolute pathname of IO device |
pr@host | transfer to pr on remote host |
host%port | open a TCP/IP connection to port on host. host can be name or IP address |
|filter | run the filter program; it STDIN will be used as device |
lp
is opened write-only or read-write if the
rw
flag is true, and the resulting file descriptor is io_fd.
If the nb
flag is set,
a non-blocking open will be done as well.
If the lk
(lock device) flag is true,
the device will be locked against use by other LPD servers.host%port
combination,
a TCP/IP connection will be opened to the remote port and the connection will
be used as io_fd.rp@rm
combination,
or none of the above combinations are true and the
rm
and rp
values are non-zero,
then the job will be transferred to a remote printer.
The type of operation will be a job transfer,
rather than printing operation.connect_timeout
value is non-zero,
a timeout is setup for the device or socket open.
If the device or connection open does not succeed within the timeout,
then the open operation fails.connect()
system call)
and the connection attempt fails with an ECONNREFUSED
error,
if the retry_econnrefused
flag is set then the connection attempt is retried,
but this time using an alternative port number.
See
RFC1179 for details.
This is repeated until all of the possible originating port numbers
are exhausted.retry_nolink
flag is set,
then the server will pause for a minimum of
connect_grace
plus a multiple of
connect_interval
seconds
based on the number of attempts
before retrying the open operation.
Note that the interval may increase as the number of attempts
increases.of
filter is specified,
it is created with its STDOUT (fd 1) attached to the io_fd.
Its stdin (of_fd) will be used in the steps listed below.
If there is no
of
filter,
then the of_fd value will be the io_fd descriptor.control_filter
option is specified,
then the program specified by the control_filter
value will be run. It will have its STDIN set to the control file,
and its STDOUT output will be used as the new value of the control file
to transfer to the remote host.
See
Filter Command Line Flags
for details of options passed to the control filter,
and
errorcodes for the exit codes of the filter.la
(local accounting) is true and we are printing a job
or ar
(remote accounting) is true and we are transferring a job,
the as
value is examined.
If it is a filter (program) specification,
then the program is started with its STDIN attached to
/dev/null
and STDOUT to the io_fd,
STDERR to the error file,
and file descriptor 3 to the accounting file descriptor af_fd.
The lpd program will wait until it terminates,
and examine the error code for action, as for the filters
(see
errorcodes below).
If it is a string,
then it is interpreted, the escape sequences replaced with the appropriate
information, and written to the accounting file.achk
(accounting check) flag is set,
a line is read from the accounting filter af_fd file descriptor.
This line should be accept
,
otherwise the job processing terminates with a JFAIL indication.ld
(leader on open) value is provided,
the string
is translated (escapes removed)
and written to the of_fd file descriptor.fo
(form feed on open) flag is true, then the
ff
(form feed) string
is translated (escapes removed)
and written to the of_fd file descriptor.Options used:
ab
Always print banner (default FALSE)be=
End banner generator programbl=
Short banner line formatbp=
Banner generator programbs=
Start banner generatorhl
Banner (header) Lastof=
Banner and File Separator Filtersb
Short banner (default FALSE)sh
Suppress header (banners) (default FALSE)sh
(suppress header) flag is true, no banner is
printed,
and the actions in this section are skipped.hl
flag is true, the banner is printed at the end
of the job,
and the actions in this section are skipped.L
line in the control file)
and
ab
(always print a banner) is false
(the default),
then no banner is printed.
If no name is supplied and
ab
is true, then ANONYMOUS is used.sb
flag is set, then we send the
bl
(banner line) contents directly to the of_fd;
By default the
bl
value is:
bl=$-'C:$-'n Job: $-'J Date: $-'t
(See
Filter Command Line Flags
for details.)
This will get translated to:papowell:A Job: file1 file2 Date: Thu Nov 27 23:02:04 PST 1997
sb
flag is clear,
we will generate a long banner using a program instead.
If
bs
(start banner) program is specified, then it is used
to generate a banner,
otherwise if the
bp
(banner) program is specified, then it is used
to generate a banner.
If no program is available, we skip the banner generation.
The banner generator program is started with the normal command line
flags
(see
Filter Command Line Flags),
with its STDOUT attached to the of_fd descriptor.
The short banner string described in the previous step is written
to the STDIN.
The banner printer is responsible for generating a banner
appropriate to the printing device.ff
(form feed) string
will be interpreted and sent to the of_fd.Options used:
Xf=
Format Filterdirect_read
Direct connection to fileif=
Default F Format Filterpr=
pr formatting programsend_job_rw_timeout=
print job read/write timeout send_query_rw_timeout=
status query operation read/write timeout sf
Suppress FF Print File SeparatorsSequence of Operations: for each job in listed in the control file, the following operations are done in turn.
of
filter present,
the suspend string \031\001
is written to of_fd
and the no further action is taken until the of filter is suspended.p
,
the job is first processed by the program specified by the
pr
program,
and the program output used as the print file.f
,
l
,
or
p
then the if
filter is used,
otherwise the keyword
Xf
is used.
Note that certain formats such as
p, a, l
, may not be used as formats.direct_read
flag determines how the print file is provided
to the filter.
Normally, the lpd
writes the file to the filter process,
and can monitor the printing activity in this way.
However,
some filters require a direct connection in order to
do lseek
or other operations on the file.
If the
direct_read
flag is true,
then the print file is opened and passed directly to the filter
process,
otherwise the lpd
program will read the file
and write its contents to the filter.lf
),
and file descriptor 3 to the accounting fd af_fd.
If direct_read
is false,
the file is then written to the STDIN of the filter.
This allows the server to monitor job progress.send_job_rw_timeout
value is used.
When doing a status or query operation,
the send_query_rw_timeout
value is used.
If a write or write operation does not complete within
the specified timeout seconds, then we have an error
condition and job processing or the query operation
is terminated with JFAIL status.
If the timeout value is 0, then no timeout is done.lpd
will then wait for the filter to exit.
The exit status can be as follows:
Key Value Meaning JSUCC 0 Successful JFAIL 1, 32 Failed - retry later JABORT 2, 33 Abort - terminate queue processing JREMOVE 3, 34 Failed - remove job JHOLD 6, 37 Failed - hold this job Other Abort - terminate queue processing
of
filter is present,
then it is reactivated with a kill -CONT
signal.sf
(suppress FF print file separators ) is false,
then the
ff
(form feed) string
will be interpreted and sent to the of_fd.Options used:
hl
Header (Banner) LastThe actions taken in this step are identical to those for the
Printing Banner At Beginning,
with the exception that the
be
(end banner program) is used in the procedure
rather than the
bs
(start banner program).
Options used:
fq
Form Feed on Closela
Local Printer Accountingtr=
Trailer on Closeae=
Accounting at endsave_when_done
Save when doneSequence of Operations:
fq
flag is set and the
sf
(suppress interfile FF) flag is set,
then the
ff
(form feed) string
will be interpreted and sent to the of_fd.tr
(trailer) string
will be interpreted and sent to the of_fd.la
(local printer accounting) flag is set
or transferring a job and the ar
(remote accounting) flag is set,
the
ae
is examined and accounting is done as described
for the
as field.
of
filter is present,
its STDIN is closed,
and the lpd
server waits for it to exit.
The exit status is used as described above.save_when_done
flag is not specified,
the job is removed.Options used:
mail_from=
Mail from user namemail_operator_on_error=
Mail to operator on errorrt#
Maximum Print or Transfer Attemptssend_try#
(alias for rt
save_on_error
Do not delete on errorsend_failure_action=
Action on Failuresendmail=
sendmail path name and optionsstop_on_abort
Stop processing queue on filter abortIf the job processing terminates abnormally, the following sequence of events occurs:
kill -INT
,
kill -QUIT
,
and finally
kill -KILL
operations.mail_operator_on_error
value,
the specified operator will be mailed an error indication.
The sendmail
option specifies the pathname of the
sendmail program and the options needed to have it read
mail addresses from its standard input.
For example, sendmail=/usr/sbin/sendmail -oi -t
is a commonly used set of options.mail_from
value specifies the user name used for
mail origination. If not specified, the default is to use the print spool
queue or printer name.send_failure_action
specified,
then it is decoded and the corresponding action taken.
If the value is
remove
,
hold
,
abort
,
or
retry
,
then the job is removed, held, aborted, or retried.
If the value is |/program
,
the program is executed and
the number of attempts are written to the filter STDIN.
The exit status of the filter will be used to determine the consequent actions.
That is, JSUCC (0) will be success, and the standard success action will
be taken;
JFAIL will cause retry,
JREMOVE will cause the job to be removed,
JHOLD will cause the job to be held,
JABORT or other status will abort processing.stop_on_abort
flag is set,
then further processing of jobs is terminated.
The job is not removed from the queue.save_on_error
flag is clear
then the job is removed from the spool queue.lpd
server will stop processing jobs.rt
value is 0 or the number of attempts is less than
the rt
value,
then the job is retried.
Between each attempt to transfer a job to a remote site.
This pause will double after each attempt,
reaching a maximum of max_connect_interval
seconds.
If max_connect_interval
is 0, there is no limit on the interval value.Options used:
lpd_force_poll=
Force LPD to periodically poll print queues lpd_poll_time#
Time between pollsmax_servers_active#
Maximum number of active serversWhen the lpd
server starts,
it will fork a set of subserver processes,
each which will handle an individual queue.
If a system has a large number of queues,
then this forking operation may result in the lpd
server
exhausting the process resources.
To control this, the
max_servers_active
value restricts the number of active
children to the specified value.
If this value is 0,
then 50% of the maximum system processes value will be used.
Due to the limits on the number of processes,
there may be times when a job is placed in a queue,
but the lpd
server is unable to start handling the job.
When all of the children of the main lpd
server have
exited,
the server starts a timer.
After lpd_poll_time
seconds, it will scan the queues,
looking for jobs to process,
and starts a process to service them.
If it does not find any jobs it remains idle.
The lpd_force_poll
flag causes the server to periodically
poll the queues.
This is useful when there is a high possibility that jobs could fail to be
printed due to high loads on the server.
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
and PGPPATH
are specified./dev/null
.There are a few situations in which a filter of a bounce queue will behave differently from an ordinary queue.
The -p
format doesn't behave as expected. Instead of running
pr | if
, the daemon will try to call the :pf
filter.
After filtering, the file might be of a different type than before. Since the result is transfered to another print service (which might do its own filtering), it is important that the right file type (by means of the print format) is passed on to the second queue.
Use the
translate_format
=oNoN...
printcap option.
Its value takes the form of old/new pairs of formats. For example:
translate_format=pf
The -p
format file will now be renamed with the
f
format.
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, CTI-ifhp-<em>version</em>.tgz
This filter supports a wide variety of Hewlett-Packard printers, or to be more specific, printers which support the Hewlett-Packard PCL and/or PJL languages. In addition, they try to detect PostScript jobs and send the correct commands to the printers to enable PostScript rather than PJL operation.
This filter was originally developed by
Panos Dimakopoulos, Systems Programmer,
of the CTI-Print project
at the Division of Computing Facilities of the Computer
Technology Institute (CTI), Patras, Greece.
The code has been heavily modified by Patrick Powell
<papowell@astart.com>
to support newer versions of HP Printers.
It is intended to replace the HPJetDirect drivers supplied by Hewlett-Packard.
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.
These options are specified by the -Tkey=value [key=value]*
on the command line.
Option | Purpose |
accounting=accounting_script_pathname | Invoke the accounting script with a subset of theoptions passed to the filter. In addition, the-bpagecount option indicates the number of pagesprinted for the job. |
autodetect=[on|off*] | The printer has or does not have job type autode-tect capability. Do not download fonts or try todetermine job type if autodetect is on. |
banner=[on|off*] | If banner is on, then the ifhp filter will attemptto print a banner using information passed on thecommand line or on the standard input. The titleoption can be used to specify additional titleinformation on the banner. See BANNERS below fordetails. |
cartridge=[*on|off] | (Alias for postscript)If cartridge is on, the printer has PostScript sup-port. The filter will try to determine if a job ispostscript and send Printer Job Language commandsto put the printer in PostScript mode. |
debug=debuglevel | Sets the debugging level; 2 is the default; alarger number causes more verbose error messages. |
defaultfont=fontname | Sets the default font to be downloaded; default isNONE. |
dev=/device or dev=host%port | Open the specified device or connection to remotehost; by default ifhp filter uses file descriptor 1(stdout). If the optional orig_port is specified,connections will be originated from this port.Some printers require that connections originatefrom a port in the range 1-1024. |
infostatus=[*on|off] | The PJL INFOSTATUS request is not supported on someHP printers. Use this to turn the status requestoff. Note that you cannot get real time reports ofthe printer status if you do this. This will alsosuppress getting pagecount information using thePJL facilities. |
forcepagecount=[on|off*] | If you have a printer that has PostScript pagecount information support, you can set infostatusto OFF and forcepagecount to ON. This will causethe PostScript facility to be used. If you setcartridge or postscript to OFF then this will notbe done. |
logall | Save all of the error and information messages fromthe printer in the log file. This is useful whenyou wish to examine returned status from theprinter. |
model=(C5M|III|IIID|IIISi|IV*) | The model of HP printer. C5M is Color 5M, III isHP LaserJet 3, IIID is HP LaserJet 3D, etc. Addi-tional printers may be added or defined at varioustimes - please consult the source for details.This selects various timing and format characteristic-tics. This is a desperation parameter for userswith antique or non-conforming PJL based equipment;read the source code for details on the particularpeculiarities. |
pagecount=[on*|off] | Get the hardware pagecounter value for accounting.Some printers such as the HP LJ4s do not have hard-ware support for pagecounters, and return bogusnumbers. Use this to suppress attempting to getvalid information. If your printer does supportPostScript, then you can get the page count valueusing PostScript by setting forcepagecount to ON. |
plp=[on|off*] | Return PLP status values on exit; by default LPRngstatus values are returned. |
postscript=[on*|off] | The printer has postscript support. |
quiet=[on|off*] | If set, do not report common status messages. |
retries=count | The number of times to retry connecting to theprinter. |
sleep=time | The number of seconds to wait before trying to con-nect to the printer. |
status=[*on|off] | When on, the printer is treated as a write onlydevice and is not queried for pagecount and statusinformation. Set status=OFF for parallel printers.If status is OFF, then the ifhp filter simply addsjob control language headers, fonts, and trailersto the jobs. |
stty=stty flags | if the output device is a serial line, set the linecharacters according to the stty flags. Theseflags are (most likely) identical to those avail-able with the stty(1) command on the host system. |
summary=[filename|host%port] | This option specifies that summary or informationalmessages should be placed in the specified file orsent, using the UDP protocol, to the indicated hostand port address. This allows remote monitoring ofthe printing and error activity. The undocumentedprogram included with the filter distribution is asimple program that can be used to perform the mon-itoring. |
sync=[*on|off] | Try to synchronize communications with printer.This will ensure that the printer has been reset,and no problems involving the previous job willresult. |
tbcp=[on|*off] | When invoked as an IF filter and transferring aPostScript job, the filter will use the AdobeTagged Binary Communications protocol. This allowsbinary data to be transferred and not interpretedas control information. |
title=line[/line]* | The title information is printed on the bannerpage; it consists of a list of / separated lineswhich are added to the banner information. |
wrap=[on|off*] | enables or disables line wrapping in PCLmode. |
On a parallel port printer, you cannot get status, or do much besides set up the printer to either handle PostScript or do autosensee. The following is a typical printcap entry:
pr:.... options :of=/usr/local/lib/filters/ifhp -Tstatus=off :if=/usr/local/lib/filters/ifhp -Tstatus=off
You might want to also look at the autodetect
or postscript
options.
By default, the ifhp
filter when used as an OF filter will
interpret the first line to it as a
short banner line,
and use the information on this line to produce a PCL based banner.
The short banner line should have the format:
class:username Job:
jobinfo Date:
dateformat
Example: A:papowell Job: (stdin) Date: Sun Dec 14 07:13:34 PST 1997
This is produced by the default short banner line option value:
bl=$-'C:$-'n Job: $-'J Date: $-'t
If you want to suppress banner printing,
then you need to suppress generation of this short banner line.
If you want to have the lpd
program to generate the
default long special banner,
then you need to suppress ifhp
from interpreting the
information sent to is as banner information.
Finally, you may want to have lpd
invoke the bp
(banner program) and have its output used as the banner.
Here are the various possible ways:
# no banner at all, use :sh: - suppress headers lp:.... :sh :of=/usr/local/lib/filters/ifhp # have ifhp generate banner from short banner input lp:.... :sb :of=/usr/local/lib/filters/ifhp # have LPD generate long banner, have of filter pass it lp:... :sb@ :of=/usr/local/lib/filters/ifhp -Tbanner=off # have LPD invoke bp banner generation program, have of filter pass it # bp programs require short banner on STDIN to work, so we need to # generate short banner lp:... :sb :bp=/usr/local/lib/filters/banner_program :of=/usr/local/lib/filters/ifhp -Tbanner=off
The ifhp
banner is generated in PCL,
and uses the minimum PCL facilities.
Since when you send a banner to an autosensing printer you cause it to enter
the requested mode, the if
filter (ifhp
) will need to reset
the printer to autosense mode. The ifhp
filter automatically does this.
If you want very fancy banners,
the
banner.sh
(PCL) and
psbanner.sh
(PostScript) banner generating programs
in the CTI-ifhp distribution make a good starting point.
Error logging and reporting is done by the ifhp
filter as follows.
ifhp
software.
This are logged to the STDERR output of the filter.-Tstatus=on
(default) option is enabled.
These are classified according to the Hewlett-Packard Printer Job Language
error status definitions,
and logged to the STDERR output of the filter.ps=
statusfile entry and the
statusfile exists and is writeable,
then the error and status messages will be written to the log file.-Tsummary=
summaryfile option. For example,
ifhp -Tsummary=taco%3000would send messages to UDP port 3000 on host taco.
-Tquiet
option to suppress this, or
compile it with the -DQUIET option.Doing printer accounting is not simple. Read LPRng Accounting for more information.
In order to help aid in accounting,
by default the ifhp
filter will query the printer
to get the current value of the hardware page counter value,
if there is such a thing on the printer.
Unfortunately,
due to different types of printers and errors in their PJL, PCL,
and PostScript implementations,
several different methods need to be used.
Unfortunately,
some printers return an idle
indication even when
they are printing pages of the previous job.
This means that the printer has to be polled,
and only when it is idle and the pagecounter value has been
stable for a reasonable time (5 seconds?)
can you trust the page counter value.
This slows down job printing very seriously.
Some of the newer PJL printers have a
PJL TEOJ
,
or return end of job indication when the last page of a job
has been printed.
If you have this capability,
you can speed up printing.
PJL INFO PAGECOUNT
facility,
then it will first be tried to get the page count./ps { print flush } def (\tPAGECOUNT ) ps statusdict begin pagecount end == flush
start -ppagecounter -Ff -kjob -uuser -hhost -R... end -ppages -qpagecounter -Ff -kjob -uuser -hhost -R...
When we use the OF filter and/or banners, we will see the individual jobs bracketed by the OF filter records:
start -p100 -Fo -kcfA100taco -uuser -hhost -R... start -p101 -Ff -kcfA100taco -uuser -hhost -R... end -p1 -q102 -Ff -kcfA100taco -uuser -hhost -R... start -p102 -Ff -kcfA100taco -uuser -hhost -R...
We can use the various job numbers and other information to track page usage.
The following are a selected set of printcap entries that can be used to get page counting information:
# use defaults, try to get pagecount using all methods, wait for stable # value of pagecount before proceeding pr:... :of=/usr/local/lib/filter/ifhp # printer support PJL True End of Job and PAGECOUNT pr:... :of=/usr/local/lib/filter/ifhp -Ttrue_eoj=on # no PJL INFO status available, but you can get page count using postscript pr:... :of=/usr/local/lib/filter/ifhp -Tinfostatus=off,forcepagecount
You should try connecting to your printer directly
and testing the accounting facilities.
You can do this by using the ifhp -Tdev=...
facility.
For example:
ifhp '-Tdev=/dev/ttyb,stty=38400 -echo -crmod -raw -oddp \ -evenp ixon pass8 -ixany cbreak' -Tdebug=5 <ellipse.ps ifhp -Tdev=astart14%9100 -Tdebug=5 -Ttrue_eoj <ellipse.ps
Source code: LPRng Distribution, psfilter-<version>.tgz
The
psfilter
is similar to the CTI-ifhp
filter in its operation and functionality.
Its general operation and procedures are similar,
but it has the following additions:
During the installation process,
psif
and
psof
symbolic links are made to the
psfilter
executable.
Thus,
the following printcap entries can be used:
# common use: lp:... :of=/usr/local/lib/filters/psof :if=/usr/local/lib/filters/psif # same effect: lp:... :of=/usr/local/lib/filters/psfilter :if=/usr/local/lib/filters/psfilter
The -Tkey=value[,key=value]
convention is used to
pass options to the psfilter.
The following options are supported.
Many of these are identical in intent to CTI-ifhp options.
Option | Purpose |
accounting=/pathname_to_executable | When the -Taccounting is specified, the specifiedprogram is executed with the same options as thefilter. |
debug=level | set debugging level. The default level is 2;higher values produce more verbose output. |
dev=/device | dev=host%portOpen a connection to either the device or to theport on the host and send output to it. Bydefault, output is send to stdout. |
endpause=delay | When used as the OF filter, at the start and end ofthe job psfilter will query the printer for thevalue of the hardware pagecounter. The differencebetween the start and end values is reported as thenumber of pages used for the job. Unfortunately,some printers such as the HP LaserJet 4 and HPLaserJet 5 report the current value of the pagecounter at the time of request, and it is difficultto determine if the last page has been completelyprinted by examining returned PostScript status.Before querying the printer at the end of a job,the psfilter software will wait endpause seconds(default is 5). On a 12 page per minute printer,this appears to be sufficient to allow the lastpage to be completely printed. However, if theprinter jams on the last page, it will still not bereported and the page count will be off by one. |
forcepagecount=[off*|on] | To find the pagecount value, a PostScript programis sent to the printer. This overrides any otherflags and forces the program to be sent. Usuallyused in combination with -Tstatus=off -Tforceps,and -Tnosync flags. See the comments below forprinter specific problems. |
forceps=[off*|on] | Forces a dummy PostScript job to be sent at thestart of operations. This usually tricks autosense-ing printers into going into PostScript mode andresponding to the PostScript conventions. See thecomments below for printer specific problems. |
maxresponse=seconds(default30seconds) | Specifies how long to wait for a status responsebefore giving an error indication. |
nosync=[off*|on] | Suppresses trying to get status from the PostScriptprinter, as would normally be returned by sending a^T. See the comments below for printer specificproblems. |
pagecount=[off|on*] | Get the pagecounter value from the printer and usefor accounting information. Note that some HPprinters (LJ4s) do not appear to have pagecounters.(Default is on). |
reverse=[off*|on] | Reverse page order on output. |
status=[off|on*] | Query the print device for status and page countinformation. If status is off, then psfilter sim-ply formats input into postscript and does not doaccounting. |
stty=stty_options | If the output device is a serial port, set the con-figuration according to the stty options. Theseoptions should be identical to those used bystty(1). |
summary=destination | Write a one line status summary to the destination.The destination can be a file (i.e. - /tmp/status)or a UDP port on a host (host%port). The host namecan be an hostname or an IP address (i.e.-info.sdsu.edu%2000 or 130.191.163.56%1000). |
tbcp=[off*|on] | Use the Adobe Tagged Binary Communications protocolto send the document when invoked as an IF filter.The OF filter cannot handle binary PostScript docu-ments as it will remove various control sequences.The -Ztbcp LPRng option will also enable TBCP oper-ations. |
udp_status_port=host%port | The HP5m and possibly other printers use port 9101(UDP) to request and send status. When sent a UDPpacket on this port, the printer responds by sendingstatus back to the sender. This option forces theuse of this port for sending status. However, pagecounts and other information still use the standardconnection to the printer. |
The psfilter
uses the same methods for doing accounting as the
CTI-ifhp
filter.
See
IFHP Accounting for details.
Consult your printer's PostScript Printer Description file
to determine the PostScript script needed to do accounting.
You may need to modify the default one supplied in the psfilter
code.
Always test that the printer returns the right accounting information using a test similar to the following:
psfilter -Tdebug=8 '-Tdev=/dev/ttyb,stty=38400 -echo -crmod -raw -oddp \ -evenp ixon pass8 -ixany cbreak' <ellipse.ps psfilter -Tdebug=8 -Tdev=astart14%9100 -Ttrue_eoj <ellipse.ps
Source code: LPRng Distribution, part of FILTERS_LPRng-<version>.tgz
The lp_pipe
family of filters was developed to act
as a network pipe to network devices.
They are largely replaced by the lp=host%port
, facility.
tcp-pipe
: uses a tcp socket (OBSOLETED by
lp=host%port
), but good starting point if you have special
device requirements;annex-pipe
: supports annex terminal server.Source code: LPRng Distribution, apsfilter-<version>.tgz
The apsfilter
is basically a simple front end to the a2ps
program
(See:
http://www-inf.enst.fr/~demaille/a2ps/ for details),
and is an example of a MagicFilter that has powerful
processing capability.
The apsfilter
program sets up options for the
a2ps
program and then invokes it.
The a2ps
program can convert just about any type of file
into PostScript,
and then by using the GhostScript facility can convert this to
the output compatible with a particular printer.
Combined with the LPRng qq
and force_queuename
options, we can set up virtual queues that do various types of reformatting.
Here is a sample set of printcap entries:
# seen by users - note that the queue name is put into control file, # and we then send it to the frontend@host queue for processing raw:qq:lp=frontend@host twoup:qq:lp=frontend@host landscape:qq:lp=frontend@host frontend:lp=frontend@host:force_queuename=raw # frontend does the job conversions and accounting frontend:server :lp=/dev/lp:force_queuename=raw :if=/usr/local/lib/filter/apsfilter
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.