Annotation of wikisrc/guide/print.mdwn, revision 1.1

1.1 ! jdf 1: # Printing
! 2:
! 3: This chapter describes a simple configuration for printing, using an HP Deskjet
! 4: 690C printer connected to the first parallel port and the lpd printing system
! 5: that comes with NetBSD. First, the system will be configured to print text
! 6: documents, and next the configuration will be extended to print PostScript
! 7: documents using the Ghostscript program
! 8: ([`print/ghostscript`](http://ftp.NetBSD.org/pub/pkgsrc/current/pkgsrc/print/ghostscript/README.html)). ! 9: Please note that there are other, alternative printing systems available from
! 10: the [packages collection](http://www.NetBSD.org/docs/software/packages.html), ! 11: like LPRng
! 12: ([`print/LPRng`](http://ftp.NetBSD.org/pub/pkgsrc/current/pkgsrc/print/LPRng/README.html)) ! 13: and the Common Unix Printing System (CUPS)
! 14: ([`print/cups`](http://ftp.NetBSD.org/pub/pkgsrc/current/pkgsrc/print/cups/README.html)) ! 15: which are not covered here.
! 16:
! 17: ## Enabling the printer daemon
! 18:
! 19: After installation it is not yet possible to print, because the
! 20: [lpd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?lpd+8+NetBSD-current) printer
! 21: spooler daemon is not enabled. To enable `lpd`, one line in the `/etc/rc.conf`
! 22: file must be changed from:
! 23:
! 24: lpd=NO
! 25:
! 26: to
! 27:
! 28: lpd=YES
! 29:
! 30: Or rather, insert it, it won't be in your `rc.conf` by default.
! 31:
! 32: The change will come into effect at the next boot, but the daemon can be started
! 33: manually now:
! 34:
! 35: # sh /etc/rc.d/lpd start
! 36:
! 37: To check if lpd is active, type the following command:
! 38:
! 39: # ps ax | grep lpd
! 40: 179 ?? Is 0:00.01 lpd
! 41:
! 42: If you don't see an entry for lpd in the output of the previous command, the
! 43: daemon is not active.
! 44:
! 45: The lpd system is configured via `/etc/printcap`. Before configuring
! 46: `/etc/printcap` it is a good idea to make a printer test, to check if the
! 47: physical connection between your computer and the printer is working. The test
! 48: sends out some data directly to the printer device. Assuming you use a printer
! 49: connected to the parallel port, this is `/dev/lpt0`; if you use an USB printer
! 50: try `/dev/ulpt0`. Please check the manpages of these devices
! 51: ([lpt(4)](http://netbsd.gw.com/cgi-bin/man-cgi?lpt+4+NetBSD-5.0.1+i386), ! 52: [ulpt(4)](http://netbsd.gw.com/cgi-bin/man-cgi?ulpt+4+NetBSD-5.0.1+i386)) ! 53: for more information!
! 54:
! 55: In our example we have a printer attached to the parallel port, so we run this:
! 56:
! 57: # lptest 70 5 > /dev/lpt0
! 58:
! 59: To see what the output should look like, try the same command without
! 60: redirecting the output to the printer:
! 61:
! 62: # lptest 70 5
! 63: !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdef
! 64: "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefg
! 65: #$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefgh
! 66: $%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghi
! 67: %&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghij
! 68:
! 69: A frequent problem is that the output on the printer is not correctly aligned in
! 70: columns but has a "staircase" configuration. This usually means that the printer
! 71: is configured to begin a new line at the left margin after receiving both a
! 72: `<CR\>` (carriage return, ASCII 13) character and a `<LF\>` (line feed, ASCII
! 73: 10) character. NetBSD only sends a <LF\> character. You can fix this problem in
! 74: two ways:
! 75:
! 76: * by changing the configuration of the printer
! 77: * by using a simple printer filter (described later)
! 78:
! 79: *Note*: In the previous example the lpd spooler is not involved because the
! 80: program output is sent directly to the printer device (`/dev/lpt0`) and is not
! 81: spooled.
! 82:
! 83: ## Configuring `/etc/printcap`
! 84:
! 85: This section explains how to configure the example printer to print text
! 86: documents.
! 87:
! 88: The printer must have an entry in the `/etc/printcap` file; the entry contains
! 89: the printer id (the name of the printer) and the printer description. The
! 90: [lp(1)](http://netbsd.gw.com/cgi-bin/man-cgi?lp+1+NetBSD-current) ! 91: id is the default used by many programs. Here is an example entry:
! 92:
! 93: **Example `/etc/printcap`**
! 94:
! 95: lp|local printer|HP DeskJet 690C:\
! 96: :lp=/dev/lpa0:sd=/var/spool/lpd/lp:lf=/var/log/lpd-errs:\
! 97: :sh:pl#66:pw#80:if=/usr/local/libexec/lpfilter:
! 98:
! 99: The file format and options are described in detail in the
! 100: [printcap(5)](http://netbsd.gw.com/cgi-bin/man-cgi?printcap+5+NetBSD-5.0.1+i386) ! 101: manpage. Please note that an *input filter* has been specified (with the `if`
! 102: option) which will take care of eliminating the staircase problem:
! 103:
! 104: if=/usr/local/libexec/lpfilter
! 105:
! 106: ### Printer driver and HP printers
! 107:
! 108: The example above uses the `lpa0` device (polled driver) for the printer,
! 109: instead of the `lpd0` (interrupt driven driver). Using interrupts there is a
! 110: communication problem with some printers, and the HP Deskjet 690C is one of
! 111: them: printing is very slow and one PostScript page can take hours. The problem
! 112: is solved using the `lpa` driver. It is also possible to compile a custom kernel
! 113: where lpt is polled.
! 114:
! 115: The printcap entry for the printer also specifies a spool directory, which must
! 116: be created; this directory will be used by the lpd daemon to accumulate the data
! 117: to be printed:
! 118:
! 119: # cd /var/spool/lpd
! 120: # mkdir lp
! 121: # chown daemon:daemon lp
! 122: # chmod 770 lp
! 123:
! 124: The only missing part is the `lpfilter` input filter, which must be written. The
! 125: only task performed by this filter is to configure the printer for the
! 126: elimination of the staircase problem before sending the text to be printed. The
! 127: printer used in this example requires the following initialization string:
! 128: `<ESC>&k2G`.
! 129:
! 130: **Example `/usr/local/libexec/lpfilter`**
! 131:
! 132: #!/bin/sh
! 133: # Treat LF as CR+LF
! 134: printf "\033&k2G" && cat && exit 0
! 135: exit 2
! 136:
! 137: After saving this script into the name you used in `/etc/printcap`, you need to
! 138: make sure it's executable:
! 139:
! 140: # chmod 755 /usr/local/libexec/lpfilter*
! 141:
! 142: *Note*: There is another filter that can be used:
! 143:
! 144: if=/usr/libexec/lpr/lpf:
! 145:
! 146: This filter is much more complex than the one presented before. It is written to
! 147: process the output of
! 148: [nroff(1)](http://netbsd.gw.com/cgi-bin/man-cgi?nroff+1+NetBSD-current) ! 149: and handles underline and overprinting, expands tab characters and converts `LF`
! 150: to `CR + LF`. The source to this filter program can be found in
! 151: `/usr/src/usr.sbin/lpr/filters/lpf.c`.
! 152:
! 153: After everything is in place now, the
! 154: [lptest(1)](http://netbsd.gw.com/cgi-bin/man-cgi?lptest+1+NetBSD-current) ! 155: command can be run again now, this time using the
! 156: [lpr(1)](http://netbsd.gw.com/cgi-bin/man-cgi?lpr+1+NetBSD-current) command,
! 157: which will first send the data to the lpd spooler, then runs the filter and
! 158: sends the data off to the printer:
! 159:
! 160: # lptest 70 5 | lpr -h
! 161:
! 162: The `lpr` program prints text using the spooler to send data to the printer; the
! 163: `-h` option turns off the printing of a banner page (not really necessary,
! 164: because of the `sh` option in `/etc/printcap`). Users more familiar with the
! 165: System V printing system can also use the
! 166: [lp(1)](http://netbsd.gw.com/cgi-bin/man-cgi?lp+1+NetBSD-5.0.1+i386) command
! 167: that comes as an alternative to
! 168: [lpr(1)](http://netbsd.gw.com/cgi-bin/man-cgi?lpr+1+NetBSD-5.0.1+i386). ! 169:
! 170: ## Configuring Ghostscript
! 171:
! 172: Now that basic printing works, the functionality for printing PostScript files
! 173: can be added. The simple printer used in this example does not support native
! 174: printing of PostScript files; a program must be used which is capable of
! 175: converting a PostScript document in a sequence of commands that the printer
! 176: understands. The Ghostscript program, which can be found in packages collection,
! 177: can be used to this purpose. This section explains how to configure lpd to use
! 178: Ghostscript to print PostScript files on the HP Deskjet 690C.
! 179:
! 180: A second id for the printer will be created in `/etc/printcap`: this new id will
! 181: use a different input filter, which will call Ghostscript to perform the actual
! 182: print of the PostScript document. Therefore, text documents will be printed on
! 183: the *lp* printer and PostScript documents on the *ps* printer: both entries use
! 184: the same physical printer but have different printing filters.
! 185:
! 186: The same result can be achieved using different configurations. For example, a
! 187: single entry with only one filter could be used. For this, the filter should be
! 188: able to automatically determine the format of the document being printed, and
! 189: use the appropriate printing program. This approach is simpler but leads to a
! 190: more complex filter; if you like it you should consider installing the
! 191: magicfilter program from the packages collection: it does this and many other
! 192: things automatically.
! 193:
! 194: For our approach, the new `/etc/printcap` file looks like this:
! 195:
! 196: **Example `/etc/printcap`**
! 197:
! 198: lp|local printer|HP DeskJet 690C:\
! 199: :lp=/dev/lpa0:sd=/var/spool/lpd/lp:lf=/var/log/lpd-errs:\
! 200: :sh:pl#66:pw#80:if=/usr/local/libexec/lpfilter:
! 201:
! 202: ps|Ghostscript driver:\
! 203: :lp=/dev/lpa0:sd=/var/spool/lpd/ps:lf=/var/log/lpd-errs:\
! 204: :mx#0:sh:if=/usr/local/libexec/lpfilter-ps:
! 205:
! 206: Option `mx#0` is very important for printing PostScript files because it
! 207: eliminates size restrictions on the input file; PostScript documents tend to be
! 208: very big. The `if` option points to the new filter. There is also a new spool
! 209: directory.
! 210:
! 211: The next steps are the creation of the new spool directory and of the filter
! 212: program. The procedure for the spool directory is the same as above:
! 213:
! 214: # cd /var/spool/lpd
! 215: # mkdir ps
! 216: # chown daemon:daemon ps
! 217: # chmod 770 ps
! 218:
! 219: The filter program for PostScript output is more complex than the text base one:
! 220: the file to be printed is fed to the interpreter which converts it into a
! 221: sequence of commands in the printer's control language, and then sends that off
! 222: to the printer. We have achieved to transform a cheap color printer in a device
! 223: suitable for PostScript output, by virtue of the NetBSD operating system and
! 224: some powerful freeware packages. The options used to configure Ghostscript are
! 225: described in the Ghostscript documentation: `cdj550` is the device used to drive
! 226: the HP printer.
! 227:
! 228: **Example `/usr/local/libexec/lpfilter-ps`**
! 229:
! 230: #!/bin/sh
! 231: # Treat LF as CR+LF
! 232: printf "\033&k2G" || exit 2
! 233: # Print the postscript file
! 234: /usr/pkg/bin/gs -dSAFER -dBATCH -dQUIET -dNOPAUSE -q -sDEVICE=cdj550 \
! 235: -sOutputFile=- -sPAPERSIZE=a4 - && exit 0
! 236: exit 2
! 237:
! 238: To summarize: two different printer names have been created on the system, which
! 239: point to the same physical printer but use different options, different filters
! 240: and different spool directories. Text files and PostScript files can be printed.
! 241: To print PostScript files the Ghostscript package must be installed on the
! 242: system.
! 243:
! 244: ## Printer management commands
! 245:
! 246: This section lists some useful BSD commands for printer and print jobs
! 247: administration. Besides the already mentioned `lpr` and `lpd` commands, we
! 248: have:
! 249:
! 250: * [lpq(1)](http://netbsd.gw.com/cgi-bin/man-cgi?lpq+1+NetBSD-current) ! 251: -- examine the printer job queue.
! 252: * [lprm(1)](http://netbsd.gw.com/cgi-bin/man-cgi?lprm+1+NetBSD-current) ! 253: -- delete jobs from the printer's queue.
! 254: * [lpc(8)](http://netbsd.gw.com/cgi-bin/man-cgi?lpc+8+NetBSD-current) ! 255: -- check the printing system, enable/disable printers and printer
! 256: features.
! 257:
! 258: ## Remote printing
! 259:
! 260: It is possible to configure the printing system in order to print on a printer
! 261: connected to a remote host. Let's say that, for example, you work on the *wotan*
! 262: host and you want to print on the printer connected to the *loge* host. The
! 263: `/etc/printcap` file of loge is the one of the last example. From wotan it will
! 264: be possible to print Postscript files using Ghostscript on loge.
! 265:
! 266: The first step is to accept the print jobs submitted from the wotan host to the
! 267: loge host. To accomplish this, a line with the wotan host name must be added to
! 268: the `/etc/hosts.lpd` file on loge:
! 269:
! 270: # hostname
! 271: loge
! 272: # cat /etc/hosts.lpd
! 273: wotan
! 274:
! 275: The format of this file is very simple: each line contains the name of a host
! 276: which is permitted to print on the local system. By default the lpd daemon only
! 277: listens on UNIX domain sockets for local connections, it won't accept any
! 278: network connects. To ensure the daemon also accepts incoming network traffic,
! 279: the following will need to be added to `/etc/rc.conf`:
! 280:
! 281: lpd_flags=""
! 282:
! 283: Next, the `/etc/printcap` file on wotan must be configured in order to send
! 284: print jobs to loge. For example:
! 285:
! 286: lp|line printer on loge:\
! 287: :lp=:sd=/var/spool/lpd/lp:lf=/var/log/lp-errs:\
! 288: :rm=loge:rp=lp
! 289:
! 290: ps|Ghostscript driver on loge:\
! 291: :lp=:sd=/var/spool/lpd/ps:lf=/var/log/lp-errs:\
! 292: :mx#0:\
! 293: :rm=loge:rp=ps
! 294:
! 295: There are four main differences between this configuration and the earlier one:
! 296:
! 297: 1. The definition of `lp` is empty.
! 298: 2. The `rm` (remote machine) entry defines the name of the host to which the printer is connected.
! 299: 3. The `rp` (remote printer) entry defines the name of the printer connected to the remote host.
! 300: 4. It is not necessary to specify input filters because the definitions on the loge host will be used.
! 301: 5. The spool directories must still be created locally on wotan:
! 302:
! 303: # cd /var/spool/lpd
! 304: # mkdir lp
! 305: # chown daemon:daemon lp
! 306: # chmod 770 lp
! 307: # mkdir ps
! 308: # chown daemon:daemon ps
! 309: # chmod 770 ps
! 310:
! 311: Now the print jobs for the `lp` and `ps` queues on wotan will be sent
! 312: automatically to the printer connected to loge.
! 313: