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