Um einen, oder, wie am Ende dargestellt, mehrere verschiedene PDF-Drucker zur Verfügung zu stellen, ist zunächst das cups-pdf-Paket zu installieren.

Die PPD-Treiber

Das Paket bringt neben dem CUPS-PDF-Backend zwei PPD-Dateien mit:

  • CUPS-PDF_noopt.ppd
  • CUPS-PDF_opt.ppd

Diese unterscheiden sich dadurch, dass die Treiber-Optionen

  • PDFVer
  • Truncate
  • Label
  • TitlePref
  • LogType

entweder im CUPS-Webinterface unter „Standardeinstellungen festlegen“ (CUPS-PDF_opt.ppd) oder in der Konfigurationsdatei /etc/cups/cups-pdf.conf (CUPS-PDF_noopt.ppd) festgelegt werden. Die Konfigurationsdatei /etc/cups/cups-pdf.conf enthält weitere Konfigurationsoptionen, die sich auf beide PPD-Treiberdateien auswirken. Die Optionen sind in der Konfigurationsdatei ausführlich beschrieben. In /etc/cups liegt auch noch eine cups-pdf.conf.default, die dem Ausgangzustand der Konfigurationsdatei darstellt. Diese sollte nicht verändert werden, sondern nur als Vorlage für eigene Konfigurationsdateien dienen.

Die Label-Option

Die Voreinstellung der Label-Option ist 0, was bedeutet, dass nur unbetitelte Dokumente beim PDF-Druck eine Job-ID erhalten. Bei betitelten Dokumenten führt dies nun dazu, dass ein erneuter PDF-Druck des gleichen Dokumentes oder eines zufällig gleich betitelten Dokumentes zum Überschreiben des vorher erzeugten PDF-Dokumentes führen würde. Mit den Einstellungen Label 1 oder Label 2 wird jedem PDF-Druck eine Job-ID voran- oder nachgestellt.

Die PostProcessing-Option

Die Konfigurationdatei enthält die Option PostProcessing, mit der man nach Erzeugung des PDF-Dokuments noch in den Prozess mit einem eigenen Skript (bzw. Programm) eingreifen kann. Dem Skript werden neben eventuell hinzugefügten eigenen Argumenten und Optionen automatisch die folgenden drei Argumente von CUPS automatisch übergeben:

  • Name des PDF-Dokumentes
  • Benutzer, wie er von CUPS-PDF ermittelt wurde.
  • Benutzer, wie er CUPS-PDF übergeben wurde.

Da das Skript/Programm mit den Rechten des druckenden Users ausgeführt wird, das kann auch ein anonymer User sein, der also auf dem CUPS-Serrver-System nicht existiert, muss das Skript für jeden erreichbar und ausführbar sein.

Die PostProcessing-Option könnte etwa so aussehen:

PostProcessing /path/to/myscript Argument_1 ... Argument_n

Effektiv ergibt sich bei Ausführung durch CUPS dann die folgende Kommandozeile:

/path/to/myscript Argument_1 ... Argument_n PDF-Dateiname Username Username

Einrichtung des PDF-Druckers

In der CUPS-Weboberfläche wählt man als Administrator nach Anwahl von „Drucker hinzufügen“ aus der Liste der „lokalen Drucker“ den

  • ……
  • CUPS-PDF (Virtual PDF Printer)
  • ……

aus und macht auf den folgenden Konfigurationsseiten, wie für jeden anderen Druckertyp, weitere Einstellungen, darunter auch die Auswahl der PPD-Datei, die man unter dem Hersteller „Generic“ findet.

Verwendung verschiedener Konfigurationsdateien

Von der Standardkonfigurationsdatei /etc/cups/cups-pdf.conf können Kopien im gleichen Verzeichnis für Varianten des CUPS-PDF-Druckers angelegt werden, die man nach dem Schema cups-pdf-variante.conf benennt, wobei für variante jeder beliebige Text erlaubt ist. Ein solcher Drucker erscheint dann in der Auswahlliste der CUPS-Weboberfläche ind er Form:

  • ……
  • CUPS-PDF (Virtual PDF Printer)
  • CUPS-PDF (Virtual Variante Printer)
  • ……

Nun kann diese Variante als zusätzlicher PDF-Drucker erstellt werden.

Beispiel eines PostProcessing-Skript zur Erstellung verschiedener PDF-Drucker-Varianten

