Βοήθεια για την εφαρμογή TaxSpooler

SCO openserver 5.0.5:
Το ελαφρά τροποποιημένο το φίλτρο του SCO Unix
Με bold και ιδιαίτερο χρώμα ξεχωρίζουν οι παρεμβάσεις (γραμμή 942)
#  :
#	@(#) standard 69.1 98/03/16
#
#	Copyright (C) 1988-1998 The Santa Cruz Operation, Inc.
#		All Rights Reserved.
#	The information in this file is provided for the exclusive use of
#	the licensees of The Santa Cruz Operation, Inc.  Such users have the
#	right to use, modify, and incorporate this code into other products
#	for purposes authorized by the license agreement provided they include
#	this notice and the associated copyright notice with any such product.
#	The information in this file is provided "AS IS" without warranty.
#
###########
##
## Standard printer interface program.
##
###########
#

#####
#
# Until we get to the point below where the printer port
# and physical printer are initialized, we can't do much
# except exit if the Spooler/Scheduler cancels us.
#####
trap 'exit' 15

#####
#
# We can be clever about getting a hangup or interrupt, though, at least
# until the filter runs. Do this early, even though $LPTELL
# isn't defined, so that we're covered.
#####
catch_hangup () {
	if [ -n "${LPTELL}" ]
	then
		echo \
"The connection to the printer dropped; perhaps the printer went off-line?" \
		| ${LPTELL} ${printer}
	fi
	return 0
}
catch_interrupt () {
	if [ -n "${LPTELL}" ]
	then
		echo \
"Received an interrupt from the printer.  The reason is unknown,
although a common cause is that the baud rate is too high." \
		| ${LPTELL} ${printer}
	fi
	return 0
}
trap 'catch_hangup; exit_code=129 exit 129' 1
trap 'catch_interrupt; exit_code=129 exit 129' 2 3

#####
#
# Most of the time we don't want the standard error to be captured
# by the Spooler, mainly to avoid "Terminated" messages that the
# shell puts out when we get a SIGTERM. We'll save the standard
# error channel under another number, so we can use it when it
# should be captured.
#####
exec 5>&2 2>/dev/null

#####
#
# Set some globally used variables and functions.
#####

: ${TMPDIR:=/tmp}
: ${SPOOLDIR:=/usr/spool/lp}
: ${TERMINFO:=/usr/lib/terminfo}
: ${CHARSETDIR:=/usr/lib/charsets}

: ${LOCALPATH:=${SPOOLDIR}/bin}
PATH="/bin:/usr/bin:${LOCALPATH}"

MAX_COLS_SMALL_BANNER=40

#####
# Use ${TMPPREFIX} as the prefix for all temporary files, so
# that cleanup is easy. The prefix may be up to 13 characters
# long, so you only have space for one more character to make
# a file name. If necessary, make a directory using this prefix
# for better management of unique temporary file names.
#####
TMPPREFIX=${TMPDIR}/`uname -n`$$

#####
# Before exiting, set ${exit_code} to the value with which to exit.
# Otherwise, the exit from this script will be 0.
#####
trap 'rm -fr ${TMPPREFIX}?; exit ${exit_code}' 0

#####
# ${LPTELL} is the name of a program that will send its
# standard input to the Spooler. It is used to forward
# the description of a printer fault to the Spooler,
# which uses it in an alert to the administrator.
#####
if [ ! -x "${LPTELL:=${LOCALPATH}/lp.tell}" ]
then
	fake_lptell () {
		header="no"
		while read line
		do
			if [ "no" = "${header}" ]
			then
				errmsg ERROR ${E_IP_UNKNOWN} \
		"unknown printer/interface failure" \
		"consult your system administrator;
		reasons for failure (if any) follow:"
				header=yes
			fi
			echo "${line}" >&2
		done
		return 1
	}
	LPTELL=fake_lptell
fi

#####
# ${DRAIN} is the name of a program that will wait
# long enough for data sent to the printer to print.
#####
if [ -x "${LOCALPATH}/drain.output" ]
then
	DRAIN="${LOCALPATH}/drain.output 5"	# wait only five seconds
else
	DRAIN=
fi

#####
# ${LPCAT} is the name of a program to use as a default
# filter. Minimally it should copy its standard input to
# the standard output, but it should also trap printer
# faults. The current LPCAT traps hangups (DCD dropping, SIGHUP),
# interrupts (SIGINT, SIGQUIT), broken pipe (SIGPIPE), and
# excess delays in sending data to the printer, interpreting all
# as printer faults.
#####
if [ ! -x "${LPCAT:=${LOCALPATH}/lp.cat}" ]
then
	LPCAT="cat"
