Welcome to the new location of Alien's Wiki, sharing a single dokuwiki install with the SlackDocs Wiki.

Welcome to Eric Hameleers (Alien BOB)'s Wiki pages.

If you want to support my work, please consider a small donation:

no way to compare when less than two revisions

Differences

This shows you the differences between two versions of the page.


Previous revision
Next revision
slackware:cups [2006/11/08 20:56] alien
Line 1: Line 1:
 +====== Printing with CUPS ======
  
 +FIXME __this page is a work in progress__ FIXME
 +
 +CUPS (the //Common UNIX Printing System//) is now the default printing subsystem in Slackware, after years of faithful service by //lpr/lpd//.
 +CUPS has a browser-based graphical user interface (check out yours at [[http://127.0.0.1:631/|http://127.0.0.1:631/]]) for administering the service, like creating print queues, monitoring, deleting and restarting print jobs and such. CUPS servers in a network can be configured to talk to each other, so that printing from one CUPS machine (the client) to another CUPS machine (a CUPS server with attached printer) works automagically.\\
 +Not everything can be done through the graphical interface though. The basic initial setup of the CUPS service is still a matter of hand-editing certain configuration files.
 +
 +===== Setting up the CUPS service =====
 +
 +Slackware comes with a functional CUPS server out of the box. All you have to do is make the file ''/etc/rc.d/rc.cups'' executable and start the server. After that you can point your browser to [[http://127.0.0.1:631/|http://127.0.0.1:631/]] for the administratitive interface, and start adding printer queues. <code>
 +chmod +x /etc/rc.d/rc.cups
 +/etc/rc.d/rc.cups start
 +</code>
 +
 +==== /etc/cups/cupsd.conf ====
 +
 +==== Creating print queues ====
 +
 +==== Securing the admin web interface ====
 +
 +
 +===== Configuring CUPS clients =====
 +
 +TODO
 +
 +===== Making CUPS work with Samba =====
 +
 +TODO
 +
 +===== A PDF printer for CUPS =====
 +
 +Usually, the CUPS print queues will print to paper of course. But there are cases when you want an electronic image of some document, or web page, that you do not need on paper. The [[wp>PDF]] file format is the ideal candidate for this, since this format is supported on virtually all operating systems and architectures.\\ 
 +So, we need to add a print queue to CUPS which does not print our submitted jobs to paper sheets but instead generates a PDF file from our input, and makes this file available to us in some way.\\ 
 +This section describes exactly how to set this up, leaving the choice up to you whether you want your PDF files delivered to you via email, or have them dumped into a directory of your choice.\\ 
 +This setup uses no proprietary software to create the PDF files - all you need is already present on your Slackware machine. For those with several computers in a network, having a CUPS server to generate the PDF's has the additional advantage that it does not matter what the client computer is. Your Linux and Windows workstation, or your Mac, will be equally able to use this pdfprinter as long as your CUPS service allows job submissions from the network.
 +
 +If you are running a network server with Samba, your CUPS pdfprinter will be integrated into the Samba configuration if you tell it to use CUPS for printing support (which is the default behaviour anyway). Windows clients will be able to generate PDF's by using a Samba print queue.
 +
 +I came across an implementation of a PDF printer that supports CUPS and Samba. It can be found at [[http://www.linux-als-server.de/html/special-pdfprinter.php|http://www.linux-als-server.de/html/special-pdfprinter.php]]. My recipe below is based on the instructions found at that URL. Since the original text is in german, my article will help you non-german speaking persons setting this up I hope :-)
 +
 +==== Required software ====
 +
 +You will need to meet the following software requirements on your CUPS machine:
 +  * CUPS installed and configured (naturally)
 +  * GhostScript installed
 +Only if you want to deliver PDF files by email, you'll need these too:
 +  * Sendmail configured to deliver emails
 +  * Perl installed, with the additional module MIME::Entity. If you don't have MIME::Entity installed, you can compile it yourself (it is part of MIME::tools, which in turn requires the IO::stringy and Mail perl modules), or use the program [[http://software.jaos.org/#cpan2tgz|cpan2tgz]] to create Slackware packages for it yourself, or download my precompiled Slackware packages ([[http://www.slackware.com/~alien/slackbuilds/perl-modules/|in my repository]]).
 +
 +==== Installing a new CUPS backend ====
 +
 +CUPS uses so-called //backends// to support output to printing devices. Examples of these backends are //ipp//, //lpd// and //socket//; they show up in the CUPS URI that you define when creating a new CUPS print queue, for instance printing via IPP: "''ipp:%%//%%192.168.0.1/print/hp6''".\\ 
 +We are going to create a __new__ backend, which supports printing to PDF files and delivering these files to the correct end location (mailbox or directory path). The backend is going to be called **pdf** since that name is not yet being used.
 +
 +  * First off, let's start with creating the necessary directories (as root). The PDF files are going to be output to a temporary location (the //spool// directory) before being emailed to their final destination. We'll be using a new directory "''/var/spool/pdf''" for that, and make sure that everyone has write access there. If you do not want to use email delivery, this spool directory must be accessible by everyone who wants to use your pdfprinter. That means if you offer the pdfprinter as a network service to other computers in your network, you will have to export this spool directory using Samba or NFS. It is not within the scope of this article to describe how you would do that.\\ \\ The executables (in the form of Shell and Perl scripts) for the ''pdf'' backend are going to be stored in another new directory called ''/usr/lib/cups/pdf'': <code>
 +mkdir -p /var/spool/pdf
 +chmod 1777  /var/spool/pdf
 +mkdir /usr/lib/cups/pdf
 +chmod 775 /usr/lib/cups/pdf
 +</code> The ''chmod 1777 /var/spool/pdf'' makes ''/var/spool/pdf'' writable for everyone, plus sets the //sticky bit// which means that other users will be unable to delete files that they do not own themselves.
 +
 +  * Defining the new "pdf" backend is really no more than creating an executable file called "pdf" in CUPS's backends directory ''/usr/lib/cups/backend''. The "pdf" program in our case is a shellscript which you can find in the section below - [[#pdf_printer_scripts|PDF Printer Scripts]]. Do not forget to make the "pdf" script executable: <code>
 +chmod 755 /usr/lib/cups/backend/pdf
 +</code> This backend will in turn call two other scripts which we shall place in the library directory ''/usr/lib/cups/pdf'' - see next bullit point.
 +
 +  * All right, we will now create the two scripts that will do all the hard work for us. Install the two files "''ps2pdf.cups''" and "''sendpdf''" into the cups library directory which we just created: ''/usr/lib/cups/pdf''. You can find these scripts in the section below called [[#pdf_printer_scripts|PDF Printer Scripts]]. Do not forget to make these files executable: <code>
 +chmod 755 /usr/lib/cups/pdf/ps2pdf.cups
 +chmod 755 /usr/lib/cups/pdf/sendpdf
 +</code> The first script, ''ps2pdf.cups'' is seemingly derived from the ''ps2pdf'' script that came with an old version of GhostScript. It converts the PostScript input that CUPS generated for us into PDF output. The ''sendpdf'' script takes this PDF file and delivers it. By default, the version of the script as found in [[#pdf_printer_scripts|PDF Printer Scripts]] uses the ''sendmail'' program to deliver the PDF file to your inbox. It uses your logon name as the destination address, so if you have not setup local email delivery, you might be better off by editing the last part of the ''ps2pdf.cups'' script, commenting out the email delivery part and uncommenting the directory part. That piece of script would then look like this: <code>
 +## Normally the PDF file will be emailed to the creating user.
 +## Alternatively, you can decide not to email it,
 +## but leave the file on the server and restrict access by others:
 +#if [ "$2" != "" ]; then
 +#  $MAILBIN $2 $OUTPUTFILENAME
 +#  rm -f $OUTPUTFILENAME
 +#fi
 +if [ "$2" != "" ]; then
 +       chown $2 $OUTPUTFILENAME
 +       chmod 700 $OUTPUTFILENAME
 +fi
 +exit 0
 +</code> The thing to remember here, is that the output directory for the PDF files in this case is the directory name you are going to use with the ''lpadmin'' command when you create the print queue - see the last bullet point. Remember to make that directory writeable by everyone and also set the //sticky bit// by running <code>chmod 1777 /your/pdf/output_dir</code> just like I did for my example directory ''/var/spool/pdf''.
 +
 +  * CUPS uses //PPD// files (PostScript Printer Definition files) for outputting correctly formatted print data. For our PDF backend, we will need a PPD file that can output color information in PostScript format (if you prefer grey-scale PDF files, you should of course get an appropriate non-colour PPD file).\\ Adobe wrote a PPD file ''distiller.ppd'' which you can freely download [[http://www.adobe.com/support/downloads/detail.jsp?ftpID=141|at their web site]]. The Adobe site is often inaccessible, but fortunately there are many mirrors of that PPD file. Here is one: [[http://www.linux-als-server.de/download/destiller.ppd|destiller.ppd]]; note that this file is called "d**e**stiller.ppd" instead. \\ \\ Another (really free) PPD file can be found on the //cups-pdf// web site, where you can find another implementation of a CUPS PDF print solution which I have not yet tried. The URL to this PPD file is [[http://www.physik.uni-wuerzburg.de/~vrbehr/cups-pdf/cups-pdf-CURRENT/extra/PostscriptColor.ppd|PostscriptColor.ppd]] \\ \\ Save either of those files in the CUPS ppd-collection directory, under the name of ''/usr/share/cups/model/pdfcolor.ppd'' - the name does not really matter, you can keep the original filename if you wish, but I am using that name ''pdfcolor.ppd'' in the rest of this example as well. CUPS PPD files are gzipped - probably to save space. It is not a requirement to do so for our own PPD file, but we will do it anyway: <code>
 +gzip /usr/share/cups/model/pdfcolor.ppd</code> This creates the file ''/usr/share/cups/model/pdfcolor.ppd.gz'' which we will use in the ''lpadmin'' command further down.
 +
 +  * Finally, we need to restart the CUPS service to activate our new ''pdf'' backend, so we can create our pdfprinter queue . <code>
 +/etc/rc.d/rc.cups restart
 +</code>
 +
 +  * Using the commandline tool ''lpadmin'' we create a new CUPS print queue for our PDF backend. <code>
 +lpadmin -p pdfprinter -v pdf:/var/spool/pdf/ -D "Generate PDF files" -E -P /usr/share/cups/model/pdfcolor.ppd.gz
 +</code> This creates the print queue called **pdfprinter** using the **pdf** backend, with the directory **/var/spool/pdf** to generate PDF files in, and it will use **/usr/share/cups/model/pdfcolor.ppd.gz** as the PPD file for this printer definition.\\ \\ If you want to add the printer queue through the CUPS web interface, you should pick "//PDF Creator//" as the device and "//Adobe | Adobe Distiller//" as the Model/Type of the printer.
 +
 +We're ready! The PDF printer setup is complete.
 +
 +
 +==== Using the PDF printer ====
 +
 +Client computers (or you on your local computer) can create a PDF file of any printable data, by just printing to the CUPS print queue "//pdfprinter//". Linux client computers on the network which have CUPS configured as a client, will pick up the CUPS server automatically (CUPS services talk among each other on the network) so this will all work completely transparently.
 +
 +If you have a network with Windows computers, the best thing is to setup a Samba server on the CUPS server and let Samba use CUPS for printing. That way, our "pdfprinter" will automatically become available to these Windows computers as a network printer. Windows machines should install this network printer queue using a //Generic PostScript// driver. 
 +
 +
 +===== PDF Printer Scripts =====
 +
 +  * Script ''/usr/lib/cups/backend/pdf'' <file>
 +#!/bin/sh
 +# -------------------------------------------------------------------
 +# "/usr/lib/cups/backend/pdf":
 +# -------------------------------------------------------------------
 +#
 +PDFBIN=/usr/lib/cups/pdf/ps2pdf.cups
 +MAILBIN=/usr/lib/cups/pdf/sendpdf
 +FILENAME=
 +# filename of the PDF File
 +PRINTTIME=`date +%Y-%m-%d_%H.%M.%S`
 +# no argument, prints available URIs
 +if [ $# -eq 0 ]; then
 +  if [ ! -x "$PDFBIN" ]; then
 +    exit 0
 +  fi
 +  echo "direct pdf \"Unknown\" \"PDF Creator\""
 +  exit 0
 +fi
 +# case of wrong number of arguments
 +if [ $# -ne 5 -a $# -ne 6 ]; then
 +  echo "Usage: pdf job-id user title copies options [file]"
 +  exit 1
 +fi
 +# get PDF directory from device URI, and check write status
 +PDFDIR=${DEVICE_URI#pdf:}
 +if [ ! -d "$PDFDIR" -o ! -w "$PDFDIR" ]; then
 +  echo "ERROR: directory $PDFDIR not writable"
 +  exit 1
 +fi
 +# generate output filename
 +OUTPUTFILENAME=
 +if [ "$3" = "" ]; then
 +  OUTPUTFILENAME="$PDFDIR/unknown.pdf"
 +else
 +  if [ "$2" != "" ]; then
 +    OUTPUTFILENAME="$PDFDIR/$2-$PRINTTIME.pdf"
 +  else
 +    OUTPUTFILENAME="$PDFDIR/$PRINTTIME.pdf"
 +  fi
 +  echo "PDF file: $OUTPUTFILENAME placed in: $PDFDIR" >> $LOGFILE
 +fi
 +# run ghostscript
 +if [ $# -eq 6 ]; then
 +  $PDFBIN $6 $OUTPUTFILENAME >& /dev/null
 +else
 +  $PDFBIN - $OUTPUTFILENAME >& /dev/null
 +fi
 +
 +# Make the file visible (but read-only except for owner);
 +# This is only needed when the username ($2) is not set,
 +# for instance when printing a test page from the web interface.
 +chmod 644 $OUTPUTFILENAME
 +
 +## Normally the PDF file will be emailed to the creating user.
 +## Alternatively, you can decide not to email it,
 +## but leave the file on the server and restrict access by others:
 +if [ "$2" != "" ]; then
 +  $MAILBIN $2 $OUTPUTFILENAME
 +  rm -f $OUTPUTFILENAME
 +fi
 +#if [ "$2" != "" ]; then
 +#       chown $2 $OUTPUTFILENAME
 +#       chmod 700 $OUTPUTFILENAME
 +#fi
 +exit 0
 +
 +# EOF
 +# -------------------------------------------------------------------
 +</file>
 +
 +
 +  * Script ''/usr/lib/cups/pdf/ps2pdf.cups'' <file>
 +#!/bin/sh
 +# -------------------------------------------------------------------
 +# "/usr/lib/cups/pdf/ps2pdf.cups":
 +# Convert PostScript to PDF.
 +# -------------------------------------------------------------------
 +
 +OPTIONS=""
 +while true
 +do
 +        case "$1" in
 +        -*) OPTIONS="$OPTIONS $1" ;;
 +        *)  break ;;
 +
 +        esac
 +        shift
 +done
 +
 +if [ $# -lt 1 -o $# -gt 2 ]; then
 +        echo "Usage: `basename $0` [options...] input.ps [output.pdf]" 1>&2
 +        exit 1
 +fi
 +
 +infile=$1;
 +
 +if [ $# -eq 1 ]
 +then
 +        outfile=$1
 +else
 +        outfile=$2
 +fi
 +
 +# Doing an initial 'save' helps keep fonts from being flushed between pages.
 +exec gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite \
 +        -sOutputFile=$outfile $OPTIONS -c save pop -f $infile
 +
 +# EOF
 +# -------------------------------------------------------------------
 +</file>
 +
 +
 +  * Script ''/usr/lib/cups/pdf/sendpdf'' <file>
 +#!/usr/bin/perl
 +# -------------------------------------------------------------------
 +# "/usr/lib/cups/pdf/sendpdf":
 +# Parameter: Username, PDF File
 +# -------------------------------------------------------------------
 +use MIME::Entity;
 +# Get the ARGS
 +$to = $ARGV[0];
 +$pdffile = $ARGV[1];
 +# Set some variables
 +$mailpipe = '| /usr/sbin/sendmail -t -oi';
 +$from = "pdfprinter";
 +$subject ="PDF File";
 +$content = "Your PDF print";
 +# create the mail
 +my $mail = MIME::Entity->build( Type    => 'text/plain',
 +                                From    => $from,
 +                                To      => $to,
 +                                Subject => $subject,
 +                                Data    => $content
 +                              );
 +# Attach the pdf file
 +$mail->attach( Path     => $pdffile,
 +               Type     => 'application/pdf',
 +               Encoding => 'base64'
 +             );
 +# Open mailpipe and send the mail
 +open MAIL, "$mailpipe" or die "Could not open mailpipe \"$mailpipe\" !\n";
 +$mail->print(\*MAIL);
 +close MAIL;
 +
 +# EOF
 +# -------------------------------------------------------------------
 +</file>
 Printing with CUPS ()
SlackDocs