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