fi

#####
# ${LPSET} is the name of a program that will set the
# character pitch, line pitch, page width, page length,
# and character set. It helps to have this in a single
# binary program so that (1) it's faster than calls
# to "tput"; and (2) it can access the new Terminfo
# capabilities for printers (on pre SVR3.2 machines, tput can't).
#####
if [ ! -x "${LPSET:=${LOCALPATH}/lp.set}" ]
then
	fake_lpset () {
		echo H V W L S >&2
		false
	}
	LPSET=fake_lpset
fi

#####
# ${TPUT} is "tput" IFF it works. We'll disable it if we get an
# ugly error message the first time we use it. See the TERM variable
# later in the script.
#
# NOTE: The check we use to see if "tput" works is to use an OLD
# Terminfo capability, like "lines". If it works with that it may
# still fail with some of the newer capabilities like "init" (SVR3.0)
# or "swidm" (SVR3.2), because the version of "tput" we have on your
# machine is older. Thus, on some of the code where ${TPUT} is used
# you'll see "2>/dev/null" being used to avoid ugly error messages.
#####
TPUT=tput

#####
#
# ${LPPAGER} is the name of a filter that will pad its input at
# the tail to make it exactly fit the last page. This is only
# used for simple printers that don't have a formfeed. (Unfortunately,
# the "pr" command won't work.) ${LPPAGER} takes one argument, the
# page length (in lines).
#
# NOTE: This program must trap SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGTERM.
# The first four can occur with various real and imaginary printers.
# The last occurs when we are terminated (disable, cancel). On SIGTERM
# the ${LPPAGER} program must finish a full page before exiting!
#####
if [ ! -x "${LPPAGER:=${LOCALPATH}/lp.page}" ]
then
	LPPAGER=
fi

#####
# Error message formatter:
#
# Invoke as
#
#	errmsg severity message-number problem help
#
# where severity is "ERROR" or "WARNING", message-number is
# a unique identifier, problem is a short description of the
# problem, and help is a short suggestion for fixing the problem.
#####

LP_ERR_LABEL="UX:lp"

E_IP_ARGS=1
E_IP_OPTS=2
#E_IP_FILTER=3
E_IP_STTY=4
E_IP_UNKNOWN=5
E_IP_BADFILE=6
E_IP_BADCHARSET=7
E_IP_BADCPI=8
E_IP_BADLPI=9
E_IP_BADWIDTH=10
E_IP_BADLENGTH=11
E_IP_ERRORS=12		# (in slow.filter)

errmsg () {
	case $1 in
	ERROR )
		sev="  ERROR";
		;;
	WARNING )
		sev="WARNING";
		;;
	esac
#	tag=`expr "${LP_ERR_LABEL}" : "\(.*\):"``expr "${LP_ERR_LABEL}" : ".*:\(.*\)"`
	echo "${LP_ERR_LABEL}: ${sev}: $3
        TO FIX: $4" >&5
}


###########
##
## Check arguments
###########

parse () {
	echo "`expr \"$1\" : \"^[^=]*=\(.*\)\"`"
}

#####
#
# This program is invoked as
#
# ${SPOOLDIR}/.../printer request-id user title copies options files...
#
# The first three arguments are simply reprinted on the banner page,
# the fourth (copies) is used to control the number of copies to print,
# the fifth (options) is a blank separated list (in a single argument)
# of user or Spooler supplied options (without the -o prefix),
# and the last arguments are the files to print.
#####

if [ $# -lt 6 ]
then
	errmsg ERROR ${E_IP_ARGS} \
		"wrong number of arguments to interface program" \
		"consult your system administrator"
	exit_code=1
	exit 0
fi

printer=`basename $0`
request_id=$1
user_name=$2
title=$3
copies=$4
option_list=$5

shift 5
files="$*"
nfiles=$#

if [ -z "${BANNERS}" ]
then
	nhead=1
else
	nhead=${BANNERS}
fi

nobanner="no"
nofilebreak="no"
stty=

inlist=
for i in ${option_list}
do
	case "${i}" in

	nobanner )
		nobanner="yes"
		;;

	nofilebreak )
		nofilebreak="yes"
		;;

	cpi=pica )
		cpi=10
		;;
	cpi=elite )
		cpi=12
		;;
	cpi=* )
		cpi=`parse ${i}`
		;;

	lpi=* )
		lpi=`parse ${i}`
		;;

	length=* )
		length=`parse ${i}`
		;;

	width=* )
		width=`parse ${i}`
		;;

	stty=\'* )
		#####
		#
		# If you want to add options that, like "stty",
		# take a list (e.g. foo='a b c'), identify
		# them here and below.
