tsol_standard revision f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# CDDL HEADER START
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# The contents of this file are subject to the terms of the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Common Development and Distribution License (the "License").
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# You may not use this file except in compliance with the License.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# See the License for the specific language governing permissions
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# and limitations under the License.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# When distributing Covered Code, include this CDDL HEADER in each
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# If applicable, add the following below this CDDL HEADER, with the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# fields enclosed by brackets "[]" replaced with your own identifying
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# information: Portions Copyright [yyyy] [name of copyright owner]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# CDDL HEADER END
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Use is subject to license terms.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#pragma ident "%Z%%M% %I% %E% SMI"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica###########
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica## Standard printer interface program.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica###########
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Until we get to the point below where the printer port
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# and physical printer are initialized, we can't do much
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# except exit if the Spooler/Scheduler cancels us.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricatrap 'exit' 15
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# We can be clever about getting a hangup or interrupt, though, at least
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# until the filter runs. Do this early, even though $LPTELL
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# isn't defined, so that we're covered.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricacatch_hangup () {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ -n "${LPTELL}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica"The connection to the printer dropped; perhaps the printer went off-line?" \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica | ${LPTELL} ${printer}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricacatch_interrupt () {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ -n "${LPTELL}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica"Received an interrupt from the printer. The reason is unknown,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaalthough a common cause is that the baud rate is too high." \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica | ${LPTELL} ${printer}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricatrap 'catch_hangup; exit_code=129 exit 129' 1
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricatrap 'catch_interrupt; exit_code=129 exit 129' 2 3
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Most of the time we don't want the standard error to be captured
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# by the Spooler, mainly to avoid "Terminated" messages that the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# shell puts out when we get a SIGTERM. We'll save the standard
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# error channel under another number, so we can use it when it
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# should be captured.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Open another channel to the printer port, for use when the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# regular standard output won't be directed there, such as in
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# command substitution (`cmd`).
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaexec 5>&2 2>/dev/null 3>&1
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Set some globally used variables and functions.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica: ${TMPDIR:=/tmp}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica: ${SPOOLDIR:=/usr/spool/lp}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica: ${CHARSETDIR:=/usr/lib/charsets}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica: ${LOCALPATH:=${SPOOLDIR}/bin}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaPATH="/bin:/usr/bin:${LOCALPATH}"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaMAX_COLS_SMALL_BANNER=40
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# On the 3.2 release of the 386unix product, the parallel port does
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# not support any ioctl calls. As a result, we cannot set the opost
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# and onlcr attributes to have <NL>'s expanded to <CR><NL>. This
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# "filter" gets the job done for us.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica: ${FIX386BD:=${LOCALPATH}/386parallel}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaif [ -n "${FIX386BD}" -a -x "${FIX386BD}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica FIX386BD="| ${FIX386BD}"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica FIX386BD=""
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Use ${TMPPREFIX} as the prefix for all temporary files, so
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# that cleanup is easy. The prefix may be up to 13 characters
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# long, so you only have space for one more character to make
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# a file name. If necessary, make a directory using this prefix
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# for better management of unique temporary file names.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaTMPPREFIX=${TMPDIR}/`uname -n`$$
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Before exiting, set ${exit_code} to the value with which to exit.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Otherwise, the exit from this script will be 0.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricatrap 'rm -fr ${TMPPREFIX}*; exit ${exit_code}' 0
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# ${LPTELL} is the name of a program that will send its
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# standard input to the Spooler. It is used to forward
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# the description of a printer fault to the Spooler,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# which uses it in an alert to the administrator.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaif [ ! -x "${LPTELL:=${LOCALPATH}/lp.tell}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica fake_lptell () {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica header="no"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica while read line
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ "no" = "${header}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica errmsg ERROR ${E_IP_UNKNOWN} \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "unknown printer/interface failure" \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "consult your system administrator;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica reasons for failure (if any) follow:"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica header=yes
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${line}" >&2
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica LPTELL=fake_lptell
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# ${DRAIN} is the name of a program that will wait
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# long enough for data sent to the printer to print.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaif [ -x "${LOCALPATH}/drain.output" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica DRAIN="${LOCALPATH}/drain.output 5" # wait only five seconds
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# ${LPTSOLSEPARATOR} is the name of a program to put banner and trailer
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# pages around the job.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaif [ -x ${LOCALPATH}/lp.tsol_separator ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica LPTSOLSEPARATOR=${LOCALPATH}/lp.tsol_separator
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${LOCALPATH}/lp.tsol_separator not found." >&2
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# ${LPCAT} is the name of a program to use as a default
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# filter. Minimally it should copy its standard input to
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# the standard output, but it should also trap printer
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# faults. The current LPCAT traps hangups (DCD dropping, SIGHUP),
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# interrupts (SIGINT, SIGQUIT), broken pipe (SIGPIPE), and
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# excess delays in sending data to the printer, interpreting all
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# as printer faults.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaif [ ! -x "${LPCAT:=${LOCALPATH}/lp.cat}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica LPCAT="cat"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# ${LPSET} is the name of a program that will set the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# character pitch, line pitch, page width, page length,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# and character set. It helps to have this in a single
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# binary program so that (1) it's faster than calls
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# to "tput"; and (2) it can access the new Terminfo
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# capabilities for printers (on pre SVR3.2 machines, tput can't).
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaif [ ! -x "${LPSET:=${LOCALPATH}/lp.set}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica fake_lpset () {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo H V W L S >&2
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica LPSET=fake_lpset
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricainternal_lpset () {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # The funny business with the "2>&1 1>&3" is to let us capture
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # the standard ERROR, not the standard OUTPUT as is the usual case
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # with foo=`cmd`. The standard output will go to the printer.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica [ -n "${stty1}" ] && stty ${stty1} 0<&1
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica chk=`${LPSET} "$1" "$2" "$3" "$4" "$5" 2>&1 1>&3`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica [ -n "${stty2}" ] && stty ${stty2} 0<&1
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # The standard error of the delivered ${LPSET} program
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # is a string of letters, H, V, W, L, S, which correspond
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # to cpi, lpi, width, length, and character set. A letter
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # is present only if the corresponding attribute could not
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica for err in ${chk}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica case ${err} in
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica errmsg WARNING ${E_IP_BADCPI} \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "can't select the character pitch \"${cpi}\"" \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "check the valid pitches for the printer,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica or consult your system administrator;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica printing continues"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica errmsg WARNING ${E_IP_BADLPI} \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "can't select the line pitch \"${lpi}\"" \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "check the valid pitches for the printer,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica or consult your system administrator;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica printing continues"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica width=${cols}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica errmsg WARNING ${E_IP_BADWIDTH} \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "can't select the page width \"${width}\"" \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "check the valid widths for the printer,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica or consult your system administrator;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica printing continues"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica length=${lines}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica errmsg WARNING ${E_IP_BADLENGTH} \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "can't select the page length \"${length}\"" \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "check the valid lengths for the printer,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica or consult your system administrator;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica printing continues"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica errmsg WARNING ${E_IP_BADCHARSET} \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "can't select the character set \"${CHARSET}\"" \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "check the name given in the -S option,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica or consult your system administrator;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica printing continues"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# ${TPUT} is "tput" IF it works. We'll disable it if we get an
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# ugly error message the first time we use it. See the TERM variable
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# later in the script.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# NOTE: The check we use to see if "tput" works is to use an OLD
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Terminfo capability, like "lines". If it works with that it may
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# still fail with some of the newer capabilities like "init" (SVR3.0)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# or "swidm" (SVR3.2), because the version of "tput" we have on your
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# machine is older. Thus, on some of the code where ${TPUT} is used
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# you'll see "2>/dev/null" being used to avoid ugly error messages.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Error message formatter:
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Invoke as
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# errmsg severity message-number problem help
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# where severity is "ERROR" or "WARNING", message-number is
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# a unique identifier, problem is a short description of the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# problem, and help is a short suggestion for fixing the problem.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaLP_ERR_LABEL="UX:lp"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaE_IP_ARGS=1
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaE_IP_OPTS=2
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#E_IP_FILTER=3
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaE_IP_STTY=4
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaE_IP_UNKNOWN=5
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaE_IP_BADFILE=6
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaE_IP_BADCHARSET=7
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaE_IP_BADCPI=8
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaE_IP_BADLPI=9
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaE_IP_BADWIDTH=10
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaE_IP_BADLENGTH=11
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaE_IP_ERRORS=12 # (in slow.filter)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaerrmsg () {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica case $1 in
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica sev=" ERROR";
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica sev="WARNING";
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# tag=`expr "${LP_ERR_LABEL}" : "\(.*\):"``expr "${LP_ERR_LABEL}" : ".*:\(.*\)"`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${LP_ERR_LABEL}: ${sev}: $3
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica TO FIX: $4" >&5
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica###########
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica## Check arguments
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica###########
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "`expr \"$1\" : \"^[^=]*=\(.*\)\"`"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# This program is invoked as
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# ${SPOOLDIR}/.../printer request-id user title copies options files...
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# The first three arguments are simply reprinted on the banner page,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# the fourth (copies) is used to control the number of copies to print,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# the fifth (options) is a blank separated list (in a single argument)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# of user or Spooler supplied options (without the -o prefix),
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# and the last arguments are the files to print.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaif [ $# -lt 5 ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica errmsg ERROR ${E_IP_ARGS} \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "wrong number of arguments to interface program" \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "consult your system administrator"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaprinter=`basename $0`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricarequest_id=$1
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricauser_name=$2
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaoption_list=$5
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricanobanner="no"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricanofilebreak="no"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricanolabels="no"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricafor i in ${option_list}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica case "${inlist}${i}" in
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica nobanner )
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica nobanner="yes"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica nofilebreak )
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica nofilebreak="yes"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica nolabels )
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica nolabels="yes"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # If you want to add simple options (e.g. -o simple)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # identify them here.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# simple="yes"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica cpi=pica )
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica cpi=elite )
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica cpi=`parse ${i}`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica lpi=`parse ${i}`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica length=* )
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica length=`parse ${i}`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica width=`parse ${i}`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # If you want to add simple-value options (e.g. -o value=a)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # identify them here.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# value=* )
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# value=`parse ${i}`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # If you want to add options that, like "stty",
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # take a list (e.g. -o lopt='a b c'), identify
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # them here and below (look for LOPT).
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica stty=* | flist=* | lpd=* )
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#LOPT stty=* | flist=* | lpd=* | lopt=* )
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica inlist=`expr "${inlist}${i}" : "^\([^=]*=\)"`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica case "${i}" in
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ${inlist}\'*\' )
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica item=`expr "${i}" : "^[^=]*='*\(.*\)'\$"`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ${inlist}\' )
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ${inlist}\'* )
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica item=`expr "${i}" : "^[^=]*='*\(.*\)\$"`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ${inlist}* )
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica item=`expr "${i}" : "^[^=]*=\(.*\)\$"`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica item=`expr "${i}" : "^\(.*\)'\$"`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica item="${i}"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # We don't dare use "eval" because a clever user could
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # put something in an option value that we'd end up
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # exec'ing.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica case "${inlist}" in
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica stty="${stty} ${item}"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica flist="${flist} ${item}"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica lpd="${lpd} ${item}"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#LOPT lopt= )
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica#LOPT lopt="${lopt} ${item}"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica case "${i}" in
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ${inlist}\'*\' )
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ${inlist}\'* )
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica *\' | ${inlist}* )
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica errmsg WARNING ${E_IP_OPTS} \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "unrecognized \"-o ${i}\" option" \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "check the option, resubmit if necessary
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica printing continues"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Additional ``parameters'' are passed via Shell environment
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# variables:
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# TERM The printer type (used for Terminfo access)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# CHARSET The character set to choose
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# FILTER The filter to run
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Set defaults for unset variables.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica: ${TERM:=unknown}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricatput lines 1>/dev/null 2>&1 || TPUT=:
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica: ${CHARSET:=cs0}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaif [ -z "${FILTER}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # If no filter is being used, we have a little routine that
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # will push the data to the printer. It traps hangups (loss
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # of carrier) and checks for excessive delays in sending the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # data to the printer. The lesser of the print rate of the printer
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # (obtained from Terminfo) or the baud rate is used to compute
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # the expected delay. If neither of these is correct, you
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # may be experiencing false alarms. If so, give the correct
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # rate, in characters per second, as a single argument.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # An argument of 0 means don't check for delays.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # Give an -r option to get a printout of actual delays.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # (QUOTES ARE IMPORTANT!)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica case "$TERM" in
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # make the "postscript" printers use postio to
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # talk to the printer and periodically get a
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # status from them
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # make the "reverse postscript" printers reverse the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # output and the use postio to talk to the printer
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # we don't know the type, so just assume that the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # input and output are the same
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ `basename "${LPCAT}"` = "lp.cat" ] ; then
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica FILTER="${LPCAT} 0" # infinite delays
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # FILTER="${LPCAT} 120" # e.g. 120 CPS
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # FILTER="${LPCAT} -r 0 2>/tmp/delays"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # FILTER=${LPCAT}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica###########
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica## Initialize the printer port
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica###########
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# SERIAL PORTS:
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Initialize everything.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# PARALLEL PORTS:
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Don't initialize baud rate.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# It's not obvious how to tell if a port is parallel or serial.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# However, by splitting the initialization into two steps and letting
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# the serial-only part fail nicely, it'll work.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Another point: The output must be a ``tty'' device. If not, don't
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# bother with any of this.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricastty1= stty2=
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricatty 0<&1 1>/dev/null 2>&1 && {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # First set the default parameters,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # then the requested parameters.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica cs8 -cstopb -parenb -parodd \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ixon -ixany \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica opost -olcuc onlcr -ocrnl -onocr -onlret -ofill \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica nl0 cr0 tab0 bs0 vt0 ff0 \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ -n "${stty}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if stty ${stty} 0<&1 1>/dev/null 2>&5
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica errmsg ERROR ${E_IP_STTY} \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "stty option list failed" \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "check the \"-o stty\" option you used,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica or consult your system administrator"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # Here you may want to add other port initialization code.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # Some examples:
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # estty # for printer needing hardware flow control (3B2/EPORTS)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # fctty # for printer needing hardware flow control (3B15,3B20)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica #estty 0<&1
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica #fctty 0<&1
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ##########
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # Find out if we have to turn off opost before initializing the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # printer and on after. Likewise, check clocal.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # Turning OFF opost (output postprocessing) keeps the UNIX system
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # from changing what we try to send to the printer. Turning ON
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # clocal keeps the UNIX system from dropping what we are trying to
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # send if the printer drops DTR. An example of the former is the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # AT&T 479, which wants to send a linefeed (ASCII 10) when a page
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # width of 10 is set; with opost on, this COULD BE turned into a
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # carriage-return/linefeed pair. An example of the latter is the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # AT&T 455, which momentarily drops DTR when it gets the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # initialization string, is2; with clocal off, the UNIX system
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # stops sending the rest of the initialization sequence at that
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # THIS CODE MUST FOLLOW THE REST OF THE PORT INITIALIZATION CODE.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ##########
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica cur_stty=`stty -a 0<&3`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica expr "${cur_stty}" : '.*-opost' 1>/dev/null 2>&1 \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica || stty1="${stty1} -opost" stty2="${stty2} opost"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica expr "${cur_stty}" : '.*-clocal' 1>/dev/null 2>&1 \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica && stty1="${stty1} clocal" stty2="${stty2} -clocal"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica expr "${cur_stty}" : '.* opost.*' 1>/dev/null 2>&1 \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica || banner_filter=${FIX386BD}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica###########
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica## Initialize the physical printer (Part I).
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica## Here we bring the printer to a sane state and set the page size.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica###########
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# WARNING! The "echo" command will catch backslashes (\) and
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# try to interpret the characters following it. Thus, using
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# "echo" to print string values obtained from "tput" is dangerous.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# We're confident that most printers don't have backslashes
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# in the control sequences for carriage return and form-feed.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# We're also confident that these don't contain newlines.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# We're also confident that most printers have a linefeed
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# in the control sequence for doing a newline (move to beginning
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# of next line), but we can't capture it like we do the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# carriage return or form-feed. Thus we set it unconditionally.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# We don't set form-feed if it isn't defined, however, because
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# maybe the printer doesn't have a formfeed. If not set, we're
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# out of luck.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaCR=`${TPUT} cr`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica[ -z "${CR}" ] && CR="\r"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaFF=`${TPUT} ff`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaNL="${CR}\n"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricalines=`${TPUT} lines`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica[ -z "${lines}" -o 0 -ge "${lines}" ] && lines=66
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricacols=`${TPUT} cols`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica[ -z "${cols}" -o 0 -ge "${cols}" ] && cols=132
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Basic initialization. The ``else'' clause is equivalent,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# but covers cases where old Terminal Information Utilities are present.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica[ -n "${stty1}" ] && stty ${stty1} 0<&1
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# "tput init" will return an "^M" in many cases to "stdout", i.e., printer!
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# This creates problems for some PS printers
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaif [ "${TERM}" = "PS" -o "${TERM}" = "PSR" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaelif ${TPUT} init 2>/dev/null
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica pgm=`${TPUT} iprog`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ -x "${pgm}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica eval ${pgm}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ${TPUT} is1
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ${TPUT} is2
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ "8" != "`${TPUT} it`" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica stty tab3 0<&1 1>/dev/null 2>&1
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica elif `${TPUT} ht >/dev/null`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica tabset="/usr/lib/tabset/${TERM}"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ -r ${tabset} ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica cat -s ${tabset}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica stty tab3 0<&1 1>/dev/null 2>&1
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica file=`${TPUT} if`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ "${tabset}" != "${file}" -a -r "${file}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica cat -s "${file}"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ${TPUT} is3
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${CR}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica[ -n "${stty2}" ] && stty ${stty2} 0<&1
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Set the page size and print spacing, but not the character set.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# We will be doing the character set later (after the header).
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricainternal_lpset "${cpi}" "${lpi}" "${width}" "${length}" ""
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# The banner page (and cancellation page) will
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# use double width characters if they're available.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaWIDE_CS=`${TPUT} swidm 2>/dev/null` && NORM_CS=`${TPUT} rwidm 2>/dev/null`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaPAD="#####${NL}"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Some printers need to have the banner page filtered.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricacase "${TERM}" in
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica banner_filter="/usr/lib/lp/postscript/postprint | /usr/lib/lp/postscript/postio"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica LPTELL_OPTS="-l"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaif [ -n "${banner_filter}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica banner_filter="| ${banner_filter}"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Now that the printer is ready for printing, we're able
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# to record on paper a cancellation.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricacancel_banner () {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${PAD}${PAD}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "#####${WIDE_CS} Job ${request_id}${NORM_CS}${NL}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "#####${WIDE_CS} suspended or canceled${NORM_CS}${NL}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${PAD}${PAD}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricacanceled () {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ${TPUT} scs 0 2>/dev/null
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${CR}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ "${width:-${cols}}" -lt "${MAX_COLS_SMALL_BANNER}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica WIDE_CS= NORM_CS=
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica cancel_banner
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ -n "${FF}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${CR}${FF}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricatrap 'eval canceled ${banner_filter}; exit_code=0 exit' 15
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica###########
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica## Print the banner page
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica###########
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# You may want to change the following code to get a custom banner.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaregular_banner () {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${CR}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${PAD}${PAD}${PAD}${PAD}${PAD}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "#####${WIDE_CS} User: ${user_name}${NORM_CS}${NL}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ -n "$ALIAS_USERNAME" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${PAD}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "#####${WIDE_CS} Alias: ${ALIAS_USERNAME}${NORM_CS}${NL}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ -n "${title}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${PAD}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "#####${WIDE_CS} Title: ${title}${NORM_CS}${NL}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${PAD}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "#####${WIDE_CS} Printed: `LANG=C date '+%a %H:%M %h %d, %Y'`${NORM_CS}${NL}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${PAD}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "#####${WIDE_CS} Job number: ${request_id}${NORM_CS}${NL}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${PAD}${PAD}${PAD}${PAD}${PAD}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ -n "${FF}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${CR}${FF}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricasmall_banner () {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${CR}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${PAD}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "##### User: ${user_name}${NL}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ -n "${title}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "##### Title: ${title}${NL}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "##### Date: `LANG=C date '+%a %H:%M %h %d, %Y'`${NL}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "##### Job: ${request_id}${NL}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${PAD}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ -n "${FF}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${CR}${FF}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaif [ "${width:-${cols}}" -lt "${MAX_COLS_SMALL_BANNER}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica banner=small_banner
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica banner=regular_banner
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica## Skip this for PS/PSR in TSOL, since lp.tsol_separator handles the banners
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaif [ "no" = "${nobanner}" -a "${TERM}" != "PSR" -a "${TERM}" != "PS" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ( eval "${banner} ${banner_filter}" 2>&1 1>&3 ) \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica | ${LPTELL} ${LPTELL_OPTS} ${printer}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica###########
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica## Surround the job by PostScript code to produce banner
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica## and trailerpages and page headers and footers.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica###########
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaBANNER_EXIT_CODE=${TMPPREFIX}.banner.exit_code
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaecho 0 > ${BANNER_EXIT_CODE}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaTSOLSEPARATOR_LOG=${TMPPREFIX}.banner.errmsg
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricatsol_bannerize () {
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica TSOLSEPARATOR_OPTS="-e ${TSOLSEPARATOR_LOG}"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ "yes" = "${nolabels}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -l"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ "yes" = "${nobanner}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -t /dev/null -b /dev/null"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ "${TERM}" = "PSR" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -r"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # Get rid of the #, TAB and NL characters in the title
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica tsol_title=`echo $title`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica tsol_title=`echo $tsol_title | sed 's/#//g'`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica LC_TIME=C ${LPTSOLSEPARATOR} ${TSOLSEPARATOR_OPTS} "${printer}" \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "${request_id}" "${user_name}" "${tsol_title}" "${file}"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo $? > ${BANNER_EXIT_CODE}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricabannerize=tsol_bannerize
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaif [ "yes" = "${nobanner}" -a "yes" = "${nolabels}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica bannerize=cat
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaif [ "${TERM}" != "PSR" -a "${TERM}" != "PS" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica bannerize=cat
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica###########
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica## Initialize the physical printer (Part II)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica## Here we select the character set.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica## One could argue that this should be done before the banner is printed,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica## but we don't, to keep the banner page looking consistent for the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica## operator. You can move this code before the banner code if you
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica## disagree. If you do, combine it with the other call to "internal_lpset"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica## to do everything in one shot.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica###########
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricainternal_lpset "" "" "" "" "${CHARSET}"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica###########
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica## Print some copies of the file(s)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica###########
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# The protocol between the interface program and the Spooler
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# is fairly simple:
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# All standard error output is assumed to indicate a
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# fault WITH THE REQUEST. The output is mailed to the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# user who submitted the print request and the print
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# request is finished.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# If the interface program sets a zero exit code,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# it is assumed that the file printed correctly.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# If the interface program sets a non-zero exit code
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# less than 128, it is assumed that the file did not
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# print correctly, and the user will be notified.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# In either case the print request is finished.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# If the interface program sets an exit code greater
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# than 128, it is assumed that the file did not print
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# because of a printer fault. If an alert isn't already
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# active (see below) one will be activated. (Exit code
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# 128 should not be used at all. The shell, which executes
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# this program, turns SIGTERM, used to kill this program
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# for a cancellation or disabling, into exit 128. The
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Spooler thus interpretes 128 as SIGTERM.)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# A message sent to the standard input of the ${LPTELL}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# program is assumed to describe a fault WITH THE PRINTER.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# The output is used in an alert (if alerts are defined).
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# If the fault recovery is "wait" or "begin", the printer
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# is disabled (killing the interface program if need be),
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# and the print request is left on the queue.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# If the fault recovery is "continue", the interface program
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# is allowed to wait for the printer fault to be cleared so
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# it can resume printing.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# This interface program relies on filters to detect printer faults.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# In absence of a filter provided by the customer, it uses a simple
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# filter (${LPCAT}) to detect the class of faults that cause DCD
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# (``carrier'') drop. The protocol between the interface program and
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# the filter:
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# The filter should exit with zero if printing was
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# successful and non-zero if printing failed because
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# of a printer fault. This interface program turns a
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# non-zero exit of the filter into an "exit 129" from
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# itself, thus telling the Spooler that a printer fault
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# (still) exists.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# The filter should report printer faults via a message
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# to its standard error. This interface program takes all
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# standard error output from the filter and feeds it as
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# standard input to the ${LPTELL} program.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# The filter should wait for a printer fault to clear,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# and should resume printing when the fault clears.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Preferably it should resume at the top of the page
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# that was being printed when the fault occurred.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# If it waits and finishes printing, it should exit
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# with a 0 exit code. If it can't wait, it should exit
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# with a non-zero exit code.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# The interface program expects that ANY message on the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# standard error from the filter indicates a printer fault.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Therefore, a filter should not put user (input) error
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# messages on the standard error, but on the standard output
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# (where the user can read them when he or she examines
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# the print-out).
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricabadfileyet=
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricawhile [ $i -le $copies ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica for file in ${files}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ -r "${file}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # Here's where we set up the $LPTELL program to
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # capture fault messages, and...
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # Here's where we print the file.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # We set up a pipeline to $LPTELL, but play a trick
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # to get the filter's standard ERROR piped instead of
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # its standard OUTPUT: Divert the standard error (#2) to
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # the standard output (#1) IN THE PIPELINE. The shell
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # will have changed #1 to be the pipe, not the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # printer, so diverting #2 connects it to the pipe.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # We then change the filter's #1 to a copy of the real
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # standard output (the printer port) made earlier,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # so that is connected back to the printer again.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # We do all this inside a parenthesized expression
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # so that we can get the exit code; this is necessary
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # because the exit code of a pipeline is the exit
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # code of the right-most command, which isn't the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # These two tricks could be avoided by using a named
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # pipe to connect the standard error to $LPTELL. In
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # fact an early prototype of this script did just
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # that; however, the named pipe introduced a timing
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # problem. The processes that open a named pipe hang
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # until both ends of the pipe are opened. Cancelling
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # a request or disabling the printer often killed one
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # of the processes, causing the other process to hang
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # forever waiting for the other end of the pipe to
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # be opened.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica EXIT_CODE=${TMPPREFIX}e
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica trap '' 1 # Let the filter handle a hangup
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica trap '' 2 3 # and interrupts
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # Put the 0<${file} before the "eval" to keep
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # clever users from giving a file name that
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # evaluates as something to execute.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica 0<${file} $bannerize | eval ${FILTER} 2>&1 1>&3
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo $? >${EXIT_CODE}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # if lp.tsol_separator had an error, send its logged
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # error message to LPTELL.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica banner_exit_code=`cat ${BANNER_EXIT_CODE}`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ -n "${banner_exit_code}" -a \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica 0 -ne "${banner_exit_code}" -a \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica -n "${LPTELL}" -a \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica -r "${TSOLSEPARATOR_LOG}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica cat ${TSOLSEPARATOR_LOG} | ${LPTELL} ${printer}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo 77 > ${EXIT_CODE}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica trap 'catch_hangup; exit_code=129 exit 129' 1
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica trap 'catch_interrupt; exit_code=129 exit 129' 2 3
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica exit_code=`cat ${EXIT_CODE}`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ -n "${exit_code}" -a 0 -ne "${exit_code}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica trap '' 15 # Avoid dying from disable
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica sleep 4 # Give $LPTELL a chance to tell
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica exit ${exit_code}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ -n "${FF}" -a "no" = "${nofilebreak}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${CR}${FF}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # Don't complain about not being able to read
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # a file on second and subsequent copies, unless
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # we've not complained yet. This removes repeated
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # messages about the same file yet reduces the
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # chance that the user can remove a file and not
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica # know that we had trouble finding it.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica if [ "${i}" -le 1 -o -z "${badfileyet}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica errmsg WARNING ${E_IP_BADFILE} \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "cannot read file \"${file}\"" \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica "see if the file still exists and is readable,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica or consult your system administrator;
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica printing continues"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica badfileyet=yes
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica i=`expr $i + 1`
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Skip this for TSOL, since lp.tsol_separator handles the banners
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# if [ "no" = "${nobanner}" -a "${TERM}" = "PSR" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# ( eval "${banner} ${banner_filter}" 2>&1 1>&3 ) \
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# | ${LPTELL} ${LPTELL_OPTS} ${printer}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaif [ -n "${exit_code}" -a 0 -ne "${exit_code}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica exit ${exit_code}
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# Always ensure the complete job ends with a ``formfeed'', to
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# let the next job start on a new page. (If someone wants to
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# concatenate files, they can give them in one job.)
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# So, if we haven't been putting out a ``formfeed'' between files,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# it means we haven't followed the last file with a formfeed,
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica# so we do it here.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaif [ -n "${FF}" -a "yes" = "${nofilebreak}" ]
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica echo "${CR}${FF}\c"
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01ricaexit_code=0 exit 0