[comp.unix.misc] One way to print to an attached terminal printer

dickson@escob1.UUCP (Dave Dickson) (05/31/91)

There has recently been interest in how to use a printer
attached to the auxiliary port of a terminal.  I don't remember
what newsgroup(s) the questions were directed to.  If this is not
the appropriate group, I apologize in advance.

Included below is a series of scripts that I use for remote
printing to a printer attached to the auxiliary port of a
hard-wired terminal or a terminal connected via modem to a remote
machine (primary use).  Even though probably not the most elegant
solution we have been using this routine for some time, with no
problems.  This method allows use of the attached printer with
any application package, or command line lp jobs.

We are running in a system V environment and are using the KSH
exclusively, so you will need to modify the scripts if necessary.

The drill follows:

1) Upon login the user is asked for the terminal type (askterm).  If
he/she replies that they are using  "Aux_printer" they are then asked
to chose a printer type.  After chosing one of the auxiliary printers
(T????), they are then asked to chose a terminal type.  At that time
/usr/local/auxprint/mkpdev is invoked.

2) mkpdev is a script that:
	+ Saves the current stty settings (log_stty)
	which is compatible with the settings that will work
	and are needed when sending output back to the terminal/printer;

	+ Creates variables used for turning the auxiliary port on and
	off (prtr_off and prtr_on). You must, define mc5 and mc4 in the
	terminfo entry.  /usr/llbin/see is a simple "C" program
	that outputs non-printable characters in octal format. For example,
	prtr_on may end up set to, say "\033[2h\033[5iv2", or whatever.

	+ Sets up several other variables, some that are not really
	necessary, but handy for tracking problems in the logfile
	that is also created by mkpdev.

	+ Deletes from, "tplog" any entries for the current user, to
	obviate any problems with duplicate user entries.

	+ Creates a log entry "tplog" that includes username, device, terminal
	type, printer on and printer off codes, the default (login stty)
	stty setting and the date and time.

	+ Changes the mode on /dev/tty to 666, so "lp" will be able to
	write to the port.  It was decided to do this instead of writing
	suid code that could possibly be abused more than a permissive
	port (??).

	+ The variables that will be used to control the port are of
	var_name=var_value nature so that they can be simply "eval'd" into
	a yet another script (tprint).

3)	This brings us to the lp model file, which is a normal model file
	with minor modifications.  First a variable, logname, is set;
	secondly, the basic script part is "wrapped" in a subshell and
	piped to "tprint".

	+ When building the printer (lpadmin), /dev/null was chosen as
	the device (... -v/dev/null).

4)	The last scipt in this process, tprint, works as follows:
	
	+ tprint is invoked via lp with the user name as an argument,
	i.e., "piped lp output ... | tprint username".  The first line
	of this script selects username from tplog, doing an eval on the
	line selected. This sets and initializes all the variables
	necessary for the port manipulation and file redirection.

	+ The current application stty settings are stored in a variable,
	app_stty; the port will have to be set back to this setting when
	the print job is done (remember, you may be in an application
	that has completely re-configured your tty port).

	+ The stty is now set to the same mode that was saved when you
	initially logged in.  This is necessary in order that the port
	can be properly addressed from the model file.

	+ Now the auxiliary port is turned on and you are about ready
	to receive input.

	+ Now the input is simply piped through cat and redirected to the
	device (tty); the auxiliary port is then turned off and then the
	tty is restored to the previous condition.


There are probably many other ways to do this and the above is
only intended as a guideline.  It is specific to one and only one
environment and needless to say requires modification for
other environments.

I apologize for the size of this article, but felt that it may not be
obvious what was going on.  Below are each of the scripts, explained
above.

############## SCRIPTS ###############

script askterm:
set -A Term_list  vt100 xterm wy75 wy85 alt2 alt3 5425 \
netmac xtermh at386-m ansi dumb other Training Aux_printer

set -A Aux_Term_list  vt100 wy75 wy85 alt2 alt3 5425

set -A Prtr_list T855 T5310 T321