#	foo=\'* )
		#####
		inlist=`expr "${i}" : "^\([^=]*\)="`
		case "${i}" in
		${inlist}=\'*\' )
			list=`expr "${i}" : "^[^=]*='\(.*\)'"`
			case "${inlist}" in
			stty )
				stty="${stty} ${list}"
				;;
#			foo )
#				foo="${foo} ${list}"
#				;;
			esac
			inlist=
			;;
		* )
			list=`expr "${i}" : "^[^=]*='\(.*\)"`
			;;
		esac
		;;

	stty=* )
		stty="${stty} `parse ${i}`"
		;;

#	foo=* )
#		foo="${foo} `parse ${i}`"
#		;;
	*\' )
		list="${list} "`expr "${i}" : "\(.*\)'\$"`
		case "${inlist}" in
		stty )
			stty="${stty} ${list}"
			;;
#		foo )
#			foo="${foo} ${list}"
#			;;
		esac
		;;

	#####
	#
	# If you want to add simple options (e.g. bar=a, e.g. stuff)
	# identify them here.
	#####
#	bar=* )
#		bar=`parse ${i}`
#		;;
#	stuff )
#		stuff="yes"
#		;;

	* )
		if [ -n "${inlist}" ]
		then
			list="${list} ${i}"
		else
			errmsg WARNING ${E_IP_OPTS} \
				"unrecognized \"-o ${i}\" option" \
				"check the option, resubmit if necessary
		printing continues"
		fi
		;;
	esac
done

#####
#
# Additional ``parameters'' are passed via Shell environment
# variables:
#
#	TERM	The printer type (used for Terminfo access)
#	CHARSET	The character set to choose
#	FILTER	The filter to run
#####

#####
# Set defaults for unset variables.
#####

: ${TERM:=unknown}
tput lines 1>/dev/null 2>&1 || TPUT=:

: ${CHARSET:=cs0}

if [ -z "${FILTER}" ]
then
	#####
	#
	# If no filter is being used, we have a little routine that
	# will push the data to the printer. It traps hangups (loss
	# of carrier) and checks for excessive delays in sending the
	# data to the printer. The lesser of the print rate of the printer
	# (obtained from Terminfo) or the baud rate is used to compute
	# the expected delay. If neither of these is correct, you
	# may be experiencing false alarms. If so, give the correct
	# rate, in characters per second, as a single argument.
	# An argument of 0 means don't check for delays.
	# Give an -r option to get a printout of actual delays.
	# (QUOTES ARE IMPORTANT!)
	#####
	# FILTER="${LPCAT} 120"			# e.g. 120 CPS
	FILTER="${LPCAT} 0"			# allow infinite delays
	# FILTER="${LPCAT} -r 0 2>/tmp/delays"	# check actual delays
	# FILTER=${LPCAT}
fi


###########
##
## Initialize the printer port
###########