Das im folgenden aufgeführte Beispielskript, kann dazu dienen, verschiedene Varianten des PDF-Druckers zu Erstellen. Das Skript erwartet als ersten Parameter den Namen einer Aktion, deren Namen man sinnvollerweise auch in der zugehörigen Konfigurationsdatei verwendet, also z. B. für die Aktion mail2printuser die Konfigurationsdatei cups-pdf-mail2printuser.conf nennt. Die PostProcessing-Option sähe in diesem eispiel dann so aus:

PostProcessing /path/to/cups-pdf-postprocessing mail2printuser "mail body text" "mail subject text"

Nach Ergänzung der von CUPS automatisch hinzugefügten Optionen wird somit

/path/to/cups-pdf-postprocessing mail2printuser "mail body text" "mail subject text" PDF-Dateiname Username Username

gestartet und vom Beispielskript dann

echo "mail body text" | mailx -s "mail subject text" -a PDF-Dateiname Username
rm PDF-Dateiname

ausgeführt, also das PDF-Dokument dem lokalen User per Mail zugestellt und dann das PDF-Dokument gelöscht. Bitte beachten, dass hier noch weitere Prüfungen notwendig sind, z. B. ob der Versand erfolgreich war, der User nicht anonym ist, usw.

Als Ideengeber hier der komplette Code des Skriptes, wobei natürlich keinerlei Gewähr übernommen wird, da es sich auch um eine reine Machbarkeitsstudie handelt:

#!/bin/sh

# Usage: cups-pdf-postprocessing action [...] pdf-file user user
#
# arg1 : action
# arg2 to arg<count-3> : additional arguments
# Next three (last arguments) on commandline added by the pdf printer automatically
# arg<count-2> : pdffile
# arg<count-1> : user
# arg<count> : user

argscount=$#

additionalargscount=$((argscount - 4))

if [ "${argscount}" -lt 4 ]
then
    echo "Too less arguments; minimum 4 including the 3 arguments added by pdf print driver!"
else
    action="${1}"
    shift
    # Additional arguments are counted beginning with 2
    # corresponding to there position in the commandline.
    i=2
    while [ -n "${1}" ]
    do
        if [ $# -eq 3 ]
        then
            pdffile="${1}"
            shift
            user="${1}"
            shift
            user2="${1}"
            shift
        else
            eval 'arg'${i}='${1}'
            shift
            i=$((i + 1))
        fi
    done

    case ${action} in
        move2public)
            # move all pdf's to public dir
            # no additional argument
            if [ "$(dirname ${pdffile})" != "/public" ]
            then
                mv ${pdffile} /public
            fi
        ;;
        move2dir)
            # move all pdf's to the directory given as argument
            # arg2 : path to move file to
            if [ "${additionalargscount}" -ge "1" ]
            then
                if [ "$(dirname ${pdffile})" != "${arg2}" ] && [ "$(dirname ${pdffile})/" != "${arg2}" ]
                then
                    mv ${pdffile} ${arg2}
                fi
            fi
        ;;
        mail2printuser)
            # mail pdf's to that local user who has printed it
            # arg2 : mail text
            # arg3 : mail subject
            if [ "${additionalargscount}" -ge "2" ]
            then
                echo ${arg2} | mailx -s ${arg3} -a ${pdffile} ${user}
                rm ${pdffile}
            fi
        ;;
        mail2address)
            # mail all pdf's to a single mail address (local or extern)
            # arg2 : mail text
            # arg3 : mail subject
            # arg4 : mail recipient
            # arg5 : mail sender (eventually needed for external recipients (smarthosts)
            if [ "${additionalargscount}" -ge "4" ]
            then
                echo ${arg2} | mailx -s ${arg3} -r ${arg5} -a ${pdffile} ${arg4}
                rm ${pdffile}
            else
                if [ "${additionalargscount}" -ge "3" ]
                then
                    echo ${arg2} | mailx -s ${arg3} -a ${pdffile} ${arg4}
                    rm ${pdffile}
                fi
            fi
        ;;
        userdependend)
            # Do differnt things for some users
            # Check for number of arguments: has to be additional needed
            # parameters + 4
            if [ "${additionalargscount}" -ge "....." ]
            then
                case ${user} in
                    username)
                        echo "do something"
                    ;;
                    otheruser|anotheruser)
                        echo "do something different"
                    ;;
                    yetanotheruser)
                        echo "do something completely different"
                    ;;
                    *)
                        echo "No special action for all other users."
                    ;;
                esac
            fi
        ;;
        *)
            echo action not defined
        ;;
    esac
fi