(( LINES = ${#Term_list[*]}/3 ))
PS3="Enter number associated with Term_Type: "

select Term_Type in "${Term_list[@]}"
do
	if (( REPLY >= 1 )) && (( REPLY <= "${#Term_list[@]}" ))
	then
		break
	else
		print -u2 "$REPLY is invalid. Please try again"
	fi
done

if [[ $Term_Type = Aux_printer ]]
then
	select Prtr_Type in "${Prtr_list[@]}"
	do
		if (( REPLY >= 1 )) && (( REPLY <= "${#Prtr_list[@]}" ))
		then
			LJDEST=$Prtr_Type
			LPDEST=$Prtr_Type
			break
		else
			print -u2 "$REPLY is invalid. Please try again"
		fi
	done
	select Term_Type in "${Aux_Term_list[@]}"
	do
		if (( REPLY >= 1 )) && (( REPLY <= "${#Prtr_list[@]}" ))
		then
			break
		else
			print -u2 "$REPLY is invalid. Please try again"
		fi
	done

fi

[[ $Term_Type = Training ]] && Term_Type=train

if [[ $Term_Type = other ]]
then
	Term_Type=
	while [[  $Term_Type = "" ]]
	do
		read Term_Type?"Terminal type ? "
	done
fi

TERM=$Term_Type
PS3="#? "
[[ $Prtr_Type != "" ]] && /usr/local/auxprint/mkpdev
unset LINES  Prtr_Type


script mkpdev:

# Used to setup environment for printing via termials with attached
# printers.  This script will enter a line in "_tp_log", indentifying
# user, dev, and other info needed to drive an attached printer.  Even
# though it is intended that this script be run by something like "askterm",
# it could be invoked directly - as long as user is savy enough to have
# set up LP and LJ DEST's.  _tp_log is used by print spooling model file
# filter (tprint) to control the terminal/printer.
# This script must run under KSH.
# 02/06/91 OBT-ESCOM (dickson):

_tty=`tty`
log_stty=`stty -g`
_date=`date "+ %D %T"`
_tp_log=/usr/local/auxprint/tplog
_prog=${0##*/}
_tmp_log=/tmp/${_tp_log##*/}.$$
trap 'rm -f $_tmp_log' 0 1 2 15
prtr_off=`tput mc4 2>/dev/null | /usr/llbin/see` 
prtr_on=`tput mc5  2>/dev/null | /usr/llbin/see`

if [ -z "$prtr_on" -o -z "$prtr_off" ]
then
	print -u2 "$_prog: Terminal attached printing not possible for $TERM"
	exit 1
fi

OFS=$IFS
IFS="=()
"
set -- `id`
IFS=$OFS
_user=$3

sed "/^$_user/d" $_tp_log > $_tmp_log	# a purge of user (_user)
cat  $_tmp_log > $_tp_log		# fresh start
print -r $_user TTY_DEV=$_tty $TERM prtr_on=\'$prtr_on\' \
prtr_off=\'$prtr_off\' log_stty=$log_stty $_date >> $_tp_log
chmod 666 $_tty  # messages must be enabled - Lp needs write permission



lp model file example:

# @(#)Tti.855	1.1
logname=$2
copies=$4
(
	Body of model file script goes here
	.
	.
) | /usr/local/auxprint/tprint $logname
exit 0


script tprint:

# Used as a filter for Lp model files that interface to printers attached
# to the AUX port, of terminals.
# Usage: <Output_from_model_file> | tprint username
# 02/07/91 OBT-ESCOM (dickson):

eval `awk '/^'"$1"'/{print $2,$4,$5,$6}' /usr/local/auxprint/tplog` # in situ
app_stty=`stty -g < $TTY_DEV`
stty $log_stty < $TTY_DEV
echo "$prtr_on\c" > $TTY_DEV
cat > $TTY_DEV
echo "$prtr_off\c" > $TTY_DEV
stty $app_stty < $TTY_DEV


ttyplog file:
NOTE, the escaped, broken lines below, are really single lines. I have
broken the lines only for the example.

dickson TTY_DEV=/dev/ttyrd wy85 prtr_on='\033[2h\033[5i' \
prtr_off='\033[4i\033[2l' \
log_stty=d26:5:1ad:15b:7f:1c:8:15:4:1b:0:1a 05/28/91 16:19:57
place TTY_DEV=/dev/ttyr6 wy75 prtr_on='\033[2h\033[5i' \
prtr_off='\033[4i\033[2l' \
log_stty=d26:1805:5af:17b:7f:1c:8:15:4:0:0:1a 05/29/91 11:03:54
-- 
David G. Dickson
Ohio Bell Telephone Co. (614-223-8134)
uunet!escob1!dickson