Newsgroups: comp.unix.sco.announce,comp.answers,news.answers
Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!howland.erols.net!nntp.flash.net!enews.sgi.com!coop.net!world!apl
From:
[email protected] (Tony Lawrence)
Subject: comp.unix.sco Technical FAQ (7/7)
Message-ID: <
[email protected]>
Approved:
[email protected]
Date: Thu, 12 Oct 2000 23:34:37 GMT
Organization:
http://www.aplawrence.com
Keywords: FAQ SCO Xenix Unix Frequently Asked Questions
Followup-To: comp.unix.sco.misc
Lines: 1188
Xref: senator-bedfellow.mit.edu comp.unix.sco.announce:2483 comp.answers:42690 news.answers:193884
Archive-Name: comp.unix.sco Technical FAQ 7/7
Posting-Frequency: Monthly (mid month)
Last-modified: Oct 12
comp.unix.sco Technical FAQ 7/7
Questions and Answers Related to Printing
FAQ Starting Page
http://aplawrence.com/SCOFAQ/index.html
These FAQS were developed and maintained for years by
[email protected] (Stephen M. Dunn). Steve no longer has the time to
maintain them, and has asked me to take them over. Please remember the
debt all of us owe to Steve for his efforts- I myself spent many hours
learning from these very documents, and I'm sure many of us can say
similar things.
Because Steve has not been able to maintain these for a while now,
some of the information herein is outdated. I am working to correct
that, but it's a lot to catch up on, so if you spot something, please
let me know. For the moment, I'm just marking some of it as probably
being useless; as I have time, I'll check further to be certain before
I remove anything.
Suggestion: Use my
http://aplawrence.com/search.html to find what you
are looking for.
What are printer interface scripts?
Much of the printer information here makes references to "interface
scripts". Some people call them "printer drivers" (they aren't). These
scripts are what controls what happens to your print job as it goes to
the printer.
The scripts are found in /usr/spool/lp/admins/lp/interfaces (or
/var/spool/lp/admins/lp/interfaces on modern systems, though the "old"
path will still work). You will find that each of the printers listed
by lpstat will have a script here, and the names will be the same as
the name of the printers.
Note that if you are using HP JetDirect printers, the script will be
there, but the actual script you want to modify is in the
sub-directory "model.orig".
To make changes to interface scripts permanent, you want to make the
same changes in the model script that was used to create the printer.
The model scripts are usually in /usr/spool/lp/model, but it's
possible for a printer to get its script from anywhere, so it's best
to check. You can look in /usr/spool/lp/admins/lp/printers where you
will find a sub-directory for each printer you have. Within that
sub-directory is the file "configuration", and you can "cat
configuration" to see where the script originated.
If you want your script changes to survive upgrades, copy them to a
new name in /usr/spool/lp/model, and change the configuration file to
reflect this, either by setting the model in the Printer Manager or by
directly editing
/usr/spool/lp/admins/lp/printers/yourprinter/configuration.
[Table of Contents]
_________________________________________________________________
Which Interface script do I use?
That depends upon both the printers ability to emulate other printers
and your need for special effects.
For example, the "dumb" and "standard" interfaces just send along
characters. They don't know how to make things bold or change fonts;
they just send out characters. Most dot-matrix and even quite a few
lasers are quite happy with that, and will produce output that is
entirely suitable for typical office reports, though perhaps not for
word processing.
If you *do* need more control, you simply need to know what the
printer can emulate, and choose the appropriate interface from that
knowledge. Almost all printers emulate something, and in the rare case
where they don't emulate anything useful, you need to get the control
codes for the features you want from the manual, and then modify some
other script.
Of course, that won't help with programs like Word Perfect that
provide their own drivers and use the interface files only as a means
of co-existing with other programs using the spooler. In that case,
you either need to emulate something that Word Perfect or your other
high level program can understand, or you have to settle for simple,
no frills output.
[Table of Contents]
_________________________________________________________________
How do I stop banners from printing?
You need to edit the file /etc/default/lpd. You need one of the
following lines:
For Xenix: BANNERS=0
For Unix: BANNERS=nobanner
Note that there are some Unix printer interface scripts which do not
use /etc/default/lpd, and you must use an option to these to disable
banners. Also, some Unix printer interface scripts expect the Xenix
syntax above. Aren't standards wonderful? Should you encounter one of
these, if you're reasonably adept at shell scripts, you might want to
cut and paste the section that reads /etc/default/lpd from a script
that works properly. Of course, be sure you make note of your changes
so that you can redo them the next time an upgrade replaces your
printer drivers.
On Unix systems, *sometimes* setting it to BANNERS=nobanner was the
supposedly correct thing to do, but not usually.
Some printer scripts work from default/lpd even now, but some don't,
and that can be annoying.
On Release 5, you are supposed to be able to choose Advanced settings
from the Printer Configuration manager, and set the number of banners
to 0.
The problem is that some of the interface scripts that SCO provides
don't respect or even check the settings in /etc/default/lpd, and
although most of the modern ones respect the setting from the Printer
Manager, there are no guarantees. Do try the simple ways first. If you
have a current version, you should be able to modify this completely
within the printer manager. But, if that doesn't work (perhaps because
you have third party scripts) you need to modify the scripts
themselves.
You'll need to modify the scripts to take away the banners.
Unfortunately, there are differences between the scripts, and even
after that, there is still more work you'll have to do to make the
changes permanent.
To begin with, search in the script for "banner=" at the start of the
line. You can do this in vi by typing "/^banner=" and pressing enter.
If you find nothing, try "/^nobanner=". If you still find nothing, try
"/^BANNER".
Most of the scripts will say :
banners="yes"
On these, you want to change the "yes" to "no". But watch out: some
scripts (the HPLaserJet for example) need it to be
banners=""
You need to read more of the script to see if that is the case.
Unfortunately, some scripts say:
nobanners="no"
and on these, of course, you must change "no" to "yes".
A few scripts might have:
BANNERPAGE="yes"
This, of course, requires a change to "no".
Some scripts expect that a variable will be passed to them in the
environment. These generally test something like this:
if [ -z "${BANNERS}" ]
then
nhead=1
else
nhead=${BANNERS}
fi
For these, you'd set "nhead=0" after this section of the script. You
should also be able to accomplish this from the SCO 5 print manager by
setting the BANNERS setting to 0, but editing the script is absolute.
Some of the scripts are really dumb about all of this.
It is entirely possible that you may have a script that does not use
any such variables, but just blindly prints headers and or trailers.
In such cases, you need to find where it's doing the printing and
comment out those lines by putting a "#" ahead of them. If you are not
sure what to comment out, you might be better off replacing this
script with something more user friendly from /usr/spool/lp/model. Be
sure to make a safe copy first, though. Having unwanted banners is
better than not printing at all.
LPD printers are another story all together. Roberto Zini offers the
following:
We had a customer who was lazy enaugh not to specify the
'nobanner' option along with the lp(C) command: for every
print job submitted a banner page got printed too and the
customer was not pretty happy about it (he already tried by
inserting the "BANNERS=nobanner" parameter in /etc/default/lpd
but unsuccesfully.
By following the printcap(SFF) manual pages, he inserted the
'sh' parameter in the line remote printer line: that should
tell lp(C) to add the 'nobanner' option on its command line
but it didn't work. So, to ease his pain, I wrote the following
lp "wrapper" script, which actually did the job:
=== cut here ===
#!/bin/sh
#
# Faked lp(C) frontend to fool the lp(C) subsystem when
# it's unable to process the 'sh' flag in the /etc/printcap file.
#
# This file should be placed under /usr/bin and replaces the
# original lp(C) file which gets renamed as lp.orig; please
# set this script permissions accordingly to the original
# lp(C) ones.
# (chmod 2111 lp)
#
# R.Zini - Strhold (22/03/2000)
#
MLPDEF=`lpstat -d | awk '{ print $4 }'`
MYOPTS="$*"
MYPRT=""
MYBAN=0
MYDEF=""
#
# Grab the '-d <printer>' option; if it's not given, use the
# the DEFAULT destination printer.
#
while getopts :d: a
do
case $a in
d) MYPRT=$OPTARG;;
esac
done
#
# Do we have to use the default printer ?
#
if [ "Z$MYPRT" = "Z" ]
then
MYPRT=$MLPDEF
MYDEF="-d $MYPRT "
fi
#
# Check if we have to give the '-onobanner' option;
# in the /etc/printcap file the administrator has to insert
# the 'sh' flag for this trick to work.
#
grep ":rp=$MYPRT:" /etc/printcap | grep "sh" 1>/dev/null 2>&1 && MYBAN=1
if [ $MYBAN -eq 1 ]
then
exec lp.orig $MYDEF -onobanner $MYOPTS
else
exec lp.orig $MYDEF $MYOPTS
fi
=== cut here ===
It's a "quick & dirty" script and perhaps it should be
rewritten by making use of a more consistent style
(I'm not that good at shell programming) but I've
been told that it suited my customer's needs.
See also
http://aplawrence.com/Unixart/printing.html
[Table of Contents]
_________________________________________________________________
Print jobs fail, and I get mail complaining "tcgetattr failed: No such device"
This is caused by an "stty" line in the interface script for a printer
that is not connected to a serial or parallel port. Remove the line or
use a different interface script.
[Table of Contents]
_________________________________________________________________
Why does printed output garble or stop after several pages?
This is flow control. The computer and the printer have not made the
proper arrangements so that the computer can know when to pause to let
the printer catch up. You aren't likely to see this problem on
parallel printers, though a bad cable can do this.
There are two choices for flow control: software or hardware. Software
flow control is often referred to as XON or XON/XOFF, and you may see
hardware flow control referred to as "ctsflow" or sometimes "dtrflow".
Under high speed conditions, hardware flow control is preferred, but
you do need to know HOW the printer should be wired to set this up, so
software flow control is simpler.
The purpose of flow control is so that the printer can tell the
computer that it is momentarily overwhelmed, cannot handle any more
input right now, and the computer should suspend sending data until
the printer notifies it that it is once again ready to receive data.
If the computer and the printer do not agree on flow control, you will
lose data. Whether or not the printer notifies you that this has
happened is entirely up to the designer of the printer, so HP laser
printers, for example. will display an error message on their front
panel, but many other printers simply throw away data.
Most printers don't rely entirely on flow control. They usually also
have a buffer that fills up with incoming data and gets emptied as it
prints. If the buffer is larger than the print job, no flow control is
necessarily needed. That's why small jobs print OK, but larger jobs
may not- when the buffer fills, the printer needs to yell "Stop".
As the computer sending the data might not respond instantly to that
request, the printer has a "high water mark" for the buffer. It might,
for example, send the "Stop" signal when the buffer is 90% full. Some
printers let you control that high-water mark. If yours does, setting
it lower could help.
But by default, the Operating System provides NO flow control on a
serial port. If nothing else has been done, a serial port will default
to 9600 baud, 8 bit, no parity, and NO flow control.
The very first thing you want to do is DISABLE the serial port
(example: "disable tty1a"). This may be confusing because you ENABLE a
printer attached to a port, but you never, never want a printer port
itself enabled for login. To be safe, check the upper case version of
the port also ("disable tty1A").
Many intelligent serial ports (Digiboard, Equinox, Computone, Maxpeed)
have ways to set and keep serial parameters on their ports. For
example, if you have a Digiboard, you can type
"ditty /dev/ttyb02 9600 ixon printer"
to force the port to stay at 9600 with software flow control.
However, for the standard com ports (tty1a, tty2a), it's not as easy,
and you need what's called a "hold-open" script.
The problem is that while intelligent serial boards have special
commands to set flow control and keep it set, the standard Unix stty
command doesn't work that way. To set any option, you have to "open"
the port, which is simply done by combining the stty command with a
redirection symbol:
stty ixon < /dev/tty1a
Technically, this command actually works, but the problem is that the
port will be reset to defaults -ixon the instant that the port is
"closed", and that happens just microseconds after you press return!
So, effectively, it does nothing.
SCO technical articles suggest the following command:
( stty 9600 ixon -ixany ; while : ; do sleep 3600; done ) < /dev/tty1a &
The 9600 is the baud rate, and could be different, and of course your
printer might be on a different port. You need to put this in a
startup script so that it will run on each reboot.
Also see Jeff Liebermann's Serial Printing article and
http://aplawrence.com/Unixart/printing.html.
[Table of Contents]
_________________________________________________________________
Why do I lose the last few lines of my print job?
This shouldn't happen on modern Unixes, but if you do have this, you
can try adding "sleep 30" (or even longer) at the very end of the
interface script.
The problem in older kernels was that the script would end before all
the output had been sent out through the driver. The kernel would see
that that no process was using that data, so it would flush it away.
Adding the "sleep" keeps the script from exiting, hopefully long
enough for all the data to get out. If not, increase it. Note that
this doesn't cause you to wait longer for anything in the printing
process if the sleep time is equal to the time it takes to print the
last page.
[Table of Contents]
_________________________________________________________________
Large print jobs fail on remote printers
This is a silly artifact from the days when printing was expensive.
The "mx" setting in /etc/printcap determines how large a print job can
be, and if there is no "mx" then it sets the size very small. Add
"mx#0" to have unlimited size. Just stick it in (between :'s) with the
other stuff.
[Table of Contents]
What are the escape sequences to select the trays on my HP printer?
Back before the dinosaurs died, printers came with manuals that had
all this stuff in them. Nowadays, you are lucky if it's on the CD, and
if it is, good luck finding it. Here's a few that may help:
Hexadecimal Code Decimal Code Octal Code Action
1B 11 27 17 033 021 Standard Tray
1B 15 27 21 033 025 (4050) Standard Tray
1B 14 27 20 033 024 MP Paper Tray
1B 15 27 21 033 025 500 Sheet Tray
1B 18 27 24 033 030 (4050) 500 Sheet Tray
1B 16 27 22 033 026 Optional Envelope Feeder
The octal codes are what you'd probably use in an interface script:
echo "\033\030\c"
Thanks to Jean-Pierre Radley and Richard Seeder
[Table of Contents]
_________________________________________________________________
How can I print from Netscape without a Postscript printer?
If you don't have a Postscript printer, you might be able to use
Ghostscript (available from SCO's Skunkware Page ) to get some
functionality. Ghostscript is slow and has had a few problems now and
then, but you might find that you can live with it.
You can install ghostscript from the Skunkware CD; don't forget that
you also need the Glib (Graphics Library) package.
To see the printers that ghostscript supports, type
gs -?
You may have to experiment a bit to find out what works best with your
printer; for example I found that "ljet4" was good for my LaserJet 6L.
I suggest that you create a simple Postscript file for testing:
echo "testing" | text2post > /tmp/test.ps
so that you don't get page after page of junk if your first try
doesn't work.
My script looks like this:
#!/bin/sh
/usr/local/bin/gs -q -sDEVICE=ljet4 -r600 -sPAPERSIZE=letter -dNOPAUSE -dSAFER
-sOutputFile="-" - | lp -dlaser -o raw
I call that "webprint", and once you've told Netscape to use it
instead of "lp",that's what continues to pop up in the Netscape print
dialog.
Or, you can get fancy and build gs support into your interface script,
even to the point of automatically recognizing Postscript files. That
can be a little tricky, and really has no advantage over the shell
script, but some people like to do it that way.
[Table of Contents]
_________________________________________________________________
How can I make a device that will print to a network printer?
First, are you really sure you need to do this? Only very lame
software can't handle a spooled printer. However, if you must:
The basic concept is to create a named pipe. For example, you might do
this:
mknod /dev/myfakenetprint p
That creates a "device" that your application can print to. Use
"chmod" as necessary to give it whatever permissions you need (666 if
everyone needs to use it).
Now you need something that runs all the time in background. It's a
shell script (see New to Unix if you don't know how to make a shell
script) and it needs to start automatically whenever the machine is
rebooted (see Automating Program Startup). This script assumes that
your network printer already exists in the spooler:
while true
do
cat /dev/myfakenetprint | lp -dmyrealnetprinter
done
You could also use hpnpf or netcat (see Network Printing ) directly:
while true
do
cat /dev/myfakenetprint | netcat -h printername -p 3001
done
These work because the "cat" will hang until something (your
application) writes data to the named pipe. The "lp" won't complete
until cat is done reading, which will be when your application closes
its writing. Although it might look like this ties up your cpu, it
doesn't- the cat sleeps while it hangs, and so does lp or netcat:
there's nothing going on until you write data to the named pipe.
[Table of Contents]
_________________________________________________________________
How do I stop extra form feeds that spit out blank pages?
The concept here is the same as for getting rid of banners and
trailers, but the scripts are even less standardized. The best place
to look is in the section that (usually) starts with:
for file in $files
Following that maybe a line that does:
echo "\f"
or perhaps:
echo "\014"
or (less likely):
echo "^L"
and sometimes something obvious like:
echo "$formfeed"
Your job is to stop that formfeed from echoing. Some of the more
complex scripts even have a whole separate formfeed program that they
call. Whatever it is, if it's controlled by a variable set earlier in
the script (most scripts are this way, including the Laserjet
scripts), you should change that variable.
Remember that HP Jet Direct printers have the real script in
model.orig (see the first section of this article) and that you need
to modify the models if the change is to be safely permanent.
Examples: the "dumb" and "hp" models have this code around line 100:
for file in $files
do
0<${file} eval ${FILTER} 2>&1
echo "\014\c"
done
You'd need to remove the "echo "\014\c" line, or comment it out:
# echo "\014\c"
There's another "echo" a few lines above; this is the one that spits
out before your print job.
However, in the "standard" model, you'll find this around line 289:
nobanner="no"
nofilebreak="no"
Just as you would change "nobanner" to "yes" to stop banners, you
change "nofilebreak" to "yes" to prevent extra blank pages. Hans
Fuller (
[email protected]) reminds me that if an HP script isn't
already doing an echo "\033E\c" , you should replace the "\f\c" with
that to reset the printer.
[Table of Contents]
_________________________________________________________________
How do I make a printer send a form feed at the end of the job?
Sometimes people complain of the opposite problem: they want form
feeds and aren't getting them. The answer for this is just the
opposite of what was covered above: either add "\f" at an appropriate
place or, if the interface has settings for filebreaks, use that.
[Table of Contents]
_________________________________________________________________
How do I stop a print job and restart it from the beginning?
When pages jam, it is sometimes a major job to re-print the job.
Fortunately, it's pretty simple to starts a job over if it has not
already all spooled into the printer's buffer.
The very first thing to do is turn the printer OFF-LINE. That's
usually done with a ON-LINE or SELECT button.
Now type "disable printer", or "disable hallway", or whatever the name
of your printer is.
Now turn the printer OFF. This will flush out whatever is in it's
buffer. Turn it back on, and adjust the top of form on tractor feed
models if necessary. Finally, "enable printer", again, using the name
of your printer.
(If you don't know the name, "lpstat -t | more" should help you).
[Table of Contents]
_________________________________________________________________
How can I get the file from the print spooler before it prints?
Sometimes you want the results of a print job so that you can e-mail
it to someone else, import it into a Word Processing document or
whatever. This is simple to do.
Put the printer OFF-LINE as described above. Alternately, if you have
not yet printed, "disable" the printer (see above). Now
cd /usr/spool/lp/temp
l [0-9]*-* | more
You will see something like this:
rw-rw---- 1 lp lp 71 Dec 1 09:15 178-0
rw-rw---- 1 lp lp 83 Dec 1 09:16 179-0
rw-rw---- 1 lp lp 7809 Dec 1 09:15 179-1
Your dates and sizes will be different, as will the names of the
files.
These files are information about what is to be printed and how. For
example, if you looked at that 178-0 file on my machine, you'd find it
contained:
C 1
D myprinter
F /etc/passwd
P 20
t simple
U root
s 0000
l C_C.C
m C_C.C
while the 179-0 had this in it:
C 1
D myprinter
F /usr/spool/lp/temp/179-1
P 20
t simple
U root
s 0000
l C_C.C
m C_C.C
Notice the difference between the two. You might have already guessed
that the "C" line is the number of copies, the "D" is the printer it's
going to print on, and the "U" is the user who printed it. The "F" is
the file that will be printed, and if it was generated as the result
of program output (as opposed to "lp /etc/termcap"), it will refer to
another file in this directory.
If you have more than one print job, you might not know which file is
the one you want. If the size of the -1 files combined with the
destination and user isn't enough to help you, then examine each -1
file in turn. Once you have what you want, copy the file wherever you
want it. If you don't want it to print after that, cancel it. For
example, I might say:
cp /usr/spool/lp/temp/179-1 /tmp/printfile
cancel myprinter-179
[Table of Contents]
_________________________________________________________________
What is a virtual printer?
You can have a printer that sends its output to another printer; pipe
the final output to lp -s -dotherprinter You'll probably want the
first printer's device to be /dev/null, but consider that it does not
have to be: you can have a printer that prints to multiple places at
the same time.
This scheme can be very useful for network printers that use lpd.
Rather than trying to pass options through, front end with a script
that does whatever needs to be done (like running it through
/usr/lib/lponlcr) and then passes it to the lpd printer.
This is how you do "virtual" printers: many names all going to the
same print device, but all with diferent options. This is often easier
than handling all the testing for different switches inside one
interface, and it gives you mnemonic names like "HPLandscape",
"HPLetterTray", etc.
The easiest model to use for that is the "network" script. Let's say
you want to actually send to "kyocera":
cp /usr/spool/lp/model/network
/usr/spool/lp/model/yourscript
vi /usr/spool/lp/model/yourscript
(add whatever you need and then)
/usr/lib/lpadmin -p wrapit -m yourscript -v /dev/null
/usr/lib/accept wrapit
enable wrapit
echo "wrapit: lp -dkyocera" >> /usr/spool/lp/remote
Now when you print to "wrapit", it will go to the kyocera carrying
whatever you added in the script.
[Table of Contents]
_________________________________________________________________
How can different users have different default printers?
Sometimes you want a person's default printer to be different than
someone else's (the default printer is the one that gets used when you
just use "lp" by itself). One way to control that is with LPDEST. For
example, the following lines in .profile will set the default
differently when logging in on different tty's:
DEFPRINT=`tty | sed 's/.dev.tty//'
LPDEST=biglaser; export LPDEST
case $DEFPRINT in
A0[1-8]) LPDEST=printer_7;;
A09) LPDEST=accounting;;
0[1-9]) LPDEST=console_laser;;
B*) LPDEST=ohio;;
C*) LPDEST=california;;
esac
This assumes that the port being used determines the persons physical
location. Sometimes you need to be even trickier than that, or you
want to change multiple "printers" at the same time. Consider the case
where you have multiple offices, but you want to have your software
just use "checks" and "forms" so that the choices it presents aren't
cluttered with entries like "la_forms", "denver_checks", etc. To do
this, you need to front-end the lp program itself- you have a script
that pretends to be "lp", but it decides where the job should really
go and passes that to the real "lp" program. When it saw a request to
print to "forms", it would decide what real printer to send to, and
re-route it appropriately. Here's a post from Bill Vermillion
describing a similar idea:
Newsgroups: comp.unix.sco.misc
Path: news.randori.com!feed2.onemain.com!feed1.onemain.com!isdnet!skynet.be!oa
news!info.usuhs.mil!uky.edu!news.xenitec.on.ca!news
From: Bill Campbell <
[email protected]>
Subject: Re: How do I set default printers?
Resent-From:
[email protected]
Submit-To:
[email protected]
Content-Type: text/plain; charset=us-ascii
Reply-To:
[email protected]
Organization: [resent by] The SCOMSC gateway and Propagation Society
Date: Fri, 28 Apr 2000 18:17:50 GMT
Message-ID: <
[email protected]>
Mime-Version: 1.0
In-Reply-To: <
[email protected]>; from
[email protected]
nta-cruz.ca.us on Fri, Apr 28, 2000 at 10:52:04AM -0700
References: <
[email protected]> <yJjO4.10289$9A6.56
[email protected]> <
[email protected]>
Sender:
[email protected] (xenitec.on.ca News Administrator)
Precedence: list
Lines: 55
Xref: news.randori.com comp.unix.sco.misc:59126
X-Mozilla-Status: 8010
X-Mozilla-Status2: 00000000
On Fri, Apr 28, 2000 at 10:52:04AM -0700, Jeff Liebermann wrote:
>On Fri, 28 Apr 2000 17:18:22 GMT, "jmt" <
[email protected]> wrote:
>
>>I forgotten to mention if the running application has the printer name
>>hardcoded into there application to which printer to print to, how can I
>>change that printer? I know what the printer name is, just need to redirect
>>there print job to another printer name.
>
>If your unspecified application has something like:
> lp -d printer_name
>imbedded in some configuration file, then you're stuck. It takes priority
>over $LPDEST and over the print spoolers default printer.
>
>However, I know of no application, written by mortals, that cannot be
>twisted into doing what I want it to do. First, find the configuration file
>that goes with your unspecified application, and see if you can find the
>place where the printer is defined. If it looks like:
I have a system that does exactly that. I have a file, /etc/printers
that has entries mapping logical printer names to real printer names,
and the system on which to print them. The file looks like this:
default laser localhost
laser laser localhost
oldprn printer someotherhost
...
I then have /usr/local/bin/lp that's in the PATH before /usr/bin/lp
and further I move the original /usr/bin/lp to /usr/bin/lp.original,
and link it to /usr/local/bin/lp to make sure that everybody uses it.
My script then reads the /etc/printers file, and maps the printer name
to the real printer. If the printer's local, then it forwards the job
to the local with a pipe to ``/usr/bin/lp.original -ddestination''.
If it's a different system, then it pipes to the remote system using:
"|ssh someotherhost /usr/local/bin/lp @ARGV"
This is in perl so it passes the appropriate arguments to the remote
system's /usr/local/bin/lp program which goes through exactly the same
process. It would even be possible to have the job get in a loop if
each system redirected the job to the other (I suppose this could be
done intentionally if there were a printer problem, breaking the loop
when the printer was working again :-).
The code you use to decide where to re-route can be as simple or as
complex as you need it to be. It can be based on the serial port, or
you could have exported an environment variable. You might even need
to ask the user in their .profile which "set" of printers they want to
use, or where they are presently located. Store that information in a
variable and export it.
[Table of Contents]
_________________________________________________________________
How do I stop staircase output on the printer?
Staircase is when you printer prints like this:
Everything starts out OK, but when you reach
the end of a line, it moves
down
but not back
This is caused by the different ways that DOS and Unix handle the end
of a text line. Unix ends a line with a LF (Line Feed, 0x0A)
character, while DOS uses both a LF and a CR (Carriage Return, 0x0D).
If a printer is expecting both characters, getting only a LF tells it
to only do a Line Feed without a Carriage Return, so that's just what
it does, and that's just what you get.
There are at least five ways to fix this:
* Change the printer so that it generates a CR when it gets a line
feed. Most printers can do this, and if you use it for DOS, it
just means there is an "extra" CR, which changes nothing. This is
done with dip switches or a printer configuration panel.
* Change the printer by sending it whatever escape sequences it
needs to add CR's to LF's. This is going to vary, and you are
going to need to add it in the interface script low enough that it
doesn't get reset by some other command being sent out.
* Set the "stty onlcr opost" in the interface script. This can be
done from the printer manager on Release 4 and 5, or by using the
"crnlmap" model; unfortunately it does not always work (for
example, it can't work for network printers). See:
http://www.aplawrence.com/Unixart/netprint.shtml
* Move the "stty onlcr opost" to a "hold-open" script (see the
article on serial printers) for this port. This works, but it's
annoying, and again won't work for network printers.
* Filter the output through /usr/lib/lponlcr. This involves piping
the output through that on it's way out. In the "standard" script,
you might set "FILTER=/usr/lib/lponlcr". In other scripts, just
add " | /usr/lib/lponlcr" on the line that cats the file.
* If you are using an HP network printer, you can add "-n" or even
"-N" to the the interface.
Don't add it to the "HPNPF=" line; add it in the line(s) that
actually uses $HPNPF. For example, you'd change
if $REALMODEL "$@" | $HPNPF -x $PERIPH 2> $LOG > /dev/null
to
if $REALMODEL "$@" | $HPNPF -x $PERIPH -n 2> $LOG > /dev/null
See man hpnpf
David DiPieto offered these thoughts:
Date: Tue, 29 Dec 1998 16:05:40 -0500
From: David DiPietro <
[email protected]>
To:
[email protected]
Subject: printer stairstepping ...
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
I thought I'd share a little opost experience with you. When I install
our application software I automatically add a "holdopen" for each
parallel and serial printer to append the <cr> to <lf> as you mention in
your printer discussion. Most of our sites now involve some kind of
networking and printer sharing. I had been putting the high-speed
lasers on the parallel ports on the SCO Unix server but starting having
a problem with Windows applications printing graphics. I would often
loose data or get garbled graphics. I finally decided to take the time
to figure out what was going on using the hex dump mode on a Lexmark
Laser. Apparently, and with understanding, having opost onlcr turned on
will do a straight binary filter of the printer data replacing all <nl>
with <cr><nl> - even if it occurs in the middle of a raster graphics
string. This could - and will most likely - reak havoc on the output!
You may want to address this in your discussion. In my case, the
problem was solved completely by turning on the auto <cr> at the
printer.
Dave DiPietro/Abacus Systems Inc.
(973) 875-9900
[Table of Contents]
_________________________________________________________________
My printer doesn't work at all!
The first test is whether or not you can print to the raw device (if
this is a network printer, see Network Printers). If you aren't sure
about how the printer handles line feeds, do this:
/usr/lib/lponlcr > /dev/lp0
(assuming that your printer is /dev/lp0, of course). Type a few lines,
and then press enter and CTRL-D. If it gets to the printer, then the
port is fine.
The port does show up in "hwconfig", doesn't it? Type "hwconfig | grep
parallel" or "grep serial" just to be sure. If it doesn't, you either
never defined it (run "mkdev serial" or "mkdev parallel") or the
definition is wrong: for example, you said it's a parallel port at
378, but it's actually at 278.
If this is a parallel printer, be sure that your BIOS has it set to
"Standard Parallel Port" (sometimes it's "SPP"). If it's EPP, it will
not work with current SCO Unix.
Similarly, there are some "Windows Only" printers that require EPP
ports and Windows software- those just are not going to work, period.
See Windows Printers for one way around this.
Note : Okidata serial printers require DSR Invalid when using 3 wire
xon/xoff flow control. Set this on the printer, using the front panel
menus.
If it just hangs, the interrupt is wrong or the card just plain
doesn't work (and no, "it works in DOS" doesn't help). It's probably
an interrupt problem; the port is never acknowledging receipt of
characters so it hangs.
Understand that the "vec=" info in hwconfig for non pnp devices is
just a parroting of what YOU told the machine the interrupt is. The lp
or serial driver trusts you, but it doesn't really have a clue. It
checks the address (378, etc.) by poking certain patterns into certain
offsets and then reading the results; if the results are what a
parallel or serial port should be sending, then it assumes it has a
working port (see
http://www.aplawrence.com/Unixart/driverart.shtml if
you really want to know the gory details). Whether or not the port
works otherwise is not the job of the initialization routine, and it
definitely is not going to check that interrupts are working or even
correct.
Of course, you could have a bad cable, or even a bad printer. I had a
customer recently who spend half of a day being very frustrated after
an upgrade because he'd done everything right, had double and triple
checked everything, but one printer wouldn't print. I suggested
putting another printer in, and, yep, that was it: a printer that
worked fine the day before had coincidentally died.
Check power, too: I once had a printer that would turn on; the panel
lights worked and all that, but it wouldn't print. It turned out that
we had only 80 volts at the outlet, and it wasn't enough to drive the
motors (this was some years ago).
[Table of Contents]
_________________________________________________________________
Can I use "Windows" printers?
You could also use Visionfs or Samba, but there are now Windows
printers that require Windows software and those won't work even that
way. These are generally less expensive units, and won't mention Dos
or Macintosh or anything but Windows in their descriptions. At this
moment, I don't know any way to have these work on Unix, but I did
receive a great suggestion on this:
Date: Tue, 29 Dec 1998 16:05:40 -0500
From: David DiPietro <
[email protected]>
Reply-To:
[email protected]
Organization: Abacus Systems Inc
To:
[email protected]
Subject: HOST BASED PRINTERS
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
I was looking for a solution to an lpstat hang problem in SCO unix with
TCP based printer server and I noticed you have a remark that you could
not get the "cheapo" windows printers to work from Unix. I had a
conversation with an engineer at Lexmark recently about this.
Apparently, due to some quirk in the HP PCL licensing agreements,
printer manufacturers must pay HP a royalty if they use PCL code in the
printer firmware. If they use an emulation in the driver, however, they
do not have to pay the royalty. So, manufacturers like Lexmark and
Cannon have developed their own machine language to communicate between
windows and the printer. The windows driver converts the HP PCL
commands to their own machine language and uses that to drive the
printer. Since the driver is specific to windows, the printer will not
work under any other operating system - including DOS. A sure fire way
to check is to boot the machine to DOS and try a print-screen. Note
that if you shell to DOS it will still print because the windows print
manager is still resident. All this to save a few bucks!
I did find a way around this using a shared drive and an emulator that
lets you submit DOS commands from the Unix host. We use a product from
April Designs in Sweden called Fusion95 to take the place of Advanced
File and Printer Server, and an emulator called ANITA from the same
company. If you have never seen these products, check out APRIL.SE -
they have 30 day trial versions available for download.
The way I get this to work is by modifying the standard or dumb model to
put the output in a shared directory on the server. When the file is
done spooling, I issue a DOS COPY command to the emulator to COPY the
file to the printer port. Since windows is active, the print manager
picks up the file and does the proper translation to machine code before
sending it to the printer.
In the real world, I do not recommend that our users buy these host
based printers to use with Unix. It would cost us more to support them
than the printers are worth. With REAL laser's coming down in price,
why bother!
I hope I was able to provide you with some information you didn't
already have!
Happy Holidays,
David DiPietro/Abacus Systems Inc.
Sussex, NJ (973) 875-9900
[Table of Contents]
_________________________________________________________________
My printer faults and prints same document over and over
The only time I've seen this happen is when some very old interface
scripts were copied up to a new version. I never took the time to look
at the scripts to see why they weren't working, but apparently they'd
hang for some reason, so lp would assume a printer fault, stop the
job, wait a bit, and then send it again. And again, and again..
Replacing the interfaces with current versions fixed it instantly.
[Table of Contents]
_________________________________________________________________
Mixing Synchronics and Realworld or other mixed marriages
Sometimes mixing more than one program causes printer grief because
one program adds form feeds to its reports and the other does not, so
you have a nasty problem. It's usually not all that hard to fix,
though; here's what I did for one customer with that problem:
Synchronics spooled printers are defined in the "synsuppl" file in the
Synchronics directory (/syn on ssirw1). These take the form of:
dd_printername="lp -s -dhpjet5"; export dd_printername
What I did was add "-o syn" to each line:
dd_printername="lp -s -o syn -dhpjet5"; export
dd_printername
Next, I modified the interface scripts. For the hpjet printers, these
are found in the directory
/usr/spool/lp/admins/lp/interfaces/model.orig/ Each file there is the
script that print jobs are processed by. Within the scripts, the
options are extracted by a section that begins:
for i in $5
do
case "$i" in
-postscript | postscript)
format="PS"
outputmode="raw";;
I added a test for "syn" to this:
for i in $5
do
case "$i" in
syn)
outputmode="raw" ;
FILTER="sed '$d'";
SYN="true";;
-postscript | postscript)
format="PS"
outputmode="raw";;
Therefore the script acts this way ONLY if "-o syn" is used, which
will only be for Synchronics. Further on in the script, I added a
section that tests for $SYN being true, and there I set the lines per
page to 66. Finally, the FILTER setting above deletes the very last
line of the report, which contains an extra form feed I don't think we
want. To disable this, just change
syn)
to
notsyn)
[Table of Contents]
_________________________________________________________________
How do I do Transparent or pass-through printing?
Many terminals, and just about all terminal emulators, have the
ability to do "local" printing. It's sometimes called "transparent
printing" or "pass-through", but the idea is that if the terminal sees
a special key sequence, it will start sending the data out some other
port (parallel or serial) until it sees some sequence that tells it to
stop.
In general terms, it's a lousy way to print. If you can possibly do
this any other way, you'll be much better off.
If you have an intelligent multiport card serving these terminals, the
vendor may have provided a way to make this better (still not great,
but definitely much better). Digiboard, for example, creates
transparent print devices that match your tty id's- if you have
terminals /dev/ttyb01 through /dev/ttyb16, you also have /dev/prb01
through /dev/prb16, and as long as you have told the Digiboard driver
what escape sequence will start and stop the printing (common terminal
types like ansi and wyse60 are configurable by name), the driver will
do a nice job of handling this for you: anything directed at those
"pr" ports will get printed.
If you don't have something like this, you use commands like "lprint"
(SCO OSR5) or you wrap your data in the start-stop sequences yourself.
[Table of Contents]
_________________________________________________________________
How can I add or remove printers from the command line?
The "lpadmin" command can add printers without using SCOAdmin:
/usr/lib/lpadmin -p printer1 -v /dev/lp -m HPLaserJet
/usr/lib/accept printer1
enable printer1
/usr/lib/lpadmin -d printer1
adds a new printer named "printer1" which prints to the parallel port
and uses the "HPLaserJet" model. "lpadmin -d" makes it the default
printer.
/usr/lib/lpadmin -x printer1
removes the printer "printer1".
There are other options to lpadmin; see the man page.
Xenix printers can be transferred with a script like this (which
assumes that the Xenix hierarchy is located under "/xenixsys"):
cd /xenixsys/usr/spool/lp/member
for i in *
do
# make sure we aren't overwriting an existing model
if test -r /usr/spool/lp/model/$i
then
echo "Model $i already exists"
else
cp ../interface/$i /usr/spool/lp/model
/usr/lib/lpadmin -p $i -v `cat $i` -m $i
/usr/lib/accept $i
enable $i
fi
done
[Table of Contents]
_________________________________________________________________
Some print jobs from my application fail mysteriously.
If the application prints temporary files, you may need to change it
so that it does an "lp -c" rather than just "lp". This forces lp to
make a copy of the file immediately.
[Table of Contents]
_________________________________________________________________