#####
#
# SERIAL PORTS:
# Initialize everything.
#
# PARALLEL PORTS:
# Don't initialize baud rate.
#
# It's not obvious how to tell if a port is parallel or serial.
# However, by splitting the initialization into two steps and letting
# the serial-only part fail nicely, it'll work.
#
# Another point: The output must be a ``tty'' device. If not, don't
# bother with any of this.
#####
stty1= stty2=
tty 0<&1 1>/dev/null 2>&1 && {

	#####
	#
	# First set the default parameters,
	# then the requested parameters.
	#####

	stty \
		9600 \
			0<&1 2>/dev/null 1>&2
	stty \
		cs8 -cstopb -parenb -parodd \
		ixon -ixany \
		opost -olcuc onlcr -ocrnl -onocr -onlret -ofill \
		nl0 cr0 tab0 bs0 vt0 ff0 \
			0<&1 2>/dev/null 1>&2

	if [ -n "${stty}" ]
	then
		if stty ${stty} 0<&1 1>/dev/null 2>&5
		then
			:
		else
			errmsg ERROR ${E_IP_STTY} \
				"stty option list failed" \
				"check the \"-o stty\" option you used,
		or consult your system administrator"
			exit_code=1
			exit 0
		fi
	fi

	#####
	#
	# Here you may want to add other port initialization code.
	# Some examples:
	#
	# estty	# for printer needing hardware flow control (3B2/EPORTS)
	# fctty	# for printer needing hardware flow control (3B15,3B20)
	#####
	#estty 0<&1
	#fctty 0<&1


	##########
	#
	# Find out if we have to turn off opost before initializing the
	# printer and on after. Likewise, check clocal.
	#
	# Turning OFF opost (output postprocessing) keeps the UNIX system
	# from changing what we try to send to the printer. Turning ON
	# clocal keeps the UNIX system from dropping what we are trying to
	# send if the printer drops DTR. An example of the former is the
	# AT&T 479, which wants to send a linefeed (ASCII 10) when a page
	# width of 10 is set; with opost on, this COULD BE turned into a
	# carriage-return/linefeed pair. An example of the latter is the
	# AT&T 455, which momentarily drops DTR when it gets the
	# initialization string, is2; with clocal off, the UNIX system
	# stops sending the rest of the initialization sequence at that
	# point.
	#
	# THIS CODE MUST FOLLOW THE REST OF THE PORT INITIALIZATION CODE.
	##########
	exec 3>&1
	cur_stty=`stty -a 0<&3`
	exec 3>&-
	expr "${cur_stty}" : '.*-opost' 1>/dev/null 2>&1 \
		|| stty1="${stty1} -opost" stty2="${stty2} opost"
	expr "${cur_stty}" : '.*-clocal' 1>/dev/null 2>&1 \
		&& stty1="${stty1} clocal" stty2="${stty2} -clocal"

}


###########
##
## Initialize the physical printer (Part I).
## Here we bring the printer to a sane state.
###########

##########
#
# WARNING! The "echo" command will catch backslashes (\) and
# try to interpret the characters following it. Thus, using
# "echo" to print string values obtained from "tput" is dangerous.
##########

#####
# We're confident that most printers don't have backslashes
# in the control sequences for carriage return and form-feed.
# We're also confident that these don't contain newlines.
# We're also confident that most printers have a linefeed
# in the control sequence for doing a newline (move to beginning
# of next line), but we can't capture it like we do the
# carriage return or form-feed. Thus we set it unconditionally.
# We don't set form-feed if it isn't defined, however, because
# maybe the printer doesn't have a formfeed. If not set, we'll
# have to pass the banner page(s) through the LPPAGER program
# to make sure they end at a page break.
#####

CR=`${TPUT} cr`
[ -z "${CR}" ] && CR="\r"

FF=`${TPUT} ff`

NL="${CR}\n"

lines=`${TPUT} lines`
[ -z "${lines}" -o 0 -ge "${lines}" ] && lines=66

cols=`${TPUT} cols`
[ -z "${cols}" -o 0 -ge "${cols}" ] && cols=132

#####
#
# Basic initialization. The ``else'' clause is equivalent,
# but covers cases where old Terminal Information Utilities are present.
#####
[ -n "${stty1}" ] && stty ${stty1} 0<&1
if ${TPUT} init 2>/dev/null
then
	:
else
	pgm=`${TPUT} iprog`
	if [ -x "${pgm}" ]
	then
		eval ${pgm}
	fi

	${TPUT} is1
	${TPUT} is2

	tabset=
	if [ "8" != "`${TPUT} it`" ]
	then
		stty tab3 0<&1 1>/dev/null 2>&1

	elif `${TPUT} ht >/dev/null`
	then
		tabset="/usr/lib/tabset/${TERM}"
		if [ -r ${tabset} ]
		then
			cat -s ${tabset}
		fi
		stty tab3 0<&1 1>/dev/null 2>&1
	fi

	file=`${TPUT} if`
	if [ "${tabset}" != "${file}" -a -r "${file}" ]
	then
		cat -s "${file}"
	fi

	${TPUT} is3
	echo "${CR}\c"
fi
[ -n "${stty2}" ] && stty ${stty2} 0<&1

#####
#
# The banner page (and cancellation page) will
# use double width characters if they're available.
#####
WIDE_CS=`${TPUT} swidm 2>/dev/null` && NORM_CS=`${TPUT} rwidm 2>/dev/null`
PAD="#####${NL}"

