The
ifhp
filter operates by first reading a configuration file
to determine the type of printer it is working with,
and then proceeds to carry out operations requested by the values of
option variables passed on the command line or found in the configuration
files.
In normal operation,
input is read from
STDIN
(file descriptor 0),
massaged in the appropriate manner,
and then written out to
STDOUT
(file descriptor 1).
Status reports are written to
a status file, or optionally to
STDERR
(file descriptor 2),
together with any error messages or diagnostics.
In addition to normal operation the filter can run in the OF mode and act as a printer initializer and job terminator. This is discussed in detail in the LPRng documentation. When in the OF mode, The first nonblank input line will be treated as a request to generate a banner. The string "\031\001" will cause the filter to suspend operations using a SIGSUSP signal. At this point, job files will be sent to the output device by the spooler, and the filter will then be restarted with a SIGCONT signal.
These steps are best explained algorithmically.
The following is a pseudo-code description of the steps
performed during the printing activity.
The sections marked with ###
are discussed later in this document
in detail.
///
See:
Options, Initialization and Setup
###+++ Initialization and Setup
// get ifhp information from PRINTCAP_ENTRY environment variable
if( PRINTCAP_ENTRY environment variable has a value ){
split printcap information into printcap fields
if( :ifhp=options,options is present in printcap ){
split the options list and place in the Toptions list
}
}
foreach option in -Toptions, -Zoptions do
if( option = "debug=level" and Debuglevel not set ){
set Debuglevel = level;
}
if( option = "trace" ){
output error and trace on STDERR
}
if( option = "config=pathlist" and from -Toption ){
set configuration pathlist = pathlist;
}
if( option = "model=name" and model not set ){
set model = name;
}
}
///
See:
Operation Configuration Options
// extract configuration information
foreach path in configuration pathlist {
open path;
for each line in file information {
if( line is selected to be in configuration ){
process input line, adding it to configuration
if( line is 'debug=','model='
and the corresponding value not set ){
set the value;
}
}
}
}
// get values of options with predefined meanings
// these include status, forcestatus, etc
foreach option in predefined list {
if( option=value is in selected configuration information ){
set option=value;
}
}
// open a direct connection if specified
if( device specified using -Tdev=device ){
// if device is host%port, we open TCP/IP connection
fd = open(device);
// Note - option read_write will open the device or file read write
dup fd to 1; close fd;
}
if( appsocket procotol specified and TCP/IP device ){
udp_socket = open( udp socket to device%port+1 )
}
###---
///
See:
Synchronization and Pagecount
###+++ Synchronization and Pagecount
if( status returned by printer and sync requested ){
// APPSOCKET protocol
// sync has the form sync@ (none), sync=ps, sync=pjl, ...
if( appsocket ){
command = "\n\r"
} else {
// decode status=language and determine sync
if( sync = pjl and PJL ECHO available ){
send PJL ECHO command to printer
} else if( sync = ps ){
send PS program to printer
} else {
terminate with error;
}
do{
send command and wait for timeout;
} while( no response );
if( appsocket ){
close and reopen TCP/IP connection;
}
// pagecount has the form pagecount@ (none),
// pagecount=ps, pagecount=pjl, ...
if( pagecount=language has value ) do {
if( pagecount TRUE ){
set pagecount= pjl or ps depending on availability
}
if( pagecount = pjl and PJL INFO available ){
send PJL INFO PAGECOUNT command to printer
} else if( pagecount = ps ){
send PS program to printer
} else {
terminate with error;
}
} while( no pagecount response );
if( appsocket ){
close and reopen TCP/IP connection;
}
}
###---
///
See:
PJL Initialization
### PJL Initialization
if( PJL enabled ){
language = "pjl_"
foreach option in pjl_init=[...] {
expand the option using the language value
#+++ PJL OPTION ACTIONS +++
if( option in pjl_vars_set=[ ... ]
and option not in pjl_vars_except
expand "@PJL SET OPTION=\%{option}"
output = expanded string value
} else {
if( option value is a string ){
output = expanded string value;
}
}
// output has the form @PJL COMMAND ....
if( COMMAND is in pjl_only=[ ... ]
and not in pjl_except=[ ... ] ){
send output to printer
}
#--- end PJL OPTION ACTIONS
}
if( !OF_mode ){
foreach option in -Toption=value {
if( option in pjl_user_opts ){
#+++ USER PJL OPTIONS
// join 'pjl_' and the option name
expand 'pjl_' . option
// perform PJL actions as above
#+++ PJL OPTION ACTIONS +++
....
#-- PJL OPTION ACTIONS +++
#--- USER PJL OPTIONS
}
}
foreach option in -Zoption=value {
if( option in pjl_user_opts ){
// perform USER PJL actions as above
#+++ USER PJL OPTIONS
#--- USER PJL OPTIONS
}
}
}
}
###--- PJL INITIALIZATION
///
See:
Text File Conversion
// language is set to the type of job language
// - PS, PCL, TEXT, RAW, UNKNOWN
// the first part of the job file is read and the filter takes
// a (wimpy) guess at the job file based only on the first couple
// of characters; language is be PJL, PS, or TEXT, or RAW
// This is the same algorithm as the UNIX FILE utility
language = UNKNOWN
if( command line -c (binary) option present ){
language = RAW;
} else if( -Zlanguage=xxx option present ){
language=xxx
} else if( file is PS file ){
language=PS
if( file starts with PS EOJ (CTRL-D)
and no_ps_eoj is set ){
remove the PS EOJ
} else {
send a PS EOJ first
}
} else if( file is PCL file ){
language=PCL
if( file starts with PCL EOJ (ESC E)
and no_pcl_eoj is set ){
remove the PCL EOJ
}
} else if( file_util_path=/pathname ){
use UNIX file utility to get file type
}
if( language = UNKNOWN and
default_language option has value ){
language = value of default_language;
}
if( language = TEXT ){
if( text_converter=/path option has value ){
run text converter on input
} else if( printer does not support TEXT output ){
exit with error;
}
language = value of text_converter_output option
}
if( language = UNKNOWN ){
exit with error;
}
if( PJL ENTER supported ){
use PJL ENTER command to select language;
send nullpad NULLS to force full buffer condition
}
///
See:
Language Specific Initialization
// LANGUAGE SPECIFIC INITIALIZATIONS
if( language = PCL ){
foreach option in pcl_init {
###+++ expansion
do expansion similar to PJL OPTION actions
using "pcl_" prefix for option lookup;
###---
}
if( not in OF_MODE ){
foreach option in -Toption do {
if( option in pcl_user_vars=[ ... ] ){
###+++ expansion as above
###---
}
foreach option in -Zoption do {
if( option in pcl_user_vars=[ ... ] ){
###+++ expansion as above
###---
}
}
remove whitespace and expand string results;
} else if( language = PS ){
###+++ language specific actions as above,
using the ps_ prefix for lookup
expand string results but do not remove whitespace
}
///
See:
File Transfer and Error Status Monitoring
Transfer job to printer, reading error and other information
back from the printer if enabled
if( language = PCL ){
send PCL End of Job
} else if( language = PS ){
send PS End of Job
}
// job terminaton
###+++ Synchronization and Pagecount as above
if( waitend ){
if( sync requested previously ){
if( sync with PJL ){
wait for end of job using UINFO;
} else if( sync with PS ){
request status using ^T and wait for
printing to stop
}
}
if( appsocket ){
close and reopen connection;
}
get pagecount using previously descibed algorithm
}
###---
exit
The
ifhp
filter is designed to work with the LPRng print spooler,
but will also work with other spooling systems.
The LPRng system will set the
PRINTCAP_ENTRY
environment variable to the current printcap value.
By convention,
the filter command line
-Toptions
are reserved for the print spooler to pass configurtion inforamtion
and the
-Zoptions
are passed by the user.
For example,
examine the following
lpr
command and printcap example:
Printcap:
pr:...
:ifhp=opt1=value1,opt2=value2
:if=/usr/ifhp -Topt1=value4,opt3=value3
Command:
lpr -Zopt4=value4
PRINTCAP_ENTRY envionment variable:
pr:...\n
:ifhp=opt1=value1,opt2=value2\n
:if=/usr/ifhp -Topt1=value4,opt3=value3\n
Resulting option list:
-Toptions:
opt1=value4
opt2=value2
opt3=value3
-Zoptions:
opt4=value4
When started,
the
ifhp
filter process the environment and command line options as follows.
PRINTCAP_ENTRY
environment variable has a value,
then this value is used to initialize the
-Toption
list.-Toption
command line option,
then these values are added to the
option list,
overriding values from the
PRINTCAP_ENTRY
set.-Zoption
list is generated by splitting the
-Zoption
command line option.The option lists are scanned for values for the
debug
,
trace
,
config
,
and
model
options.
These options
have the property that once they are set, then they cannot be modified
(i.e. - sticky values).
There is another,
and rather bizarre way to specify the printer model,
and that is the
model_from_option
option in the configuration file.
This option causes the command line options to be scanned,
and if there is a value for the command line option then it
is used as the model.
For example:
model_from_option=Q
The above setting will cause the model to be taken from the
Q
option.
This can be used to select a configuration for the printer
based on values specifed by the user.
The value of the
debug
option sets the debugging level.
It can be increased, but not decreased.
The
trace
flag causes debugging information to be sent to STDERR (file descriptor 2)
as well as to the status file.
The main source of configuration information are the configuration files. The
config=pathname,pathname
option can be used to specify the list of configuration files to be read.
This can only be done using the
PRINTCAP_ENTRY
:ifhp
entry or the
-Tconfig=pathname,pathname
command line option.
The
model=name
option is used to establishes the model name for extracting
configuration information.
For details on this, see
Configuration Files.
During initialization,
the
-Toptions
list is scanned for a
-Tmodel=name
entry.
Once the model name is set, it cannot be changed.
After this,
the configuration files are read,
and the first
model=name
option encountered will set the
model
option to
name
.
The recommended method of model selection is to
specify it in the
LPRng printcap entry for the printer,
using the :ifhp=...
printcap field.
For example:
lp:ifhp=model=HP4,status@
:if=/usr/local/ifhp
Resulting -Toption List:
model=HP4
status@
This will cause the
-Toption
list to be initialized as indicated,
and the
model
option value will be set to
HP4
.
The next method is use a
-Toption
command line option.
lp:...
:if=/usr/local/ifhp -Tmodel=HP4
Resulting -Toption List:
model=HP4
This will cause the
-Toption
list to be initialized as indicated,
and the
model
option value will be set to
HP4
.
Another method is to put the model information in a
./ifhp.conf
file in the spool directory of the print queue.
The
config=/pathname,/pathname,...
option specifies the list of configuration files to read,
and the default value is:
config=./ifhp.conf,/etc/ifhp.conf,./ifhp.conf
If the model information is put in the
./ifhp.conf
configuration file,
the first reading will set the model name,
and the name is used to select the model information from the
/etc/ifhp.conf
file.
When the
./ifhp.conf
is reread, the values in it can be used to override values from the
/etc/ifhp.conf
file.
For example:
./ifhp.conf:
model=HP4
lines=66
/etc/ifhp.conf:
[ hp* ]
lines=60
[ apple* ]
lines=20
When the
./ifhp.conf
is first read,
it will establish
model=hp
(sticky) and
lines=66
.
When the
/etc/ifhp.conf
file is read,
the model name matches the
hp*
selector
(case insensive GLOB matching is used),
and the
lines=60
is selected and overrides the
lines=66
value.
Finally,
when the
./ifhp.conf
file is reread,
lines=66
will establish the final value.
The status file pathname is set by the command line
-s /pathname
or the
statusfile=/pathname
configurtion file entry.
If the
/pathname
file does not exist then it will not be created.
If the statusfile is larger than the
statusfile_max=max
K bytes option value (default 8K),
then it will be truncated to
statusfile_min=min
K bytes.
For historical and vintage software compatibility,
the
summaryfile=/pathname
or
summaryfile=host%port
option will cause either a file to be open or a UDP network connection
established to the host and port combination.
Debugging or trace information will be written to this file or network
connection as well, but the file will be truncated each time,
holding only the last line of trace information.
The
-Toption=value
and model configuration information is scanned
to set values of options which control filter activity.
There are some options whose related actions do not fall into
the simple model of string expansion.
These usually require generating commands dynamically,
or sending files containing font or setup information to the printer.
The following is a list of these options.
These options have the side effect of enabling the reception of status and error information from the printer.
These flags set the lanaguages that are recognized or processed by the filter.
The
crlf
causes LF (\n
) to be translated to CR-LF
(\r\n
) sequences.
The following options will turn the
ifhp
filter into a simple CRLF translation filter.
Note that CRLF translation should have no effect
on PostScript, Text, or PCL files.
status@
pjl@
ps@
pcl@
text
text_converter_output@
text_converter@
crlf
If PJL is enabled and this flag is SET, a PJL JOB and PJL EOJ command will be generated and sent to the printer. The JOB command has the form:
@PJL JOB NAME = "..." [ START = nnn ] [ END = mmm ]
The START and END values can be specified by
-Zstart=nnn
and
-Zend=mmm
command line options.
The EOJ command has must match the JOB command.
@PJL EOJ NAME = "..." [ START = nnn ] [ END = nnn ]
If PJL is enabled and this flag is SET, a PJL ENTER LANGUAGE = xx command will be generated when PCL or PS files are sent to the printer.
@PJL ENTER LANGUAGE = PCL
@PJL ENTER LANGUAGE = POSTSCRIPT
Some older model HP printers required sending a large number of
NULL (0) characters to force commands in the input buffer to be read.
This can be done using the
nullpad
option.
In practice, this has turned out to be largely historical, as most printers do not have this problem.
When this flag is set,
PJL is available,
and the PJL
RDYMSG
command is supported,
then a short message will be put on the console.
The
remove_ctrl
string option species a list of (control) characters
that will be removed from PostScript jobs.
This solves the problem of jobs with embedded Control-T or Control-C
characters causing abnormal printer operation.
For example:
remove_ctrl=CT
would cause Control-C and Control-T characters to be removed.
The
tbcp
flag can be specified as a user option as well as a
configuration file option.
If the file type is PostScript and this flag is set,
then the file is transferred using the Transparent Binary Communication
Protocol.
(See the Adobe PostScript Language Reference Manual for details on
the protocol.)
At the start of the PostScript job,
the sequence \001
M
is sent.
Afterwards, all control characters in the set
0x01, 0x03, 0x04, 0x05,
0x11, 0x13, 0x14, 0x1C,
are replaced by the two character sequence \001
X+'@'
or
X+'\100'
or
is sent.
For example:
C\001\003 -> \001\115\103\001\101\001\103 or \001MC\001A\001C
Many printers are able to provide status information back to the
filter.
It is assumed that in these circumstances file descriptor 1
(FD1)
is
bidirectional
and status information can be read from it.
When the
status
or
forcestatus
option is TRUE,
then the filter assumes that it can read FD1.
In order to simplify configuration,
the
ifhp
filter will test FD1, and if it is not
a serial port or a network socket, will set
status@
or OFF.
However, there are some devices such as bidirectional printer ports
that will report status.
By setting
forcestatus
ON,
the filter can be forced to check for status.
This can have fatal or unexpected effects if status is not returned
correctly.
Synchronization is usually done in order to ensure that a previously spooled job or printer action has completed correctly, and the printer is ready to accept a new job. It is usally carried out by sending a request to the printer to echo a string back to the filter. Clearly, if the printer cannot provide status or echo values back, then synchronization is impossible.
The value of the
sync
option determines if a PJL ECHO command or simple PostScript
program is used.
The PostScript program has the form:
\004%!PS-Adobe-2.0
( %%[ echo: TODSTR ]%% ) print () = flush
\004
where TODSTR is replaced with the current Time of Day.
To control obtaining synchronization,
the
and
sync_timeout=nnn
options are used.
The PJL or PS command is repeated at
sync_interval=nnn
second intervals; if nnn is 0, then it is sent only once.
If synchronization is not obtained within
sync_timeout=nnn
seconds, then the filter exits with an error status.
A 0 value or
sync_timeout@
disables timeouts.
Pagecounts are used to do accounting and report the number of pages used for a job. Most printer have a hardware based pagecounter mechanism whose value can be read by the appropriate PJL command or PostScript program. For example, if the PJL INFO command
@PJL INFO PAGECOUNT
is supported by a printer,
the printer will return a status message containing the current pagecounter
value.
Printers that support PostScript may also be able to access the pagecounter
value using a PostScript program.
The exact details of the PostScript program vary from vendor to vendor and
the
pagecount_ps_code=...
option specifies the PostScript program to use.
For example:
pagecount_ps_code=
/p {print} def ( %%[ pagecount: ) p
statusdict begin pagecount end 20 string cvs p
( ]%% ) p () = flush
Pagecounting is supported by the
pagecount=
language,
pagecount_interval=nnn
,
and
pagecount_timeout=nnn
options.
The
pagecount=
language
option enables pagecounting, and sets the language to be used.
Currently
ps
(PostScript)
and
pjl
(PJL)
are supported.
The pagecount request is repeated every
pagecount_interval=nnn
second intervals; if nnn is 0, then it is sent only once.
If no pagecount value is obtained within
pagecount_timeout=nnn
seconds, then the filter exits with an error.
A 0 value or
sync_timeout@
disables timeouts.
Some printers do not correctly report end of job and must be polled until the pagecount information stabilizes. The PJL TEOJ (True End Of Job) PJL has been tried with limited success on various printers to force End of Job reporting only when the job has finished.
pjl_init=[ ... teoj ... ]
pjl_teoj=@PJL TEOJ=ON
If a printer supports PJL, the many printer operations can be initiated and controlled using PJL commands. Unfortunately, not all printers support the same set of commands. In addition, not all printers support the same set of operations or options. A PJL command has the form:
@PJL COMMAND OPTION OPTION ...
A PJL variable is set using:
@PJL SET var = value ...
The
pjl_only=[ ... ]
,
pjl_except=[ ... ]
,
pjl_vars_set=[ ... ]
,
and
pjl_vars_except=[ ... ]
options are used to control which PJL commands and which PJL variables
can be set.
The
pjl_only
variable lists the commands supported by the printer,
and the
pjl_except
lists commands not
supported by the printer.
Before sending a PJL command,
the
ifhp
filter checks to make sure that the command name is in
pjl_only
and not in
pjl_except
.
If the tests fail, then tne command is not sent.
Similarly,
when sending a command to set a PJL variable,
the
pjl_vars_set
and
pjl_vars_except
lists are checked to determine if the variable name is in
pjl_vars_set
and not in
pjl_except
list.
If the tests fail, then tne command is not sent.
If PJL is enabled, then the following actions are taken.
\033%-12345X
is sent to the printer.
This is required to ensure that the following PJL commands are accepted.
-Zstartpage=nnn
or
-Zendpage=mmm
option is present, then the PJL JOB command has the form:
@PJL JOB START=nnn END=mmm
pjl_init=[ ... ]
value option is expanded using the PJL
("pjl_"
) language context as described above.-Toption=value
s
and
-Zoption=value
s
are scanned for matching option names in the
pjl_user_opts=[ ... ]
list.
If they are found,
then the options are recursively evaluated in the PJL language context.
The expansion alorithm will cause the option value to be used to set PJL
variables.
For example:
Configuration:
pjl_vars_set=[ OUTBIN AUTOSELECT JAM=YES ]
Command
ifhp -Zoutbin=upper,autoselect,jam
PJL command generated:
@PJL SET OUTBIN=UPPER
@PJL SET AUTOSELECT=ON
@PJL SET JAM=YES
Many PostScript printers cannot handle text files,
and produce many hundreds of pages of garbage
output if they are sent to the printer without being translated
into PostScript.
Also,
while most PCL printers will accept text files and do a reasonable
job of printing them
some form of initialization strings or setup may need to be done.
Finally,
you might want to try using a
MagicFilter
that will convert just about any type of file into a PostScript file.
This method specifies that the default file type
will be
text
.
If the simple ifhp
type detection code cannot decide
what type of file this is,
it will invoke a converter program.
This operation is controlled by the following options.
default_language=text
When the default lanague is text
then the
text_converter
and
text_converter_output
options are used.
text_converter=/pathname
specifies the pathname of a text to language program.
text_converter_output=language
Specifies the output language of the conversion program.
Language can be
ps
,
pcl
,
text
,
raw
,
unknown
tempfile=/pathname
A temporary file location, used to store
intermediate conversion results.
The
/pathname
value has the string
XXXXXX
appended to it and is used as input to the POSIX
mktemp()
function.
The print file language is determined using the following algorithm.
unknown
or the
default_language=language
value if it exists.-c
(binary) option is present,
or the
autodetect
configuration option is TRUE,
then the language is set to
RAW
.
(The autodetect option is not recommended for general use).-Zlanguage=value
command line option,
the language is set to
value
.ps
)
or PCL
(language=pcl
)
are performed.
These are the same checks that the UNIX
file
utility uses.text
then the
text_converter
program is run to translate the file and the results stored in
the tempfile
.One technique used with varying degrees of sophistication is to use a general purpose file to PostScript conversion program. These have generally been known as MagicFilters, due to their high degree of flexibility.
As described above,
the various
MagicFilter packages can do conversion.
However, most of the time there is only a limited need for the
general purpose conversions.
This can be met by using the
file
program, which will determine the type of a file based on
its contents,
and having ifhp
invoke a program based on the type of file found.
This method is used when
default_language=unknown
and the
file_util_path=/path
and
file_output_match=[ ... ]
values are defined.
A typical configuration is shown below.
Configuration:
#
# Method 2 -
# Use the file util and match the output
# file reports format information
# glob text_output_format text_converter
# - you do a glob match against pattern and use the converter
#
default_language=unknown
file_util_path=/usr/bin/file -
file_output_match = [
# glob output converter
*text* ps /usr/local/bin/a2ps -q -B -o-
*gif* ps /usr/local/bin/gif2ps
]
The
file_output_match
entry consists of a list of lines containing
a glob pattern,
a language type (ps
, pcl
, or raw
),
and a program to invoke to do the conversions.
The
file
utility is run and its output is matched against the specified
glob patterns.
When a match is found the specified program is run,
with STDIN attached to the original input file and its
STDOUT sent to the printer.
While this algorithm may appear to be overly complex, it will handle a wide range of desired configurations.
If your printer can handle text files without conversion,
but require PCL intialization, then the following combination
will simply set the language to
pcl
:
text_converter@
text_converter_output=pcl
Your printer may be capable of handling a wide variety of job formats. If you want to simply pass through files of unknown type or language then use:
text_converter@
text_converter_output=raw
After determining the output file language type,
language specific operations are then carried out by
expanding the
language__init=[ ... ]
options in the language context,
and then the options in the
-Toption=value
and
-Zoption=value
command line options.
The
-T
options are expanded before the
-Z
,
allowing the
-Z
actions to override any set by the
-T
actions.
As mentioned elsewhere, the reason for the language specific processing is to allow different actions for the same command line option, depending on the file type that is being processed. For example, when processing a PCL file it might be necessary to send PCL command strings and when processing a PostScript file, you would need to send PostScript commands.
If the printer can return status, i.e., the
status
or
forcestatus
flag is set,
then the
ifhp
filter will read status information back from the printer.
If the
logall
flag is SET,
then all error messages will be written to the status or log file.
If the printer is returning PJL status information, then this has a specific format:
@PJL UINFO DEVICE
CODE=nnnn
DISLAY="value"
...
@PJL UINFO JOB
START
...
@PJL UINFO JOB
END
...
The
ifhp
program will extract the
CODE
and job start and end flags,
and log these as appropriate.
Unfortunately,
some PJL based printers are extremely verbose in their generation of status
messages.
In order to reduce the amount of logging of redundant information,
ifhp
will only record when a device status has
changed,
rather than when it has been reported.
The
pjl_quiet_codes=[ code code code ]
value is used to suppress reporting of selected error codes.
If the error code is in the pjl_quiet_codes list, then the error status
will not be reported to the user unless the
logall
option is set.
For example:
pjl_quiet_codes=[ 10000 10001 10003 10023 10024 35078 ]
Also, there may be error codes which does not have a builtin error
message available. New messages can be added using the
pjl_error_codes
option.
Its value is a list of lines, each line consisting of an error code
followed by the corresonding error message:
pjl_error_codes=[
code=msg
code=msg
...
]
Example:
pjl_error_codes=[
10000=powersave mode
10001=Ready Online
10002=Ready Offline
10003=Warming Up
10004=Self Test
10005=Reset
]
The waitend
option controls the job termination sequence.
By default,
this will do the same work as the
sync
operation,
and the option takes the same set of values.
If waitend
is suppressed using waitend@
,
then as soon as a job has been transferred,
the next step,
pagecount
,
will be attempted.
If the print job has not finished at this point,
then erroneous page counts will be reported.
When using the appsocket
protocol,
then suppressing waitend
will cause no error messages from the printer to
be reported.
The Tektronix Phaser PostScript printers uses the AppSocket protcol
for sending a job to the printer over a network connection.
The
appsocket
flag enables this operation.
The protocol is (briefly):
To use this protocol,
the printer TCP/IP address and port must be specified using the
-Tdev=host%port
option;
usually port is 9100.
Also,
the printer device in the printcap entry should be lp=/dev/null
.
When using the Appsocket protocol,
the ifhp
filter will open a UDP port and use it to send
query packets to the printer UDP port 9101.
In addition,
it will try to open a connection to port 9100.
When a connection has been established,
and pagecount has been determined,
the connection will be close and reopened.
After job transfer,
the connecion will be half-closed
.
That is,
the shutdown()
facility will be used to cause the TCP/IP connection
to be set to closed for transmission but open for reception.
The printer will send status information until the job is completed,
and then close the connection.
If page count information is needed,
the ifhp
filter will then reopen the connection and get the page count information.