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]
    _________________________________________________________________