#####
#
# Now that the printer is ready for printing, we're able
# to record on paper a cancellation.
#####

cancel_banner () {
	echo "${PAD}${PAD}\c"
	echo "#####${WIDE_CS} Job ${request_id}${NORM_CS}${NL}\c"
	echo "#####${WIDE_CS} suspended or canceled${NORM_CS}${NL}\c"
	echo "${PAD}${PAD}\c"
}

canceled () {
	${TPUT} scs 0 2>/dev/null
	echo "${CR}\c"
	if [ "${width:-${cols}}" -lt "${MAX_COLS_SMALL_BANNER}" ]
	then
		WIDE_CS= NORM_CS=
	fi
	if [ -z "${FF}" ]
	then
		cancel_banner | ${LPPAGER} ${length}
	else
		cancel_banner; echo "${CR}${FF}\c"
	fi
}

trap 'canceled; exit_code=0 exit' 15


###########
##
## Print the banner page
###########

#####
#
# You may want to change the following code to get a custom banner.
#####

regular_banner () {
	echo "${CR}\c"
	echo "${PAD}${PAD}${PAD}${PAD}${PAD}\c"
	echo "#####${WIDE_CS}       User: ${user_name}${NORM_CS}${NL}\c"
	if [ -n "${title}" ]
	then
		echo "${PAD}\c"
		echo "#####${WIDE_CS}      Title: ${title}${NORM_CS}${NL}\c"
	fi
	echo "${PAD}\c"
	echo "#####${WIDE_CS}    Printed: `date '+%a %H:%M %h %d, %Y'`${NORM_CS}${NL}\c"
	echo "${PAD}\c"
	echo "#####${WIDE_CS} Job number: ${request_id}${NORM_CS}${NL}\c"
	echo "${PAD}${PAD}${PAD}${PAD}${PAD}\c"
}

small_banner () {
	echo "${CR}\c"
	echo "${PAD}\c"
	echo "#####  User: ${user_name}${NL}\c"
	if [ -n "${title}" ]
	then
		echo "##### Title: ${title}${NL}\c"
	fi
	echo "#####  Date: `date '+%a %H:%M %h %d, %Y'`${NL}\c"
	echo "#####   Job: ${request_id}${NL}\c"
	echo "${PAD}\c"
}

if [ "no" = "${nobanner}" ]
then
	if [ "${width:-${cols}}" -lt "${MAX_COLS_SMALL_BANNER}" ]
	then
		ban=small_banner
	else
		ban=regular_banner
	fi

# Added for XENIX compatability with /etc/default/lpd

	while [ $nhead -gt 0 ]
	do

		if [ -z "${FF}" ]
		then
			${ban} | ${LPPAGER} ${length}
		else
			${ban}; echo "${CR}${FF}\c"
		fi
		nhead=`expr $nhead - 1`
	done
fi


###########
##
## Initialize the physical printer (Part II)
## Here we select the character and line pitches, page size,
## and character pitch. One could argue that this should be
## done before the banner is printed, so that the banner fits
## on a preprinted form. We don't, to keep the banner page
## looking consistent for the operator.
## You can move this code before the banner code if you disagree.
###########

#####
#
# The funny business with the "exec" and "2>&1". is to let us capture
# the standard ERROR, not the standard OUTPUT as is the usual case
# with foo=`cmd`. We duplicate the standard output (i.e the
# channel to the printer) as channel 3, then do the foo=`cmd`.
# Inside the `cmd` we redirect the standard error to the same
# place as the standard output (now being captured), then redirect
# the standard output to the same place as channel 3 (the printer,
# where we want it).
#####
[ -n "${stty1}" ] && stty ${stty1} 0<&1
exec 3>&1
chk=`${LPSET} "${cpi}" "${lpi}" "${width}" "${length}" "${CHARSET}" 2>&1 1>&3`
exec 3>&-
[ -n "${stty2}" ] && stty ${stty2} 0<&1

