From 014f0e14a3c6a044d99a67c8f4e1c4065452479e Mon Sep 17 00:00:00 2001 From: Didier Raboud Date: Sun, 23 May 2010 00:05:04 +0200 Subject: Imported Upstream version 4.0-20090301 --- foomatic-rip.in | 6617 ------------------------------------------------------- 1 file changed, 6617 deletions(-) delete mode 100644 foomatic-rip.in (limited to 'foomatic-rip.in') diff --git a/foomatic-rip.in b/foomatic-rip.in deleted file mode 100644 index 18b06a0..0000000 --- a/foomatic-rip.in +++ /dev/null @@ -1,6617 +0,0 @@ -#!@PERL@ -# The above Perl path may vary on your system; fix it!!! -*- perl -*- - -use strict; -use POSIX; -use Cwd; - -my $ripversion='$Revision$'; -#'# Fix emacs syntax highlighting - -# foomatic-rip is a spooler-independent filter script which takes -# PostScript as standard input and generates the printer's page -# description language (PDL)/raster format as standard output. This -# kind of filter is usually called Raster Image Processor (RIP), -# therefore the name "foomatic-rip". - -# Save it in one of the directories of your $PATH, so that it gets -# found when called from the command line (for spooler-less printing), -# link it to spooler-specific directories when you use CUPS or PPR: - -# ln -s /usr/bin/foomatic-rip /usr/lib/cups/filter/ -# ln -s /usr/bin/foomatic-rip /usr/lib/ppr/lib/ -# ln -s /usr/bin/foomatic-rip /usr/lib/ppr/interfaces/ - -# Mark this filter world-readable and world-executable (note that most -# spoolers run the print filters as a special user, as "lp", not as -# "root" or as the user who sent the job). - -# See http://www.openprinting.org/cups-doc.html -# http://www.openprinting.org/lpd-doc.html -# http://www.openprinting.org/ppr-doc.html -# http://www.openprinting.org/pdq-doc.html -# http://www.openprinting.org/direct-doc.html -# http://www.openprinting.org/ppd-doc.html - -# ========================================================================== -# -# User-configurable settings, edit them if needed -# -# ========================================================================== - -# What path to use for filter programs and such. Your printer driver -# must be in the path, as must be the renderer, $enscriptcommand, and -# possibly other stuff. The default path is often fine on Linux, but -# may not be on other systems. -# -my $execpath = "@EXECPATH@"; - -# CUPS raster drivers are searched here -my $cupsfilterpath = "@prefix@/lib/cups/filter:/usr/local/lib/cups/filter:/usr/local/libexec/cups/filter:/opt/cups/filter:/usr/lib/cups/filter"; - -# Location of the configuration file "filter.conf", this file can be -# used to change the settings of foomatic-rip without editing -# foomatic-rip. itself. This variable must contain the full pathname -# of the directory which contains the configuration file, usually -# "/etc/foomatic". -# Some versions of configure do not fully expand $sysconfdir -my $prefix = "@prefix@"; -my $configpath = "@sysconfdir@/foomatic"; - -# For the stuff below, the settings in the configuration file have priority. - -# Set to 1 to insert postscript code for page accounting (CUPS only). -my $ps_accounting = 1; -my $accounting_prolog = ""; - -# Enter here your personal command for converting non-postscript files -# (especially text) to PostScript. If you leave it blank, at first the -# line "textfilter: ..." from /etc/foomatic/filter.conf is read and -# then the commands given on the list below are tried, beginning with -# the first one. -# You can set this to "a2ps", "enscript" or "mpage" to select one of the -# default command strings. -my $fileconverter = '@FILECONVERTER@'; - -my($kid0,$kid1,$kid2,$kid3,$kid4); -my($kidfailed,$kid3finished,$kid4finished); -my($convkidfailed,$dockidfailed,$kid0finished,$kid1finished,$kid2finished); -my($fileconverterpid,$rendererpid,$fileconverterhandle,$rendererhandle); -my($jobhasjcl); - -# What 'echo' program to use. It needs -e and -n. Linux's builtin -# and regular echo work fine; non-GNU platforms may need to install -# gnu echo and put gecho here or something. -# -my $myecho = '@ECHO@'; - -# Which shell to use for executing shell commands. Some of the PPD files -# specify a FoomaticRIPCommandLine that makes use of constructs not available -# from a vanilla Bourne shell. On systems where /bin/sh is a vanilla Bourne -# we need to use a more "modern" shell to execute the command. This will -# be set via a 'preferred_shell: (shell)' setting in the foomatic.conf file -# or automatically detected at runtime later on in this program. -# -my $modern_shell = ''; - -# Set debug to 1 to enable the debug logfile for this filter; it will -# appear as defined by $logfile. It will contain status from this -# filter, plus the renderer's stderr output. You can also add a line -# "debug: 1" to your /etc/foomatic/filter.conf to get all your -# Foomatic filters into debug mode. -# -# WARNING: This logfile is a security hole; do not use in production. -my $debug = 0; - -# This is the location of the debug logfile (and also the copy of the -# processed PostScript data) in case you have enabled debugging above. -# The logfile will get the extension ".log", the PostScript data ".ps". -my $logfile = "/tmp/foomatic-rip"; - -# End interesting enduser options - -# ========================================================================== -# -# foomatic-rip spooler-independent PS->Printer filter (RIP) of Foomatic -# -# Copyright 2002 - 2007 Grant Taylor -# & Till Kamppeter -# & Helge Blischke -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -# USA. -# - -my $added_lf = "\n"; - -# Flush everything immediately. -$|=1; - - - -## Constants used by this filter - -# Error codes, as some spooles behave different depending on the reason why -# the RIP failed, we return an error code. As I have only found a table of -# error codes for the PPR spooler. If our spooler is really PPR, these -# definitions get overwritten by the ones of the PPR version currently in -# use. - -my $EXIT_PRINTED = 0; # file was printed normally -my $EXIT_PRNERR = 1; # printer error occured -my $EXIT_PRNERR_NORETRY = 2; # printer error with no hope of retry -my $EXIT_JOBERR = 3; # job is defective -my $EXIT_SIGNAL = 4; # terminated after catching signal -my $EXIT_ENGAGED = 5; # printer is otherwise engaged (connection - # refused) -my $EXIT_STARVED = 6; # starved for system resources -my $EXIT_PRNERR_NORETRY_ACCESS_DENIED = 7; # bad password? bad port - # permissions? -my $EXIT_PRNERR_NOT_RESPONDING = 8; # just doesn't answer at all - # (turned off?) -my $EXIT_PRNERR_NORETRY_BAD_SETTINGS = 9; # interface settings are invalid -my $EXIT_PRNERR_NO_SUCH_ADDRESS = 10; # address lookup failed, may be - # transient -my $EXIT_PRNERR_NORETRY_NO_SUCH_ADDRESS = 11; # address lookup failed, not - # transient -my $EXIT_INCAPABLE = 50; # printer wants (lacks) features - # or resources -# Standard Unix signal names -#my SIGHUP = 1; -#my SIGINT = 2; -#my SIGQUIT = 3; -#my SIGKILL = 9; -#my SIGTERM = 15; -#my SIGUSR1 = 10; -#my SIGUSR2 = 12; -#my SIGTTIN = 21; -#my SIGTTOU = 22; - -my $ESPIPE = 29; # the errno value when seeking a pipe or socket - - - -## Some important variables - -# We don't know yet, which spooler will be used. If we don't detect -# one. we assume that we do spooler-less printing. Supported spoolers -# are currently: - -# cups - CUPS - Common Unix Printing System -# solaris - Solaris LP (possibly some other SysV LP services as well) -# lpd - LPD - Line Printer Daemon -# lprng - LPRng - LPR - New Generation -# gnulpr - GNUlpr, an enhanced LPD (development stopped) -# ppr - PPR (foomatic-rip runs as a PPR RIP) -# ppr_int - PPR (foomatic-rip runs as an interface) -# cps - CPS - Coherent Printing System -# pdq - PDQ - Print, Don't Queue (development stopped) -# direct - Direct, spooler-less printing - -my $spooler = 'direct'; - -# PPD file name -my $ppdfile = ""; - -# Printer model -my $model = ""; - -# Printer queue name -my $printer = ""; - -# Printing options -my $optstr = ""; - -# Job ID -my $jobid = ""; - -# User who sent job -my $jobuser = ((getpwuid($<))[0] || `whoami` || ""); -chomp $jobuser; - -# Host from which job was sent -my $jobhost = `hostname`; -chomp $jobhost; - -# Job title -my $jobtitle = "$jobuser\@$jobhost"; - -# Number of copies -my $copies = "1"; - -# Post pipe (command into which the output of this filter should be piped) -my $postpipe = ""; - -# job meta-data file path (for Solaris LP) -my $attrpath = ''; - -# Files to be printed -my @filelist = (); - -# Where to send debugging log output. Initialized to STDERR until the command -# line arguments are parsed. -my $logh = *STDERR; - -# JCL prefix to put before the JCL options (Can be modified by a -# "*JCLBegin:" keyword in the PPD file): -my $jclbegin = "\033%-12345X\@PJL\n"; - -# JCL command to switch the printer to the PostScript interpreter (Can -# be modified by a "*JCLToPSInterpreter:" keyword in the PPD file): -my $jcltointerpreter = ""; - -# JCL command to close a print job (Can be modified by a "*JCLEnd:" -# keyword in the PPD file): -my $jclend = "\033%-12345X\@PJL RESET\n"; - -# Prefix for starting every JCL command (Can be modified by -# "*FoomaticJCLPrefix:" keyword in the PPD file): -my $jclprefix = "\@PJL "; - -# Under which name were we called and in which directory do we reside -$0 =~ m!^(.*/)([^/]+)$!; -my $programdir = $1; -my $programname = $2; - -# Filters to convert non-PostScript files -my @fileconverters = - (# a2ps (converts also other files than text) - 'a2ps -1 @@--medium=@@PAGESIZE@@ @@--center-title=@@JOBTITLE@@ -o -', - # enscript - 'enscript -G @@-M @@PAGESIZE@@ @@-b "Page $%|@@JOBTITLE@@ ' . - '--margins=36:36:36:36 --mark-wrapped-lines=arrow --word-wrap -p-', - # mpage - 'mpage -o -1 @@-b @@PAGESIZE@@ @@-H -h @@JOBTITLE@@ -m36l36b36t36r ' . - '-f -P- -'); - -# spooler-specific file converters, default for the specific spooler when -# none of the converters above is chosen. Remove weird characters from the -# command line arguments to enhance security -my @fixed_args = - (defined($ARGV[0])?removespecialchars($ARGV[0]):"", - defined($ARGV[1])?removespecialchars($ARGV[1]):"", - defined($ARGV[2])?removespecialchars($ARGV[2]):"", - defined($ARGV[3])?removespecialchars($ARGV[3]):"", - defined($ARGV[4])?removespecialchars($ARGV[4]):""); -my $spoolerfileconverters = { - 'cups' => "${programdir}texttops '$fixed_args[0]' '$fixed_args[1]' '$fixed_args[2]' " . - "'$fixed_args[3]' '$fixed_args[4] page-top=36 page-bottom=36 " . - "page-left=36 page-right=36 nolandscape cpi=12 lpi=7 " . - "columns=1 wrap'" - }; - -## Config file - -# Read config file if present -my %conf = readConfFile("$configpath/filter.conf"); - -# Get execution path from config file -$execpath = $conf{execpath} if defined $conf{execpath}; -$ENV{'PATH'} = $execpath; - -# Get CUPS filter path from config file -$cupsfilterpath = $conf{cupsfilterpath} if defined $conf{cupsfilterpath}; - -# Set debug mode -$debug = $conf{debug} if defined $conf{debug}; - -# Determine which filter to use for non-PostScript files to be converted -# to PostScript -if (defined $conf{textfilter}) { - $fileconverter = $conf{textfilter}; - $fileconverter eq 'a2ps' and $fileconverter = $fileconverters[0]; - $fileconverter eq 'enscript' and $fileconverter = $fileconverters[1]; - $fileconverter eq 'mpage' and $fileconverter = $fileconverters[2]; -} - -# Set the preferred shell for "system()" execution -(defined $conf{preferred_shell}) && - ($modern_shell = $conf{preferred_shell}); -# if none was preferred, look for a shell that will work -foreach my $shell ('/bin/sh', '/bin/bash', '/bin/ksh', '/bin/zsh') { - if (($modern_shell eq '') && (-x $shell)) { - open(FD, "| ".$shell." -c \"((0<1))\" 2>/dev/null"); - (close(FD) == 1) && ($modern_shell = $shell); - } -} - -## Environment variables; - -# "PPD": PPD file name for CUPS, Solaris, or PPR (if we run as PPR RIP) -if (defined($ENV{'PPD'})) { - # Clean the file name from weird characters which could cause - # unexpected behaviour - $ppdfile = removespecialchars($ENV{'PPD'}); - # CUPS, Solaris LP, and PPR (RIP filter) use the "PPD" environment variable - # to make the PPD file name available (we set CUPS here preliminarily, - # in the next step we check for Solaris LP and the PPR) - $spooler = 'cups'; -} - -# "SPOOLER_KEY": Solaris LP print service -if (defined($ENV{'SPOOLER_KEY'})) { - $spooler = 'solaris'; - - $ppdfile = $ENV{'PPD'}; - # set the printer name from the PPD file name - ($ppdfile =~ m!^.*/([^/]+)\.ppd$!) && - ($printer = $1); - - # Solaris LP may augment the "options" string argument from the command - # line with an attributes file ($ATTRPATH) - (defined($attrpath = $ENV{'ATTRPATH'})) && - ($optstr = read_attribute_file($attrpath)); -} - -# "PPR_VERSION": PPR -if (defined($ENV{'PPR_VERSION'})) { - # We have PPR - $spooler = 'ppr'; -} - -# "PPR_RIPOPTS": PPR -if (defined($ENV{'PPR_RIPOPTS'})) { - # PPR 1.5 allows the user to specify options for the PPR RIP with the - # "--ripopts" option on the "ppr" command line. They are provided to - # the RIP via the "PPR_RIPOPTS" environment variable. - # Clean the option string from weird characters which could cause - # unexpected behaviour - $optstr .= removespecialchars("$ENV{'PPR_RIPOPTS'} "); - # We have PPR - $spooler = 'ppr'; -} - -# "LPOPTS": Option settings for some LPD implementations (ex: GNUlpr) -if (defined($ENV{'LPOPTS'})) { - my @lpopts = split(/,/, removespecialchars($ENV{'LPOPTS'})); - foreach my $opt (@lpopts) { - $opt =~ s/^\s+//; - $opt =~ s/\s+$//; - if ($opt =~ /\s+/) { - $opt = "\"$opt\""; - } - $optstr .= "$opt "; - } - # We have an LPD which accepts "-o" for options - $spooler = 'gnulpr'; -} - - - -## Named command line options - -# We do not use Getopt::Long because it does not work when between the -# option and the argument is no space ("-w80" instead of "-w 80"). This -# happens in the command line of LPRng, but also users could type in -# options this way when printing without spooler. - -# Make one option string with a non-printable character as separator, -# So we can parse it more easily. - -# To avoid the separator to be in the options itselves, it is filters -# out of the options. This does not break anything as having non -# printable characters in the command line options does not make sense -# nor is this needed. This way misinterpretation and even abuse is -# prevented. - -my $argstr = "\x01" . - join("\x01", map { removeunprintables($_) } @ARGV) . "\x01"; - -# Debug mode activated via command line -if ($argstr =~ s/\x01--debug\x01/\x01/) { - $debug = 1; -} - -# Command line options for verbosity -my $verbose = ($argstr =~ s/\x01-v\x01/\x01/); -my $quiet = ($argstr =~ s/\x01-q\x01/\x01/); -my $show_docs = ($argstr =~ s/\x01-d\x01/\x01/); -my $do_docs; -my $cupscolorprofile; - -if ($debug) { - # Grotesquely unsecure; use for debugging only - open LOG, "> ${logfile}.log"; - $logh = *LOG; - - use IO::Handle; - $logh->autoflush(1); -} elsif (($quiet) && (!$verbose)) { - # Quiet mode, do not log - open LOG, "> /dev/null"; - $logh = *LOG; - - use IO::Handle; - $logh->autoflush(1); -} else { - # Default: log to STDERR - $logh=*STDERR; -} - - - -## Start debug logging -if ($debug) { - # If we are not in debug mode, we do this later, as we must find out at - # first which spooler is used. When printing without spooler we - # suppress logging because foomatic-rip is called directly on the - # command line and so we avoid logging onto the console. - print $logh "foomatic-rip version $ripversion running...\n"; - # Print the command line only in debug mode, Mac OS X adds very many - # options so that CUPS cannot handle the output of the command line - # in its log files. If CUPS encounters a line with more than 1024 - # characters sent into its log files, it aborts the job with an error. - if (($debug) || ($spooler ne 'cups')) { - print $logh "called with arguments: '", join("', '",@ARGV), "'\n"; - } -} - - - -## Continue with named options - -# Check for LPRng first so we do not pick up bogus ppd files by the -p option -if ($argstr =~ s/\x01--lprng\x01/\x01/) { - # We have LPRng - $spooler = 'lprng'; -} -# 'PRINTCAP_ENTRY' environment variable is : LPRng -# the :ppd=/path/to/ppdfile printcap entry should be used -if (defined($ENV{'PRINTCAP_ENTRY'})){ - $spooler = 'lprng'; - my( @pc); - @pc = split( /\s*:\s*/, $ENV{'PRINTCAP_ENTRY'} ); - shift @pc; - foreach (@pc) { - if( /^ppd=(.*)$/ or /^ppdfile=(.*)$/ ){ - $ppdfile = removespecialchars($1) if $1; - } - } -} elsif ($argstr =~ s/\x01--lprng\x01/\x01/g) { - # We have LPRng - $spooler = 'lprng'; -} - - -# PPD file name given via the command line -# allow duplicates, and use the last specified one -while ( ($spooler ne 'lprng') and ($argstr =~ s/\x01-p(\x01|)([^\x01]+)\x01/\x01/)) { - $ppdfile = removeshellescapes($2); -} -while ($argstr =~ s/\x01--ppd(\x01|=|)([^\x01]+)\x01/\x01/) { - $ppdfile = removeshellescapes($2); -} - -# Check for LPD/GNUlpr by typical options which the spooler puts onto -# the filter's command line (options "-w": text width, "-l": text -# length, "-i": indent, "-x", "-y": graphics size, "-c": raw printing, -# "-n": user name, "-h": host name) -if ($argstr =~ s/\x01-h(\x01|)([^\x01]+)\x01/\x01/) { - # We have LPD or GNUlpr - if (($spooler ne 'lpd') && ($spooler ne 'gnulpr') && ($spooler ne 'lprng')) { - $spooler = 'lpd'; - } - $jobhost = $2; -} -if ($argstr =~ s/\x01-n(\x01|)([^\x01]+)\x01/\x01/) { - # We have LPD or GNUlpr - if (($spooler ne 'lpd') && ($spooler ne 'gnulpr') && ($spooler ne 'lprng')) { - $spooler = 'lpd'; - } - $jobuser = $2; -} -if (($argstr =~ s/\x01-w(\x01|)\d+\x01/\x01/) || - ($argstr =~ s/\x01-l(\x01|)\d+\x01/\x01/) || - ($argstr =~ s/\x01-x(\x01|)\d+\x01/\x01/) || - ($argstr =~ s/\x01-y(\x01|)\d+\x01/\x01/) || - ($argstr =~ s/\x01-i(\x01|)\d+\x01/\x01/) || - ($argstr =~ s/\x01-c\x01/\x01/)) { - # We have LPD or GNUlpr - if (($spooler ne 'lpd') && ($spooler ne 'gnulpr') && ($spooler ne 'lprng')) { - $spooler = 'lpd'; - } -} - -# LPRng delivers the option settings via the "-Z" argument -if ($argstr =~ s/\x01-Z(\x01|)([^\x01]+)\x01/\x01/) { - my @lpopts = split(/,/, $2); - foreach my $opt (@lpopts) { - $opt =~ s/^\s+//; - $opt =~ s/\s+$//; - $opt = removeshellescapes($opt); - if ($opt =~ /\s+/) { - $opt = "\"$opt\""; - } - $optstr .= "$opt "; - } - # We have LPRng - $spooler = 'lprng'; -} - -# Job title and options for stock LPD -if ($argstr =~ s/\x01-[jJ](\x01|)([^\x01]+)\x01/\x01/) { - # An LPD - $jobtitle = removeshellescapes($2); - # Classic LPD hack - if ($spooler eq "lpd") { - $optstr .= "$jobtitle "; - } -} - -# Check for CPS -if ($argstr =~ s/\x01--cps\x01/\x01/) { - # We have cps - $spooler = 'cps'; -} - -# Options for spooler-less printing, CPS, or PDQ -while ($argstr =~ s/\x01-o(\x01|)([^\x01]+)\x01/\x01/) { - my $opt = $2; - $opt =~ s/^\s+//; - $opt =~ s/\s+$//; - $opt = removeshellescapes($opt); - if ($opt =~ /\s+/) { - $opt = "\"$opt\""; - } - $optstr .= "$opt "; - # If we don't print as a PPR RIP or as a CPS filter, we print without - # spooler (we check for PDQ later) - if (($spooler ne 'ppr') && ($spooler ne 'cps')) { - $spooler = 'direct'; - } -} - -# Printer for spooler-less printing or PDQ -if ($argstr =~ s/\x01-d(\x01|)([^\x01]+)\x01/\x01/) { - $printer = removeshellescapes($2); -} -# Printer for spooler-less printing, PDQ, or LPRng -if ($argstr =~ s/\x01-P(\x01|)([^\x01]+)\x01/\x01/) { - $printer = removeshellescapes($2); -} - -# Were we called from a PDQ wrapper? -if ($argstr =~ s/\x01--pdq\x01/\x01/) { - # We have PDQ - $spooler = 'pdq'; -} - -# Were we called to build the PDQ driver declaration file? -# "--appendpdq=" appends the data to the , -# "--genpdq=" creates/overwrites for the data, and -# "--genpdq" writes to standard output -my $genpdqfile = ""; -if (($argstr =~ s/\x01--(gen)(raw|)pdq(\x01|=|)([^\x01]*)\x01/\x01/) || - ($argstr =~ s/\x01--(append)(raw|)pdq(\x01|=|)([^\x01]+)\x01/\x01/)) { - # Determine output file name - if (!$4) { - $genpdqfile = ">&STDOUT"; - } else { - if ($1 eq 'gen') { - $genpdqfile = "> " . removeshellescapes($4); - } else { - $genpdqfile = ">> " . removeshellescapes($4); - } - } - # Do we want to have a PDQ driver declaration for a raw printer? - if ($2 eq 'raw') { - my $time = time(); - my @pdqfile = -"driver \"Raw-Printer-$time\" { - # This PDQ driver declaration file was generated automatically by - # foomatic-rip to allow raw (filter-less) printing. - language_driver all { - # We accept all file types and pass them through without any changes - filetype_regx \"\" - convert_exec { - ln -s \$INPUT \$OUTPUT - } - } - filter_exec { - ln -s \$INPUT \$OUTPUT - } -}"; - open PDQFILE, $genpdqfile or - rip_die("Cannot write PDQ driver declaration file", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - print PDQFILE join('', @pdqfile); - close PDQFILE; - exit $EXIT_PRINTED; - } - # We have PDQ - $spooler = 'pdq'; -} - - -# remove extra spacing if running as LPRng filter -$added_lf = "" if $spooler eq 'lprng'; - -## Command line arguments without name - -# Remaining arguments -my @rargs = split(/\x01/, $argstr); -shift @rargs; - -# Load definitions for PPR error messages, check whether we run as -# PPR interface or as PPR RIP -my( $ppr_printer, $ppr_address, $ppr_options, $ppr_jobbreak, $ppr_feedback, - $ppr_codes, $ppr_jobname, $ppr_routing, $ppr_for, $ppr_filetype, - $ppr_filetoprint ); -if ($spooler eq 'ppr') { - # Read interface.sh so we will know the correct exit codes and - # also signal.sh for the signal codes - my $deffound = 0; # Did we find one of the definition files - my @definitions; - for my $file (("lib/interface.sh", "lib/signal.sh")) { - - open FILE, "< $file" || do { - print $logh "error opening $file.\n"; - next; - }; - - $deffound = 1; - while(my $line = ) { - # Translate the shell script to Perl - if (($line !~ m/^\s*$/) && ($line !~ m/^\s*\#/)) { - $line =~ s/^\s*([^\#\s]*)/\$$1;/; - push (@definitions, $line); - } - } - close FILE; - } - - if ($deffound) { - # Apply the definitions loaded from PPR - eval join('',@definitions) || do { - print $logh "unable to evaluate definitions\n"; - rip_die ("Error in definitions evaluation", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - }; - } - - # Check whether we run as a PPR interface (if not, we run as a PPR RIP) - if (($rargs[3] =~ /^\s*\d\d?\s*$/) && - ($rargs[5] =~ /^\s*\d\d?\s*$/) && - (($#rargs == 10) || ($#rargs == 9) || ($#rargs == 7))) { - # PPR calls interfaces with many command line parameters, - # where the forth and the sixth is a small integer - # number. In addition, we have 8 (PPR <= 1.31), 10 - # (PPR>=1.32), 11 (PPR >= 1.50) command line parameters. - # We also check whether the current working directory is a - # PPR directory. - - # Get all command line parameters - $ppr_printer = removeshellescapes($rargs[0]); - $ppr_address = $rargs[1]; - $ppr_options = removeshellescapes($rargs[2]); - $ppr_jobbreak = $rargs[3]; - $ppr_feedback = $rargs[4]; - $ppr_codes = $rargs[5]; - $ppr_jobname = removeshellescapes($rargs[6]); - $ppr_routing = removeshellescapes($rargs[7]); - $ppr_for = $rargs[8]; - $ppr_filetype = $rargs[9]; - $ppr_filetoprint = removeshellescapes($rargs[10]); - - # Common job parameters - $printer = $ppr_printer; - $jobtitle = $ppr_jobname; - if ((!$jobtitle) && ($ppr_filetoprint)) { - $jobtitle = $ppr_filetoprint; - } - $optstr .= "$ppr_options $ppr_routing"; - - # Get the path of the PPD file from the queue configuration - $ppdfile = `LANG=en_US; ppad show $ppr_printer | grep PPDFile`; - $ppdfile = removeshellescapes($ppdfile); - $ppdfile =~ s/PPDFile:\s+//; - if ($ppdfile !~ m!^/!) { - $ppdfile = "../../share/ppr/PPDFiles/$ppdfile"; - } - chomp($ppdfile); - - # We have PPR and run as an interface - $spooler = 'ppr_int'; - } -} - -# CUPS -my( $cups_jobid, $cups_user, $cups_jobtitle, $cups_copies, $cups_options, - $cups_filename ); -if ($spooler eq 'cups') { - - # Use CUPS font path ("FontPath" in /etc/cups/cupsd.conf) - if ($ENV{'CUPS_FONTPATH'}) { - $ENV{'GS_LIB'} = $ENV{'CUPS_FONTPATH'} . - ($ENV{'GS_LIB'} ? ":$ENV{'GS_LIB'}" : ""); - } else { - if ($ENV{'CUPS_DATADIR'}) { - $ENV{'GS_LIB'} = "$ENV{'CUPS_DATADIR'}/fonts" . - ($ENV{'GS_LIB'} ? ":$ENV{'GS_LIB'}" : ""); - } - } - - # Get all command line parameters - $cups_jobid = removeshellescapes($rargs[0]); - $cups_user = removeshellescapes($rargs[1]); - $cups_jobtitle = removeshellescapes($rargs[2]); - $cups_copies = removeshellescapes($rargs[3]); - $cups_options = removeshellescapes($rargs[4]); - $cups_filename = removeshellescapes($rargs[5]); - - # Common job parameters - #$printer = $cups_printer; - $jobid = $cups_jobid; - $jobtitle = $cups_jobtitle; - $jobuser = $cups_user; - $copies = $cups_copies; - $optstr .= $cups_options; - - # Check for and handle inputfile vs stdin - if ((defined($cups_filename)) && ($cups_filename) && - ($cups_filename ne '-')) { - # We get the input from a file - @filelist = ($cups_filename); - print $logh "Getting input from file $cups_filename\n"; - } -} - -# Solaris LP spooler -if ($spooler eq 'solaris') { - # Get all command line parameters - # $printer = # argv[0] - # ($rargs[0] =~ m!^.*/([^/]+)$!); - # $request_id = removeshellescapes($rargs[0]); # argv[1] - # $user_name = removeshellescapes($rargs[1]); # argv[2] - $jobtitle = removeshellescapes($rargs[2]); # argv[3] - # $copies = removeshellescapes($rargs[3]); # argv[4] # handled by the - # interface script - $optstr .= removeshellescapes($rargs[4]); # argv[5] - ($#rargs > 4) && # argv[6...] - (@filelist = @rargs[5, $#rargs]); -} - -# LPD/LPRng/GNUlpr -if (($spooler eq 'lpd') || - ($spooler eq 'lprng' and !$ppdfile) || - ($spooler eq 'gnulpr')) { - - # Get PPD file name as the last command line argument - $ppdfile = removeshellescapes($rargs[$#rargs]); - -} - - -# No spooler, CPS, or PDQ -if (($spooler eq 'direct') || ($spooler eq 'cps') || ($spooler eq 'pdq')) { - # Which files do we want to print? - @filelist = map { removeshellescapes($_) } @rargs; -} - - - -## Additional spooler-specific preparations - -# CUPS - -if ($spooler eq 'cups') { - - # This piece of PostScript code (initial idea 2001 by Michael - # Allerhand (michael.allerhand at ed dot ac dot uk, vastly - # improved by Till Kamppeter in 2002) lets GhostScript output - # the page accounting information which CUPS needs on standard - # error. - # Redesign by Helge Blischke (2004-11-17): - # - As the PostScript job itself may define BeginPage and/or EndPage - # procedures, or the alternate pstops filter may have inserted - # such procedures, we make sure that the accounting routine - # will safely coexist with those. To achieve this, we force - # - the accountint stuff to be inserted at the very end of the - # PostScript job's setup section, - # - the accounting stuff just using the return value of the - # existing EndPage procedure, if any (and providing a default one - # if not). - # - As PostScript jobs may contain calls to setpagedevice "between" - # pages, e.g. to change media type, do in-job stapling, etc., - # we cannot rely on the "showpage count since last pagedevice - # activation" but instead count the physical pages by ourselves - # (in a global dictionary). - - if (defined $conf{ps_accounting}) { - $ps_accounting = $conf{ps_accounting}; - } - $accounting_prolog = $ps_accounting ? "[{ -%% Code for writing CUPS accounting tags on standard error - -/cupsPSLevel2 % Determine whether we can do PostScript level 2 or newer - systemdict/languagelevel 2 copy - known{get exec}{pop pop 1}ifelse 2 ge -def - -cupsPSLevel2 -{ % in case of level 2 or higher - currentglobal true setglobal % define a dictioary foomaticDict - globaldict begin % in global VM and establish a - /foomaticDict % pages count key there - << - /PhysPages 0 - >>def - end - setglobal -}if - -/cupsGetNumCopies { % Read the number of Copies requested for the current - % page - cupsPSLevel2 - { - % PS Level 2+: Get number of copies from Page Device dictionary - currentpagedevice /NumCopies get - } - { - % PS Level 1: Number of copies not in Page Device dictionary - null - } - ifelse - % Check whether the number is defined, if it is \"null\" use #copies - % instead - dup null eq { - pop #copies - } - if - % Check whether the number is defined now, if it is still \"null\" use 1 - % instead - dup null eq { - pop 1 - } if -} bind def - -/cupsWrite { % write a string onto standard error - (%stderr) (w) file - exch writestring -} bind def - -/cupsFlush % flush standard error to make it sort of unbuffered -{ - (%stderr)(w)file flushfile -}bind def - -cupsPSLevel2 -{ % In language level 2, we try to do something reasonable - << - /EndPage - [ % start the array that becomes the procedure - currentpagedevice/EndPage 2 copy known - {get} % get the existing EndPage procedure - {pop pop {exch pop 2 ne}bind}ifelse % there is none, define the default - /exec load % make sure it will be executed, whatever it is - /dup load % duplicate the result value - { % true: a sheet gets printed, do accounting - currentglobal true setglobal % switch to global VM ... - foomaticDict begin % ... and access our special dictionary - PhysPages 1 add % count the sheets printed (including this one) - dup /PhysPages exch def % and save the value - end % leave our dict - exch setglobal % return to previous VM - (PAGE: )cupsWrite % assemble and print the accounting string ... - 16 string cvs cupsWrite % ... the sheet count ... - ( )cupsWrite % ... a space ... - cupsGetNumCopies % ... the number of copies ... - 16 string cvs cupsWrite % ... - (\\n)cupsWrite % ... a newline - cupsFlush - }/if load - % false: current page gets discarded; do nothing - ]cvx bind % make the array executable and apply bind - >>setpagedevice -} -{ - % In language level 1, we do no accounting currently, as there is no global VM - % the contents of which are undesturbed by save and restore. - % If we may be sure that showpage never gets called inside a page related save / restore pair - % we might implement an hack with showpage similar to the one above. -}ifelse - -} stopped cleartomark -" : ""; - - # On which queue are we printing? - # CUPS gives the PPD file the same name as the printer queue, - # so we can get the queue name from the name of the PPD file. - $ppdfile =~ m!^(.*/)([^/]+)\.ppd$!; - $printer = $2; -} - -# No spooler, CPS, or PDQ - -if (($spooler eq 'direct') || ($spooler eq 'cps') || ($spooler eq 'pdq')) { - - # Path for personal Foomatic configuration - my $user_default_path = "$ENV{'HOME'}/.foomatic"; - - if (!$ppdfile) { - if (!$printer) { - # No printer definition file selected, check whether we have a - # default printer defined. - for my $conf_file (("./.directconfig", - "./directconfig", - "./.config", - "$user_default_path/direct/.config", - "$user_default_path/direct.conf", - "$configpath/direct/.config", - "$configpath/direct.conf")) { - if (open CONFIG, "< $conf_file") { - while (my $line = ) { - chomp $line; - if ($line =~ /^default\s*:\s*([^:\s]+)\s*$/) { - $printer = $1; - last; - } - } - close CONFIG; - } - if ($printer) { - last; - } - } - } - - # Neither in a config file nor on the command line a printer was - # selected. - if (!$printer) { - rip_die("No printer definition (option \"-P \") " . - "specified!", $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - - # Search for the PPD file - - # Search also common spooler-specific locations, this way a printer - # configured under a certain spooler can also be used without - # spooler - - if (-r $printer) { - $ppdfile = $printer; - # CPS can have the PPD in the spool directory - } elsif (($spooler eq 'cps') && - (-r "/var/spool/lpd/${printer}/${printer}.ppd")) { - $ppdfile = "/var/spool/lpd/${printer}/${printer}.ppd"; - } elsif (($spooler eq 'cps') && - (-r "/var/local/spool/lpd/${printer}/${printer}.ppd")) { - $ppdfile = "/var/local/spool/lpd/${printer}/${printer}.ppd"; - } elsif (($spooler eq 'cps') && - (-r "/var/local/lpd/${printer}/${printer}.ppd")) { - $ppdfile = "/var/local/lpd/${printer}/${printer}.ppd"; - } elsif (($spooler eq 'cps') && - (-r "/var/spool/lpd/${printer}.ppd")) { - $ppdfile = "/var/spool/lpd/${printer}.ppd"; - } elsif (($spooler eq 'cps') && - (-r "/var/local/spool/lpd/${printer}.ppd")) { - $ppdfile = "/var/local/spool/lpd/${printer}.ppd"; - } elsif (($spooler eq 'cps') && - (-r "/var/local/lpd/${printer}.ppd")) { - $ppdfile = "/var/local/lpd/${printer}.ppd"; - } elsif (-r "${printer}.ppd") { # current dir - $ppdfile = "${printer}.ppd"; - } elsif (-r "$user_default_path/${printer}.ppd") { # user dir - $ppdfile = "$user_default_path/${printer}.ppd"; - } elsif (-r "$configpath/direct/${printer}.ppd") { # system dir - $ppdfile = "$configpath/direct/${printer}.ppd"; - } elsif (-r "$configpath/${printer}.ppd") { # system dir - $ppdfile = "$configpath/${printer}.ppd"; - } elsif (-r "/etc/cups/ppd/${printer}.ppd") { # CUPS config dir - $ppdfile = "/etc/cups/ppd/${printer}.ppd"; - } elsif (-r "/usr/local/etc/cups/ppd/${printer}.ppd") { - $ppdfile = "/usr/local/etc/cups/ppd/${printer}.ppd"; - } elsif (-r "/usr/share/ppr/PPDFiles/${printer}.ppd") { # PPR PPDs - $ppdfile = "/usr/share/ppr/PPDFiles/${printer}.ppd"; - } elsif (-r "/usr/local/share/ppr/PPDFiles/${printer}.ppd") { - $ppdfile = "/usr/local/share/ppr/PPDFiles/${printer}.ppd"; - } else { - rip_die ("There is no readable PPD file for the printer " . - "$printer, is it configured?", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - } -} - - - -## Files to be printed (can be more than one for spooler-less printing) - -# Empty file list -> print STDIN -if ($#filelist < 0) { - @filelist = (""); -} - -# Check file list -my $file; -my $filecnt = 0; -for $file (@filelist) { - if ($file ne "") { - if ($file =~ /^-/) { - rip_die ("Invalid argument: $file", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } elsif (! -r $file) { - print $logh "File $file does not exist/is not readable\n"; - splice(@filelist, $filecnt, 1); - $filecnt --; - } - } - $filecnt ++; -} - - - -## When we print without spooler or with CPS do not log onto STDERR unless -## the "-v" ('Verbose') is set or the debug mode is used -if ((($spooler eq 'direct') || ($spooler eq 'cps') || ($genpdqfile)) && - (!$verbose) && (!$debug)) { - close $logh; - open LOG, "> /dev/null"; - $logh = *LOG; - - use IO::Handle; - $logh->autoflush(1); -} - - - -## Start logging -if (!$debug) { - # If we are in debug mode, we do this earlier. - print $logh "foomatic-rip version $ripversion running...\n"; - # Print the command line only in debug mode, Mac OS X adds very many - # options so that CUPS cannot handle the output of the command line - # in its log files. If CUPS encounters a line with more than 1024 - # characters sent into its log files, it aborts the job with an error. - if (($debug) || ($spooler ne 'cups')) { - print $logh "called with arguments: '", join("', '",@ARGV), "'\n"; - } -} - - - -## PPD file - -# Load the PPD file and build a data structure for the renderer's -# command line and the options -open PPD, "< $ppdfile" || do { - print $logh "error opening $ppdfile.\n"; - rip_die ("Unable to open PPD file $ppdfile", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); -}; - -print $logh "Parsing PPD file ...\n"; - -my $dat = {}; # data structure for the options -my $currentargument = ""; # We are currently reading this argument - -# If we have an old Foomatic 2.0.x PPD file, read its built-in Perl -# data structure into @datablob and the default values in %ppddefaults -# Then delete the $dat structure, replace it by the one "eval"ed from -# @datablob, and correct the default settings according to the ones of -# the main PPD structure -my @datablob; -my $jclprefixset = 0; - -# Parse the PPD file -sub undossify( $ ); -while() { - # foomatic-rip should also work with PPD file downloaded under Windows. - $_ = undossify($_); - # Parse keywords - if (m!^\*NickName:\s*\"(.*)$!) { - # "*NickName: " - my $line = $1; - # Store the value - # Code string can have multiple lines, read all of them - my $cmd = ""; - while ($line !~ m!\"!) { - if ($line =~ m!&&$!) { - # line continues in next line - $cmd .= substr($line, 0, -2); - } else { - # line ends here - $cmd .= "$line\n"; - } - # Read next line - $line = ; - chomp $line; - } - $line =~ m!^([^\"]*)\"!; - $cmd .= $1; - $model = unhtmlify($cmd); - } elsif (m!^\*FoomaticIDs:\s*\"?\s*(\S+?)\s+(\S+?)\s*\"?\s*$!) { - # "*FoomaticIDs: " - my $id = $1; - my $driver = $2; - # Store the values - $dat->{'id'} = $id; - $dat->{'driver'} = $driver; - } elsif (m!^\*FoomaticRIPPostPipe:\s*\"(.*)$!) { - # "*FoomaticRIPPostPipe: " - my $line = $1; - # Store the value - # Code string can have multiple lines, read all of them - my $cmd = ""; - while ($line !~ m!\"!) { - if ($line =~ m!&&$!) { - # line continues in next line - $cmd .= substr($line, 0, -2); - } else { - # line ends here - $cmd .= "$line\n"; - } - # Read next line - $line = ; - chomp $line; - } - $line =~ m!^([^\"]*)\"!; - $cmd .= $1; - $postpipe = unhtmlify($cmd); - } elsif (m!^\*FoomaticRIPCommandLine:\s*\"(.*)$!) { - # "*FoomaticRIPCommandLine: " - my $line = $1; - # Store the value - # Code string can have multiple lines, read all of them - my $cmd = ""; - while ($line !~ m!\"!) { - if ($line =~ m!&&$!) { - # line continues in next line - $cmd .= substr($line, 0, -2); - } else { - # line ends here - $cmd .= "$line\n"; - } - # Read next line - $line = ; - chomp $line; - } - $line =~ m!^([^\"]*)\"!; - $cmd .= $1; - $dat->{'cmd'} = unhtmlify($cmd); - } elsif (m!^\*FoomaticNoPageAccounting:\s*\"?\s*(\S+?)\s*\"?\s*$!) { - # "*FoomaticRIPNoPageAccounting: " - my $value = $1; - # Apply the value - if ($value =~ /^True$/i) { - # Driver is not compatible with page accounting according to the - # Foomatic database, so turn it off for this driver - $ps_accounting = 0; - $accounting_prolog = ''; - print $logh "CUPS page accounting disabled by driver.\n"; - } - } elsif (m!^\*cupsFilter:\s*\"(.*)$!) { - # "*cupsFilter: " - my $line = $1; - # Store the value - # Code string can have multiple lines, read all of them - my $cmd = ""; - while ($line !~ m!\"!) { - if ($line =~ m!&&$!) { - # line continues in next line - $cmd .= substr($line, 0, -2); - } else { - # line ends here - $cmd .= "$line\n"; - } - # Read next line - $line = ; - chomp $line; - } - $line =~ m!^([^\"]*)\"!; - $cmd .= $1; - my $cupsfilterline = unhtmlify($cmd); - if ($cupsfilterline =~ /^\s*(\S+)\s+\d+\s+(\S+)\s*$/) { - print $logh "*cupsFilter: \"$cupsfilterline\"\n"; - # Make a hash by mime type for all CUPS filters set in this PPD - $dat->{'cupsfilter'}{$1} = $2; - } - } elsif (m!^\*CustomPageSize\s+True:\s*\"(.*)$!) { - # "*CustomPageSize True: " - my $setting = "Custom"; - my $translation = "Custom Size"; - my $line = $1; - # Make sure that the argument is in the data structure - checkarg ($dat, "PageSize"); - checkarg ($dat, "PageRegion"); - # Make sure that the setting is in the data structure - checksetting ($dat, "PageSize", $setting); - checksetting ($dat, "PageRegion", $setting); - $dat->{'args_byname'}{'PageSize'}{'vals_byname'}{$setting}{'comment'} = $translation; - $dat->{'args_byname'}{'PageRegion'}{'vals_byname'}{$setting}{'comment'} = $translation; - # Store the value - # Code string can have multiple lines, read all of them - my $code = ""; - while ($line !~ m!\"!) { - if ($line =~ m!&&$!) { - # line continues in next line - $code .= substr($line, 0, -2); - } else { - # line ends here - $code .= "$line\n"; - } - # Read next line - $line = ; - chomp $line; - } - $line =~ m!^([^\"]*)\"!; - $code .= $1; - if ($code !~ m!^%% FoomaticRIPOptionSetting!m) { - $dat->{'args_byname'}{'PageSize'}{'vals_byname'}{$setting}{'driverval'} = $code; - $dat->{'args_byname'}{'PageRegion'}{'vals_byname'}{$setting}{'driverval'} = $code; - } - } elsif (m!^\*(JCL|)OpenUI\s+\*([^:]+):\s*(\S+)\s*$!) { - # "*[JCL]OpenUI *