[comp.sys.masscomp] How to output completely uninterpreted bytes through a lineprinter

carter%octopus@masscomp.UUCP (x2275) (05/05/88)

If the question is "How can I write a program that manipulates
a tty port in order to send RAW output to the lineprinter", then it
is a fairly simple matter to perform a TCGETA/TCSETA ioctl(2) against
the file descripter and make it work. If someone would like the code,
send mail to me.

If the real question is "How do I get a data file that contains escape
sequences and other interesting things like tabs and backspaces printed
on the dot matrix printer using the lp spooler /usr/bin/lp ?" then it
is also fairly easy, but will require an explanation of how the Sys V
lp spooler works. First, I assume you have reached the point of being
able to print text files on the printer via lp(1). If this doesn't
work, see the System Management Guide for your machine.

/usr/bin/lp queues a data file to be printed on a named printer or
printer class. It is possible to have many different types of printers
attached to the system, each with it's own queue. lpsched (the spooler daemon)
has know idea at all how to manipulate an individual printer. When a
file is ready to be printed, lpsched invokes a shell script and hands
the necessary information to find the file and the information the user
passed to lp(1). The shell script for an active printer is found in
/usr/spool/lp/{printername}. These are created by using the lpadmin(8)
command to copy an existing named printer, or to install a printer based on
a "model" script. The models are kept in /usr/spool/lp/model.

The citoh printer would normally be set up using the citfil model, and is
typically named "lp1". The citfil script sets various stty modes, then
runs the files through /usr/lib/citfil. This does the "right thing" for 
backspaces and tabs embedded in a text file, but the wrong thing, most
likely, for graphics dumps. The key to being able to do both is the "options"
passed to the printer interface by /usr/bin/lp. Anything appearing
after a -o is passed through to the interface script in the fifth positional
argument. For example, to establish -og as meaning "graphics file" copy
/usr/spool/lp/model/citfil to another name, for example citgraph. Modify
it as follows. Note that the definition of "$filter" has been changed to make
it easier to eliminate it when we wish raw output. This filter also works for
normal text. By customizing the interface, I have successfully spooled
a 7475 pen plotter, an inkjet printer, various diablo printers and printronix
dot matrix line printers. Other options might be to eliminate or reduce the
banner information (especially on things like inkjet printers)

Recreate lp1 with the lpadmin command, using the newly created model
(daring individuals can simply "mv" the new filter into place, when the
printer isn't running)
(as user lp) $ /usr/lib/lpadmin -plp1 -mcitgraph -v/dev/lp

After lp1 has been recreated with the new -og option, print
a graphics file via: % lp -og filename
It is also possible to do things like have an "troff" printer, that accepts
raw troff source files, and invokes the formatter rather than actually
printing the file. It could then queue it's output to the actual printer.

#! /bin/sh
# lp interface for citoh line printer with "raw" graphics option
# Works on citoh 8510 printer: uses /usr/lib/citfil for correct
# handling of backspaces
filter="/usr/lib/citfil"
if [ ! -x $filter ]
then
	disable -r"can't execute $filter" `basename $0`
	exit 1
fi
filter="|$filter"
stty ixon ixoff <&1
x="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
echo "$x\n$x\n$x\n$x\n"
banner "$2"
echo "\n"
user=`grep "^$2:" /etc/passwd | line | cut -d: -f5`
if [ -n "$user" ]
then
	echo "User: $user\n"
else
	echo "\n"
fi
echo "Request id: $1    Printer: `basename $0`\n"
date
echo "\n"
if [ -n "$3" ]
then
	banner $3
fi
echo "\n\n$x\n$x\n$x\n$x\n"
copies=$4
options="$5"
for i in $options
do	case $i in
	-g|g)	filter="";;	# print graphics file (no interpretation)
	esac
done
echo "\014\c"
shift; shift; shift; shift; shift
files="$*"
i=1
while [ $i -le $copies ]
do
	for file in $files
	do
		cat "$file" $filter 2>&1
		echo "\014\c"
	done
	i=`expr $i + 1`
done
exit 0