#####
#
# The standard error of the delivered ${LPSET} program
# is a string of letters, H, V, W, L, S, which correspond
# to cpi, lpi, width, length, and character set. A letter
# is present only if the corresponding attribute could not
# be set.
#####
for err in ${chk}
do
	case ${err} in
	H )
		errmsg WARNING ${E_IP_BADCPI} \
			"can't select the character pitch \"${cpi}\"" \
			"check the valid pitches for the printer,
		or consult your system administrator;
		printing continues"
		;;
	V )
		errmsg WARNING ${E_IP_BADLPI} \
			"can't select the line pitch \"${lpi}\"" \
			"check the valid pitches for the printer,
		or consult your system administrator;
		printing continues"
		;;
	W )
		width=${cols}
		errmsg WARNING ${E_IP_BADWIDTH} \
			"can't select the page width \"${width}\"" \
			"check the valid widths for the printer,
		or consult your system administrator;
		printing continues"
		;;
	L )
		length=${lines}
		errmsg WARNING ${E_IP_BADLENGTH} \
			"can't select the page length \"${length}\"" \
			"check the valid lengths for the printer,
		or consult your system administrator;
		printing continues"
		;;
	S )
		errmsg WARNING ${E_IP_BADCHARSET} \
			"can't select the character set \"${CHARSET}\"" \
			"check the name given in the -S option,
		or consult your system administrator;
		printing continues"
		;;
	esac
done


###########
##
## Print some copies of the file(s)
###########

#####
#
# The protocol between the interface program and the Spooler
# is fairly simple:
#
#	All standard error output is assumed to indicate a
#	fault WITH THE REQUEST. The output is mailed to the
#	user who submitted the print request and the print
#	request is finished.
#
#	If the interface program sets a zero exit code,
#	it is assumed that the file printed correctly.
#	If the interface program sets a non-zero exit code
#	less than 128, it is assumed that the file did not
#	print correctly, and the user will be notified.
#	In either case the print request is finished.
#
#	If the interface program sets an exit code greater
#	than 128, it is assumed that the file did not print
#	because of a printer fault. If an alert isn't already
#	active (see below) one will be activated. (Exit code
#	128 should not be used at all. The shell, which executes
#	this program, turns SIGTERM, used to kill this program
#	for a cancellation or disabling, into exit 128. The
#	Spooler thus interpretes 128 as SIGTERM.)
#
#	A message sent to the standard input of the ${LPTELL}
#	program is assumed to describe a fault WITH THE PRINTER.
#	The output is used in an alert (if alerts are defined).
#	If the fault recovery is "wait" or "begin", the printer
#	is disabled (killing the interface program if need be),
#	and the print request is left on the queue.
#	If the fault recovery is "continue", the interface program
#	is allowed to wait for the printer fault to be cleared so
#	it can resume printing.
#
# This interface program relies on filters to detect printer faults.
# In absence of a filter provided by the customer, it uses a simple
# filter (${LPCAT}) to detect the class of faults that cause DCD
# (``carrier'') drop. The protocol between the interface program and
# the filter:
#
#	The filter should exit with zero if printing was
#	successful and non-zero if printing failed because
#	of a printer fault. This interface program turns a
#	non-zero exit of the filter into an "exit 129" from
#	itself, thus telling the Spooler that a printer fault
#	(still) exists.
#
#	The filter should report printer faults via a message
#	to its standard error. This interface program takes all
#	standard error output from the filter and feeds it as
#	standard input to the ${LPTELL} program.
#
#	The filter should wait for a printer fault to clear,
#	and should resume printing when the fault clears.
#	Preferably it should resume at the top of the page
#	that was being printed when the fault occurred.
#	If it waits and finishes printing, it should exit
#	with a 0 exit code. If it can't wait, it should exit
#	with a non-zero exit code.
#
#	The interface program expects that ANY message on the
#	standard error from the filter indicates a printer fault.
#	Therefore, a filter should not put user (input) error
#	messages on the standard error, but on the standard output
#	(where the user can read them when he or she examines
#	the print-out).
#
#####

badfileyet=
EXIT_CODE=${TMPPREFIX}e
trap 'catch_hangup; echo 129 >${EXIT_CODE}; exit_code=129 exit 129' 1
trap 'catch_interrupt; echo 129 >${EXIT_CODE}; exit_code=129 exit 129' 2 3

