6.3. Printing to Printer Shares
A popular SMB/CIFS client feature on Linux is the ability to print to printers that are connected to Windows systems or to other systems that support SMB/CIFS printing. (Many dedicated print server appliances support SMB/CIFS printing, for instance.) Precisely how this task is accomplished depends on the software installed on your Linux system. One way that should always work, given an appropriately formatted file, is to use smbclient to submit a print job. You can also configure your Linux print queue to submit jobs to a remote server via SMB/CIFS, but the details vary with your local print queue. This section describes how to configure CUPS to configure an SMB/CIFS printer, as well as how to do the job with BSD LPD or LPRng.
6.3.1. Printing Using smbclient
If you have a one-time need to print to a Windows printer from Linux, you may want to consider using smbclient to do the job directly. As described earlier, smbclient is a basic text-mode tool for transferring files using SMB/CIFS. Many smbclient features and commands are modelled after those in text-mode FTP clients. One command in particular, though, is of interest here: print. Once you've started smbclient and connected to a print server, you can use this command to transfer a print job to the server. The transaction looks something like this:
$ smbclient //MANDRAGORA/HP4000 Password: Domain=[GREENHOUSE] OS=[Unix] Server=[Samba 3.0.3] smb: \> print myoutput.ps putting file myoutput.ps as myoutput.ps (29.8 kb/s) (average 29.8 kb/s) smb: \> quit
This operation is fairly straightforward for printing a single file (or even a few files), but it does have a few caveats. Most obviously, it requires that you have a file on hand. Most Linux programs that can print can also "print" to a file, so this requirement is seldom a problem. A more important caveat is that the file you submit (myoutput.ps in this example) must be in a format that the remote printer can parse. Most Linux programs generate PostScript output, so if you're printing to a PostScript printer, this will probably work fine. If the printer isn't a PostScript model, though, you may be in a bind. Many printers can handle ASCII (a.k.a. plain text) files, so if you want to print simple text (such as the output of an ls command), you may be fine; just put the information in a text file and submit it. For more complex data, you may need to use Ghostscript (gs) to convert PostScript to the remote printer's native format. For instance, to convert PostScript to PCL, which is used by many mid-range laser printers, you might type a command like this:
$ gs -dNOPAUSE -dBATCH -sDEVICE=ljet4 -sOutputFile=myoutput.pcl myoutput.ps
The -sDEVICE option sets the output driver; ljet4 stands for LaserJet 4one of Hewlett-Packard's (HP's) PCL printers (and for which one PCL version's Ghostscript driver is named). If you don't know what driver to use, you may need to check http://www.linuxprinting.org for advice, or at least type gs --help to obtain a list of drivers available in your Ghostscript executable. With luck, one of the abbreviations will be familiar to you.
Using smbclient directly can become tedious. If you need to print to an SMB/CIFS printer on a regular basis, you can configure your local Linux printing queue to do so automatically. To do so, manually configure a queue or use a configuration tool, as described in the next two sections.
6.3.2. Defining SMB/CIFS Printers Using CUPS
Most Linux distributions today ship with the Common Unix Printing System, which provides both local and remote printing services for Linux systems. Chapter 4 describes basic CUPS configuration, so if you're not already familiar with CUPS, you should consult the relevant section of that chapter before proceeding.
Configuring an SMB/CIFS printer from CUPS works much like configuring a local printer. Instead of selecting the local printer port (such as a parallel or USB port), though, you pick the "Windows Printer via SAMBA" option as the device. Once you do this, the CUPS GUI asks you for the printer device's uniform resource identifier (URI). In theory, this is the same as the share name, as delivered to smbclient and other tools, except that it's preceded by smb:. This basic form, though, works only with printers that are shared for anonymous users. If your printer share requires a username and password, you must add this information to the URI, so that it takes the form smb://username:password@NetBIOS-name/share-name. For instance, you might enter smb://linnaeus:bu9N!nEp@BIRCH/EPSON to print to the EPSON share on BIRCH using the linnaeus account and the password bu9N!nEp. Several variants on this form are possible; consult the smbspool manpage for details (smbspool is a part of the Samba package that helps CUPS by submitting the print job to the remote server). If you include a username and password in the device URI, they won't appear in subsequent pages of the CUPS web-based configuration tool; they're hidden from view, but used internally.
When printing to a printer on a Windows server, you should normally select a CUPS printer definition for the printer in question, as described in Chapter 4. This causes the Linux system to pass programs' output through Ghostscript, if necessary, and turn it into a form that's acceptable to the remote printer. If the server is a Linux or Unix system running Samba, though, a raw queue may work better than a printer-specific queue. This is true even for genuine PostScript printers and their printer-specific definitions; sometimes these definitions add lines to the PostScript file that can confuse the server's print queue and cause it to print PostScript code rather than the file you want to see. Of course, when printing from Linux to another Linux or Unix system, chances are you'll use Unix-centric printing protocols rather than SMB/CIFS, but you can use SMB/CIFS if you have some reason to do so.
6.3.3. Defining SMB/CIFS Printers Using LPRng or BSD LPD
Although CUPS has become the most popular printing package in Linux, some distributions still provide an option to use LPRng or even BSD LPD. These printing systems weren't designed with much thought for printing to non-LPD remote printers, but they can do so by bypassing the normal local printer queue and calling a remote-printing tool as part of a print filter. For instance, a normal local printer queue using LPRng or BSD LPD is defined by a set of lines in /etc/printcap:
lp|lp0|hp4000:\ :sd=/var/spool/lpd/hp4000:\ :mx#0:\ :sh:\ :lp=/dev/lp0:\ :if=/var/spool/lpd/hp4000/filter:
The if line defines an input filter for the queuea program that processes the print jobs for printing. Normally, this filter attempts to identify the file's type and passes it through programs such as Ghostscript to convert it to a format that's appropriate for the printer, whereupon the print job continues on to the output device specified by lp. To print to an SMB/CIFS printer, you instead point if at a program that delivers the print job to the remote queue, bypassing the lp line entirely.
Normally the task of submitting the print job to an SMB/CIFS queue is fairly complex: the submitted file's type must be identified, the file must be converted into a format suitable for the printer, and the file is delivered via an SMB/CIFS client program. Printer configuration tools can handle all these tasks. In the past, distributions such as Red Hat and SuSE shipped with distribution-specific tools for printer configuration. (These tools frequently called smbprint as part of their operation, but this detail was hidden from the user.) Most such tools have now been altered to configure CUPS rather than BSD LPD or LPRng, though, or omitted entirely in favor of CUPS web-based tools. If you're still using a non-CUPS print queue, you should check your distribution's documentation and look for options akin to those provided by CUPS.
If you've deliberately installed BSD LPD or LPRng on a distribution that normally uses CUPS, you may want to look into Apsfilter (http://www.apsfilter.org). This package is a set of configuration tools and smart filters that can identify various file types and apply appropriate transformations to them. Once you've installed Apsfilter, you should be able to launch its configuration utility by typing /usr/share/apsfilter/SETUP (the SETUP utility might exist in another directory on some systems, though). When you set up a queue, select the Windows/NT (Samba) option and then enter the appropriate information about the server's name, the queue name, etc.