carter%octopus@masscomp.UUCP (Jeff Carter) (05/06/88)

Origanization: MASSCOMP, Westford, MA


[The original version of this contained a bug that Jeff sent me a note about.
Please disregard the original article. -- sob]

If the question is "How can I write a program that manipulates
a tty port in order to send RAW output to the lineprinter", then it
is a fairly simple matter to perform a TCGETA/TCSETA ioctl(2) against
the file descripter and make it work. If someone would like the code,
send mail to me.

If the real question is "How do I get a data file that contains escape
sequences and other interesting things like tabs and backspaces printed
on the dot matrix printer using the lp spooler /usr/bin/lp ?" then it
is also fairly easy, but will require an explanation of how the Sys V
lp spooler works. First, I assume you have reached the point of being
able to print text files on the printer via lp(1). If this doesn't
work, see the System Management Guide for your machine.

/usr/bin/lp queues a data file to be printed on a named printer or
printer class. It is possible to have many different types of printers
attached to the system, each with it's own queue. lpsched (the spooler daemon)
has know idea at all how to manipulate an individual printer. When a
file is ready to be printed, lpsched invokes a shell script and hands
the necessary information to find the file and the information the user
passed to lp(1). The shell script for an active printer is found in
/usr/spool/lp/{printername}. These are created by using the lpadmin(8)
command to copy an existing named printer, or to install a printer based on
a "model" script. The models are kept in /usr/spool/lp/model.

The citoh printer would normally be set up using the citfil model, and is
typically named "lp1". The citfil script sets various stty modes, then
runs the files through /usr/lib/citfil. This does the "right thing" for 
backspaces and tabs embedded in a text file, but the wrong thing, most
likely, for graphics dumps. The key to being able to do both is the "options"
passed to the printer interface by /usr/bin/lp. Anything appearing
after a -o is passed through to the interface script in the fifth positional
argument. For example, to establish -og as meaning "graphics file" copy
/usr/spool/lp/model/citfil to another name, for example citgraph. Modify
it as follows. Note that the definition of "$filter" has been changed to make
it easier to eliminate it when we wish raw output. This filter also works for
normal text. By customizing the interface, I have successfully spooled
a 7475 pen plotter, an inkjet printer, various diablo printers and printronix
dot matrix line printers. Other options might be to eliminate or reduce the
banner information (especially on things like inkjet printers)

Recreate lp1 with the lpadmin command, using the newly created model
(daring individuals can simply "mv" the new filter into place, when the
printer isn't running)
(as user lp) $ /usr/lib/lpadmin -plp1 -mcitgraph -v/dev/lp

After lp1 has been recreated with the new -og option, print
a graphics file via: % lp -og filename
It is also possible to do things like have an "troff" printer, that accepts
raw troff source files, and invokes the formatter rather than actually
printing the file. It could then queue it's output to the actual printer.

#! /bin/sh
# lp interface for citoh line printer with "raw" graphics option
# Works on citoh 8510 printer: uses /usr/lib/citfil for correct
# handling of backspaces
filter="/usr/lib/citfil"
if [ ! -x $filter ]
then
	disable -r"can't execute $filter" `basename $0`
	exit 1
fi
filter="|$filter"
stty ixon ixoff <&1
x="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
echo "$x\n$x\n$x\n$x\n"
banner "$2"
echo "\n"
user=`grep "^$2:" /etc/passwd | line | cut -d: -f5`
if [ -n "$user" ]
then
	echo "User: $user\n"
else
	echo "\n"
fi
echo "Request id: $1    Printer: `basename $0`\n"
date
echo "\n"
if [ -n "$3" ]
then
	banner $3
fi
echo "\n\n$x\n$x\n$x\n$x\n"
copies=$4
options="$5"
for i in $options
do	case $i in
	-g|g)	filter="";;	# print graphics file (no interpretation)
	esac
done
echo "\014\c"
shift; shift; shift; shift; shift
files="$*"
i=1
while [ $i -le $copies ]
do
	for file in $files
	do
		eval cat "$file" $filter 2>&1
		echo "\014\c"
	done
	i=`expr $i + 1`
done
exit 0