##########
#
# Here's where we set up the $LPTELL program to capture
# fault messages. It is at the other end of the shell pipeline;
# the ``left-hand'' side of the pipeline is the following loop.
#
#	while [ $i -le $copies ]
#	do
#		...
#	done | ${LPTELL} ...
#
# WARNING: The standard output of the following loop is directed
# to $LPTELL, not the printer. To send something to the printer,
# direct it to channel 3. E.g. echo "output" 1>&3
#
# WARNING: Because this loop is the first in a pipeline, it is in
# a sub-shell. To propagate an exit code to the original shell,
# copy it into the file ${EXIT_CODE}.
##########
exec 3>&1
i=1
while [ $i -le $copies ]
do

	#####
	# Set FORMFEED to be a pipeline that will simulate a formfeed
	# if we don't have a real formfeed and want filebreaks.
	#####
	if [ -z "${FF}" -a "no" = "${nofilebreak}" -a -n "${LPPAGER}" ]
	then
		FORMFEED="${LPPAGER} ${length}"
	fi

	n=1
	for file in ${files}
	do

		#####
		# Set FORMFEED to be a pipeline that will simulate a
		# formfeed if we don't have a real formfeed and DON'T
		# want filebreaks--last file only.
		#####
		if [ \
			-z "${FF}" \
		     -a "yes" = "${nofilebreak}" \
		     -a -n "${LPPAGER}" \
		     -a "${n}" = "${nfiles}" \
		]
		then
			FORMFEED="${LPPAGER} ${length}"
		fi

		if [ -r "${file}" ]
		then
		   
			/inca/prog/taxspooler/itaxtcp nota "${file}" "${file}" -iUnix 2>>/tmp/itaxtcp.log

			#####
			# Here's where we print the file.
			# Put the 0<${file} before the "eval" to keep
			# clever users from giving a file name that
			# evaluates as something to execute (like LPTELL!)
			# We send the standard output of the
			# filter directly to the printer, while
			# piping the standard error to $LPTELL.
			#####
			trap '' 1	# Let the filter handle a hangup
			trap '' 2 3	# and interrupts
			if [ -z "${FORMFEED}" ]
			then
				0<${file} eval ${FILTER} 2>&1 1>&3
				exit_code=$?
			else
				exec 4>&1
				(
					0<${file} eval ${FILTER} 2>&4
					echo $? >${EXIT_CODE}
				) | eval ${FORMFEED} 1>&3
				exec 4>&-
				exit_code=`cat ${EXIT_CODE}`
			fi
			trap 'catch_hangup; echo 129 >${EXIT_CODE}; exit' 1
			trap 'catch_interrupt; echo 129 >${EXIT_CODE}; exit' 2 3

			if [ 0 != "${exit_code}" ]
			then
				trap '' 15
				sleep 4
				exit_code=129
				echo ${exit_code} >${EXIT_CODE}
				exit ${exit_code}
			fi

			if [ -n "${FF}" -a "no" = "${nofilebreak}" ]
			then
				echo "${CR}${FF}\c" 1>&3
			fi

		else

			#####
			#
			# Don't complain about not being able to read
			# a file on second and subsequent copies, unless
			# we've not complained yet. This removes repeated
			# messages about the same file yet reduces the
			# chance that the user can remove a file and not
			# know that we had trouble finding it.
			#####
			if [ "${i}" -le 1 -o -z "${badfileyet}" ]
			then
				errmsg WARNING ${E_IP_BADFILE} \
					"cannot read file \"${file}\"" \
					"see if the file still exists and is readable,
		or consult your system administrator;
		printing continues"
				badfileyet=yes
			fi

		fi
		n=`expr $n + 1`

	done
	i=`expr $i + 1`

done | ${LPTELL} ${printer}
exec 3>&-

exit_code=`cat ${EXIT_CODE} 2>/dev/null`
if [ -n "${exit_code}" -a 0 != "${exit_code}" ]
then
	exit ${exit_code}
fi

if [ -n "${FF}" -a "yes" = "${nofilebreak}" ]
then
	echo "${CR}${FF}\c"
fi

${DRAIN}

exit_code=0 exit 0
   
Προσέξτε την γραμμή 942 στο script.
Με κόκκινο χρώμα είναι το πλήρες όνομα (full pathname) του itaxtcp, με μπλέ το όνομα - θα μπορούσε να είναι η IP διεύθυνση - της μηχανής Windows όπου βρίσκεται η ΕΑΦΔΣΣ, με πράσινο το string με το οποίο η μηχανή Windows αναγνωρίζει την αίτηση (για το παράδειμγα με -iUnix, η μηχανή Windows περιμένει ένα εκτυπωτή Windows με όνομα Unix), και με πορτοκαλί είναι το όνομα ενός logbook για να παρακολουθείτε τυχόν λάθη στην επικοινωνία. To τελευταίο δεν είναι απαραίτητο. Θα μπορούσατε να δηλώσετε 2>/dev/null αντί γι αυτό.