1*7c478bd9Sstevel@tonic-gate# 2*7c478bd9Sstevel@tonic-gate# Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate# Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate# 5*7c478bd9Sstevel@tonic-gate# CDDL HEADER START 6*7c478bd9Sstevel@tonic-gate# 7*7c478bd9Sstevel@tonic-gate# The contents of this file are subject to the terms of the 8*7c478bd9Sstevel@tonic-gate# Common Development and Distribution License, Version 1.0 only 9*7c478bd9Sstevel@tonic-gate# (the "License"). You may not use this file except in compliance 10*7c478bd9Sstevel@tonic-gate# with the License. 11*7c478bd9Sstevel@tonic-gate# 12*7c478bd9Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 13*7c478bd9Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing. 14*7c478bd9Sstevel@tonic-gate# See the License for the specific language governing permissions 15*7c478bd9Sstevel@tonic-gate# and limitations under the License. 16*7c478bd9Sstevel@tonic-gate# 17*7c478bd9Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each 18*7c478bd9Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 19*7c478bd9Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the 20*7c478bd9Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying 21*7c478bd9Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner] 22*7c478bd9Sstevel@tonic-gate# 23*7c478bd9Sstevel@tonic-gate# CDDL HEADER END 24*7c478bd9Sstevel@tonic-gate# 25*7c478bd9Sstevel@tonic-gate#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.26 */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate########### 28*7c478bd9Sstevel@tonic-gate## 29*7c478bd9Sstevel@tonic-gate## Standard printer interface program. 30*7c478bd9Sstevel@tonic-gate########### 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate##### 33*7c478bd9Sstevel@tonic-gate# 34*7c478bd9Sstevel@tonic-gate# Until we get to the point below where the printer port 35*7c478bd9Sstevel@tonic-gate# and physical printer are initialized, we can't do much 36*7c478bd9Sstevel@tonic-gate# except exit if the Spooler/Scheduler cancels us. 37*7c478bd9Sstevel@tonic-gate##### 38*7c478bd9Sstevel@tonic-gatetrap 'exit' 15 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate##### 41*7c478bd9Sstevel@tonic-gate# 42*7c478bd9Sstevel@tonic-gate# We can be clever about getting a hangup or interrupt, though, at least 43*7c478bd9Sstevel@tonic-gate# until the filter runs. Do this early, even though $LPTELL 44*7c478bd9Sstevel@tonic-gate# isn't defined, so that we're covered. 45*7c478bd9Sstevel@tonic-gate##### 46*7c478bd9Sstevel@tonic-gatecatch_hangup () { 47*7c478bd9Sstevel@tonic-gate if [ -n "${LPTELL}" ] 48*7c478bd9Sstevel@tonic-gate then 49*7c478bd9Sstevel@tonic-gate echo \ 50*7c478bd9Sstevel@tonic-gate"The connection to the printer dropped; perhaps the printer went off-line?" \ 51*7c478bd9Sstevel@tonic-gate | ${LPTELL} ${printer} 52*7c478bd9Sstevel@tonic-gate fi 53*7c478bd9Sstevel@tonic-gate return 0 54*7c478bd9Sstevel@tonic-gate} 55*7c478bd9Sstevel@tonic-gatecatch_interrupt () { 56*7c478bd9Sstevel@tonic-gate if [ -n "${LPTELL}" ] 57*7c478bd9Sstevel@tonic-gate then 58*7c478bd9Sstevel@tonic-gate echo \ 59*7c478bd9Sstevel@tonic-gate"Received an interrupt from the printer. The reason is unknown, 60*7c478bd9Sstevel@tonic-gatealthough a common cause is that the baud rate is too high." \ 61*7c478bd9Sstevel@tonic-gate | ${LPTELL} ${printer} 62*7c478bd9Sstevel@tonic-gate fi 63*7c478bd9Sstevel@tonic-gate return 0 64*7c478bd9Sstevel@tonic-gate} 65*7c478bd9Sstevel@tonic-gatetrap 'catch_hangup; exit_code=129 exit 129' 1 66*7c478bd9Sstevel@tonic-gatetrap 'catch_interrupt; exit_code=129 exit 129' 2 3 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate##### 69*7c478bd9Sstevel@tonic-gate# 70*7c478bd9Sstevel@tonic-gate# Most of the time we don't want the standard error to be captured 71*7c478bd9Sstevel@tonic-gate# by the Spooler, mainly to avoid "Terminated" messages that the 72*7c478bd9Sstevel@tonic-gate# shell puts out when we get a SIGTERM. We'll save the standard 73*7c478bd9Sstevel@tonic-gate# error channel under another number, so we can use it when it 74*7c478bd9Sstevel@tonic-gate# should be captured. 75*7c478bd9Sstevel@tonic-gate# 76*7c478bd9Sstevel@tonic-gate# Open another channel to the printer port, for use when the 77*7c478bd9Sstevel@tonic-gate# regular standard output won't be directed there, such as in 78*7c478bd9Sstevel@tonic-gate# command substitution (`cmd`). 79*7c478bd9Sstevel@tonic-gate##### 80*7c478bd9Sstevel@tonic-gateexec 5>&2 2>/dev/null 3>&1 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate##### 83*7c478bd9Sstevel@tonic-gate# 84*7c478bd9Sstevel@tonic-gate# Set some globally used variables and functions. 85*7c478bd9Sstevel@tonic-gate##### 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate: ${TMPDIR:=/tmp} 88*7c478bd9Sstevel@tonic-gate: ${SPOOLDIR:=/usr/spool/lp} 89*7c478bd9Sstevel@tonic-gate: ${TERMINFO:=/usr/lib/terminfo} 90*7c478bd9Sstevel@tonic-gate: ${CHARSETDIR:=/usr/lib/charsets} 91*7c478bd9Sstevel@tonic-gate 92*7c478bd9Sstevel@tonic-gate: ${LOCALPATH:=${SPOOLDIR}/bin} 93*7c478bd9Sstevel@tonic-gatePATH="/bin:/usr/bin:${LOCALPATH}" 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gateMAX_COLS_SMALL_BANNER=40 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate##### 98*7c478bd9Sstevel@tonic-gate# 99*7c478bd9Sstevel@tonic-gate# On the 3.2 release of the 386unix product, the parallel port does 100*7c478bd9Sstevel@tonic-gate# not support any ioctl calls. As a result, we cannot set the opost 101*7c478bd9Sstevel@tonic-gate# and onlcr attributes to have <NL>'s expanded to <CR><NL>. This 102*7c478bd9Sstevel@tonic-gate# "filter" gets the job done for us. 103*7c478bd9Sstevel@tonic-gate##### 104*7c478bd9Sstevel@tonic-gate: ${FIX386BD:=${LOCALPATH}/386parallel} 105*7c478bd9Sstevel@tonic-gateif [ -n "${FIX386BD}" -a -x "${FIX386BD}" ] 106*7c478bd9Sstevel@tonic-gatethen 107*7c478bd9Sstevel@tonic-gate FIX386BD="| ${FIX386BD}" 108*7c478bd9Sstevel@tonic-gateelse 109*7c478bd9Sstevel@tonic-gate FIX386BD="" 110*7c478bd9Sstevel@tonic-gatefi 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate##### 113*7c478bd9Sstevel@tonic-gate# Use ${TMPPREFIX} as the prefix for all temporary files, so 114*7c478bd9Sstevel@tonic-gate# that cleanup is easy. The prefix may be up to 13 characters 115*7c478bd9Sstevel@tonic-gate# long, so you only have space for one more character to make 116*7c478bd9Sstevel@tonic-gate# a file name. If necessary, make a directory using this prefix 117*7c478bd9Sstevel@tonic-gate# for better management of unique temporary file names. 118*7c478bd9Sstevel@tonic-gate##### 119*7c478bd9Sstevel@tonic-gateTMPPREFIX=${TMPDIR}/`uname -n`$$ 120*7c478bd9Sstevel@tonic-gate 121*7c478bd9Sstevel@tonic-gate##### 122*7c478bd9Sstevel@tonic-gate# Before exiting, set ${exit_code} to the value with which to exit. 123*7c478bd9Sstevel@tonic-gate# Otherwise, the exit from this script will be 0. 124*7c478bd9Sstevel@tonic-gate##### 125*7c478bd9Sstevel@tonic-gatetrap 'rm -fr ${TMPPREFIX}*; exit ${exit_code}' 0 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate##### 128*7c478bd9Sstevel@tonic-gate# ${LPTELL} is the name of a program that will send its 129*7c478bd9Sstevel@tonic-gate# standard input to the Spooler. It is used to forward 130*7c478bd9Sstevel@tonic-gate# the description of a printer fault to the Spooler, 131*7c478bd9Sstevel@tonic-gate# which uses it in an alert to the administrator. 132*7c478bd9Sstevel@tonic-gate##### 133*7c478bd9Sstevel@tonic-gateif [ ! -x "${LPTELL:=${LOCALPATH}/lp.tell}" ] 134*7c478bd9Sstevel@tonic-gatethen 135*7c478bd9Sstevel@tonic-gate fake_lptell () { 136*7c478bd9Sstevel@tonic-gate header="no" 137*7c478bd9Sstevel@tonic-gate while read line 138*7c478bd9Sstevel@tonic-gate do 139*7c478bd9Sstevel@tonic-gate if [ "no" = "${header}" ] 140*7c478bd9Sstevel@tonic-gate then 141*7c478bd9Sstevel@tonic-gate errmsg ERROR ${E_IP_UNKNOWN} \ 142*7c478bd9Sstevel@tonic-gate "unknown printer/interface failure" \ 143*7c478bd9Sstevel@tonic-gate "consult your system administrator; 144*7c478bd9Sstevel@tonic-gate reasons for failure (if any) follow:" 145*7c478bd9Sstevel@tonic-gate header=yes 146*7c478bd9Sstevel@tonic-gate fi 147*7c478bd9Sstevel@tonic-gate echo "${line}" >&2 148*7c478bd9Sstevel@tonic-gate done 149*7c478bd9Sstevel@tonic-gate return 1 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate LPTELL=fake_lptell 152*7c478bd9Sstevel@tonic-gatefi 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate##### 155*7c478bd9Sstevel@tonic-gate# ${DRAIN} is the name of a program that will wait 156*7c478bd9Sstevel@tonic-gate# long enough for data sent to the printer to print. 157*7c478bd9Sstevel@tonic-gate##### 158*7c478bd9Sstevel@tonic-gateif [ -x "${LOCALPATH}/drain.output" ] 159*7c478bd9Sstevel@tonic-gatethen 160*7c478bd9Sstevel@tonic-gate DRAIN="${LOCALPATH}/drain.output 5" # wait only five seconds 161*7c478bd9Sstevel@tonic-gateelse 162*7c478bd9Sstevel@tonic-gate DRAIN= 163*7c478bd9Sstevel@tonic-gatefi 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate##### 166*7c478bd9Sstevel@tonic-gate# ${LPCAT} is the name of a program to use as a default 167*7c478bd9Sstevel@tonic-gate# filter. Minimally it should copy its standard input to 168*7c478bd9Sstevel@tonic-gate# the standard output, but it should also trap printer 169*7c478bd9Sstevel@tonic-gate# faults. The current LPCAT traps hangups (DCD dropping, SIGHUP), 170*7c478bd9Sstevel@tonic-gate# interrupts (SIGINT, SIGQUIT), broken pipe (SIGPIPE), and 171*7c478bd9Sstevel@tonic-gate# excess delays in sending data to the printer, interpreting all 172*7c478bd9Sstevel@tonic-gate# as printer faults. 173*7c478bd9Sstevel@tonic-gate##### 174*7c478bd9Sstevel@tonic-gateif [ ! -x "${LPCAT:=${LOCALPATH}/lp.cat}" ] 175*7c478bd9Sstevel@tonic-gatethen 176*7c478bd9Sstevel@tonic-gate LPCAT="cat" 177*7c478bd9Sstevel@tonic-gatefi 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate##### 180*7c478bd9Sstevel@tonic-gate# ${LPSET} is the name of a program that will set the 181*7c478bd9Sstevel@tonic-gate# character pitch, line pitch, page width, page length, 182*7c478bd9Sstevel@tonic-gate# and character set. It helps to have this in a single 183*7c478bd9Sstevel@tonic-gate# binary program so that (1) it's faster than calls 184*7c478bd9Sstevel@tonic-gate# to "tput"; and (2) it can access the new Terminfo 185*7c478bd9Sstevel@tonic-gate# capabilities for printers (on pre SVR3.2 machines, tput can't). 186*7c478bd9Sstevel@tonic-gate##### 187*7c478bd9Sstevel@tonic-gateif [ ! -x "${LPSET:=${LOCALPATH}/lp.set}" ] 188*7c478bd9Sstevel@tonic-gatethen 189*7c478bd9Sstevel@tonic-gate fake_lpset () { 190*7c478bd9Sstevel@tonic-gate echo H V W L S >&2 191*7c478bd9Sstevel@tonic-gate false 192*7c478bd9Sstevel@tonic-gate } 193*7c478bd9Sstevel@tonic-gate LPSET=fake_lpset 194*7c478bd9Sstevel@tonic-gatefi 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gateinternal_lpset () { 197*7c478bd9Sstevel@tonic-gate ##### 198*7c478bd9Sstevel@tonic-gate # 199*7c478bd9Sstevel@tonic-gate # The funny business with the "2>&1 1>&3" is to let us capture 200*7c478bd9Sstevel@tonic-gate # the standard ERROR, not the standard OUTPUT as is the usual case 201*7c478bd9Sstevel@tonic-gate # with foo=`cmd`. The standard output will go to the printer. 202*7c478bd9Sstevel@tonic-gate ##### 203*7c478bd9Sstevel@tonic-gate [ -n "${stty1}" ] && stty ${stty1} 0<&1 204*7c478bd9Sstevel@tonic-gate chk=`${LPSET} "$1" "$2" "$3" "$4" "$5" 2>&1 1>&3` 205*7c478bd9Sstevel@tonic-gate [ -n "${stty2}" ] && stty ${stty2} 0<&1 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate ##### 208*7c478bd9Sstevel@tonic-gate # 209*7c478bd9Sstevel@tonic-gate # The standard error of the delivered ${LPSET} program 210*7c478bd9Sstevel@tonic-gate # is a string of letters, H, V, W, L, S, which correspond 211*7c478bd9Sstevel@tonic-gate # to cpi, lpi, width, length, and character set. A letter 212*7c478bd9Sstevel@tonic-gate # is present only if the corresponding attribute could not 213*7c478bd9Sstevel@tonic-gate # be set. 214*7c478bd9Sstevel@tonic-gate ##### 215*7c478bd9Sstevel@tonic-gate for err in ${chk} 216*7c478bd9Sstevel@tonic-gate do 217*7c478bd9Sstevel@tonic-gate case ${err} in 218*7c478bd9Sstevel@tonic-gate H ) 219*7c478bd9Sstevel@tonic-gate errmsg WARNING ${E_IP_BADCPI} \ 220*7c478bd9Sstevel@tonic-gate "can't select the character pitch \"${cpi}\"" \ 221*7c478bd9Sstevel@tonic-gate "check the valid pitches for the printer, 222*7c478bd9Sstevel@tonic-gate or consult your system administrator; 223*7c478bd9Sstevel@tonic-gate printing continues" 224*7c478bd9Sstevel@tonic-gate ;; 225*7c478bd9Sstevel@tonic-gate V ) 226*7c478bd9Sstevel@tonic-gate errmsg WARNING ${E_IP_BADLPI} \ 227*7c478bd9Sstevel@tonic-gate "can't select the line pitch \"${lpi}\"" \ 228*7c478bd9Sstevel@tonic-gate "check the valid pitches for the printer, 229*7c478bd9Sstevel@tonic-gate or consult your system administrator; 230*7c478bd9Sstevel@tonic-gate printing continues" 231*7c478bd9Sstevel@tonic-gate ;; 232*7c478bd9Sstevel@tonic-gate W ) 233*7c478bd9Sstevel@tonic-gate width=${cols} 234*7c478bd9Sstevel@tonic-gate errmsg WARNING ${E_IP_BADWIDTH} \ 235*7c478bd9Sstevel@tonic-gate "can't select the page width \"${width}\"" \ 236*7c478bd9Sstevel@tonic-gate "check the valid widths for the printer, 237*7c478bd9Sstevel@tonic-gate or consult your system administrator; 238*7c478bd9Sstevel@tonic-gate printing continues" 239*7c478bd9Sstevel@tonic-gate ;; 240*7c478bd9Sstevel@tonic-gate L ) 241*7c478bd9Sstevel@tonic-gate length=${lines} 242*7c478bd9Sstevel@tonic-gate errmsg WARNING ${E_IP_BADLENGTH} \ 243*7c478bd9Sstevel@tonic-gate "can't select the page length \"${length}\"" \ 244*7c478bd9Sstevel@tonic-gate "check the valid lengths for the printer, 245*7c478bd9Sstevel@tonic-gate or consult your system administrator; 246*7c478bd9Sstevel@tonic-gate printing continues" 247*7c478bd9Sstevel@tonic-gate ;; 248*7c478bd9Sstevel@tonic-gate S ) 249*7c478bd9Sstevel@tonic-gate errmsg WARNING ${E_IP_BADCHARSET} \ 250*7c478bd9Sstevel@tonic-gate "can't select the character set \"${CHARSET}\"" \ 251*7c478bd9Sstevel@tonic-gate "check the name given in the -S option, 252*7c478bd9Sstevel@tonic-gate or consult your system administrator; 253*7c478bd9Sstevel@tonic-gate printing continues" 254*7c478bd9Sstevel@tonic-gate ;; 255*7c478bd9Sstevel@tonic-gate esac 256*7c478bd9Sstevel@tonic-gate done 257*7c478bd9Sstevel@tonic-gate} 258*7c478bd9Sstevel@tonic-gate 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate##### 261*7c478bd9Sstevel@tonic-gate# ${TPUT} is "tput" IF it works. We'll disable it if we get an 262*7c478bd9Sstevel@tonic-gate# ugly error message the first time we use it. See the TERM variable 263*7c478bd9Sstevel@tonic-gate# later in the script. 264*7c478bd9Sstevel@tonic-gate# 265*7c478bd9Sstevel@tonic-gate# NOTE: The check we use to see if "tput" works is to use an OLD 266*7c478bd9Sstevel@tonic-gate# Terminfo capability, like "lines". If it works with that it may 267*7c478bd9Sstevel@tonic-gate# still fail with some of the newer capabilities like "init" (SVR3.0) 268*7c478bd9Sstevel@tonic-gate# or "swidm" (SVR3.2), because the version of "tput" we have on your 269*7c478bd9Sstevel@tonic-gate# machine is older. Thus, on some of the code where ${TPUT} is used 270*7c478bd9Sstevel@tonic-gate# you'll see "2>/dev/null" being used to avoid ugly error messages. 271*7c478bd9Sstevel@tonic-gate##### 272*7c478bd9Sstevel@tonic-gateTPUT=tput 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate##### 275*7c478bd9Sstevel@tonic-gate# Error message formatter: 276*7c478bd9Sstevel@tonic-gate# 277*7c478bd9Sstevel@tonic-gate# Invoke as 278*7c478bd9Sstevel@tonic-gate# 279*7c478bd9Sstevel@tonic-gate# errmsg severity message-number problem help 280*7c478bd9Sstevel@tonic-gate# 281*7c478bd9Sstevel@tonic-gate# where severity is "ERROR" or "WARNING", message-number is 282*7c478bd9Sstevel@tonic-gate# a unique identifier, problem is a short description of the 283*7c478bd9Sstevel@tonic-gate# problem, and help is a short suggestion for fixing the problem. 284*7c478bd9Sstevel@tonic-gate##### 285*7c478bd9Sstevel@tonic-gate 286*7c478bd9Sstevel@tonic-gateLP_ERR_LABEL="UX:lp" 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gateE_IP_ARGS=1 289*7c478bd9Sstevel@tonic-gateE_IP_OPTS=2 290*7c478bd9Sstevel@tonic-gate#E_IP_FILTER=3 291*7c478bd9Sstevel@tonic-gateE_IP_STTY=4 292*7c478bd9Sstevel@tonic-gateE_IP_UNKNOWN=5 293*7c478bd9Sstevel@tonic-gateE_IP_BADFILE=6 294*7c478bd9Sstevel@tonic-gateE_IP_BADCHARSET=7 295*7c478bd9Sstevel@tonic-gateE_IP_BADCPI=8 296*7c478bd9Sstevel@tonic-gateE_IP_BADLPI=9 297*7c478bd9Sstevel@tonic-gateE_IP_BADWIDTH=10 298*7c478bd9Sstevel@tonic-gateE_IP_BADLENGTH=11 299*7c478bd9Sstevel@tonic-gateE_IP_ERRORS=12 # (in slow.filter) 300*7c478bd9Sstevel@tonic-gate 301*7c478bd9Sstevel@tonic-gateerrmsg () { 302*7c478bd9Sstevel@tonic-gate case $1 in 303*7c478bd9Sstevel@tonic-gate ERROR ) 304*7c478bd9Sstevel@tonic-gate sev=" ERROR"; 305*7c478bd9Sstevel@tonic-gate ;; 306*7c478bd9Sstevel@tonic-gate WARNING ) 307*7c478bd9Sstevel@tonic-gate sev="WARNING"; 308*7c478bd9Sstevel@tonic-gate ;; 309*7c478bd9Sstevel@tonic-gate esac 310*7c478bd9Sstevel@tonic-gate# tag=`expr "${LP_ERR_LABEL}" : "\(.*\):"``expr "${LP_ERR_LABEL}" : ".*:\(.*\)"` 311*7c478bd9Sstevel@tonic-gate echo "${LP_ERR_LABEL}: ${sev}: $3 312*7c478bd9Sstevel@tonic-gate TO FIX: $4" >&5 313*7c478bd9Sstevel@tonic-gate} 314*7c478bd9Sstevel@tonic-gate 315*7c478bd9Sstevel@tonic-gate 316*7c478bd9Sstevel@tonic-gate########### 317*7c478bd9Sstevel@tonic-gate## 318*7c478bd9Sstevel@tonic-gate## Check arguments 319*7c478bd9Sstevel@tonic-gate########### 320*7c478bd9Sstevel@tonic-gate 321*7c478bd9Sstevel@tonic-gateparse () { 322*7c478bd9Sstevel@tonic-gate echo "`expr \"$1\" : \"^[^=]*=\(.*\)\"`" 323*7c478bd9Sstevel@tonic-gate} 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate##### 326*7c478bd9Sstevel@tonic-gate# 327*7c478bd9Sstevel@tonic-gate# This program is invoked as 328*7c478bd9Sstevel@tonic-gate# 329*7c478bd9Sstevel@tonic-gate# ${SPOOLDIR}/.../printer request-id user title copies options files... 330*7c478bd9Sstevel@tonic-gate# 331*7c478bd9Sstevel@tonic-gate# The first three arguments are simply reprinted on the banner page, 332*7c478bd9Sstevel@tonic-gate# the fourth (copies) is used to control the number of copies to print, 333*7c478bd9Sstevel@tonic-gate# the fifth (options) is a blank separated list (in a single argument) 334*7c478bd9Sstevel@tonic-gate# of user or Spooler supplied options (without the -o prefix), 335*7c478bd9Sstevel@tonic-gate# and the last arguments are the files to print. 336*7c478bd9Sstevel@tonic-gate##### 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gateif [ $# -lt 5 ] 339*7c478bd9Sstevel@tonic-gatethen 340*7c478bd9Sstevel@tonic-gate errmsg ERROR ${E_IP_ARGS} \ 341*7c478bd9Sstevel@tonic-gate "wrong number of arguments to interface program" \ 342*7c478bd9Sstevel@tonic-gate "consult your system administrator" 343*7c478bd9Sstevel@tonic-gate exit 1 344*7c478bd9Sstevel@tonic-gatefi 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gateprinter=`basename $0` 347*7c478bd9Sstevel@tonic-gaterequest_id=$1 348*7c478bd9Sstevel@tonic-gateuser_name=$2 349*7c478bd9Sstevel@tonic-gatetitle=$3 350*7c478bd9Sstevel@tonic-gatecopies=$4 351*7c478bd9Sstevel@tonic-gateoption_list=$5 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gateshift 5 354*7c478bd9Sstevel@tonic-gatefiles="$*" 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gatenobanner="no" 357*7c478bd9Sstevel@tonic-gatenofilebreak="no" 358*7c478bd9Sstevel@tonic-gatestty= 359*7c478bd9Sstevel@tonic-gate 360*7c478bd9Sstevel@tonic-gateinlist= 361*7c478bd9Sstevel@tonic-gatefor i in ${option_list} 362*7c478bd9Sstevel@tonic-gatedo 363*7c478bd9Sstevel@tonic-gate case "${inlist}${i}" in 364*7c478bd9Sstevel@tonic-gate 365*7c478bd9Sstevel@tonic-gate 366*7c478bd9Sstevel@tonic-gate nobanner ) 367*7c478bd9Sstevel@tonic-gate nobanner="yes" 368*7c478bd9Sstevel@tonic-gate ;; 369*7c478bd9Sstevel@tonic-gate 370*7c478bd9Sstevel@tonic-gate nofilebreak ) 371*7c478bd9Sstevel@tonic-gate nofilebreak="yes" 372*7c478bd9Sstevel@tonic-gate ;; 373*7c478bd9Sstevel@tonic-gate 374*7c478bd9Sstevel@tonic-gate ##### 375*7c478bd9Sstevel@tonic-gate # 376*7c478bd9Sstevel@tonic-gate # If you want to add simple options (e.g. -o simple) 377*7c478bd9Sstevel@tonic-gate # identify them here. 378*7c478bd9Sstevel@tonic-gate ##### 379*7c478bd9Sstevel@tonic-gate# simple ) 380*7c478bd9Sstevel@tonic-gate# simple="yes" 381*7c478bd9Sstevel@tonic-gate# ;; 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate cpi=pica ) 385*7c478bd9Sstevel@tonic-gate cpi=10 386*7c478bd9Sstevel@tonic-gate ;; 387*7c478bd9Sstevel@tonic-gate cpi=elite ) 388*7c478bd9Sstevel@tonic-gate cpi=12 389*7c478bd9Sstevel@tonic-gate ;; 390*7c478bd9Sstevel@tonic-gate cpi=* ) 391*7c478bd9Sstevel@tonic-gate cpi=`parse ${i}` 392*7c478bd9Sstevel@tonic-gate ;; 393*7c478bd9Sstevel@tonic-gate 394*7c478bd9Sstevel@tonic-gate lpi=* ) 395*7c478bd9Sstevel@tonic-gate lpi=`parse ${i}` 396*7c478bd9Sstevel@tonic-gate ;; 397*7c478bd9Sstevel@tonic-gate 398*7c478bd9Sstevel@tonic-gate length=* ) 399*7c478bd9Sstevel@tonic-gate length=`parse ${i}` 400*7c478bd9Sstevel@tonic-gate ;; 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate width=* ) 403*7c478bd9Sstevel@tonic-gate width=`parse ${i}` 404*7c478bd9Sstevel@tonic-gate ;; 405*7c478bd9Sstevel@tonic-gate 406*7c478bd9Sstevel@tonic-gate ##### 407*7c478bd9Sstevel@tonic-gate # 408*7c478bd9Sstevel@tonic-gate # If you want to add simple-value options (e.g. -o value=a) 409*7c478bd9Sstevel@tonic-gate # identify them here. 410*7c478bd9Sstevel@tonic-gate ##### 411*7c478bd9Sstevel@tonic-gate# value=* ) 412*7c478bd9Sstevel@tonic-gate# value=`parse ${i}` 413*7c478bd9Sstevel@tonic-gate# ;; 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate 416*7c478bd9Sstevel@tonic-gate ##### 417*7c478bd9Sstevel@tonic-gate # 418*7c478bd9Sstevel@tonic-gate # If you want to add options that, like "stty", 419*7c478bd9Sstevel@tonic-gate # take a list (e.g. -o lopt='a b c'), identify 420*7c478bd9Sstevel@tonic-gate # them here and below (look for LOPT). 421*7c478bd9Sstevel@tonic-gate ##### 422*7c478bd9Sstevel@tonic-gate stty=* | flist=* | lpd=* ) 423*7c478bd9Sstevel@tonic-gate#LOPT stty=* | flist=* | lpd=* | lopt=* ) 424*7c478bd9Sstevel@tonic-gate 425*7c478bd9Sstevel@tonic-gate inlist=`expr "${inlist}${i}" : "^\([^=]*=\)"` 426*7c478bd9Sstevel@tonic-gate case "${i}" in 427*7c478bd9Sstevel@tonic-gate ${inlist}\'*\' ) 428*7c478bd9Sstevel@tonic-gate item=`expr "${i}" : "^[^=]*='*\(.*\)'\$"` 429*7c478bd9Sstevel@tonic-gate ;; 430*7c478bd9Sstevel@tonic-gate ${inlist}\' ) 431*7c478bd9Sstevel@tonic-gate continue 432*7c478bd9Sstevel@tonic-gate ;; 433*7c478bd9Sstevel@tonic-gate ${inlist}\'* ) 434*7c478bd9Sstevel@tonic-gate item=`expr "${i}" : "^[^=]*='*\(.*\)\$"` 435*7c478bd9Sstevel@tonic-gate ;; 436*7c478bd9Sstevel@tonic-gate ${inlist}* ) 437*7c478bd9Sstevel@tonic-gate item=`expr "${i}" : "^[^=]*=\(.*\)\$"` 438*7c478bd9Sstevel@tonic-gate ;; 439*7c478bd9Sstevel@tonic-gate *\' ) 440*7c478bd9Sstevel@tonic-gate item=`expr "${i}" : "^\(.*\)'\$"` 441*7c478bd9Sstevel@tonic-gate ;; 442*7c478bd9Sstevel@tonic-gate * ) 443*7c478bd9Sstevel@tonic-gate item="${i}" 444*7c478bd9Sstevel@tonic-gate ;; 445*7c478bd9Sstevel@tonic-gate esac 446*7c478bd9Sstevel@tonic-gate 447*7c478bd9Sstevel@tonic-gate ##### 448*7c478bd9Sstevel@tonic-gate # 449*7c478bd9Sstevel@tonic-gate # We don't dare use "eval" because a clever user could 450*7c478bd9Sstevel@tonic-gate # put something in an option value that we'd end up 451*7c478bd9Sstevel@tonic-gate # exec'ing. 452*7c478bd9Sstevel@tonic-gate ##### 453*7c478bd9Sstevel@tonic-gate case "${inlist}" in 454*7c478bd9Sstevel@tonic-gate stty= ) 455*7c478bd9Sstevel@tonic-gate stty="${stty} ${item}" 456*7c478bd9Sstevel@tonic-gate ;; 457*7c478bd9Sstevel@tonic-gate flist= ) 458*7c478bd9Sstevel@tonic-gate flist="${flist} ${item}" 459*7c478bd9Sstevel@tonic-gate ;; 460*7c478bd9Sstevel@tonic-gate lpd= ) 461*7c478bd9Sstevel@tonic-gate lpd="${lpd} ${item}" 462*7c478bd9Sstevel@tonic-gate ;; 463*7c478bd9Sstevel@tonic-gate#LOPT lopt= ) 464*7c478bd9Sstevel@tonic-gate#LOPT lopt="${lopt} ${item}" 465*7c478bd9Sstevel@tonic-gate#LOPT ;; 466*7c478bd9Sstevel@tonic-gate esac 467*7c478bd9Sstevel@tonic-gate 468*7c478bd9Sstevel@tonic-gate case "${i}" in 469*7c478bd9Sstevel@tonic-gate ${inlist}\'*\' ) 470*7c478bd9Sstevel@tonic-gate inlist= 471*7c478bd9Sstevel@tonic-gate ;; 472*7c478bd9Sstevel@tonic-gate ${inlist}\'* ) 473*7c478bd9Sstevel@tonic-gate ;; 474*7c478bd9Sstevel@tonic-gate *\' | ${inlist}* ) 475*7c478bd9Sstevel@tonic-gate inlist= 476*7c478bd9Sstevel@tonic-gate ;; 477*7c478bd9Sstevel@tonic-gate esac 478*7c478bd9Sstevel@tonic-gate ;; 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate * ) 481*7c478bd9Sstevel@tonic-gate errmsg WARNING ${E_IP_OPTS} \ 482*7c478bd9Sstevel@tonic-gate "unrecognized \"-o ${i}\" option" \ 483*7c478bd9Sstevel@tonic-gate "check the option, resubmit if necessary 484*7c478bd9Sstevel@tonic-gate printing continues" 485*7c478bd9Sstevel@tonic-gate ;; 486*7c478bd9Sstevel@tonic-gate esac 487*7c478bd9Sstevel@tonic-gatedone 488*7c478bd9Sstevel@tonic-gate 489*7c478bd9Sstevel@tonic-gate##### 490*7c478bd9Sstevel@tonic-gate# 491*7c478bd9Sstevel@tonic-gate# Additional ``parameters'' are passed via Shell environment 492*7c478bd9Sstevel@tonic-gate# variables: 493*7c478bd9Sstevel@tonic-gate# 494*7c478bd9Sstevel@tonic-gate# TERM The printer type (used for Terminfo access) 495*7c478bd9Sstevel@tonic-gate# CHARSET The character set to choose 496*7c478bd9Sstevel@tonic-gate# FILTER The filter to run 497*7c478bd9Sstevel@tonic-gate##### 498*7c478bd9Sstevel@tonic-gate 499*7c478bd9Sstevel@tonic-gate##### 500*7c478bd9Sstevel@tonic-gate# Set defaults for unset variables. 501*7c478bd9Sstevel@tonic-gate##### 502*7c478bd9Sstevel@tonic-gate 503*7c478bd9Sstevel@tonic-gate: ${TERM:=unknown} 504*7c478bd9Sstevel@tonic-gatetput lines 1>/dev/null 2>&1 || TPUT=: 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate: ${CHARSET:=cs0} 507*7c478bd9Sstevel@tonic-gate 508*7c478bd9Sstevel@tonic-gateif [ -z "${FILTER}" ] 509*7c478bd9Sstevel@tonic-gatethen 510*7c478bd9Sstevel@tonic-gate ##### 511*7c478bd9Sstevel@tonic-gate # 512*7c478bd9Sstevel@tonic-gate # If no filter is being used, we have a little routine that 513*7c478bd9Sstevel@tonic-gate # will push the data to the printer. It traps hangups (loss 514*7c478bd9Sstevel@tonic-gate # of carrier) and checks for excessive delays in sending the 515*7c478bd9Sstevel@tonic-gate # data to the printer. The lesser of the print rate of the printer 516*7c478bd9Sstevel@tonic-gate # (obtained from Terminfo) or the baud rate is used to compute 517*7c478bd9Sstevel@tonic-gate # the expected delay. If neither of these is correct, you 518*7c478bd9Sstevel@tonic-gate # may be experiencing false alarms. If so, give the correct 519*7c478bd9Sstevel@tonic-gate # rate, in characters per second, as a single argument. 520*7c478bd9Sstevel@tonic-gate # An argument of 0 means don't check for delays. 521*7c478bd9Sstevel@tonic-gate # Give an -r option to get a printout of actual delays. 522*7c478bd9Sstevel@tonic-gate # (QUOTES ARE IMPORTANT!) 523*7c478bd9Sstevel@tonic-gate ##### 524*7c478bd9Sstevel@tonic-gate case "$TERM" in 525*7c478bd9Sstevel@tonic-gate PS ) 526*7c478bd9Sstevel@tonic-gate # make the "postscript" printers use postio to 527*7c478bd9Sstevel@tonic-gate # talk to the printer and periodically get a 528*7c478bd9Sstevel@tonic-gate # status from them 529*7c478bd9Sstevel@tonic-gate FILTER="/usr/lib/lp/postscript/postio" 530*7c478bd9Sstevel@tonic-gate ;; 531*7c478bd9Sstevel@tonic-gate PSR ) 532*7c478bd9Sstevel@tonic-gate # make the "reverse postscript" printers reverse the 533*7c478bd9Sstevel@tonic-gate # output and the use postio to talk to the printer 534*7c478bd9Sstevel@tonic-gate FILTER="/usr/lib/lp/postscript/postreverse | \ 535*7c478bd9Sstevel@tonic-gate /usr/lib/lp/postscript/postio" 536*7c478bd9Sstevel@tonic-gate ;; 537*7c478bd9Sstevel@tonic-gate * ) 538*7c478bd9Sstevel@tonic-gate # we don't know the type, so just assume that the 539*7c478bd9Sstevel@tonic-gate # input and output are the same 540*7c478bd9Sstevel@tonic-gate if [ `basename "${LPCAT}"` = "lp.cat" ] ; then 541*7c478bd9Sstevel@tonic-gate FILTER="${LPCAT} 0" # infinite delays 542*7c478bd9Sstevel@tonic-gate # FILTER="${LPCAT} 120" # e.g. 120 CPS 543*7c478bd9Sstevel@tonic-gate # FILTER="${LPCAT} -r 0 2>/tmp/delays" 544*7c478bd9Sstevel@tonic-gate # FILTER=${LPCAT} 545*7c478bd9Sstevel@tonic-gate fi 546*7c478bd9Sstevel@tonic-gate ;; 547*7c478bd9Sstevel@tonic-gate esac 548*7c478bd9Sstevel@tonic-gatefi 549*7c478bd9Sstevel@tonic-gate 550*7c478bd9Sstevel@tonic-gate########### 551*7c478bd9Sstevel@tonic-gate## 552*7c478bd9Sstevel@tonic-gate## Initialize the printer port 553*7c478bd9Sstevel@tonic-gate########### 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate##### 556*7c478bd9Sstevel@tonic-gate# 557*7c478bd9Sstevel@tonic-gate# SERIAL PORTS: 558*7c478bd9Sstevel@tonic-gate# Initialize everything. 559*7c478bd9Sstevel@tonic-gate# 560*7c478bd9Sstevel@tonic-gate# PARALLEL PORTS: 561*7c478bd9Sstevel@tonic-gate# Don't initialize baud rate. 562*7c478bd9Sstevel@tonic-gate# 563*7c478bd9Sstevel@tonic-gate# It's not obvious how to tell if a port is parallel or serial. 564*7c478bd9Sstevel@tonic-gate# However, by splitting the initialization into two steps and letting 565*7c478bd9Sstevel@tonic-gate# the serial-only part fail nicely, it'll work. 566*7c478bd9Sstevel@tonic-gate# 567*7c478bd9Sstevel@tonic-gate# Another point: The output must be a ``tty'' device. If not, don't 568*7c478bd9Sstevel@tonic-gate# bother with any of this. 569*7c478bd9Sstevel@tonic-gate##### 570*7c478bd9Sstevel@tonic-gatestty1= stty2= 571*7c478bd9Sstevel@tonic-gatetty 0<&1 1>/dev/null 2>&1 && { 572*7c478bd9Sstevel@tonic-gate 573*7c478bd9Sstevel@tonic-gate ##### 574*7c478bd9Sstevel@tonic-gate # 575*7c478bd9Sstevel@tonic-gate # First set the default parameters, 576*7c478bd9Sstevel@tonic-gate # then the requested parameters. 577*7c478bd9Sstevel@tonic-gate ##### 578*7c478bd9Sstevel@tonic-gate 579*7c478bd9Sstevel@tonic-gate stty \ 580*7c478bd9Sstevel@tonic-gate 9600 \ 581*7c478bd9Sstevel@tonic-gate 0<&1 2>/dev/null 1>&2 582*7c478bd9Sstevel@tonic-gate stty \ 583*7c478bd9Sstevel@tonic-gate cs8 -cstopb -parenb -parodd \ 584*7c478bd9Sstevel@tonic-gate ixon -ixany \ 585*7c478bd9Sstevel@tonic-gate opost -olcuc onlcr -ocrnl -onocr -onlret -ofill \ 586*7c478bd9Sstevel@tonic-gate nl0 cr0 tab0 bs0 vt0 ff0 \ 587*7c478bd9Sstevel@tonic-gate 0<&1 2>/dev/null 1>&2 588*7c478bd9Sstevel@tonic-gate 589*7c478bd9Sstevel@tonic-gate if [ -n "${stty}" ] 590*7c478bd9Sstevel@tonic-gate then 591*7c478bd9Sstevel@tonic-gate if stty ${stty} 0<&1 1>/dev/null 2>&5 592*7c478bd9Sstevel@tonic-gate then 593*7c478bd9Sstevel@tonic-gate : 594*7c478bd9Sstevel@tonic-gate else 595*7c478bd9Sstevel@tonic-gate errmsg ERROR ${E_IP_STTY} \ 596*7c478bd9Sstevel@tonic-gate "stty option list failed" \ 597*7c478bd9Sstevel@tonic-gate "check the \"-o stty\" option you used, 598*7c478bd9Sstevel@tonic-gate or consult your system administrator" 599*7c478bd9Sstevel@tonic-gate exit 1 600*7c478bd9Sstevel@tonic-gate fi 601*7c478bd9Sstevel@tonic-gate fi 602*7c478bd9Sstevel@tonic-gate 603*7c478bd9Sstevel@tonic-gate ##### 604*7c478bd9Sstevel@tonic-gate # 605*7c478bd9Sstevel@tonic-gate # Here you may want to add other port initialization code. 606*7c478bd9Sstevel@tonic-gate # Some examples: 607*7c478bd9Sstevel@tonic-gate # 608*7c478bd9Sstevel@tonic-gate # estty # for printer needing hardware flow control (3B2/EPORTS) 609*7c478bd9Sstevel@tonic-gate # fctty # for printer needing hardware flow control (3B15,3B20) 610*7c478bd9Sstevel@tonic-gate ##### 611*7c478bd9Sstevel@tonic-gate #estty 0<&1 612*7c478bd9Sstevel@tonic-gate #fctty 0<&1 613*7c478bd9Sstevel@tonic-gate 614*7c478bd9Sstevel@tonic-gate 615*7c478bd9Sstevel@tonic-gate ########## 616*7c478bd9Sstevel@tonic-gate # 617*7c478bd9Sstevel@tonic-gate # Find out if we have to turn off opost before initializing the 618*7c478bd9Sstevel@tonic-gate # printer and on after. Likewise, check clocal. 619*7c478bd9Sstevel@tonic-gate # 620*7c478bd9Sstevel@tonic-gate # Turning OFF opost (output postprocessing) keeps the UNIX system 621*7c478bd9Sstevel@tonic-gate # from changing what we try to send to the printer. Turning ON 622*7c478bd9Sstevel@tonic-gate # clocal keeps the UNIX system from dropping what we are trying to 623*7c478bd9Sstevel@tonic-gate # send if the printer drops DTR. An example of the former is the 624*7c478bd9Sstevel@tonic-gate # AT&T 479, which wants to send a linefeed (ASCII 10) when a page 625*7c478bd9Sstevel@tonic-gate # width of 10 is set; with opost on, this COULD BE turned into a 626*7c478bd9Sstevel@tonic-gate # carriage-return/linefeed pair. An example of the latter is the 627*7c478bd9Sstevel@tonic-gate # AT&T 455, which momentarily drops DTR when it gets the 628*7c478bd9Sstevel@tonic-gate # initialization string, is2; with clocal off, the UNIX system 629*7c478bd9Sstevel@tonic-gate # stops sending the rest of the initialization sequence at that 630*7c478bd9Sstevel@tonic-gate # point. 631*7c478bd9Sstevel@tonic-gate # 632*7c478bd9Sstevel@tonic-gate # THIS CODE MUST FOLLOW THE REST OF THE PORT INITIALIZATION CODE. 633*7c478bd9Sstevel@tonic-gate ########## 634*7c478bd9Sstevel@tonic-gate cur_stty=`stty -a 0<&3` 635*7c478bd9Sstevel@tonic-gate expr "${cur_stty}" : '.*-opost' 1>/dev/null 2>&1 \ 636*7c478bd9Sstevel@tonic-gate || stty1="${stty1} -opost" stty2="${stty2} opost" 637*7c478bd9Sstevel@tonic-gate expr "${cur_stty}" : '.*-clocal' 1>/dev/null 2>&1 \ 638*7c478bd9Sstevel@tonic-gate && stty1="${stty1} clocal" stty2="${stty2} -clocal" 639*7c478bd9Sstevel@tonic-gate expr "${cur_stty}" : '.* opost.*' 1>/dev/null 2>&1 \ 640*7c478bd9Sstevel@tonic-gate || banner_filter=${FIX386BD} 641*7c478bd9Sstevel@tonic-gate 642*7c478bd9Sstevel@tonic-gate} 643*7c478bd9Sstevel@tonic-gate 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate########### 646*7c478bd9Sstevel@tonic-gate## 647*7c478bd9Sstevel@tonic-gate## Initialize the physical printer (Part I). 648*7c478bd9Sstevel@tonic-gate## Here we bring the printer to a sane state and set the page size. 649*7c478bd9Sstevel@tonic-gate########### 650*7c478bd9Sstevel@tonic-gate 651*7c478bd9Sstevel@tonic-gate########## 652*7c478bd9Sstevel@tonic-gate# 653*7c478bd9Sstevel@tonic-gate# WARNING! The "echo" command will catch backslashes (\) and 654*7c478bd9Sstevel@tonic-gate# try to interpret the characters following it. Thus, using 655*7c478bd9Sstevel@tonic-gate# "echo" to print string values obtained from "tput" is dangerous. 656*7c478bd9Sstevel@tonic-gate########## 657*7c478bd9Sstevel@tonic-gate 658*7c478bd9Sstevel@tonic-gate##### 659*7c478bd9Sstevel@tonic-gate# We're confident that most printers don't have backslashes 660*7c478bd9Sstevel@tonic-gate# in the control sequences for carriage return and form-feed. 661*7c478bd9Sstevel@tonic-gate# We're also confident that these don't contain newlines. 662*7c478bd9Sstevel@tonic-gate# We're also confident that most printers have a linefeed 663*7c478bd9Sstevel@tonic-gate# in the control sequence for doing a newline (move to beginning 664*7c478bd9Sstevel@tonic-gate# of next line), but we can't capture it like we do the 665*7c478bd9Sstevel@tonic-gate# carriage return or form-feed. Thus we set it unconditionally. 666*7c478bd9Sstevel@tonic-gate# We don't set form-feed if it isn't defined, however, because 667*7c478bd9Sstevel@tonic-gate# maybe the printer doesn't have a formfeed. If not set, we're 668*7c478bd9Sstevel@tonic-gate# out of luck. 669*7c478bd9Sstevel@tonic-gate##### 670*7c478bd9Sstevel@tonic-gate 671*7c478bd9Sstevel@tonic-gateCR=`${TPUT} cr` 672*7c478bd9Sstevel@tonic-gate[ -z "${CR}" ] && CR="\r" 673*7c478bd9Sstevel@tonic-gate 674*7c478bd9Sstevel@tonic-gateFF=`${TPUT} ff` 675*7c478bd9Sstevel@tonic-gate 676*7c478bd9Sstevel@tonic-gateNL="${CR}\n" 677*7c478bd9Sstevel@tonic-gate 678*7c478bd9Sstevel@tonic-gatelines=`${TPUT} lines` 679*7c478bd9Sstevel@tonic-gate[ -z "${lines}" -o 0 -ge "${lines}" ] && lines=66 680*7c478bd9Sstevel@tonic-gate 681*7c478bd9Sstevel@tonic-gatecols=`${TPUT} cols` 682*7c478bd9Sstevel@tonic-gate[ -z "${cols}" -o 0 -ge "${cols}" ] && cols=132 683*7c478bd9Sstevel@tonic-gate 684*7c478bd9Sstevel@tonic-gate##### 685*7c478bd9Sstevel@tonic-gate# 686*7c478bd9Sstevel@tonic-gate# Basic initialization. The ``else'' clause is equivalent, 687*7c478bd9Sstevel@tonic-gate# but covers cases where old Terminal Information Utilities are present. 688*7c478bd9Sstevel@tonic-gate##### 689*7c478bd9Sstevel@tonic-gate[ -n "${stty1}" ] && stty ${stty1} 0<&1 690*7c478bd9Sstevel@tonic-gate 691*7c478bd9Sstevel@tonic-gate# 692*7c478bd9Sstevel@tonic-gate# "tput init" will return an "^M" in many cases to "stdout", i.e., printer! 693*7c478bd9Sstevel@tonic-gate# This creates problems for some PS printers 694*7c478bd9Sstevel@tonic-gate# 695*7c478bd9Sstevel@tonic-gateif [ "${TERM}" = "PS" -o "${TERM}" = "PSR" ] 696*7c478bd9Sstevel@tonic-gatethen 697*7c478bd9Sstevel@tonic-gate : 698*7c478bd9Sstevel@tonic-gateelif ${TPUT} init 2>/dev/null 699*7c478bd9Sstevel@tonic-gatethen 700*7c478bd9Sstevel@tonic-gate : 701*7c478bd9Sstevel@tonic-gateelse 702*7c478bd9Sstevel@tonic-gate pgm=`${TPUT} iprog` 703*7c478bd9Sstevel@tonic-gate if [ -x "${pgm}" ] 704*7c478bd9Sstevel@tonic-gate then 705*7c478bd9Sstevel@tonic-gate eval ${pgm} 706*7c478bd9Sstevel@tonic-gate fi 707*7c478bd9Sstevel@tonic-gate 708*7c478bd9Sstevel@tonic-gate ${TPUT} is1 709*7c478bd9Sstevel@tonic-gate ${TPUT} is2 710*7c478bd9Sstevel@tonic-gate 711*7c478bd9Sstevel@tonic-gate tabset= 712*7c478bd9Sstevel@tonic-gate if [ "8" != "`${TPUT} it`" ] 713*7c478bd9Sstevel@tonic-gate then 714*7c478bd9Sstevel@tonic-gate stty tab3 0<&1 1>/dev/null 2>&1 715*7c478bd9Sstevel@tonic-gate 716*7c478bd9Sstevel@tonic-gate elif `${TPUT} ht >/dev/null` 717*7c478bd9Sstevel@tonic-gate then 718*7c478bd9Sstevel@tonic-gate tabset="/usr/lib/tabset/${TERM}" 719*7c478bd9Sstevel@tonic-gate if [ -r ${tabset} ] 720*7c478bd9Sstevel@tonic-gate then 721*7c478bd9Sstevel@tonic-gate cat -s ${tabset} 722*7c478bd9Sstevel@tonic-gate fi 723*7c478bd9Sstevel@tonic-gate stty tab3 0<&1 1>/dev/null 2>&1 724*7c478bd9Sstevel@tonic-gate fi 725*7c478bd9Sstevel@tonic-gate 726*7c478bd9Sstevel@tonic-gate file=`${TPUT} if` 727*7c478bd9Sstevel@tonic-gate if [ "${tabset}" != "${file}" -a -r "${file}" ] 728*7c478bd9Sstevel@tonic-gate then 729*7c478bd9Sstevel@tonic-gate cat -s "${file}" 730*7c478bd9Sstevel@tonic-gate fi 731*7c478bd9Sstevel@tonic-gate 732*7c478bd9Sstevel@tonic-gate ${TPUT} is3 733*7c478bd9Sstevel@tonic-gate echo "${CR}\c" 734*7c478bd9Sstevel@tonic-gatefi 735*7c478bd9Sstevel@tonic-gate[ -n "${stty2}" ] && stty ${stty2} 0<&1 736*7c478bd9Sstevel@tonic-gate 737*7c478bd9Sstevel@tonic-gate##### 738*7c478bd9Sstevel@tonic-gate# 739*7c478bd9Sstevel@tonic-gate# Set the page size and print spacing, but not the character set. 740*7c478bd9Sstevel@tonic-gate# We will be doing the character set later (after the header). 741*7c478bd9Sstevel@tonic-gate##### 742*7c478bd9Sstevel@tonic-gateinternal_lpset "${cpi}" "${lpi}" "${width}" "${length}" "" 743*7c478bd9Sstevel@tonic-gate 744*7c478bd9Sstevel@tonic-gate##### 745*7c478bd9Sstevel@tonic-gate# 746*7c478bd9Sstevel@tonic-gate# The banner page (and cancellation page) will 747*7c478bd9Sstevel@tonic-gate# use double width characters if they're available. 748*7c478bd9Sstevel@tonic-gate##### 749*7c478bd9Sstevel@tonic-gateWIDE_CS=`${TPUT} swidm 2>/dev/null` && NORM_CS=`${TPUT} rwidm 2>/dev/null` 750*7c478bd9Sstevel@tonic-gatePAD="#####${NL}" 751*7c478bd9Sstevel@tonic-gate 752*7c478bd9Sstevel@tonic-gate##### 753*7c478bd9Sstevel@tonic-gate# 754*7c478bd9Sstevel@tonic-gate# Some printers need to have the banner page filtered. 755*7c478bd9Sstevel@tonic-gate##### 756*7c478bd9Sstevel@tonic-gatecase "${TERM}" in 757*7c478bd9Sstevel@tonic-gate 758*7c478bd9Sstevel@tonic-gatePS | PSR ) 759*7c478bd9Sstevel@tonic-gate banner_filter="/usr/lib/lp/postscript/postprint | /usr/lib/lp/postscript/postio" 760*7c478bd9Sstevel@tonic-gate LPTELL_OPTS="-l" 761*7c478bd9Sstevel@tonic-gate ;; 762*7c478bd9Sstevel@tonic-gate 763*7c478bd9Sstevel@tonic-gateesac 764*7c478bd9Sstevel@tonic-gateif [ -n "${banner_filter}" ] 765*7c478bd9Sstevel@tonic-gatethen 766*7c478bd9Sstevel@tonic-gate banner_filter="| ${banner_filter}" 767*7c478bd9Sstevel@tonic-gatefi 768*7c478bd9Sstevel@tonic-gate 769*7c478bd9Sstevel@tonic-gate##### 770*7c478bd9Sstevel@tonic-gate# 771*7c478bd9Sstevel@tonic-gate# Now that the printer is ready for printing, we're able 772*7c478bd9Sstevel@tonic-gate# to record on paper a cancellation. 773*7c478bd9Sstevel@tonic-gate##### 774*7c478bd9Sstevel@tonic-gate 775*7c478bd9Sstevel@tonic-gatecancel_banner () { 776*7c478bd9Sstevel@tonic-gate echo "${PAD}${PAD}\c" 777*7c478bd9Sstevel@tonic-gate echo "#####${WIDE_CS} Job ${request_id}${NORM_CS}${NL}\c" 778*7c478bd9Sstevel@tonic-gate echo "#####${WIDE_CS} suspended or canceled${NORM_CS}${NL}\c" 779*7c478bd9Sstevel@tonic-gate echo "${PAD}${PAD}\c" 780*7c478bd9Sstevel@tonic-gate} 781*7c478bd9Sstevel@tonic-gate 782*7c478bd9Sstevel@tonic-gatecanceled () { 783*7c478bd9Sstevel@tonic-gate ${TPUT} scs 0 2>/dev/null 784*7c478bd9Sstevel@tonic-gate echo "${CR}\c" 785*7c478bd9Sstevel@tonic-gate if [ "${width:-${cols}}" -lt "${MAX_COLS_SMALL_BANNER}" ] 786*7c478bd9Sstevel@tonic-gate then 787*7c478bd9Sstevel@tonic-gate WIDE_CS= NORM_CS= 788*7c478bd9Sstevel@tonic-gate fi 789*7c478bd9Sstevel@tonic-gate cancel_banner 790*7c478bd9Sstevel@tonic-gate if [ -n "${FF}" ] 791*7c478bd9Sstevel@tonic-gate then 792*7c478bd9Sstevel@tonic-gate echo "${CR}${FF}\c" 793*7c478bd9Sstevel@tonic-gate fi 794*7c478bd9Sstevel@tonic-gate} 795*7c478bd9Sstevel@tonic-gate 796*7c478bd9Sstevel@tonic-gatetrap 'eval canceled ${banner_filter}; exit_code=0 exit' 15 797*7c478bd9Sstevel@tonic-gate 798*7c478bd9Sstevel@tonic-gate 799*7c478bd9Sstevel@tonic-gate########### 800*7c478bd9Sstevel@tonic-gate## 801*7c478bd9Sstevel@tonic-gate## Print the banner page 802*7c478bd9Sstevel@tonic-gate########### 803*7c478bd9Sstevel@tonic-gate 804*7c478bd9Sstevel@tonic-gate##### 805*7c478bd9Sstevel@tonic-gate# 806*7c478bd9Sstevel@tonic-gate# You may want to change the following code to get a custom banner. 807*7c478bd9Sstevel@tonic-gate##### 808*7c478bd9Sstevel@tonic-gate 809*7c478bd9Sstevel@tonic-gateregular_banner () { 810*7c478bd9Sstevel@tonic-gate echo "${CR}\c" 811*7c478bd9Sstevel@tonic-gate echo "${PAD}${PAD}${PAD}${PAD}${PAD}\c" 812*7c478bd9Sstevel@tonic-gate echo "#####${WIDE_CS} User: ${user_name}${NORM_CS}${NL}\c" 813*7c478bd9Sstevel@tonic-gate if [ -n "$ALIAS_USERNAME" ] 814*7c478bd9Sstevel@tonic-gate then 815*7c478bd9Sstevel@tonic-gate echo "${PAD}\c" 816*7c478bd9Sstevel@tonic-gate echo "#####${WIDE_CS} Alias: ${ALIAS_USERNAME}${NORM_CS}${NL}\c" 817*7c478bd9Sstevel@tonic-gate fi 818*7c478bd9Sstevel@tonic-gate if [ -n "${title}" ] 819*7c478bd9Sstevel@tonic-gate then 820*7c478bd9Sstevel@tonic-gate echo "${PAD}\c" 821*7c478bd9Sstevel@tonic-gate echo "#####${WIDE_CS} Title: ${title}${NORM_CS}${NL}\c" 822*7c478bd9Sstevel@tonic-gate fi 823*7c478bd9Sstevel@tonic-gate echo "${PAD}\c" 824*7c478bd9Sstevel@tonic-gate echo "#####${WIDE_CS} Printed: `LANG=C date '+%a %H:%M %h %d, %Y'`${NORM_CS}${NL}\c" 825*7c478bd9Sstevel@tonic-gate echo "${PAD}\c" 826*7c478bd9Sstevel@tonic-gate echo "#####${WIDE_CS} Job number: ${request_id}${NORM_CS}${NL}\c" 827*7c478bd9Sstevel@tonic-gate echo "${PAD}${PAD}${PAD}${PAD}${PAD}\c" 828*7c478bd9Sstevel@tonic-gate if [ -n "${FF}" ] 829*7c478bd9Sstevel@tonic-gate then 830*7c478bd9Sstevel@tonic-gate echo "${CR}${FF}\c" 831*7c478bd9Sstevel@tonic-gate fi 832*7c478bd9Sstevel@tonic-gate} 833*7c478bd9Sstevel@tonic-gate 834*7c478bd9Sstevel@tonic-gatesmall_banner () { 835*7c478bd9Sstevel@tonic-gate echo "${CR}\c" 836*7c478bd9Sstevel@tonic-gate echo "${PAD}\c" 837*7c478bd9Sstevel@tonic-gate echo "##### User: ${user_name}${NL}\c" 838*7c478bd9Sstevel@tonic-gate if [ -n "${title}" ] 839*7c478bd9Sstevel@tonic-gate then 840*7c478bd9Sstevel@tonic-gate echo "##### Title: ${title}${NL}\c" 841*7c478bd9Sstevel@tonic-gate fi 842*7c478bd9Sstevel@tonic-gate echo "##### Date: `LANG=C date '+%a %H:%M %h %d, %Y'`${NL}\c" 843*7c478bd9Sstevel@tonic-gate echo "##### Job: ${request_id}${NL}\c" 844*7c478bd9Sstevel@tonic-gate echo "${PAD}\c" 845*7c478bd9Sstevel@tonic-gate if [ -n "${FF}" ] 846*7c478bd9Sstevel@tonic-gate then 847*7c478bd9Sstevel@tonic-gate echo "${CR}${FF}\c" 848*7c478bd9Sstevel@tonic-gate fi 849*7c478bd9Sstevel@tonic-gate} 850*7c478bd9Sstevel@tonic-gate 851*7c478bd9Sstevel@tonic-gateif [ "${width:-${cols}}" -lt "${MAX_COLS_SMALL_BANNER}" ] 852*7c478bd9Sstevel@tonic-gatethen 853*7c478bd9Sstevel@tonic-gate banner=small_banner 854*7c478bd9Sstevel@tonic-gateelse 855*7c478bd9Sstevel@tonic-gate banner=regular_banner 856*7c478bd9Sstevel@tonic-gatefi 857*7c478bd9Sstevel@tonic-gate 858*7c478bd9Sstevel@tonic-gateif [ "no" = "${nobanner}" -a "${TERM}" != "PSR" ] 859*7c478bd9Sstevel@tonic-gatethen 860*7c478bd9Sstevel@tonic-gate ( eval "${banner} ${banner_filter}" 2>&1 1>&3 ) \ 861*7c478bd9Sstevel@tonic-gate | ${LPTELL} ${LPTELL_OPTS} ${printer} 862*7c478bd9Sstevel@tonic-gatefi 863*7c478bd9Sstevel@tonic-gate 864*7c478bd9Sstevel@tonic-gate 865*7c478bd9Sstevel@tonic-gate########### 866*7c478bd9Sstevel@tonic-gate## 867*7c478bd9Sstevel@tonic-gate## Initialize the physical printer (Part II) 868*7c478bd9Sstevel@tonic-gate## Here we select the character set. 869*7c478bd9Sstevel@tonic-gate## One could argue that this should be done before the banner is printed, 870*7c478bd9Sstevel@tonic-gate## but we don't, to keep the banner page looking consistent for the 871*7c478bd9Sstevel@tonic-gate## operator. You can move this code before the banner code if you 872*7c478bd9Sstevel@tonic-gate## disagree. If you do, combine it with the other call to "internal_lpset" 873*7c478bd9Sstevel@tonic-gate## to do everything in one shot. 874*7c478bd9Sstevel@tonic-gate########### 875*7c478bd9Sstevel@tonic-gateinternal_lpset "" "" "" "" "${CHARSET}" 876*7c478bd9Sstevel@tonic-gate 877*7c478bd9Sstevel@tonic-gate########### 878*7c478bd9Sstevel@tonic-gate## 879*7c478bd9Sstevel@tonic-gate## Print some copies of the file(s) 880*7c478bd9Sstevel@tonic-gate########### 881*7c478bd9Sstevel@tonic-gate 882*7c478bd9Sstevel@tonic-gate##### 883*7c478bd9Sstevel@tonic-gate# 884*7c478bd9Sstevel@tonic-gate# The protocol between the interface program and the Spooler 885*7c478bd9Sstevel@tonic-gate# is fairly simple: 886*7c478bd9Sstevel@tonic-gate# 887*7c478bd9Sstevel@tonic-gate# All standard error output is assumed to indicate a 888*7c478bd9Sstevel@tonic-gate# fault WITH THE REQUEST. The output is mailed to the 889*7c478bd9Sstevel@tonic-gate# user who submitted the print request and the print 890*7c478bd9Sstevel@tonic-gate# request is finished. 891*7c478bd9Sstevel@tonic-gate# 892*7c478bd9Sstevel@tonic-gate# If the interface program sets a zero exit code, 893*7c478bd9Sstevel@tonic-gate# it is assumed that the file printed correctly. 894*7c478bd9Sstevel@tonic-gate# If the interface program sets a non-zero exit code 895*7c478bd9Sstevel@tonic-gate# less than 128, it is assumed that the file did not 896*7c478bd9Sstevel@tonic-gate# print correctly, and the user will be notified. 897*7c478bd9Sstevel@tonic-gate# In either case the print request is finished. 898*7c478bd9Sstevel@tonic-gate# 899*7c478bd9Sstevel@tonic-gate# If the interface program sets an exit code greater 900*7c478bd9Sstevel@tonic-gate# than 128, it is assumed that the file did not print 901*7c478bd9Sstevel@tonic-gate# because of a printer fault. If an alert isn't already 902*7c478bd9Sstevel@tonic-gate# active (see below) one will be activated. (Exit code 903*7c478bd9Sstevel@tonic-gate# 128 should not be used at all. The shell, which executes 904*7c478bd9Sstevel@tonic-gate# this program, turns SIGTERM, used to kill this program 905*7c478bd9Sstevel@tonic-gate# for a cancellation or disabling, into exit 128. The 906*7c478bd9Sstevel@tonic-gate# Spooler thus interpretes 128 as SIGTERM.) 907*7c478bd9Sstevel@tonic-gate# 908*7c478bd9Sstevel@tonic-gate# A message sent to the standard input of the ${LPTELL} 909*7c478bd9Sstevel@tonic-gate# program is assumed to describe a fault WITH THE PRINTER. 910*7c478bd9Sstevel@tonic-gate# The output is used in an alert (if alerts are defined). 911*7c478bd9Sstevel@tonic-gate# If the fault recovery is "wait" or "begin", the printer 912*7c478bd9Sstevel@tonic-gate# is disabled (killing the interface program if need be), 913*7c478bd9Sstevel@tonic-gate# and the print request is left on the queue. 914*7c478bd9Sstevel@tonic-gate# If the fault recovery is "continue", the interface program 915*7c478bd9Sstevel@tonic-gate# is allowed to wait for the printer fault to be cleared so 916*7c478bd9Sstevel@tonic-gate# it can resume printing. 917*7c478bd9Sstevel@tonic-gate# 918*7c478bd9Sstevel@tonic-gate# This interface program relies on filters to detect printer faults. 919*7c478bd9Sstevel@tonic-gate# In absence of a filter provided by the customer, it uses a simple 920*7c478bd9Sstevel@tonic-gate# filter (${LPCAT}) to detect the class of faults that cause DCD 921*7c478bd9Sstevel@tonic-gate# (``carrier'') drop. The protocol between the interface program and 922*7c478bd9Sstevel@tonic-gate# the filter: 923*7c478bd9Sstevel@tonic-gate# 924*7c478bd9Sstevel@tonic-gate# The filter should exit with zero if printing was 925*7c478bd9Sstevel@tonic-gate# successful and non-zero if printing failed because 926*7c478bd9Sstevel@tonic-gate# of a printer fault. This interface program turns a 927*7c478bd9Sstevel@tonic-gate# non-zero exit of the filter into an "exit 129" from 928*7c478bd9Sstevel@tonic-gate# itself, thus telling the Spooler that a printer fault 929*7c478bd9Sstevel@tonic-gate# (still) exists. 930*7c478bd9Sstevel@tonic-gate# 931*7c478bd9Sstevel@tonic-gate# The filter should report printer faults via a message 932*7c478bd9Sstevel@tonic-gate# to its standard error. This interface program takes all 933*7c478bd9Sstevel@tonic-gate# standard error output from the filter and feeds it as 934*7c478bd9Sstevel@tonic-gate# standard input to the ${LPTELL} program. 935*7c478bd9Sstevel@tonic-gate# 936*7c478bd9Sstevel@tonic-gate# The filter should wait for a printer fault to clear, 937*7c478bd9Sstevel@tonic-gate# and should resume printing when the fault clears. 938*7c478bd9Sstevel@tonic-gate# Preferably it should resume at the top of the page 939*7c478bd9Sstevel@tonic-gate# that was being printed when the fault occurred. 940*7c478bd9Sstevel@tonic-gate# If it waits and finishes printing, it should exit 941*7c478bd9Sstevel@tonic-gate# with a 0 exit code. If it can't wait, it should exit 942*7c478bd9Sstevel@tonic-gate# with a non-zero exit code. 943*7c478bd9Sstevel@tonic-gate# 944*7c478bd9Sstevel@tonic-gate# The interface program expects that ANY message on the 945*7c478bd9Sstevel@tonic-gate# standard error from the filter indicates a printer fault. 946*7c478bd9Sstevel@tonic-gate# Therefore, a filter should not put user (input) error 947*7c478bd9Sstevel@tonic-gate# messages on the standard error, but on the standard output 948*7c478bd9Sstevel@tonic-gate# (where the user can read them when he or she examines 949*7c478bd9Sstevel@tonic-gate# the print-out). 950*7c478bd9Sstevel@tonic-gate# 951*7c478bd9Sstevel@tonic-gate##### 952*7c478bd9Sstevel@tonic-gate 953*7c478bd9Sstevel@tonic-gatebadfileyet= 954*7c478bd9Sstevel@tonic-gatei=1 955*7c478bd9Sstevel@tonic-gatewhile [ $i -le $copies ] 956*7c478bd9Sstevel@tonic-gatedo 957*7c478bd9Sstevel@tonic-gate for file in ${files} 958*7c478bd9Sstevel@tonic-gate do 959*7c478bd9Sstevel@tonic-gate if [ -r "${file}" ] 960*7c478bd9Sstevel@tonic-gate then 961*7c478bd9Sstevel@tonic-gate ##### 962*7c478bd9Sstevel@tonic-gate # 963*7c478bd9Sstevel@tonic-gate # Here's where we set up the $LPTELL program to 964*7c478bd9Sstevel@tonic-gate # capture fault messages, and... 965*7c478bd9Sstevel@tonic-gate # 966*7c478bd9Sstevel@tonic-gate # Here's where we print the file. 967*7c478bd9Sstevel@tonic-gate # 968*7c478bd9Sstevel@tonic-gate # We set up a pipeline to $LPTELL, but play a trick 969*7c478bd9Sstevel@tonic-gate # to get the filter's standard ERROR piped instead of 970*7c478bd9Sstevel@tonic-gate # its standard OUTPUT: Divert the standard error (#2) to 971*7c478bd9Sstevel@tonic-gate # the standard output (#1) IN THE PIPELINE. The shell 972*7c478bd9Sstevel@tonic-gate # will have changed #1 to be the pipe, not the 973*7c478bd9Sstevel@tonic-gate # printer, so diverting #2 connects it to the pipe. 974*7c478bd9Sstevel@tonic-gate # We then change the filter's #1 to a copy of the real 975*7c478bd9Sstevel@tonic-gate # standard output (the printer port) made earlier, 976*7c478bd9Sstevel@tonic-gate # so that is connected back to the printer again. 977*7c478bd9Sstevel@tonic-gate # 978*7c478bd9Sstevel@tonic-gate # We do all this inside a parenthesized expression 979*7c478bd9Sstevel@tonic-gate # so that we can get the exit code; this is necessary 980*7c478bd9Sstevel@tonic-gate # because the exit code of a pipeline is the exit 981*7c478bd9Sstevel@tonic-gate # code of the right-most command, which isn't the 982*7c478bd9Sstevel@tonic-gate # filter. 983*7c478bd9Sstevel@tonic-gate # 984*7c478bd9Sstevel@tonic-gate # These two tricks could be avoided by using a named 985*7c478bd9Sstevel@tonic-gate # pipe to connect the standard error to $LPTELL. In 986*7c478bd9Sstevel@tonic-gate # fact an early prototype of this script did just 987*7c478bd9Sstevel@tonic-gate # that; however, the named pipe introduced a timing 988*7c478bd9Sstevel@tonic-gate # problem. The processes that open a named pipe hang 989*7c478bd9Sstevel@tonic-gate # until both ends of the pipe are opened. Cancelling 990*7c478bd9Sstevel@tonic-gate # a request or disabling the printer often killed one 991*7c478bd9Sstevel@tonic-gate # of the processes, causing the other process to hang 992*7c478bd9Sstevel@tonic-gate # forever waiting for the other end of the pipe to 993*7c478bd9Sstevel@tonic-gate # be opened. 994*7c478bd9Sstevel@tonic-gate ##### 995*7c478bd9Sstevel@tonic-gate EXIT_CODE=${TMPPREFIX}e 996*7c478bd9Sstevel@tonic-gate trap '' 1 # Let the filter handle a hangup 997*7c478bd9Sstevel@tonic-gate trap '' 2 3 # and interrupts 998*7c478bd9Sstevel@tonic-gate ( 999*7c478bd9Sstevel@tonic-gate ##### 1000*7c478bd9Sstevel@tonic-gate # Put the 0<${file} before the "eval" to keep 1001*7c478bd9Sstevel@tonic-gate # clever users from giving a file name that 1002*7c478bd9Sstevel@tonic-gate # evaluates as something to execute. 1003*7c478bd9Sstevel@tonic-gate ##### 1004*7c478bd9Sstevel@tonic-gate 0<${file} eval ${FILTER} 2>&1 1>&3 1005*7c478bd9Sstevel@tonic-gate echo $? >${EXIT_CODE} 1006*7c478bd9Sstevel@tonic-gate ) | ${LPTELL} ${LPTELL_OPTS} ${printer} 1007*7c478bd9Sstevel@tonic-gate trap 'catch_hangup; exit_code=129 exit 129' 1 1008*7c478bd9Sstevel@tonic-gate trap 'catch_interrupt; exit_code=129 exit 129' 2 3 1009*7c478bd9Sstevel@tonic-gate exit_code=`cat ${EXIT_CODE}` 1010*7c478bd9Sstevel@tonic-gate 1011*7c478bd9Sstevel@tonic-gate if [ -n "${exit_code}" -a 0 -ne "${exit_code}" ] 1012*7c478bd9Sstevel@tonic-gate then 1013*7c478bd9Sstevel@tonic-gate trap '' 15 # Avoid dying from disable 1014*7c478bd9Sstevel@tonic-gate sleep 4 # Give $LPTELL a chance to tell 1015*7c478bd9Sstevel@tonic-gate exit ${exit_code} 1016*7c478bd9Sstevel@tonic-gate fi 1017*7c478bd9Sstevel@tonic-gate 1018*7c478bd9Sstevel@tonic-gate if [ -n "${FF}" -a "no" = "${nofilebreak}" ] 1019*7c478bd9Sstevel@tonic-gate then 1020*7c478bd9Sstevel@tonic-gate echo "${CR}${FF}\c" 1021*7c478bd9Sstevel@tonic-gate fi 1022*7c478bd9Sstevel@tonic-gate 1023*7c478bd9Sstevel@tonic-gate else 1024*7c478bd9Sstevel@tonic-gate 1025*7c478bd9Sstevel@tonic-gate ##### 1026*7c478bd9Sstevel@tonic-gate # 1027*7c478bd9Sstevel@tonic-gate # Don't complain about not being able to read 1028*7c478bd9Sstevel@tonic-gate # a file on second and subsequent copies, unless 1029*7c478bd9Sstevel@tonic-gate # we've not complained yet. This removes repeated 1030*7c478bd9Sstevel@tonic-gate # messages about the same file yet reduces the 1031*7c478bd9Sstevel@tonic-gate # chance that the user can remove a file and not 1032*7c478bd9Sstevel@tonic-gate # know that we had trouble finding it. 1033*7c478bd9Sstevel@tonic-gate ##### 1034*7c478bd9Sstevel@tonic-gate if [ "${i}" -le 1 -o -z "${badfileyet}" ] 1035*7c478bd9Sstevel@tonic-gate then 1036*7c478bd9Sstevel@tonic-gate errmsg WARNING ${E_IP_BADFILE} \ 1037*7c478bd9Sstevel@tonic-gate "cannot read file \"${file}\"" \ 1038*7c478bd9Sstevel@tonic-gate "see if the file still exists and is readable, 1039*7c478bd9Sstevel@tonic-gate or consult your system administrator; 1040*7c478bd9Sstevel@tonic-gate printing continues" 1041*7c478bd9Sstevel@tonic-gate badfileyet=yes 1042*7c478bd9Sstevel@tonic-gate fi 1043*7c478bd9Sstevel@tonic-gate 1044*7c478bd9Sstevel@tonic-gate fi 1045*7c478bd9Sstevel@tonic-gate 1046*7c478bd9Sstevel@tonic-gate done 1047*7c478bd9Sstevel@tonic-gate i=`expr $i + 1` 1048*7c478bd9Sstevel@tonic-gate 1049*7c478bd9Sstevel@tonic-gatedone 1050*7c478bd9Sstevel@tonic-gate 1051*7c478bd9Sstevel@tonic-gateif [ "no" = "${nobanner}" -a "${TERM}" = "PSR" ] 1052*7c478bd9Sstevel@tonic-gatethen 1053*7c478bd9Sstevel@tonic-gate ( eval "${banner} ${banner_filter}" 2>&1 1>&3 ) \ 1054*7c478bd9Sstevel@tonic-gate | ${LPTELL} ${LPTELL_OPTS} ${printer} 1055*7c478bd9Sstevel@tonic-gatefi 1056*7c478bd9Sstevel@tonic-gate 1057*7c478bd9Sstevel@tonic-gateif [ -n "${exit_code}" -a 0 -ne "${exit_code}" ] 1058*7c478bd9Sstevel@tonic-gatethen 1059*7c478bd9Sstevel@tonic-gate exit ${exit_code} 1060*7c478bd9Sstevel@tonic-gatefi 1061*7c478bd9Sstevel@tonic-gate 1062*7c478bd9Sstevel@tonic-gate##### 1063*7c478bd9Sstevel@tonic-gate# 1064*7c478bd9Sstevel@tonic-gate# Always ensure the complete job ends with a ``formfeed'', to 1065*7c478bd9Sstevel@tonic-gate# let the next job start on a new page. (If someone wants to 1066*7c478bd9Sstevel@tonic-gate# concatenate files, they can give them in one job.) 1067*7c478bd9Sstevel@tonic-gate# So, if we haven't been putting out a ``formfeed'' between files, 1068*7c478bd9Sstevel@tonic-gate# it means we haven't followed the last file with a formfeed, 1069*7c478bd9Sstevel@tonic-gate# so we do it here. 1070*7c478bd9Sstevel@tonic-gate##### 1071*7c478bd9Sstevel@tonic-gateif [ -n "${FF}" -a "yes" = "${nofilebreak}" ] 1072*7c478bd9Sstevel@tonic-gatethen 1073*7c478bd9Sstevel@tonic-gate echo "${CR}${FF}\c" 1074*7c478bd9Sstevel@tonic-gatefi 1075*7c478bd9Sstevel@tonic-gate 1076*7c478bd9Sstevel@tonic-gate${DRAIN} 1077*7c478bd9Sstevel@tonic-gate 1078*7c478bd9Sstevel@tonic-gateexit_code=0 exit 0 1079