diff options
author | Didier Raboud <didier@raboud.com> | 2010-05-23 00:07:10 +0200 |
---|---|---|
committer | Didier Raboud <didier@raboud.com> | 2010-05-23 00:07:10 +0200 |
commit | f56211f0ff4ddf9371ebc4c31e8f95df1fc81a5c (patch) | |
tree | a24f15ea2fc96e0688e96c58e35dde7adeaef3fb | |
parent | b834bd56528993fa05a5645da808227aee3e9de7 (diff) | |
parent | 014f0e14a3c6a044d99a67c8f4e1c4065452479e (diff) |
Merge branch 'upstream'
Conflicts:
debian/README.Debian
debian/changelog
debian/control
debian/copyright
debian/foomatic-filters.config
debian/foomatic-filters.postinst
debian/foomatic-filters.postrm
debian/foomatic-filters.templates
debian/parseconfig.pl
debian/po/de.po
debian/po/fr.po
debian/po/ja.po
debian/po/nl.po
debian/po/pt_BR.po
debian/po/templates.pot
debian/po/tr.po
debian/rules
72 files changed, 21435 insertions, 10661 deletions
@@ -1,3 +1,317 @@ +2009-02-11 Lars Uebernickel <larsuebernickel@gmx.de> + * foomaticrip.c: The value of the "execpath" variable in the config + file was not used fully: Only the characters leading up to the first + ':' were copied into the programs $PATH environment variable. + +2009-02-11 Lars Uebernickel <larsuebernickel@gmx.de> + * renderer.c: Fixed several bugs in the argument replacements in + massage_gs_commandline. + * foomaticrip.c: Use "gspath" and "echopath" from the config file. + +2009-02-09 Lars Uebernickel <larsuebernickel@gmx.de> + + * fileconverter.h, foomaticrip.c, renderer.c, util.c: Made + foomatic-rip building under Mac OS X, mainly by replacing + functions which are GNU-only. + +2009-02-02 Till Kamppeter <till.kamppeter@gmail.com> + + * renderer.c: When foomatic-rip looked for JCL options in the + binary output of the driver to merge them with JCL options from + the PPD file, it read binary data into a C string, which causes + problems when this data contains zeroes. Finally fixes Ubuntu bug + LP: #303691. + +2009-01-29 Till Kamppeter <till.kamppeter@gmail.com> + + * renderer.c: If there were very many JCL lines in the driver's + output or coming together by JCL options, the JCL merging + process (kid4) segfaulted (Ubuntu bug LP: #321164, + https://launchpad.net/bugs/321164). + +2009-01-14 Till Kamppeter <till.kamppeter@gmail.com> + + * Tagged branch for release 4.0.0. + +2009-01-13 Till Kamppeter <till.kamppeter@gmail.com> + + * options.c: Custom JCL options were not inserted correctly + (thanks to Bin Li from Ricoh for reporting this). Fixed also + that "None" as argument for a string or password option is + considered as the empty string. + + * options.c: String and password option settings got inserted into + the command line or the PostScript code with the "Custom." + prefix (thanks to Bin Li from Ricoh for reporting this). Fixed + also a segmentation fault due to missing initialization of + components of the param_t data structure by the + option_add_custom_param_from_string() function. Removed also + some unneeded free() calls. + +2009-01-12 Till Kamppeter <till.kamppeter@gmail.com> + + * acinclude.m4: Eliminated warnings when generating ./configure + +2009-01-08 Till Kamppeter <till.kamppeter@gmail.com> + + * README, USAGE: Version 4.0.0. + + * STANDARD_installation: Tell also that "sudo make install" works + to run "make install" as root. + + * Makefile.am: Fixed cleaning rules. Many transient files did not + get removed. + Fixed "make inplace" and uninstalling rules. + +2009-01-03 Till Kamppeter <till.kamppeter@gmail.com> + + * postscript.c: Do the workaround for PostScript input of + OpenOffice 1.1.x also for StarOffice 8 (Thanks to Martin Jacobs, + martin dot jacobs at arcor dot de, for the patch). + +2008-12-10 Till Kamppeter <till.kamppeter@gmail.com> + + * foomaticrip.c, foomaticrip.h, options.c: The PostScript code of + PostScript options did not get inserted when the spooler is CUPS + and foomatic-rip had to convert incoming PDF to PostScript + (Ubuntu bug #299918). + +2008-12-05 Till Kamppeter <till.kamppeter@gmail.com> + + * README: Updated for Foomatic 4.x + + * test/*: Added test suite based on the LSB tests for foomatic-rip + + * README, USAGE, foomatic-rip.1.in, foomaticrip.c, options.c, pdf.c. + spooler.c: s/GhostScript/Ghostscript/ + +2008-11-30 Till Kamppeter <till.kamppeter@gmail.com> + + * postscript.c: Insert the "%%PageSetup" section directly after + the DSC comment header of the page, all page drawing commands + must be after the section. + + * postscript.c: Inserted PostScript option settings from pstops + were not corrected with custom option settings done on the + command line (numerical, string, password). + + * options.c: Small fix for better readability. + + * renderer.c: If there was only one PJL option in the PPD no PJL got + added at all (Ubuntu bug #303691). + + * renderer.c: Fixed several bugs in the merging of PJL options. + In some cases equal keywords were not found in the two JCL + option sets or keywords only differing by the last character + were considered equal. Also a command in the first line of the + driver's PJL header got dropped. + +2008-11-26 Lars Uebernickel <larsuebernickel@gmx.de> + * options.c: When a numeric value is out of range, use the default + value instead of the closest valid value (i.e. min or max). Do not + truncate string options which are longer than allowed, use the + default instead. Apply AllowedChars and AllowedRegExp also to + Password options. + + Small bug fix: The generated regular expression for AllowedChars was + missing the final '$' and therefore didn't match all cases + correctly. + + Bug fix: Merge JCL options correctly + +2008-11-21 Lars Uebernickel <larsuebernickel@gmx.de> + * options.c: Fixed bug: Setting the page range of an option to + multiple ranges (seperated by comma), foomatic-rip was caught in an + infinte loop. + + * options.c: Fixed bug: Page ranges were not applied for command line + options when processing PostScript files (the renderer wasn't + restarted as it should have been). + +2008-11-13 Lars Uebernickel <larsuebernickel@gmx.de> + * options.c: Don't prepend @PJL to JCL options if they already start + with @PJL. Unhexify JCL commands. + + * options.c: Handle CustomJCL<option> and ParamCustomJCL<option>. + Prefer JCL Custom options over foomatic options (as was already done + for PostScript options). + +2008-10-22 Till Kamppeter <till.kamppeter@gmail.com> + + * postscript.c: Reset the "fromcomposite" variable when treating + a "%%BeginFeature" line. In this case we do not do the treatment + of composite options and so the variable should never remain set + from a previous "%%FoomaticRIPOption" line. Fixes the problem + described in comment #23 of bug #173. + +2008-10-15 Lars Uebernickel <larsuebernickel@gmx.de> + * ppd.c: In some cases, the code for the true and false settings of + boolean values was interchanged. E.g., if the user (or the default) + chose "false" for an option, the code for "true" was embedded in the + PostScript / JCL / Command Line. + +2008-10-15 Lars Uebernickel <larsuebernickel@gmx.de> + * postscript.c: Let foomatic-rip not try to correct the + settings of boolean and enumerated choice options embedded in + the Prolog and Setup sections of the PostScript input data. With + the current pstops filter of CUPS we cannot determine any more + whether these options come from pstops or from the application. + Corrections of these options are only needed in the PageSetup, + anyway, for page overrides (Bug #173). [ported from foomatic-rip 3] + +2008-10-01 Lars Uebernickel <larsuebernickel@gmx.de> + * pdf.c: Use $TMPDIR for storing temporary files, and only use + P_tmpdir or /tmp if $TMPDIR is not writable. + +2008-09-25 Till Kamppeter <till.kamppeter@gmail.com> + + * beh.in: Use /tmp as temporary directory when CUPS does not + supply the $TMPDIR environment variable (Ubuntu bug #268284). + +2008-09-24 Lars Uebernickel <larsuebernickel@gmx.de> + * foomaticrip.c: Remove leading whitespace from jobs instead of + passing it on. Flush() standard output after writing leading data to + ensure it comes first (not after or between the output of the + renderer). + +2008-09-24 Lars Uebernickel <larsuebernickel@gmx.de> + * pdf.c, renderer.c: Put JCL data also around PDF documents + +2008-08-13 Lars Uebernickel <larsuebernickel@gmx.de> + * pdf.c: foomatic-rip inserted the -sOutputFile GhostScript command + line argument at the wrong position when printing a PDF file (not from + stdin), which led GhostScript to crash + * options.c: Option settings can be given in the PPD file before the + option is "declared", which led foomatic-rip to think that there are + PostScript options (the default) in the PPD and the driver could not + understand PDF input. Now, foomatic-rip checks for PostScript + options after the whole PPD has been read. + +2008-08-12 Lars Uebernickel <larsuebernickel@gmx.de> + * options.c: Use FoomaticRIPCommandLinePDF if it is available. Don't + use it if at least one option wants to insert PostScript code + * pdf.c: Only create a temporary file if there actually are page + overrides, not if printing the whole document + * postscript.c: Fixed bug #142, custom input value which was wrongly + set by pstops was not set to the correct value by foomatic-rip + +2008-08-05 Lars Uebernickel <larsuebernickel@gmx.de> + * renderer.c: fixed bug #146, merging of JCL options omitted some + options. + * options.c: Fixed bug #151, crash when default value of an option was + set from a composite option. + +2008-07-30 Lars Uebernickel <larsuebernickel@gmx.de> + * *: Added support for the *FoomaticRIPCommandLinePDF keyword. It will + be used for PDF input. If it is missing, *FoomaticRIPCommandLine + will be used _only_ if it calls GhostScript, otherwise the Job is + converted to PostScript. + * pdf.c: Pagerange-specific options work correctly now. If the command + line calls GhostScript, the -d(First|Last)Page parameters are used. + Otherwise, the PDF is split with GhostScript and fed to the command + line afterwards. + +2008-06-22 Lars Uebernickel <larsuebernickel@gmx.de> + * options.c: Allow float values on *OrderDependency settings. This is + valid according to the PPD spec, and is used by some HP PPDs. + +2008-06-17 Lars Uebernickel <larsuebernickel@gmx.de> + * options.c: Allow choices starting with "From". Even if they do not + point to a valid composite option. + * renderer.c: Parse more complex command lines correctly when looking + for the "gs" executable + +2008-06-17 Lars Uebernickel <larsuebernickel@gmx.de> + * options.c, postscript.c: fixed bug #138 (foomatic-rip does not + always insert the code pieces of the members of composite options) + +2007-06-13 Till Kamppeter <till.kamppeter@gmail.com> + + * renderer.c: When replacing elements of the Ghostscript command line, + do not remove the spaces between the items. This made printing with + the new foomatic-rip not working in general for most cases. + +2008-05-11 Lars Uebernickel <larsuebernickel@gmx.de> + * pdf backend: removed poppler dependency, process pdfs with libgs + now. Changed the buildsystem to reflect this. + +2008-04-23 Lars Uebernickel <larsuebernickel@gmx.de> + + * foomatic-rip.c, configure.ac: Compose the current version out of the + contents of VERSION and `bzr revno`. It is now possible to find out + foomatic-rip's version by calling it with one of "--version", "-v", + "--help", or "-h". + +2008-04-22 Lars Uebernickel <larsuebernickel@gmx.de> + + * foomatic-rip.c, options.c: Fixed a bug in option parsing (some + options were not read correctly). + + Let option settings for the "PageSetup" sections of the + PostScript input file really be inserted in and not before the + "PageSetup" sections. + +2008-04-21 Lars Uebernickel <larsuebernickel@gmx.de> + + * postscript.c, options.c: New placeholder "&rbinumcopies;" which gets + replaced by the value set in the "%RBINumCopies: ..." or + "%%RBINumCopies: ..." line in the PostScript input. If the PostScript + input does not contain such lines, the number of copies according to + the foomatic-rip command line is inserted. Feature request of George + Liu from Ricoh. + +2008-03-17 Lars Uebernickel <larsuebernickel@gmx.de> + * foomaticrip.c, options.c: Moved buildcommandline() and + append_*_section() to options.c, where they belong. + * foomaticrip.c, spooler.c: Moved some spooler specific stuff to spooler.c + to clean up foomaticrip.c some more. + +2008-03-16 Lars Uebernickel <larsuebernickel@gmx.de> + * foomaticrip.c: Started to move all process forking to process.c - to + share it with the pdf handler. Furthermore, the functions in process.c + will keep track of all forked processes and kill them when foomatic-rip + reveives a SIGTERM. + +2008-03-08 Lars Uebernickel <larsuebernickel@gmx.de> + * options.c: Accept custom page sizes without a unit (assume pt) + +2008-03-04 Lars Uebernickel <larsuebernickel@gmx.de> + * foomatic-rip.c, options.c: Use default values for custom options with + wrong parameters (e.g. PageSize=Custom) - Ubuntu bug #196687 + +2008-03-03 Lars Uebernickel <larsuebernickel@gmx.de> + * foomatic-rip.c: Fixed minor bug in option parsing + * pdf.cc/pdf.h: Beginning of pdf printing support. Printing is done + via ghostscript, using the commandline in the ppd file that is already + used for rendering postscript. + +2008-01-26 Lars Uebernickel <larsuebernickel@gmx.de> + * foomatic-rip: Fixed minor bugs found while testing foomatic-rip + with cups. + +2008-01-22 Lars Uebernickel <larsuebernickel@gmx.de> + * foomatic-rip: Merged foomatic-gswrapper into foomatic-rip. + * *: Fixed 'make install' + +2008-01-14 Lars Uebernickel <larsuebernickel@gmx.de> + * *: Added support for CUPS custom options + (see http://www.cups.org/documentation.php/spec-ppd.html#OPTIONS) + o PPD files can contain both CUPS and foomatic custom options + o Custom options can be set like this on the command line: + Options with a single parameter: + -o optionname=Custom.value or + -o optionname=value + Options with multiple parameters: + -o optionname={param1=value1 param2=value2 ...} + + * options.c: Refactored the options system to allow for custom + options. As a nice side effect, lots of redundant code (getting + commands / drivervalues for the options, syncing PageSize + and PageRegion) could be removed from foomaticrip.c. + +2007-12-21 Lars Uebernickel <larsuebernickel@gmx.de> + * *: Converted foomatic-rip to C and updated the build system. + 2007-12-04 Till Kamppeter <till.kamppeter@gmail.com> * foomatic-gswrapper.in: Let Ghostscript always use buffered @@ -0,0 +1,236 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..03e437e --- /dev/null +++ b/Makefile.am @@ -0,0 +1,159 @@ + +# Variables +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +bindir=@bindir@ +sbindir=@sbindir@ +mandir=@mandir@ +sysconfdir=@sysconfdir@ + +PREFIX=$(prefix) +SRC=@srcdir@ + +BINDIR=$(bindir) +SBINDIR=$(sbindir) +MANDIR=$(mandir) +ETCDIR=$(sysconfdir)/foomatic +INSTALL=@INSTALL@ + +# Paths for CUPS +CUPS=@CUPS@ +CUPS_FILTERS=@CUPS_FILTERS@ +CUPS_BACKENDS=@CUPS_BACKENDS@ + +# Paths for PPR +PPR=@PPR@ +PPR_INTERFACES=@PPR_INTERFACES@ +PPR_LIB=@PPR_LIB@ + +# This is mainly useful for building a binary foomatic package +#DESTDIR= + +bin_PROGRAMS = foomatic-rip + +foomatic_ripdir = . +foomatic_rip_SOURCES = \ + foomaticrip.c \ + foomaticrip.h \ + options.c \ + options.h \ + pdf.c \ + pdf.h \ + postscript.c \ + postscript.h \ + util.c \ + util.h \ + spooler.h \ + spooler.c \ + process.h \ + process.c \ + renderer.c \ + renderer.h \ + fileconverter.c \ + fileconverter.h + +AM_CPPFLAGS = -DCONFIG_PATH='"$(sysconfdir)/foomatic"' + +# Masks for trash files which have to be removed before packaging Foomatic +TRASHFILES="*~" "*\#*" ".??*" "*.rej" + +# The install rule should check for kitloads and avoid stomping. It doesn't +install: install-main install-cups install-ppr + +install-main: install-bin install-man + +install-cups: install-bin + ${SRC}/mkinstalldirs $(DESTDIR)$(CUPS_FILTERS) + ${SRC}/mkinstalldirs $(DESTDIR)$(CUPS_BACKENDS) + ln -sf $(BINDIR)/foomatic-rip $(DESTDIR)$(CUPS_FILTERS) + ${INSTALL} -m 755 beh $(DESTDIR)$(CUPS_BACKENDS) + +install-ppr: install-bin + ${SRC}/mkinstalldirs $(DESTDIR)$(PPR_INTERFACES) + ${SRC}/mkinstalldirs $(DESTDIR)$(PPR_LIB) + ln -sf $(BINDIR)/foomatic-rip $(DESTDIR)$(PPR_INTERFACES) + ln -sf $(BINDIR)/foomatic-rip $(DESTDIR)$(PPR_LIB) + +install-bin: install-etc + ${SRC}/mkinstalldirs $(DESTDIR)$(BINDIR) + (for FILE in $(bin_PROGRAMS) ; do \ + ${INSTALL} -m 755 $$FILE $(DESTDIR)$(BINDIR) ; done) + +install-etc: + ${SRC}/mkinstalldirs $(DESTDIR)$(ETCDIR)/direct + ${INSTALL} -m 644 ${SRC}/filter.conf $(DESTDIR)$(ETCDIR)/filter.conf.sample + if [ ! -f $(DESTDIR)$(ETCDIR)/filter.conf ] ; then ${INSTALL} -m 644 ${SRC}/filter.conf $(DESTDIR)$(ETCDIR); fi; + +install-man: + ${SRC}/mkinstalldirs $(DESTDIR)$(MANDIR) + ${SRC}/mkinstalldirs $(DESTDIR)$(MANDIR)/man1 + (for FILE in *.1 ; do \ + ${INSTALL} -m 444 $$FILE $(DESTDIR)$(MANDIR)/man1 ; done) + +# Clean up the source directory +clean: remove-trash + rm -f *.o foomatic-rip foomatic-rip.1 beh + rm -f .testing-stamp stamp-h1 + rm -f test/*.out + +distclean: clean + rm -f $(AC_OUTPUT_FILES) config.log config.status config.cache configure.lineno + rm -rf autom*.cache confdefs.h config.h + rm -f Makefile test/Makefile + rm -rf .deps + +maintainer-clean: distclean + rm -f configure config.h.in Makefile.in aclocal.m4 INSTALL VERSION.full + rm -f depcomp missing +# Remove editor backup and temporary files +remove-trash: + for m in $(TRASHFILES); do \ + find . -name "$$m" -xtype f -exec rm -f "{}" \; ; \ + done + +# Uninstall an installed Foomatic + +uninstall: uninstall-cups uninstall-ppr uninstall-main + +uninstall-main: uninstall-bin uninstall-man + +uninstall-bin: + ( cd $(DESTDIR)$(BINDIR) && \ + rm -f $(bin_PROGRAMS) \ + ) + +uninstall-etc: + rm -f $(DESTDIR)$(ETCDIR)/filter.conf + rm -f $(DESTDIR)$(ETCDIR)/filter.conf.sample + rmdir $(DESTDIR)$(ETCDIR)/direct || : + rmdir $(DESTDIR)$(ETCDIR) || : + +uninstall-cups: + rm -f $(DESTDIR)$(CUPS_FILTERS)/foomatic-rip + rm -f $(DESTDIR)$(CUPS_BACKENDS)/beh + rmdir $(DESTDIR)$(CUPS_FILTERS) || : + rmdir $(DESTDIR)$(CUPS_BACKENDS) || : + rmdir $(DESTDIR)$(CUPS) || : + +uninstall-ppr: + rm -f $(DESTDIR)$(PPR_INTERFACES)/foomatic-rip + rmdir $(DESTDIR)$(PPR_INTERFACES) || : + rm -f $(DESTDIR)$(PPR_LIB)/foomatic-rip + rmdir $(DESTDIR)$(PPR_LIB) || : + rmdir $(DESTDIR)$(PPR) || : + +uninstall-man: check-config + for m in $(bin_PROGRAMS); do \ + rm -f $(DESTDIR)$(MANDIR)/man1/$$m.*; \ + done + +# Various testing/debugging/etc targets +inplace: all + chmod a+rx $(bin_PROGRAMS) + +testing tests: inplace + cd tests ; $(MAKE) + +.PHONY: all install install-bin clean distclean maintainer-clean tests inplace + diff --git a/Makefile.in b/Makefile.in index f5af444..fed1b92 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,66 +1,599 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = . +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +bin_PROGRAMS = foomatic-rip$(EXEEXT) +subdir = . +DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/beh.in $(srcdir)/config.h.in \ + $(srcdir)/foomatic-rip.1.in $(top_srcdir)/configure AUTHORS \ + COPYING ChangeLog INSTALL NEWS TODO depcomp install-sh missing \ + mkinstalldirs +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno configure.status.lineno +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = beh foomatic-rip.1 +am__installdirs = "$(DESTDIR)$(bindir)" +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) +am_foomatic_rip_OBJECTS = foomaticrip.$(OBJEXT) options.$(OBJEXT) \ + pdf.$(OBJEXT) postscript.$(OBJEXT) util.$(OBJEXT) \ + spooler.$(OBJEXT) process.$(OBJEXT) renderer.$(OBJEXT) \ + fileconverter.$(OBJEXT) +foomatic_rip_OBJECTS = $(am_foomatic_rip_OBJECTS) +foomatic_rip_LDADD = $(LDADD) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I. +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(foomatic_rip_SOURCES) +DIST_SOURCES = $(foomatic_rip_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +INSTALL = @INSTALL@ +A2PS = @A2PS@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ -# Makefile to install foomatic-filters -# $Revision$ +# Paths for CUPS +CUPS = @CUPS@ +CUPS_BACKENDS = @CUPS_BACKENDS@ +CUPS_FILTERS = @CUPS_FILTERS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENSCRIPT = @ENSCRIPT@ +EXECPATH = @EXECPATH@ +EXEEXT = @EXEEXT@ +FILECONVERTER = @FILECONVERTER@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MPAGE = @MPAGE@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +POW_LIB = @POW_LIB@ -# PREFIX defaults to /usr/local for manually installed progs, so that they -# are not messed up on a system upgrade. -# -# `architecture independent', static data files i.e. perl libs go into -# $(PREFIX)/share/foomatic -# (user) executables into $(PREFIX)/bin/ -# system binaries go into $(PREFIX)/sbin -# configuration files into /etc/foomatic/*. -# +# Paths for PPR +PPR = @PPR@ +PPR_INTERFACES = @PPR_INTERFACES@ +PPR_LIB = @PPR_LIB@ +PRINTCAP = @PRINTCAP@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TEXTTOPS = @TEXTTOPS@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ # Variables +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +PREFIX = $(prefix) +SRC = @srcdir@ +BINDIR = $(bindir) +SBINDIR = $(sbindir) +MANDIR = $(mandir) +ETCDIR = $(sysconfdir)/foomatic +foomatic_ripdir = . +foomatic_rip_SOURCES = \ + foomaticrip.c \ + foomaticrip.h \ + options.c \ + options.h \ + pdf.c \ + pdf.h \ + postscript.c \ + postscript.h \ + util.c \ + util.h \ + spooler.h \ + spooler.c \ + process.h \ + process.c \ + renderer.c \ + renderer.h \ + fileconverter.c \ + fileconverter.h + +AM_CPPFLAGS = -DCONFIG_PATH='"$(sysconfdir)/foomatic"' + +# Masks for trash files which have to be removed before packaging Foomatic +TRASHFILES = "*~" "*\#*" ".??*" "*.rej" +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +am--refresh: + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ + cd $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + cd $(top_srcdir) && $(AUTOHEADER) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +beh: $(top_builddir)/config.status $(srcdir)/beh.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +foomatic-rip.1: $(top_builddir)/config.status $(srcdir)/foomatic-rip.1.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -bindir=@bindir@ -sbindir=@sbindir@ -mandir=@mandir@ -sysconfdir=@sysconfdir@ +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) +foomatic-rip$(EXEEXT): $(foomatic_rip_OBJECTS) $(foomatic_rip_DEPENDENCIES) + @rm -f foomatic-rip$(EXEEXT) + $(LINK) $(foomatic_rip_LDFLAGS) $(foomatic_rip_OBJECTS) $(foomatic_rip_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileconverter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foomaticrip.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/postscript.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/renderer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spooler.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + mkdir $(distdir) + $(mkdir_p) $(distdir)/. + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r $(distdir) +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && cd $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' +distuninstallcheck: + @cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) config.h +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install-exec: install-exec-am +install-data: install-data-am -PREFIX=$(prefix) -SRC=@srcdir@ +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -BINDIR=$(bindir) -SBINDIR=$(sbindir) -MANDIR=$(mandir) -ETCDIR=$(sysconfdir)/foomatic -INSTALL=@INSTALL@ +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: -# Paths for CUPS -CUPS=@CUPS@ -CUPS_FILTERS=@CUPS_FILTERS@ -CUPS_BACKENDS=@CUPS_BACKENDS@ +clean-generic: -# Paths for PPR -PPR=@PPR@ -PPR_INTERFACES=@PPR_INTERFACES@ -PPR_LIB=@PPR_LIB@ +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -# This is mainly useful for building a binary foomatic package -#DESTDIR= +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean-am: clean-binPROGRAMS clean-generic mostlyclean-am -### Probably nothing to fiddle past here +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-tags -# Files generated by the AC_OUTPUT call of "./configure" -AC_OUTPUT_FILES=Makefile foomatic-gswrapper foomatic-rip beh \ - foomatic-gswrapper.1 foomatic-rip.1 +dvi: dvi-am -# User programs and helper programs -BINFILES=foomatic-gswrapper foomatic-rip +dvi-am: -# Masks for trash files which have to be removed before packaging Foomatic -TRASHFILES="*~" "*\#*" ".??*" "*.rej" +html: html-am + +info: info-am + +info-am: -$(BINFILES): - @echo "please run \"./configure\" to generate the bits" - exit 1 +install-data-am: + +install-exec-am: install-binPROGRAMS + +install-info: install-info-am + +installcheck-am: + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \ + clean-binPROGRAMS clean-generic ctags dist dist-all dist-bzip2 \ + dist-gzip dist-shar dist-tarZ dist-zip distcheck distclean \ + distclean-compile distclean-generic distclean-hdr \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am install-exec \ + install-exec-am install-info install-info-am install-man \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-info-am -all: $(BINFILES) # The install rule should check for kitloads and avoid stomping. It doesn't install: install-main install-cups install-ppr @@ -81,7 +614,7 @@ install-ppr: install-bin install-bin: install-etc ${SRC}/mkinstalldirs $(DESTDIR)$(BINDIR) - (for FILE in $(BINFILES) ; do \ + (for FILE in $(bin_PROGRAMS) ; do \ ${INSTALL} -m 755 $$FILE $(DESTDIR)$(BINDIR) ; done) install-etc: @@ -97,21 +630,23 @@ install-man: # Clean up the source directory clean: remove-trash - rm -f .testing-stamp + rm -f *.o foomatic-rip foomatic-rip.1 beh + rm -f .testing-stamp stamp-h1 rm -f test/*.out distclean: clean rm -f $(AC_OUTPUT_FILES) config.log config.status config.cache configure.lineno - rm -rf autom*.cache confdefs.h - rm -f tests/Makefile + rm -rf autom*.cache confdefs.h config.h + rm -f Makefile test/Makefile + rm -rf .deps maintainer-clean: distclean - rm -f configure aclocal.m4 - + rm -f configure config.h.in Makefile.in aclocal.m4 INSTALL VERSION.full + rm -f depcomp missing # Remove editor backup and temporary files remove-trash: for m in $(TRASHFILES); do \ - find . -name "$$m" -exec rm "{}" \; ; \ + find . -name "$$m" -xtype f -exec rm -f "{}" \; ; \ done # Uninstall an installed Foomatic @@ -122,7 +657,7 @@ uninstall-main: uninstall-bin uninstall-man uninstall-bin: ( cd $(DESTDIR)$(BINDIR) && \ - rm -f $(BINFILES) \ + rm -f $(bin_PROGRAMS) \ ) uninstall-etc: @@ -146,15 +681,18 @@ uninstall-ppr: rmdir $(DESTDIR)$(PPR) || : uninstall-man: check-config - for m in $(BINFILES); do \ + for m in $(bin_PROGRAMS); do \ rm -f $(DESTDIR)$(MANDIR)/man1/$$m.*; \ done # Various testing/debugging/etc targets inplace: all - chmod a+rx $(BINFILES) + chmod a+rx $(bin_PROGRAMS) testing tests: inplace cd tests ; $(MAKE) .PHONY: all install install-bin clean distclean maintainer-clean tests inplace +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: @@ -1,5 +1,5 @@ -Foomatic 3.0.2 +Foomatic 4.0.0 ============== @@ -11,6 +11,7 @@ PostScript data into the printer's native format using a printer/driver specific, but spooler-independent PPD file. Till Kamppeter <till.kamppeter@gmail.com> +Lars Uebernickel <larsuebernickel@gmx.de> http://www.openprinting.org/ @@ -28,163 +29,127 @@ GPL. See http://www.gnu.org/. Bugs ---- -If you spot a data error or any other bug, either post on the Foomatic -developer mailing list +If you spot a data error or any other bug, please report it on the +OpenPrinting bug tracking system: -http://lists.freestandards.org/mailman/listinfo/printing-foomatic +http://bugs.linux-foundation.org/ -or post on the OpenPrinting site support forum - -http://forums.openprinting.org/list.php?34 +Choose "OpenPrinting" as the product and "foomatic-filters" as the component. Intro ----- -This is the stable version of Foomatic. See +For getting Foomatic PPD files for this version, go to -http://www.freestandards.org/en/OpenPrinting/Database/HowToContribute#programming +http://www.openprinting.org/ -to know more about its development. +See the README file of "foomatic-db-engine" for a (more or less) +complete overview of Foomatic. -Your suggestions, bug reports, patches, ... are welcome on +User discussion happens on: http://forums.openprinting.org/list.php?34 -For getting Foomatic PPD files for this version, go to +Developer mailing list: -http://www.openprinting.org/ +https://lists.linux-foundation.org/mailman/listinfo/printing-foomatic -See the README file of "foomatic-db-engine" for a (more or less) -complete overview of Foomatic. - -Supported spoolers ------------------- +Supported printing systems/spoolers +----------------------------------- CUPS - Common Unix Printing System (http://www.cups.org/) SOLARIS - Solaris LP (lpsched) LPD - Line Printer Daemon (Does this have a home page anywhere?) -LPRng - LPR - New Generation (http://www.lprng.org/) +LPRng - LPR - New Generation (https://sourceforge.net/projects/lprng/) GNUlpr - An enhanced LPD (http://sf.net/projects/lpr, development stopped) -PPR - Page PRinter spooler (http://ppr.sourceforge.net/) +PPR - Page PRinter spooler (http://ppr.sourceforge.net/, development + stopped) PDQ - Print, Don't Queue (http://pdq.sf.net/, development stopped) -CPS - Coherent Printing System (http://www.tww.cx/cps.php) +CPS - Coherent Printing System (http://www.tww.cx/cps.php, development + stopped) --- - Direct, spooler-less printing (http://www.openprinting.org/) +As most of the supported printing systems are not actively developed +any more, there support will be removed in a later version of +foomatic-rip. This can even happen before 5.x. For now their support +is deprecated and there were only few tests done during the +development of foomatic-rip 4.x. So be prepared that there are bugs +(patches welcome). Testing were mostly done with the de-facto standard +CUPS and spooler-less. -Programs and important files from this package ----------------------------------------------- - -This package contains only two scripts and its man pages: foomatic-rip -and foomatic-gswrapper. foomatic-rip is the main -PostScript-to-printer's-native-language filter and foomatic-gswrapper -is an m auxiliary filter ironing out some GhostScript quirks. - -foomatic-rip works with all spoolers and always uses PPD files for -printer/driver capabilities info. Manufacturer-supplied PPDs of -PostScript printers can be used, too. - -Note: The scripts appear as ".in" files in the source tree and CVS, -because the path for the Perl interpreter is inserted by the -"configure" script. The "configure" script makes the final files from -them with the inserted path of the Perl interpreter. - -configure.in - - The source from which GNU autoconf generates the "configure" script - -acinclude.m4 - - Additional macros for the "configure" script -make_configure +What is in this package? +------------------------ - Calls aclocal and autoconf to generate "configure" from "configure.ac" - and "acinclude.m4" +This package contains only two programs, its man pages, and a test +suite. The programs arw foomatic-rip and beh (Backend Error +Handler). foomatic-rip is the main +PostScript/PDF-to-printer's-native-language filter and beh is a CUPS +backend wrapper for fine-tuning how a CUPS queue should behave on +failure of its backend. -Makefile.in - - The template from which "configure" generates the Makefile - -install-sh - - Helper script for "configure" - -foomatic-rip - - Universal print filter (PostScript -> printer's native language) to be - used with all known printer spoolers (CUPS, Solaris LP, LPRng, LPD, GNUlpr, - PPR, PDQ, CPS, spooler-less printing). It Gets printer/driver capability - information from PPD files. The PPD files can either be generated from - the Foomatic database or they can be manufacturer-supplied PPD files - for PostScript printers. - -foomatic-gswrapper - - This is not really a file conversion or print filter, but it is used - by foomatic-rip when it is present. This is a wrapper around - Ghostscript. It regularizes options if they differ between gs - flavors. It also assures that the GhostScript output is not mixed up - with messages produced by some PostScript files (esp. files from - Windows). foomatic-rip auto-detects the presence of - foomatic-gswrapper. - -beh - - Usually, if a CUPS backend exits with an error status other than zero - (for example if a printer is not turned on or not reachable on the - network), CUPS disables the print queue and one can only print again - if a system administrator re-enables the queue manually. Even restarting - CUPS (or rebooting) does not re-enable disabled queues. - - This script makes the handling of such backend errors configurable, so - that the problem can easily be worked around. The execution of the backend - can be periodically repeated and/or the error state of the backend can - be kept away from CUPS, so that the queue stays active. - - See instructions in the beginning of the beh script and in the USAGE file. - -foomatic-rip.1 -foomatic-gswrapper,1 - - man pages for the filter scripts. +foomatic-rip works with all spoolers and always uses PPD files for +printer/driver capabilities info. Manufacturer-supplied PPDs (in most +cases of of PostScript printers) can be used, too. + +foomatic-rip is now written in C, in contrary to Perl in Foomatic +3.x. This allows foomatic-rip to link directly with libraries. Besides +the standard libraries, foomatic-rip currently only uses the +Ghostscript library libgs. The functionality of the former +foomatic-gswrapper is now integrated into foomatic-rip, so the +foomatic-gswrapper is not needed any more. + +beh is still written in Perl and does not need anything else than a +Perl interpreter.It is only for use with CUPS. + +The test/ subdirectory contains a test suite, originally developed for +the distribution compliance tests of the LSB. It also serves as a +regression test for further development of foomatic-rip. To execute +the test, go into that directory and run "./testfoomaticrip" as root +(as normal user the test series #13, CUPS queues, will not work) and +you test the foomatic-rip installed on your system. You can modify the +testing configuration by the variables in the beginning of the +script. The test suite will not get installed with the "make install" +command. + +The main directory contains the source code of foomatic-rip, beh, and +the infrastructure for building and installing the package. It also +contains the documentation. Dependencies ------------ -To build and run this package only a Perl interpreter (5.6.0 and -newer) is needed. +To build this package you need a C compiler, its standard libraries, +and the Ghostscript library (libgs, /usr/lib/libgs.so*). For the +latter Ghostscript must be built in shared library mode ("make +so"). If your libgs is provided by your operating system distribution, +make sure that its C headers (package libgs.dev(el) or +ghostscript.dev(el)) are installed. + +To run foomatic-rip you need to have the Ghostscript library installed. -To connect to remote printers, you need additional connectivity -software (as "rlpr", "nc", "smbspool', ...). +To run beh a Perl interpreter (5.6.0 and newer) is needed. + +To connect to remote printers in non-CUPS printing environments, you +need additional connectivity software (as "rlpr", "nc", "smbspool', +...). How does it work? ----------------- -foomatic-rip is a filter which takes PostScript (and also certain -non-PostScript formats) from standard input and translates it to the -printer's native language. The resulting data is usually directed to -standard output, but depending on the spooler abnd its configuration -it can also be directed to elsewhere. The information how to do this +foomatic-rip is a filter which takes PostScript or PDF (and for +non-CUPS operation also certain other formats which will get converted +to PostScript) from standard input and translates it to the printer's +native language. The resulting data is usually directed to standard +output, but depending on the spooler abnd its configuration it can +also be directed to elsewhere. The information how to do this translation it gets from a PPD file, from command line options, environment variables, and spooler configuration files. -foomatic-rip is designed in a way that it does neither use any -temporary files nor reads the whole print job into memory. So even -huge jobs can be printed without needing big resources. Data is only -buffered in memory as long as it is not clear how to treat the -data. This happens for example when we don't know yet whether the -input file is PostScript, or when we are searching for embedded option -settings. This is done by forking into up to 6 subprocesses which do -all the tasks of the filter chain in parallel, see the overview of -these subprocesses below. - -See also the numerous comments in the foomatic-rip Perl script. - - foomatic-rip does the following steps to do its work: @@ -210,7 +175,7 @@ Reading the PPD file In one of the previous steps we have found the name of the PPD file assigned to the print queue currently in use. Now the PPD file is read to get all information needed to build the renderer's (Usually, the -renderer is GhostScript, when no renderer is needed, as for a +renderer is Ghostscript, when no renderer is needed, as for a PostScript printer, "cat" is used) command line, the available options, their default values, and how to apply them. After having parsed the PPD file we have a renderer command line and a list of @@ -226,7 +191,7 @@ Applying user-supplied settings All option settings which the user has supplied on the command line are checked whether they are valid (option exists, choice in range) -and then applied to the list of default settigs, replacing the +and then applied to the list of default settings, replacing the defaults by the values given by the user. The options not mentioned on the command line keep their default values from the PPD file. @@ -247,7 +212,7 @@ Print files With some spoolers the job(s) to be printed is supplied in (a) file(s), in this case we close standard input and open the file on the -stabdard input handler. This way the following steps read from the +standard input handler. This way the following steps read from the file instead of from standard input. The rest of the foomatic-rip process is repeated for every input file, to print them one after the other. @@ -262,15 +227,34 @@ following steps will be omitted then. Print the job -After all the preparation, the PostScript job is examined for traces -of option settings supposed to be applied to the renderer's command -line or to the JCL (Job Coomand Language, for example PJL) header -which is sent to the printer before the renderer's output is sent. -PPD-aware applications and spoolers stuff option settings directly -into the file, they do not necessarily send PPD options by the command -line. There is also stuffed in PostScript code to apply option -settings given by the command line of the printing command ("lpr", -"lp", ...) and to set the defaults given in the PPD file. +Jobs are usually expected to be sent in PostScript or PDF format +(handling of other formats in non-CUPS environment will be shown +later). PostScript is the standard format for print jobs under Unix +and Linux for many years. Currently, we are on the way to move to PDF +as standard format +(http://www.linuxfoundation.org/en/OpenPrinting/PDF_as_Standard_Print_Job_Format). +Therefore we accept both formats. In most cases Ghostscript is the +renderer which understands both formats equally. So we do not convert +PDF to PostScript if either the renderer command line starts with "gs +..." as then Ghostscript is the renderer and no pre-processing of +incoming PostScript happens or we have a dedicated commad line +prototype for PDF defined in the PPD file +("*FoomaticRIPCommandLinePDF:" keyword). In addition there must be no +option at all which is implemented by inserting active PostScript code +(not only comments starting with "%") into a PostScript input data +stream. If these criteria are not fulfilled, the PDF job will be +converted to PostScript. + +After all the preparation, and if the job is PostScript the data +stream is examined for traces of option settings supposed to be +applied to the renderer's command line or to the JCL (Job Command +Language, for example PJL) header which is sent to the printer before +the renderer's output is sent. PPD-aware applications and spoolers +stuff option settings directly into the file, they do not necessarily +send PPD options by the command line. There is also stuffed in +PostScript code to apply option settings given by the command line of +the printing command ("lpr", "lp", ...) and to set the defaults given +in the PPD file. Examination strategy: We read lines from standard input until the first %%Page: comment appears and save them as @psheader. This is the @@ -332,18 +316,29 @@ setting in the first occurence of the option's code, as this one is the one added by CUPS, later occurences come from applications and should not be touched. -If the input is not PostScript (if there is no "%!" after -$maxlinestopsstart lines) a file conversion filter will automatically -be applied to the incoming data, so that we will process the resulting -PostScript here. This way we have always PostScript data here and so -we can apply the printer/driver features described in the PPD -file. For the file conversion filter two subprocesses are started, the -task of the first one is to pass the already buffered lines into the -filter and then to continue reading standard input (without parsing -the data) to pass the rest of the job to the filter. The second -subprocess is the filter itself, getting its standard input from the -first subprocess and the giving its standard output to the main -process. This way the main process has again PostScript as its +If the input data is PDF then we do not search for options in the data +stream nor do we try to insert settings, as this is not forseen by +PDF. As told above, data in PDF format is only passed on as PDF if +there are no options in the PPD file which are implemented by +PostScript code to be embedded in the data stream. All options are +command line or JCL options. If there are page-dependent option +changes we always restart the renderer with the changed JCL and +command line options. We tell the renderer by command line options +which pages he has to print. + +If we are in a non-CUPS environment and the input is neither +PostScript nor PDF (if there is no "%!" after $maxlinestopsstart +lines) a file conversion filter (input format -> PostScript) will +automatically be applied to the incoming data, so that we will process +the resulting PostScript here. This way we have always PostScript data +here and so we can apply the printer/driver features described in the +PPD file. For the file conversion filter two subprocesses are started, +the task of the first one is to pass the already buffered lines into +the filter and then to continue reading standard input (without +parsing the data) to pass the rest of the job to the filter. The +second subprocess is the filter itself, getting its standard input +from the first subprocess and the giving its standard output to the +main process. This way the main process has again PostScript as its standard input. Supported file conversion filters are "a2ps", "enscript", "mpage", and @@ -353,25 +348,25 @@ used when one prints the documentation pages, as they are created as plain text, when CUPS is the spooler "pstops" is executed after the filter so that the default option settings from the PPD file and CUPS-specific options as N-up get applied. On regular printouts one -gets always PostScript when CUPS or PPR is the spooler, so the filter -is only used for regular printouts under LPD, LPRng, GNUlpr, PDQ, or -without spooler. +gets always PostScript or PDF when CUPS is the spooler and PostScript +in the case of PPR, so the filter is only used for regular printouts +under LPD, LPRng, GNUlpr, PDQ, or without spooler. -The main process keeps always parsing the PostScript onput, it -launches the renderer in one subprocess and launches and additional -subprocess for bracketing the renderer's output with the JCL commands -and putting the resulting data to standard output or to the postpipe. +The main process keeps always parsing the PostScript input or feeding +through the PDF input, it launches the renderer in one subprocess and +launches an additional subprocess for bracketing the renderer's output +with the JCL commands and putting the resulting data to standard +output or to the postpipe. Overview of the subprocesses ---------------------------- To do the filtering without loading the whole file into memory we work -on a data stream, we read the data line by line analyse it to decide what +on a data stream, we read the data line by line, analyse it to decide what filters to use and start the filters if we have found out which we need. We buffer the data only as long as we didn't determine which filters to -use for this piece of data and with which options. There are no temporary -files used. +use for this piece of data and with which options. foomatic-rip splits into up to 6 parallel processes to do the whole filtering (listed in the order of the data flow): @@ -391,7 +386,7 @@ filtering (listed in the order of the data flow): as soon as it knows its command line and restarts it when page-specific option settings need another command line or different JCL commands. - KID3: The rendering process. In most cases GhostScript, "cat" + KID3: The rendering process. In most cases Ghostscript, "cat" for native PostScript printers with their manufacturer's PPD files. KID4: Put together the JCL commands and the renderer's output diff --git a/STANDARD_installation b/STANDARD_installation index e957c6c..e2647da 100644 --- a/STANDARD_installation +++ b/STANDARD_installation @@ -7,7 +7,9 @@ make make -n install set +x if [ "`id -u`" != 0 ] ; then - echo "run make install as root" + echo "run make install as root:" echo "su root -c 'make install'" + echo " OR " + echo "sudo make install" exit 1 fi @@ -8,8 +8,6 @@ See also the bugtracker at foomatic.sourceforge.net. - Write a few key lint-like and transforming tools for the xml data. - - Fold foomatic-gswrapper into the foomatic-rip - - Improve ascii support to lpdomatic and pdq files. ASCII should simply be a matter of observing the ascii bit in the printer $dat and sending either crlf-ed text or postscriptifying and running @@ -1,5 +1,5 @@ -Foomatic 3.0.2 +Foomatic 4.0.0 ============== foomatic-filters @@ -10,6 +10,7 @@ PostScript data into the printer's native format using a printer/driver specific, but spooler-independent PPD file. Till Kamppeter <till.kamppeter@gmail.com> +Lars Uebernickel <larsuebernickel@gmx.de> http://www.openprinting.org/ @@ -20,46 +21,38 @@ Intro ----- Foomatic is a database providing information about the usage of -printers with free operating systems and free printer drivers, where -"free" is meant as free software in the sense of the Free Software -Foundation (http://www.gnu.org). Therefore the database only contains -information about printer drivers which are free software. The -technology of this database can also be used for non-free drivers, but -the database entries have to be published in separate packages -then. The database can also be run under non-free operating systems -(as commercial Unixes) as they often use GhostScript and free printer -drivers. - -Since most free operating systems (GNU/Linux, *BSD, ...) are -compatible to Unix, their applications send PostScript to the printer -queues. Therefore one usually hands over the PostScript directly to a -PostScript printer (sometimes with some prepended PostScript commands -for options) or uses GhostScript for generating the data format the -printer needs. This is done by the printer spooler which also stores -the data in a spool directory when the printer is still occupied by -another job, transmits the data to a print server in the network, and -so on. +printers with Unix-like operating systems (Linux, Solaris, ...). + +The applications of these operating systems send PostScript or PDF to +the printer queues. Therefore one usually hands over the PostScript +directly to a PostScript printer (sometimes with some inserted +PostScript commands for options) or uses Ghostscript for generating +the data format the printer needs from PostScript or PDF input. This +is done by the printer spooler which also stores the data in a spool +directory when the printer is still occupied by another job, transmits +the data to a print server in the network, and so on. The printer drivers for non-PostScript printers are either compiled -into GhostScript, a plug-in for GhostScript (e. g. IJS drivers), or +into Ghostscript, a plug-in for Ghostscript (e. g. IJS drivers), or they are an extra filter which converts a generic bitmap generated by -GhostScript into the printer's data format. For this the spooler has -to call complicated command lines of GhostScript and the extra filter -(if needed). The user of a free operating system normally does not see -these command lines because an installation program takes appropriate -filter scripts and/or description files from a database and assigns -them to the printer queue. +Ghostscript into the printer's data format. For this the spooler has +to call complicated command lines of Ghostscript and the extra filter +(if needed). The user of a Unix-like operating system normally does +not see these command lines because an installation program takes +appropriate filter scripts and/or description files from a database +and assigns them to the printer queue. Widely used databases were the RHS-Printfilters and the APS filters. Their disadvantages were that they only supported one spooler (LPD/LPRng) and only a small part of the driver's options (mostly page size and resolution). Foomatic supports all options of the drivers and -all known spoolers (LPD, LPRng, GNUlpr, CUPS, Solaris LP, PPR, PDQ, CPS, direct -spooler-less printing). In addition, all known free software printer -drivers are supported. Foomatic also supports printing of various -non-PostScript file types for spoolers which do not support this by -themselves (LPD, LPRng, GNUlpr, spooler-less printing). To enable this -feature you need to have "a2ps", "enscript", or "mpage" installed. +all known spoolers (LPD, LPRng, GNUlpr, CUPS, Solaris LP, PPR, PDQ, +CPS, direct spooler-less printing). In addition, all known free +software printer drivers are supported. Foomatic also supports +printing of various non-PostScript/PDF file types for spoolers which +do not support these by themselves (LPD, LPRng, GNUlpr, spooler-less +printing). To enable this feature you need to have "a2ps", "enscript", +or "mpage" installed. Another problem is that the way how to install queues, to print files, and to handle jobs is very different with different spoolers. LPD for @@ -79,17 +72,31 @@ Installation ------------ Foomatic runs on all systems where one can run the Perl -interpreter. +interpreter and Ghostscript. + +foomatic-filters needs the Ghostscript library for foomatic-rip and +the Perl interpreter for beh (Backend Error Handler) and the test +suite. + +To build foomatic-rip you need a C compiler, its standard libraries, +and the Ghostscript library (libgs, /usr/lib/libgs.so*). For the +latter Ghostscript must be built in shared library mode ("make +so"). If your libgs is provided by your operating system distribution, +make sure that its C headers (package libgs.dev(el) or +ghostscript.dev(el)) are installed. -foomatic-filters needs nothing else than the Perl interpreter to build -and run. +To run foomatic-rip you need to have the Ghostscript library installed. -To connect to remote printers, you need additional connectivity -software (as "rlpr", "nc", "smbspool', ...). To print non-PostScript -files with LPD, LPRng, GNUlpr, or without spooler, you will need a2ps, -enscript, mpage, or similar filters which convert non-PostScript files -to PostScript. a2ps, enscript, and mpage will be automatically used by -the scripts when they are installed. +To run beh (Backend Error Handler) or the test suite a Perl interpreter +(5.6.0 and newer) is needed. + +To connect to remote printers with a non-CUPS printing system, you +need additional connectivity software (as "rlpr", "nc", "smbspool', +...). To print non-PostScript/PDF files with LPD, LPRng, GNUlpr, or +without spooler, you will need a2ps, enscript, mpage, or similar +filters which convert non-PostScript files to PostScript. a2ps, +enscript, and mpage will be automatically used by the scripts when +they are installed. Download sources: rlpr: http://freshmeat.net/projects/rlpr/ or @@ -101,15 +108,16 @@ used with PPD files downloaded from the OpenPrinting site, with manufacturer-supplied PPDs for PostScript printers, and probably with other PPD files. -For non-PostScript printers one also needs GhostScript (5.50 or newer, -ESP GhostScript 7.05.4 or newer highly recommended) and the -appropriate printer driver. +For non-PostScript printers one also needs Ghostscript (5.50 or newer, +GPL Ghostscript 8.63 or newer highly recommended) and the appropriate +printer driver. -For drivers which have to be compiled into GhostScript ("Execution -style: GhostScript" on the driver pages on the OpenPrinting site) -check with "gs -h" whether the driver is in your GhostScript. If not -you need to compile the driver into your GhostScript or use a -GhostScript version which already contains it. +For drivers which have to be compiled into Ghostscript ("Execution +style: Ghostscript built-in" on the driver pages on the OpenPrinting +site) check with "gs -h" whether the driver is in your Ghostscript. If +not you need to compile the driver into your Ghostscript or use a +Ghostscript version which already contains it (preferably GPL +Ghostscript 8.63 or newer). If the driver page says "Execution style: Uniprint", it is much easier, check whether the appropriate ".upp" file is in one of the @@ -119,16 +127,15 @@ not there already. The third type of driver is marked with "Execution style: Filter", this means, that you have to install a filter executable in addition -to GhostScript. Check with "which <name of the filter>" whether the +to Ghostscript. Check with "which <name of the filter>" whether the filter is already there, otherwise download and install the appropriate package. - - foomatic-filters can be installed using these commands (if you have -downloaded this package from CVS, run "./make_configure" at first, for -that you will also need the "autoconf" and "aclocal" utilities, -"aclocal" is in the "automake" package in some distributions): +downloaded this package from the BZR repository, run +"./make_configure" at first, for that you will also need the +"autoconf" and "aclocal" utilities, "aclocal" is in the "automake" +package in some distributions): ./configure make @@ -137,19 +144,20 @@ that you will also need the "autoconf" and "aclocal" utilities, "make install" must be run as "root", the other commands can be run as a normal user. -The "configure" script will auto-detect where the scripts have to be -installed and where the Perl interpreter is located. If "configure" -fails because of something not being installed, do +The "configure" script will auto-detect where the programs have to be +installed and where the Perl interpreter and the Ghostscript library +are located. If "configure" fails because of something not being +installed, do rm -rf config.cache autom*.cache before you run "configure" again (after installing the missing parts). -By default, foomatic-filters is installed into subdirectories of /usr/local -(e. g. /usr/local/bin/foomatic-gswrapper), to get it into subdirectories -of /usr (/usr/bin/foomatic-gswrapper), enter: +By default, foomatic-filters is installed into subdirectories of +/usr/local (e. g. /usr/local/bin/foomatic-rip), to get it into +subdirectories of /usr (/usr/bin/foomatic-rip), enter: - ./configure --prefix=/usr + ./configure --prefix=/usr --sysconfdir=/etc make make install @@ -170,25 +178,24 @@ and enter the commands with "./" in the beginning (e. g. "./foomatic-rip ...", "man ./foomatic-rip.1"). This also works on a machine where a system-wide Foomatic is already installed. -In addition, you should install a utility to make PostScript out of -non-PostScript files, so that you can print those non-PostScript files -and also a list of available options using the "docs" option. The -supported utilities are "a2ps" +In addition, if you do not use CUPS, you should install a utility to +make PostScript out of non-PostScript files, so that you can print +those non-PostScript files and also a list of available options using +the "docs" option. The supported utilities are "a2ps" (http://www-inf.enst.fr/~demaille/a2ps/), "enscript" (http://people.ssh.fi/mtr/genscript/), and "mpage" (http://www.mesa.nl/pub/mpage). Recommended is "a2ps" because it -detects many file types (text, PDF, most image formats) and together -with ImageMagick (for images) and GNU/ESP/AFPL GhostScript 6.51 or -newer (for PDF) it converts them to PostScript. The other tools -convert only text files. The tool you have installed is auto-detected -by foomatic-rip and used automatically if necessary. PPR needs this -tool only for printing the option list, and CUPS does not need it at -all. PPR and CUPS use internal filters for printing non-PostScript -files. +detects many file types (text, most image formats) and together with +ImageMagick (for images) and Ghostscript it converts them to +PostScript. The other tools convert only text files. The tool you have +installed is auto-detected by foomatic-rip and used automatically if +necessary. PPR needs this tool only for printing the option list, and +CUPS does not need it at all. PPR and CUPS use internal filters for +printing non-PostScript files. If you have a printer or multi-function device from HP, install HPLIP from - http://hpinkjet.sourceforge.net/ + http://hplipopensource.com/ before starting to set up printer queues with foomatic-filters. This is needed for printing on certain USB devices and for scanning and @@ -0,0 +1 @@ +4.0.0 diff --git a/VERSION.full b/VERSION.full new file mode 100644 index 0000000..ff2ce95 --- /dev/null +++ b/VERSION.full @@ -0,0 +1 @@ +4.0.0.200 diff --git a/acinclude.m4 b/acinclude.m4 index 92bc6b3..1c36cea 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1,5 +1,5 @@ dnl AC_PATH_DIR(VARIABLE, DIR-TO-CHECK-FOR [, VALUE-IF-NOT-FOUND [, PATH]]) -AC_DEFUN(AC_PATH_DIR, +AC_DEFUN([AC_PATH_DIR], [# Extract the first word of "$2", so it can be a program name with args. set dummy $2; ac_word=[$]2 AC_MSG_CHECKING([for $ac_word/]) @@ -42,7 +42,7 @@ AC_SUBST($1)dnl dnl AC_PATH_DIRS(VARIABLE, DIRSS-TO-CHECK-FOR [, VALUE-IF-NOT-FOUND dnl [, PATH]]) -AC_DEFUN(AC_PATH_DIRS, +AC_DEFUN([AC_PATH_DIRS], [for ac_dir in $2 do AC_PATH_DIR($1, [$]ac_dir, , $4) @@ -11,4 +11,841 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. +# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.9.6])]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 7 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 3 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 12 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.58])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. +# +# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories +# created by `make install' are always world readable, even if the +# installer happens to have an overly restrictive umask (e.g. 077). +# This was a mistake. There are at least two reasons why we must not +# use `-m 0755': +# - it causes special bits like SGID to be ignored, +# - it may be too restrictive (some setups expect 775 directories). +# +# Do not use -m 0755 and let people choose whatever they expect by +# setting umask. +# +# We cannot accept any implementation of `mkdir' that recognizes `-p'. +# Some implementations (such as Solaris 8's) are not thread-safe: if a +# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' +# concurrently, both version can detect that a/ is missing, but only +# one can create it and the other will error out. Consequently we +# restrict ourselves to GNU make (using the --version option ensures +# this.) +AC_DEFUN([AM_PROG_MKDIR_P], +[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi +AC_SUBST([mkdir_p])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar <conftest.tar]) + grep GrepMe conftest.dir/file >/dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + m4_include([acinclude.m4]) @@ -145,7 +145,9 @@ if (!$printFile) { my $uid = $userName; $jid =~ s/\W//g; #sanity check $uid =~ s/\W//g; #sanity check - $tempFile = "$ENV{TMPDIR}/$jid-$uid-cupsjob$$"; + my $tmpDir = $ENV{TMPDIR}; + $tmpDir ||= "/tmp"; + $tempFile = "$tmpDir/$jid-$uid-cupsjob$$"; open (OUT, ">$tempFile") or die "ERROR: Cannot write $tempFile: $!\n"; diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..1c429d7 --- /dev/null +++ b/config.h.in @@ -0,0 +1,174 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +#undef HAVE_DOPRNT + +/* Define to 1 if you have the `dup2' function. */ +#undef HAVE_DUP2 + +/* Define to 1 if you have the <fcntl.h> header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `fork' function. */ +#undef HAVE_FORK + +/* Define to 1 if you have the `getcwd' function. */ +#undef HAVE_GETCWD + +/* Define to 1 if you have the `gethostname' function. */ +#undef HAVE_GETHOSTNAME + +/* Define to 1 if you have the <ghostscript/iapi.h> header file. */ +#undef HAVE_GHOSTSCRIPT_IAPI_H + +/* Define to 1 if you have the <ghostscript/ierrors.h> header file. */ +#undef HAVE_GHOSTSCRIPT_IERRORS_H + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `gs' library (-lgs). */ +#undef HAVE_LIBGS + +/* Define to 1 if you have the `m' library (-lm). */ +#undef HAVE_LIBM + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#undef HAVE_MALLOC + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if your system has a GNU libc compatible `realloc' function, + and to 0 otherwise. */ +#undef HAVE_REALLOC + +/* Define to 1 if you have the `regcomp' function. */ +#undef HAVE_REGCOMP + +/* Define to 1 if you have the `setenv' function. */ +#undef HAVE_SETENV + +/* Define to 1 if you have the <stddef.h> header file. */ +#undef HAVE_STDDEF_H + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the `strcspn' function. */ +#undef HAVE_STRCSPN + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strncasecmp' function. */ +#undef HAVE_STRNCASECMP + +/* Define to 1 if you have the `strndup' function. */ +#undef HAVE_STRNDUP + +/* Define to 1 if you have the `strrchr' function. */ +#undef HAVE_STRRCHR + +/* Define to 1 if you have the `strstr' function. */ +#undef HAVE_STRSTR + +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vfork' function. */ +#undef HAVE_VFORK + +/* Define to 1 if you have the <vfork.h> header file. */ +#undef HAVE_VFORK_H + +/* Define to 1 if you have the `vprintf' function. */ +#undef HAVE_VPRINTF + +/* Define to 1 if `fork' works. */ +#undef HAVE_WORKING_FORK + +/* Define to 1 if `vfork' works. */ +#undef HAVE_WORKING_VFORK + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if your <sys/time.h> declares `struct tm'. */ +#undef TM_IN_SYS_TIME + +/* Foomatic version */ +#undef VERSION + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to rpl_malloc if the replacement function should be used. */ +#undef malloc + +/* Define to `int' if <sys/types.h> does not define. */ +#undef pid_t + +/* Define to rpl_realloc if the replacement function should be used. */ +#undef realloc + +/* Define to `unsigned int' if <sys/types.h> does not define. */ +#undef size_t + +/* Define to `int' if <sys/types.h> does not define. */ +#undef ssize_t + +/* Define as `fork' if `vfork' does not work. */ +#undef vfork @@ -1,25 +1,54 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.59. +# Generated by GNU Autoconf 2.61 for foomatic-rip "4.0.0". # -# Copyright (C) 2003 Free Software Foundation, Inc. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## -# Be Bourne compatible +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh fi -DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then @@ -29,8 +58,43 @@ else fi +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + # Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done PS1='$ ' PS2='> ' PS4='+ ' @@ -44,18 +108,19 @@ do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else - $as_unset $as_var + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; then +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi -if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false @@ -63,157 +128,388 @@ fi # Name of the executable. -as_me=`$as_basename "$0" || +as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || + X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` +# CDPATH. +$as_unset CDPATH -# PATH needs CR, and LINENO needs CR and PATH. -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no fi + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in + case $as_dir in /*) - if ("$as_dir/$as_base" -c ' + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( as_lineno_1=$LINENO as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop - s,-$,, - s,^['$as_cr_digits']*\n,, + s/-\n.*// ' >$as_me.lineno && - chmod +x $as_me.lineno || + chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" # Exit status is that of the last command. exit } -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; esac -if expr a : '\(a\)' >/dev/null 2>&1; then +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi -rm -f conf$$ conf$$.exe conf$$.file +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: @@ -222,7 +518,28 @@ else as_mkdir_p=false fi -as_executable_p="test -f" +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -231,49 +548,187 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH +exec 7<&0 </dev/null 6>&1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` -exec 6>&1 - # # Initializations. # ac_default_prefix=/usr/local +ac_clean_files= ac_config_libobj_dir=. +LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} -# Maximum number of lines to put in a shell here document. -# This variable seems obsolete. It should probably be removed, and -# only ac_max_sed_lines should be used. -: ${ac_max_here_lines=38} - # Identity of this package. -PACKAGE_NAME= -PACKAGE_TARNAME= -PACKAGE_VERSION= -PACKAGE_STRING= -PACKAGE_BUGREPORT= - -ac_unique_file="foomatic-rip.in" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE PERL PRINTCAP CUPS CUPS_FILTERS CUPS_BACKENDS PPR PPR_INTERFACES PPR_LIB A2PS ENSCRIPT MPAGE TEXTTOPS FILECONVERTER ECHO EXECPATH LIBOBJS LTLIBOBJS' +PACKAGE_NAME='foomatic-rip' +PACKAGE_TARNAME='foomatic-rip' +PACKAGE_VERSION='"4.0.0"' +PACKAGE_STRING='foomatic-rip "4.0.0"' +PACKAGE_BUGREPORT='' + +ac_unique_file="options.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +CYGPATH_W +PACKAGE +VERSION +ACLOCAL +AUTOCONF +AUTOMAKE +AUTOHEADER +MAKEINFO +install_sh +STRIP +INSTALL_STRIP_PROGRAM +mkdir_p +AWK +SET_MAKE +am__leading_dot +AMTAR +am__tar +am__untar +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +DEPDIR +am__include +am__quote +AMDEP_TRUE +AMDEP_FALSE +AMDEPBACKSLASH +CCDEPMODE +am__fastdepCC_TRUE +am__fastdepCC_FALSE +CXX +CXXFLAGS +ac_ct_CXX +CXXDEPMODE +am__fastdepCXX_TRUE +am__fastdepCXX_FALSE +LN_S +CPP +GREP +EGREP +LIBOBJS +POW_LIB +PERL +PRINTCAP +CUPS +CUPS_FILTERS +CUPS_BACKENDS +PPR +PPR_INTERFACES +PPR_LIB +A2PS +ENSCRIPT +MPAGE +TEXTTOPS +FILECONVERTER +ECHO +EXECPATH +LTLIBOBJS' ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CPP' + # Initialize some variables set by options. ac_init_help= @@ -300,34 +755,48 @@ x_libraries=NONE # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' +datarootdir='${prefix}/share' +datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' ac_prev= +ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" + eval $ac_prev=\$ac_option ac_prev= continue fi - ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac # Accept the important Cygnus configure options, so we can diagnose typos. - case $ac_option in + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; @@ -349,33 +818,45 @@ do --config-cache | -C) cache_file=config.cache ;; - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) + -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - eval "enable_$ac_feature=no" ;; + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac - eval "enable_$ac_feature='$ac_optarg'" ;; + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ @@ -402,6 +883,12 @@ do -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; @@ -426,13 +913,16 @@ do | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) + | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) @@ -497,6 +987,16 @@ do | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; @@ -549,24 +1049,20 @@ do -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } - ac_package=`echo $ac_package| sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac - eval "with_$ac_package='$ac_optarg'" ;; + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/-/_/g'` - eval "with_$ac_package=no" ;; + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=no ;; --x) # Obsolete; use --with-x. @@ -597,8 +1093,7 @@ Try \`$0 --help' for more information." >&2 expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } - ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` - eval "$ac_envvar='$ac_optarg'" + eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) @@ -618,27 +1113,19 @@ if test -n "$ac_prev"; then { (exit 1); exit 1; }; } fi -# Be sure to have absolute paths. -for ac_var in exec_prefix prefix +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir do - eval ac_val=$`echo $ac_var` + eval ac_val=\$$ac_var case $ac_val in - [\\/$]* | ?:[\\/]* | NONE | '' ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; - esac -done - -# Be sure to have absolute paths. -for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ - localstatedir libdir includedir oldincludedir infodir mandir -do - eval ac_val=$`echo $ac_var` - case $ac_val in - [\\/$]* | ?:[\\/]* ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } done # There might be people who depend on the old broken behavior: `$host' @@ -665,54 +1152,76 @@ test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_confdir=`(dirname "$0") 2>/dev/null || + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || + X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X"$0" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then + if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 - { (exit 1); exit 1; }; } - else - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } - fi fi -(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || - { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } -srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` -ac_env_build_alias_set=${build_alias+set} -ac_env_build_alias_value=$build_alias -ac_cv_env_build_alias_set=${build_alias+set} -ac_cv_env_build_alias_value=$build_alias -ac_env_host_alias_set=${host_alias+set} -ac_env_host_alias_value=$host_alias -ac_cv_env_host_alias_set=${host_alias+set} -ac_cv_env_host_alias_value=$host_alias -ac_env_target_alias_set=${target_alias+set} -ac_env_target_alias_value=$target_alias -ac_cv_env_target_alias_set=${target_alias+set} -ac_cv_env_target_alias_value=$target_alias + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done # # Report the --help message. @@ -721,7 +1230,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures this package to adapt to many kinds of systems. +\`configure' configures foomatic-rip "4.0.0" to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -741,9 +1250,6 @@ Configuration: -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] -_ACEOF - - cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] @@ -761,28 +1267,44 @@ Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] - --infodir=DIR info documentation [PREFIX/info] - --mandir=DIR man documentation [PREFIX/man] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/foomatic-rip] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names _ACEOF fi if test -n "$ac_init_help"; then - + case $ac_init_help in + short | recursive ) echo "Configuration of foomatic-rip "4.0.0":";; + esac cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors --enable-file-converter-check check whether a file converter is installed default=yes Optional Packages: @@ -795,119 +1317,102 @@ Optional Packages: --with-execpath=(path to various filters) Default: ${prefix}/bin:/usr/local/bin:/usr/bin:/bin +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + _ACEOF +ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. - ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d $ac_dir || continue + test -d "$ac_dir" || continue ac_builddir=. -if test "$ac_dir" != .; then +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix case $srcdir in - .) # No --srcdir option. We are building in place. + .) # We are building in place. ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac - -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; -esac - - cd $ac_dir - # Check for guested configure; otherwise get Cygnus style configure. - if test -f $ac_srcdir/configure.gnu; then - echo - $SHELL $ac_srcdir/configure.gnu --help=recursive - elif test -f $ac_srcdir/configure; then - echo - $SHELL $ac_srcdir/configure --help=recursive - elif test -f $ac_srcdir/configure.ac || - test -f $ac_srcdir/configure.in; then - echo - $ac_configure --help +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi - cd "$ac_popdir" + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } done fi -test -n "$ac_init_help" && exit 0 +test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF +foomatic-rip configure "4.0.0" +generated by GNU Autoconf 2.61 -Copyright (C) 2003 Free Software Foundation, Inc. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF - exit 0 + exit fi -exec 5>config.log -cat >&5 <<_ACEOF +cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by $as_me, which was -generated by GNU Autoconf 2.59. Invocation command line was +It was created by foomatic-rip $as_me "4.0.0", which was +generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ _ACEOF +exec 5>>config.log { cat <<_ASUNAME ## --------- ## @@ -926,7 +1431,7 @@ uname -v = `(uname -v) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` @@ -940,6 +1445,7 @@ do test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done +IFS=$as_save_IFS } >&5 @@ -961,7 +1467,6 @@ _ACEOF ac_configure_args= ac_configure_args0= ac_configure_args1= -ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do @@ -972,7 +1477,7 @@ do -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + *\'*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in @@ -994,9 +1499,7 @@ do -* ) ac_must_keep_next=true ;; esac fi - ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" - # Get rid of the leading space. - ac_sep=" " + ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done @@ -1007,8 +1510,8 @@ $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_ # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. -# WARNING: Be sure not to use single quotes in there, as some shells, -# such as our DU 5.0 friend, will then `close' the trap. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { @@ -1021,20 +1524,34 @@ trap 'exit_status=$? _ASBOX echo # The following way of writing the cache mishandles newlines in values, -{ +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done (set) 2>&1 | - case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in - *ac_space=\ *) + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) sed -n \ - "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" - ;; + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( *) - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; - esac; -} + esac | + sort +) echo cat <<\_ASBOX @@ -1045,22 +1562,28 @@ _ASBOX echo for ac_var in $ac_subst_vars do - eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX -## ------------- ## -## Output files. ## -## ------------- ## +## ------------------- ## +## File substitutions. ## +## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do - eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" done | sort echo fi @@ -1072,26 +1595,24 @@ _ASBOX ## ----------- ## _ASBOX echo - sed "/^$/d" confdefs.h | sort + cat confdefs.h echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 - rm -f core *.core && - rm -rf conftest* confdefs* conf$$* $ac_clean_files && + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status - ' 0 +' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo >confdefs.h +rm -f -r conftest* confdefs.h # Predefined preprocessor variables. @@ -1122,14 +1643,17 @@ _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" fi -for ac_site_file in $CONFIG_SITE; do +shift +for ac_site_file +do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} @@ -1145,8 +1669,8 @@ if test -r "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in - [\\/]* | ?:[\\/]* ) . $cache_file;; - *) . ./$cache_file;; + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; esac fi else @@ -1158,12 +1682,11 @@ fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false -for ac_var in `(set) 2>&1 | - sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do +for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val="\$ac_cv_env_${ac_var}_value" - eval ac_new_val="\$ac_env_${ac_var}_value" + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 @@ -1188,8 +1711,7 @@ echo "$as_me: current value: $ac_new_val" >&2;} # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in @@ -1206,11 +1728,6 @@ echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start ov { (exit 1); exit 1; }; } fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu @@ -1232,30 +1749,47 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +am__api_version="1.9" ac_aux_dir= -for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do - if test -f $ac_dir/install-sh; then +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break - elif test -f $ac_dir/install.sh; then + elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break - elif test -f $ac_dir/shtool; then + elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then - { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 -echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } fi -ac_config_guess="$SHELL $ac_aux_dir/config.guess" -ac_config_sub="$SHELL $ac_aux_dir/config.sub" -ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -1270,8 +1804,8 @@ ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. -echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 -echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 @@ -1293,7 +1827,7 @@ case $as_dir/ in # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. @@ -1312,21 +1846,22 @@ case $as_dir/ in ;; esac done +IFS=$as_save_IFS fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else - # As a last resort, use the slow shell script. We don't cache a - # path for INSTALL within a source directory, because that will + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is - # removed, or if the path is relative. + # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi -echo "$as_me:$LINENO: result: $INSTALL" >&5 -echo "${ECHO_T}$INSTALL" >&6 +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. @@ -1336,49 +1871,4940 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' -echo "$as_me:$LINENO: checking whether ln -s works" >&5 -echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 +{ echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm -f conftest.sed + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " else - echo "$as_me:$LINENO: result: no, using $LN_S" >&5 -echo "${ECHO_T}no, using $LN_S" >&6 + am_missing_run= + { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi fi -echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 -set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` -if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } +set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF +SHELL = /bin/sh all: - @echo 'ac_maketemp="$(MAKE)"' + @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. -eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` -if test -n "$ac_maketemp"; then - eval ac_cv_prog_make_${ac_make}_set=yes +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + SET_MAKE= +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='foomatic-rip' + VERSION='"4.0.0"' + + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +install_sh=${install_sh-"$am_aux_dir/install-sh"} + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else - eval ac_cv_prog_make_${ac_make}_set=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + + + + +cat >>confdefs.h <<_ACEOF +#define VERSION "`cat VERSION.full 2> /dev/null`" +_ACEOF + + + +# Checks for programs. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi + + +{ echo "$as_me:$LINENO: result: $_am_result" >&5 +echo "${ECHO_T}$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + + +if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + + +depcc="$CC" am_compiler_list= + +{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { echo "$as_me:$LINENO: result: $CXX" >&5 +echo "${ECHO_T}$CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 +echo "${ECHO_T}$ac_ct_CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C++ compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; } +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; } +GXX=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 +echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CXXFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } +if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ echo "$as_me:$LINENO: checking whether ln -s works" >&5 +echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no, using $LN_S" >&5 +echo "${ECHO_T}no, using $LN_S" >&6; } +fi + +{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } +set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac rm -f conftest.make fi -if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } SET_MAKE= else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi +# Checks for libraries. + + +{ echo "$as_me:$LINENO: checking for roundf in -lm" >&5 +echo $ECHO_N "checking for roundf in -lm... $ECHO_C" >&6; } +if test "${ac_cv_lib_m_roundf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char roundf (); +int +main () +{ +return roundf (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_m_roundf=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_m_roundf=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_m_roundf" >&5 +echo "${ECHO_T}$ac_cv_lib_m_roundf" >&6; } +if test $ac_cv_lib_m_roundf = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBM 1 +_ACEOF + + LIBS="-lm $LIBS" + +fi + + +# Checks for header files. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_GREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + # Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_GREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_EGREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + # Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_EGREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_EGREP=$EGREP +fi + + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5 +echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6; } +if test "${ac_cv_header_sys_wait_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/types.h> +#include <sys/wait.h> +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + +int +main () +{ + int s; + wait (&s); + s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_sys_wait_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_sys_wait_h=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6; } +if test $ac_cv_header_sys_wait_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SYS_WAIT_H 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + + + + +for ac_header in fcntl.h memory.h stddef.h stdlib.h string.h strings.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +# Checks for typedefs, structures, and compiler characteristics. +{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_const=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for inline" >&5 +echo $ECHO_N "checking for inline... $ECHO_C" >&6; } +if test "${ac_cv_c_inline+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_inline=$ac_kw +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 +echo "${ECHO_T}$ac_cv_c_inline" >&6; } + + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +{ echo "$as_me:$LINENO: checking for pid_t" >&5 +echo $ECHO_N "checking for pid_t... $ECHO_C" >&6; } +if test "${ac_cv_type_pid_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef pid_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_pid_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_pid_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 +echo "${ECHO_T}$ac_cv_type_pid_t" >&6; } +if test $ac_cv_type_pid_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for size_t" >&5 +echo $ECHO_N "checking for size_t... $ECHO_C" >&6; } +if test "${ac_cv_type_size_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef size_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_size_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_size_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6; } +if test $ac_cv_type_size_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for ssize_t" >&5 +echo $ECHO_N "checking for ssize_t... $ECHO_C" >&6; } +if test "${ac_cv_type_ssize_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef ssize_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_ssize_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_ssize_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_ssize_t" >&5 +echo "${ECHO_T}$ac_cv_type_ssize_t" >&6; } +if test $ac_cv_type_ssize_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define ssize_t int +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5 +echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6; } +if test "${ac_cv_struct_tm+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/types.h> +#include <time.h> + +int +main () +{ +struct tm tm; + int *p = &tm.tm_sec; + return !p; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_struct_tm=time.h +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_struct_tm=sys/time.h +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5 +echo "${ECHO_T}$ac_cv_struct_tm" >&6; } +if test $ac_cv_struct_tm = sys/time.h; then + +cat >>confdefs.h <<\_ACEOF +#define TM_IN_SYS_TIME 1 +_ACEOF + +fi + + +# Checks for library functions. + +for ac_header in vfork.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_func in fork vfork +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func_fork" = xyes; then + { echo "$as_me:$LINENO: checking for working fork" >&5 +echo $ECHO_N "checking for working fork... $ECHO_C" >&6; } +if test "${ac_cv_func_fork_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_fork_works=cross +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* By Ruediger Kuhlmann. */ + return fork () < 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_fork_works=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_fork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_fork_works" >&5 +echo "${ECHO_T}$ac_cv_func_fork_works" >&6; } + +else + ac_cv_func_fork_works=$ac_cv_func_fork +fi +if test "x$ac_cv_func_fork_works" = xcross; then + case $host in + *-*-amigaos* | *-*-msdosdjgpp*) + # Override, as these systems have only a dummy fork() stub + ac_cv_func_fork_works=no + ;; + *) + ac_cv_func_fork_works=yes + ;; + esac + { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 +echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} +fi +ac_cv_func_vfork_works=$ac_cv_func_vfork +if test "x$ac_cv_func_vfork" = xyes; then + { echo "$as_me:$LINENO: checking for working vfork" >&5 +echo $ECHO_N "checking for working vfork... $ECHO_C" >&6; } +if test "${ac_cv_func_vfork_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_vfork_works=cross +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Thanks to Paul Eggert for this test. */ +$ac_includes_default +#include <sys/wait.h> +#ifdef HAVE_VFORK_H +# include <vfork.h> +#endif +/* On some sparc systems, changes by the child to local and incoming + argument registers are propagated back to the parent. The compiler + is told about this with #include <vfork.h>, but some compilers + (e.g. gcc -O) don't grok <vfork.h>. Test for this by using a + static variable whose address is put into a register that is + clobbered by the vfork. */ +static void +#ifdef __cplusplus +sparc_address_test (int arg) +# else +sparc_address_test (arg) int arg; +#endif +{ + static pid_t child; + if (!child) { + child = vfork (); + if (child < 0) { + perror ("vfork"); + _exit(2); + } + if (!child) { + arg = getpid(); + write(-1, "", 0); + _exit (arg); + } + } +} + +int +main () +{ + pid_t parent = getpid (); + pid_t child; + + sparc_address_test (0); + + child = vfork (); + + if (child == 0) { + /* Here is another test for sparc vfork register problems. This + test uses lots of local variables, at least as many local + variables as main has allocated so far including compiler + temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris + 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should + reuse the register of parent for one of the local variables, + since it will think that parent can't possibly be used any more + in this routine. Assigning to the local variable will thus + munge parent in the parent process. */ + pid_t + p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), + p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); + /* Convince the compiler that p..p7 are live; otherwise, it might + use the same hardware register for all 8 local variables. */ + if (p != p1 || p != p2 || p != p3 || p != p4 + || p != p5 || p != p6 || p != p7) + _exit(1); + + /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent + from child file descriptors. If the child closes a descriptor + before it execs or exits, this munges the parent's descriptor + as well. Test for this by closing stdout in the child. */ + _exit(close(fileno(stdout)) != 0); + } else { + int status; + struct stat st; + + while (wait(&status) != child) + ; + return ( + /* Was there some problem with vforking? */ + child < 0 + + /* Did the child fail? (This shouldn't happen.) */ + || status + + /* Did the vfork/compiler bug occur? */ + || parent != getpid() + + /* Did the file descriptor bug occur? */ + || fstat(fileno(stdout), &st) != 0 + ); + } +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_vfork_works=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_vfork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_vfork_works" >&5 +echo "${ECHO_T}$ac_cv_func_vfork_works" >&6; } + +fi; +if test "x$ac_cv_func_fork_works" = xcross; then + ac_cv_func_vfork_works=$ac_cv_func_vfork + { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 +echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} +fi + +if test "x$ac_cv_func_vfork_works" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_WORKING_VFORK 1 +_ACEOF + +else + +cat >>confdefs.h <<\_ACEOF +#define vfork fork +_ACEOF + +fi +if test "x$ac_cv_func_fork_works" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_WORKING_FORK 1 +_ACEOF + +fi + + +for ac_header in stdlib.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +{ echo "$as_me:$LINENO: checking for GNU libc compatible malloc" >&5 +echo $ECHO_N "checking for GNU libc compatible malloc... $ECHO_C" >&6; } +if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_malloc_0_nonnull=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if defined STDC_HEADERS || defined HAVE_STDLIB_H +# include <stdlib.h> +#else +char *malloc (); +#endif + +int +main () +{ +return ! malloc (0); + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_malloc_0_nonnull=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_malloc_0_nonnull=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_malloc_0_nonnull" >&5 +echo "${ECHO_T}$ac_cv_func_malloc_0_nonnull" >&6; } +if test $ac_cv_func_malloc_0_nonnull = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_MALLOC 1 +_ACEOF + +else + cat >>confdefs.h <<\_ACEOF +#define HAVE_MALLOC 0 +_ACEOF + + case " $LIBOBJS " in + *" malloc.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS malloc.$ac_objext" + ;; +esac + + +cat >>confdefs.h <<\_ACEOF +#define malloc rpl_malloc +_ACEOF + +fi + + + + +for ac_header in stdlib.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +{ echo "$as_me:$LINENO: checking for GNU libc compatible realloc" >&5 +echo $ECHO_N "checking for GNU libc compatible realloc... $ECHO_C" >&6; } +if test "${ac_cv_func_realloc_0_nonnull+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_realloc_0_nonnull=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if defined STDC_HEADERS || defined HAVE_STDLIB_H +# include <stdlib.h> +#else +char *realloc (); +#endif + +int +main () +{ +return ! realloc (0, 0); + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_realloc_0_nonnull=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_realloc_0_nonnull=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_realloc_0_nonnull" >&5 +echo "${ECHO_T}$ac_cv_func_realloc_0_nonnull" >&6; } +if test $ac_cv_func_realloc_0_nonnull = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_REALLOC 1 +_ACEOF + +else + cat >>confdefs.h <<\_ACEOF +#define HAVE_REALLOC 0 +_ACEOF + + case " $LIBOBJS " in + *" realloc.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS realloc.$ac_objext" + ;; +esac + + +cat >>confdefs.h <<\_ACEOF +#define realloc rpl_realloc +_ACEOF + +fi + + + +{ echo "$as_me:$LINENO: checking return type of signal handlers" >&5 +echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6; } +if test "${ac_cv_type_signal+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/types.h> +#include <signal.h> + +int +main () +{ +return *(signal (0, 0)) (0) == 1; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_signal=int +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_signal=void +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 +echo "${ECHO_T}$ac_cv_type_signal" >&6; } + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + +{ echo "$as_me:$LINENO: checking for working strtod" >&5 +echo $ECHO_N "checking for working strtod... $ECHO_C" >&6; } +if test "${ac_cv_func_strtod+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_strtod=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +$ac_includes_default +#ifndef strtod +double strtod (); +#endif +int +main() +{ + { + /* Some versions of Linux strtod mis-parse strings with leading '+'. */ + char *string = " +69"; + char *term; + double value; + value = strtod (string, &term); + if (value != 69 || term != (string + 4)) + return 1; + } + + { + /* Under Solaris 2.4, strtod returns the wrong value for the + terminating character under some conditions. */ + char *string = "NaN"; + char *term; + strtod (string, &term); + if (term != string && *(term - 1) == 0) + return 1; + } + return 0; +} + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_strtod=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_strtod=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_strtod" >&5 +echo "${ECHO_T}$ac_cv_func_strtod" >&6; } +if test $ac_cv_func_strtod = no; then + case " $LIBOBJS " in + *" strtod.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strtod.$ac_objext" + ;; +esac + +{ echo "$as_me:$LINENO: checking for pow" >&5 +echo $ECHO_N "checking for pow... $ECHO_C" >&6; } +if test "${ac_cv_func_pow+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define pow to an innocuous variant, in case <limits.h> declares pow. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define pow innocuous_pow + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char pow (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef pow + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pow (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_pow || defined __stub___pow +choke me +#endif + +int +main () +{ +return pow (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_pow=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_pow=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_pow" >&5 +echo "${ECHO_T}$ac_cv_func_pow" >&6; } + +if test $ac_cv_func_pow = no; then + { echo "$as_me:$LINENO: checking for pow in -lm" >&5 +echo $ECHO_N "checking for pow in -lm... $ECHO_C" >&6; } +if test "${ac_cv_lib_m_pow+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pow (); +int +main () +{ +return pow (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_m_pow=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_m_pow=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_m_pow" >&5 +echo "${ECHO_T}$ac_cv_lib_m_pow" >&6; } +if test $ac_cv_lib_m_pow = yes; then + POW_LIB=-lm +else + { echo "$as_me:$LINENO: WARNING: cannot find library containing definition of pow" >&5 +echo "$as_me: WARNING: cannot find library containing definition of pow" >&2;} +fi + +fi + +fi + + +for ac_func in vprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +{ echo "$as_me:$LINENO: checking for _doprnt" >&5 +echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6; } +if test "${ac_cv_func__doprnt+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define _doprnt to an innocuous variant, in case <limits.h> declares _doprnt. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define _doprnt innocuous__doprnt + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char _doprnt (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef _doprnt + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char _doprnt (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub__doprnt || defined __stub____doprnt +choke me +#endif + +int +main () +{ +return _doprnt (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func__doprnt=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func__doprnt=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5 +echo "${ECHO_T}$ac_cv_func__doprnt" >&6; } +if test $ac_cv_func__doprnt = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DOPRNT 1 +_ACEOF + +fi + +fi +done + + + + + + + + + + + + + + + + +for ac_func in dup2 getcwd gethostname regcomp setenv strcasecmp strchr strcspn strdup strncasecmp strndup strrchr strstr strtol +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + ETCSEARCHPATH=${prefix}/etc:/usr/etc:/usr/local/etc -LIBSEARCHPATH=${prefix}/lib:/usr/lib:/usr/local/lib:${prefix}/libexec:/usr/libexec:/usr/local/libexec +LIBSEARCHPATH=${prefix}/lib:${prefix}/lib64:/usr/lib:/usr/lib64:/usr/local/lib:${prefix}/libexec:/usr/libexec:/usr/local/libexec uname=`uname` uversion=`uname -r | sed -e '1,$s/[^0-9]//g'` @@ -1393,8 +6819,8 @@ fi # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_PERL+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1409,38 +6835,40 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done +IFS=$as_save_IFS ;; esac fi PERL=$ac_cv_path_PERL - if test -n "$PERL"; then - echo "$as_me:$LINENO: result: $PERL" >&5 -echo "${ECHO_T}$PERL" >&6 + { echo "$as_me:$LINENO: result: $PERL" >&5 +echo "${ECHO_T}$PERL" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi + if test -z "$PERL"; then { { echo "$as_me:$LINENO: error: Perl 5 is required to build and run" >&5 echo "$as_me: error: Perl 5 is required to build and run" >&2;} { (exit 1); exit 1; }; }; fi +# Check for /etc/printcap # Extract the first word of "printcap", so it can be a program name with args. set dummy printcap; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word/" >&5 -echo $ECHO_N "checking for $ac_word/... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word/" >&5 +echo $ECHO_N "checking for $ac_word/... $ECHO_C" >&6; } if test "${ac_cv_path_PRINTCAP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1468,18 +6896,19 @@ esac fi PRINTCAP="$ac_cv_path_PRINTCAP" if test -n "$PRINTCAP"; then - echo "$as_me:$LINENO: result: $PRINTCAP" >&5 -echo "${ECHO_T}$PRINTCAP" >&6 + { echo "$as_me:$LINENO: result: $PRINTCAP" >&5 +echo "${ECHO_T}$PRINTCAP" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi +# Check for /usr/lib/cups # Extract the first word of "cups", so it can be a program name with args. set dummy cups; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word/" >&5 -echo $ECHO_N "checking for $ac_word/... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word/" >&5 +echo $ECHO_N "checking for $ac_word/... $ECHO_C" >&6; } if test "${ac_cv_path_CUPS+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1507,18 +6936,19 @@ esac fi CUPS="$ac_cv_path_CUPS" if test -n "$CUPS"; then - echo "$as_me:$LINENO: result: $CUPS" >&5 -echo "${ECHO_T}$CUPS" >&6 + { echo "$as_me:$LINENO: result: $CUPS" >&5 +echo "${ECHO_T}$CUPS" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi +# Check for /usr/lib/cups/filter # Extract the first word of "cups/filter", so it can be a program name with args. set dummy cups/filter; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word/" >&5 -echo $ECHO_N "checking for $ac_word/... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word/" >&5 +echo $ECHO_N "checking for $ac_word/... $ECHO_C" >&6; } if test "${ac_cv_path_CUPS_FILTERS+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1546,18 +6976,19 @@ esac fi CUPS_FILTERS="$ac_cv_path_CUPS_FILTERS" if test -n "$CUPS_FILTERS"; then - echo "$as_me:$LINENO: result: $CUPS_FILTERS" >&5 -echo "${ECHO_T}$CUPS_FILTERS" >&6 + { echo "$as_me:$LINENO: result: $CUPS_FILTERS" >&5 +echo "${ECHO_T}$CUPS_FILTERS" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi +# Check for /usr/lib/cups/backend # Extract the first word of "cups/backend", so it can be a program name with args. set dummy cups/backend; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word/" >&5 -echo $ECHO_N "checking for $ac_word/... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word/" >&5 +echo $ECHO_N "checking for $ac_word/... $ECHO_C" >&6; } if test "${ac_cv_path_CUPS_BACKENDS+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1585,18 +7016,19 @@ esac fi CUPS_BACKENDS="$ac_cv_path_CUPS_BACKENDS" if test -n "$CUPS_BACKENDS"; then - echo "$as_me:$LINENO: result: $CUPS_BACKENDS" >&5 -echo "${ECHO_T}$CUPS_BACKENDS" >&6 + { echo "$as_me:$LINENO: result: $CUPS_BACKENDS" >&5 +echo "${ECHO_T}$CUPS_BACKENDS" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi +# Check for /usr/lib/ppr # Extract the first word of "ppr", so it can be a program name with args. set dummy ppr; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word/" >&5 -echo $ECHO_N "checking for $ac_word/... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word/" >&5 +echo $ECHO_N "checking for $ac_word/... $ECHO_C" >&6; } if test "${ac_cv_path_PPR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1624,18 +7056,19 @@ esac fi PPR="$ac_cv_path_PPR" if test -n "$PPR"; then - echo "$as_me:$LINENO: result: $PPR" >&5 -echo "${ECHO_T}$PPR" >&6 + { echo "$as_me:$LINENO: result: $PPR" >&5 +echo "${ECHO_T}$PPR" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi +# Check for /usr/lib/ppr/interfaces # Extract the first word of "ppr/interfaces", so it can be a program name with args. set dummy ppr/interfaces; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word/" >&5 -echo $ECHO_N "checking for $ac_word/... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word/" >&5 +echo $ECHO_N "checking for $ac_word/... $ECHO_C" >&6; } if test "${ac_cv_path_PPR_INTERFACES+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1663,18 +7096,19 @@ esac fi PPR_INTERFACES="$ac_cv_path_PPR_INTERFACES" if test -n "$PPR_INTERFACES"; then - echo "$as_me:$LINENO: result: $PPR_INTERFACES" >&5 -echo "${ECHO_T}$PPR_INTERFACES" >&6 + { echo "$as_me:$LINENO: result: $PPR_INTERFACES" >&5 +echo "${ECHO_T}$PPR_INTERFACES" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi +# Check for /usr/lib/ppr/lib # Extract the first word of "ppr/lib", so it can be a program name with args. set dummy ppr/lib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word/" >&5 -echo $ECHO_N "checking for $ac_word/... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word/" >&5 +echo $ECHO_N "checking for $ac_word/... $ECHO_C" >&6; } if test "${ac_cv_path_PPR_LIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1702,28 +7136,242 @@ esac fi PPR_LIB="$ac_cv_path_PPR_LIB" if test -n "$PPR_LIB"; then - echo "$as_me:$LINENO: result: $PPR_LIB" >&5 -echo "${ECHO_T}$PPR_LIB" >&6 + { echo "$as_me:$LINENO: result: $PPR_LIB" >&5 +echo "${ECHO_T}$PPR_LIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + + +for ac_header in ghostscript/ierrors.h ghostscript/iapi.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done -# Check whether --enable-file-converter-check or --disable-file-converter-check was given. +{ echo "$as_me:$LINENO: checking for gsapi_new_instance in -lgs" >&5 +echo $ECHO_N "checking for gsapi_new_instance in -lgs... $ECHO_C" >&6; } +if test "${ac_cv_lib_gs_gsapi_new_instance+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgs $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gsapi_new_instance (); +int +main () +{ +return gsapi_new_instance (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_gs_gsapi_new_instance=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_gs_gsapi_new_instance=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_gs_gsapi_new_instance" >&5 +echo "${ECHO_T}$ac_cv_lib_gs_gsapi_new_instance" >&6; } +if test $ac_cv_lib_gs_gsapi_new_instance = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBGS 1 +_ACEOF + + LIBS="-lgs $LIBS" + +fi + + +# Check whether --enable-file-converter-check was given. if test "${enable_file_converter_check+set}" = set; then - enableval="$enable_file_converter_check" - if eval "test x${enableval} = xno"; then + enableval=$enable_file_converter_check; if eval "test x${enableval} = xno"; then NOCONVERTERCHECK=1 { echo "$as_me:$LINENO: WARNING: Absence of a file converter is ignored, package will be built anyway" >&5 echo "$as_me: WARNING: Absence of a file converter is ignored, package will be built anyway" >&2;} fi -fi; +fi + +# Check for a2ps, enscript, mpage # Extract the first word of "a2ps", so it can be a program name with args. set dummy a2ps; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_A2PS+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1738,31 +7386,32 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_A2PS="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done +IFS=$as_save_IFS ;; esac fi A2PS=$ac_cv_path_A2PS - if test -n "$A2PS"; then - echo "$as_me:$LINENO: result: $A2PS" >&5 -echo "${ECHO_T}$A2PS" >&6 + { echo "$as_me:$LINENO: result: $A2PS" >&5 +echo "${ECHO_T}$A2PS" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi + # Extract the first word of "enscript", so it can be a program name with args. set dummy enscript; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_ENSCRIPT+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1777,31 +7426,32 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ENSCRIPT="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done +IFS=$as_save_IFS ;; esac fi ENSCRIPT=$ac_cv_path_ENSCRIPT - if test -n "$ENSCRIPT"; then - echo "$as_me:$LINENO: result: $ENSCRIPT" >&5 -echo "${ECHO_T}$ENSCRIPT" >&6 + { echo "$as_me:$LINENO: result: $ENSCRIPT" >&5 +echo "${ECHO_T}$ENSCRIPT" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi + # Extract the first word of "mpage", so it can be a program name with args. set dummy mpage; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_MPAGE+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1816,31 +7466,32 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MPAGE="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done +IFS=$as_save_IFS ;; esac fi MPAGE=$ac_cv_path_MPAGE - if test -n "$MPAGE"; then - echo "$as_me:$LINENO: result: $MPAGE" >&5 -echo "${ECHO_T}$MPAGE" >&6 + { echo "$as_me:$LINENO: result: $MPAGE" >&5 +echo "${ECHO_T}$MPAGE" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi + # Extract the first word of "texttops", so it can be a program name with args. set dummy texttops; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_TEXTTOPS+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -1855,38 +7506,39 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_TEXTTOPS="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done +IFS=$as_save_IFS ;; esac fi TEXTTOPS=$ac_cv_path_TEXTTOPS - if test -n "$TEXTTOPS"; then - echo "$as_me:$LINENO: result: $TEXTTOPS" >&5 -echo "${ECHO_T}$TEXTTOPS" >&6 + { echo "$as_me:$LINENO: result: $TEXTTOPS" >&5 +echo "${ECHO_T}$TEXTTOPS" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } fi -# Check whether --with-file-converter or --without-file-converter was given. + +# Check whether --with-file-converter was given. if test "${with_file_converter+set}" = set; then - withval="$with_file_converter" - FILECONVERTER="$withval" + withval=$with_file_converter; FILECONVERTER="$withval" else FILECONVERTER="" -fi; -echo "$as_me:$LINENO: result: file-converter: $FILECONVERTER" >&5 -echo "${ECHO_T}file-converter: $FILECONVERTER" >&6 +fi + +{ echo "$as_me:$LINENO: result: file-converter: $FILECONVERTER" >&5 +echo "${ECHO_T}file-converter: $FILECONVERTER" >&6; } if test "${NOCONVERTERCHECK}" = "" -a "${A2PS}" = "" -a "${ENSCRIPT}" = "" -a "${MPAGE}" = "" -a "${TEXTTOPS}" = "" ; then @@ -1896,30 +7548,33 @@ echo "$as_me: error: cannot find a2ps, enscript, mpage, or CUPS' texttops. You fi -# Check whether --with-echo or --without-echo was given. +# Check whether --with-echo was given. if test "${with_echo+set}" = set; then - withval="$with_echo" - ECHO="$withval" + withval=$with_echo; ECHO="$withval" else ECHO="echo" -fi; -echo "$as_me:$LINENO: result: GNU Compatible Echo: $ECHO" >&5 -echo "${ECHO_T}GNU Compatible Echo: $ECHO" >&6 +fi +{ echo "$as_me:$LINENO: result: GNU Compatible Echo: $ECHO" >&5 +echo "${ECHO_T}GNU Compatible Echo: $ECHO" >&6; } -# Check whether --with-execpath or --without-execpath was given. + +# Check whether --with-execpath was given. if test "${with_execpath+set}" = set; then - withval="$with_execpath" - EXECPATH="$withval" + withval=$with_execpath; EXECPATH="$withval" else EXECPATH="${prefix}/bin:/usr/local/bin:/usr/bin:/bin" -fi; -echo "$as_me:$LINENO: result: Execpath: $EXECPATH" >&5 -echo "${ECHO_T}Execpath: $EXECPATH" >&6 +fi + +{ echo "$as_me:$LINENO: result: Execpath: $EXECPATH" >&5 +echo "${ECHO_T}Execpath: $EXECPATH" >&6; } + +ac_config_files="$ac_config_files Makefile beh foomatic-rip.1" + +ac_config_headers="$ac_config_headers config.h" - ac_config_files="$ac_config_files Makefile beh foomatic-rip foomatic-gswrapper foomatic-rip.1 foomatic-gswrapper.1" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure @@ -1938,39 +7593,58 @@ _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. +# So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. -{ +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *ac_space=\ *) + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; + ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; - esac; -} | + esac | + sort +) | sed ' + /^ac_cv_env_/b end t clear - : clear + :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end - /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - : end' >>confcache -if diff $cache_file confcache >/dev/null 2>&1; then :; else - if test -w $cache_file; then - test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else - echo "not updating unwritable cache $cache_file" + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache @@ -1979,69 +7653,45 @@ test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/; -s/:*\${srcdir}:*/:/; -s/:*@srcdir@:*/:/; -s/^\([^=]*=[ ]*\):*/\1/; -s/:*$//; -s/^[^=]*=[ ]*$//; -}' -fi - -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -# -# If the first sed substitution is executed (which looks for macros that -# take arguments), then we branch to the quote section. Otherwise, -# look for a macro that doesn't take arguments. -cat >confdef2opt.sed <<\_ACEOF -t clear -: clear -s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g -t quote -s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g -t quote -d -: quote -s,[ `~#$^&*(){}\\|;'"<>?],\\&,g -s,\[,\\&,g -s,\],\\&,g -s,\$,$$,g -p -_ACEOF -# We use echo to avoid assuming a particular line-breaking character. -# The extra dot is to prevent the shell from consuming trailing -# line-breaks from the sub-command output. A line-break within -# single-quotes doesn't work because, if this script is created in a -# platform that uses two characters for line-breaks (e.g., DOS), tr -# would break. -ac_LF_and_DOT=`echo; echo .` -DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` -rm -f confdef2opt.sed - +DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. - ac_i=`echo "$ac_i" | - sed 's/\$U\././;s/\.o$//;s/\.obj$//'` - # 2. Add them. - ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" - ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files @@ -2066,17 +7716,45 @@ cat >>$CONFIG_STATUS <<\_ACEOF ## M4sh Initialization. ## ## --------------------- ## -# Be Bourne compatible +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh fi -DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then @@ -2086,8 +7764,43 @@ else fi +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + # Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done PS1='$ ' PS2='> ' PS4='+ ' @@ -2101,18 +7814,19 @@ do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else - $as_unset $as_var + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; then +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi -if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false @@ -2120,159 +7834,120 @@ fi # Name of the executable. -as_me=`$as_basename "$0" || +as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || + X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` - -# PATH needs CR, and LINENO needs CR and PATH. -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi +# CDPATH. +$as_unset CDPATH - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 -echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop - s,-$,, - s,^['$as_cr_digits']*\n,, + s/-\n.*// ' >$as_me.lineno && - chmod +x $as_me.lineno || - { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 -echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" # Exit status is that of the last command. exit } -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; esac -if expr a : '\(a\)' >/dev/null 2>&1; then +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi -rm -f conf$$ conf$$.exe conf$$.file +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: @@ -2281,7 +7956,28 @@ else as_mkdir_p=false fi -as_executable_p="test -f" +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -2290,31 +7986,14 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH - exec 6>&1 -# Open the log real soon, to keep \$[0] and so on meaningful, and to +# Save the log message, to keep $[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. Logging --version etc. is OK. -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX -} >&5 -cat >&5 <<_CSEOF - -This file was extended by $as_me, which was -generated by GNU Autoconf 2.59. Invocation command line was +# values after options handling. +ac_log=" +This file was extended by foomatic-rip $as_me "4.0.0", which was +generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -2322,30 +8001,20 @@ generated by GNU Autoconf 2.59. Invocation command line was CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ -_CSEOF -echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 -echo >&5 +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + _ACEOF +cat >>$CONFIG_STATUS <<_ACEOF # Files that config.status was made for. -if test -n "$ac_config_files"; then - echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS -fi +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" -if test -n "$ac_config_headers"; then - echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_links"; then - echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_commands"; then - echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS -fi +_ACEOF cat >>$CONFIG_STATUS <<\_ACEOF - ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. @@ -2353,30 +8022,40 @@ current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit - -V, --version print version number, then exit + -V, --version print version number and configuration settings, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE Configuration files: $config_files +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + Report bugs to <bug-autoconf@gnu.org>." -_ACEOF +_ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -config.status -configured by $0, generated by GNU Autoconf 2.59, - with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" +foomatic-rip config.status "4.0.0" +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" -Copyright (C) 2003 Free Software Foundation, Inc. +Copyright (C) 2006 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." -srcdir=$srcdir -INSTALL="$INSTALL" + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF @@ -2387,39 +8066,24 @@ while test $# != 0 do case $1 in --*=*) - ac_option=`expr "x$1" : 'x\([^=]*\)='` - ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; - -*) + *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; - *) # This is not an option, so the user has probably given explicit - # arguments. - ac_option=$1 - ac_need_defaults=false;; esac case $ac_option in # Handling of the options. -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; - --version | --vers* | -V ) - echo "$ac_cs_version"; exit 0 ;; - --he | --h) - # Conflict between --help and --header - { { echo "$as_me:$LINENO: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; };; - --help | --hel | -h ) - echo "$ac_cs_usage"; exit 0 ;; - --debug | --d* | -d ) + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift @@ -2429,18 +8093,24 @@ Try \`$0 --help' for more information." >&2;} $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. - -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2;} + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; - *) ac_config_targets="$ac_config_targets $1" ;; + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; esac shift @@ -2456,373 +8126,813 @@ fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then - echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 - exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" - - +_ACEOF cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. for ac_config_target in $ac_config_targets do - case "$ac_config_target" in - # Handling of arguments. - "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "beh" ) CONFIG_FILES="$CONFIG_FILES beh" ;; - "foomatic-rip" ) CONFIG_FILES="$CONFIG_FILES foomatic-rip" ;; - "foomatic-gswrapper" ) CONFIG_FILES="$CONFIG_FILES foomatic-gswrapper" ;; - "foomatic-rip.1" ) CONFIG_FILES="$CONFIG_FILES foomatic-rip.1" ;; - "foomatic-gswrapper.1" ) CONFIG_FILES="$CONFIG_FILES foomatic-gswrapper.1" ;; + case $ac_config_target in + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "beh") CONFIG_FILES="$CONFIG_FILES beh" ;; + "foomatic-rip.1") CONFIG_FILES="$CONFIG_FILES foomatic-rip.1" ;; + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done + # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason to put it here, and in addition, +# simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. -# Create a temporary directory, and hook for its removal unless debugging. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. $debug || { - trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } - # Create a (secure) tmp directory for tmp files. { - tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { - tmp=./confstat$$-$RANDOM - (umask 077 && mkdir $tmp) + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF - # -# CONFIG_FILES section. +# Set up the sed scripts for CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h -if test -n "\$CONFIG_FILES"; then - # Protect against being on the right side of a sed subst in config.status. - sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; - s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF -s,@SHELL@,$SHELL,;t t -s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t -s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t -s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t -s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t -s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t -s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t -s,@exec_prefix@,$exec_prefix,;t t -s,@prefix@,$prefix,;t t -s,@program_transform_name@,$program_transform_name,;t t -s,@bindir@,$bindir,;t t -s,@sbindir@,$sbindir,;t t -s,@libexecdir@,$libexecdir,;t t -s,@datadir@,$datadir,;t t -s,@sysconfdir@,$sysconfdir,;t t -s,@sharedstatedir@,$sharedstatedir,;t t -s,@localstatedir@,$localstatedir,;t t -s,@libdir@,$libdir,;t t -s,@includedir@,$includedir,;t t -s,@oldincludedir@,$oldincludedir,;t t -s,@infodir@,$infodir,;t t -s,@mandir@,$mandir,;t t -s,@build_alias@,$build_alias,;t t -s,@host_alias@,$host_alias,;t t -s,@target_alias@,$target_alias,;t t -s,@DEFS@,$DEFS,;t t -s,@ECHO_C@,$ECHO_C,;t t -s,@ECHO_N@,$ECHO_N,;t t -s,@ECHO_T@,$ECHO_T,;t t -s,@LIBS@,$LIBS,;t t -s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t -s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t -s,@INSTALL_DATA@,$INSTALL_DATA,;t t -s,@LN_S@,$LN_S,;t t -s,@SET_MAKE@,$SET_MAKE,;t t -s,@PERL@,$PERL,;t t -s,@PRINTCAP@,$PRINTCAP,;t t -s,@CUPS@,$CUPS,;t t -s,@CUPS_FILTERS@,$CUPS_FILTERS,;t t -s,@CUPS_BACKENDS@,$CUPS_BACKENDS,;t t -s,@PPR@,$PPR,;t t -s,@PPR_INTERFACES@,$PPR_INTERFACES,;t t -s,@PPR_LIB@,$PPR_LIB,;t t -s,@A2PS@,$A2PS,;t t -s,@ENSCRIPT@,$ENSCRIPT,;t t -s,@MPAGE@,$MPAGE,;t t -s,@TEXTTOPS@,$TEXTTOPS,;t t -s,@FILECONVERTER@,$FILECONVERTER,;t t -s,@ECHO@,$ECHO,;t t -s,@EXECPATH@,$EXECPATH,;t t -s,@LIBOBJS@,$LIBOBJS,;t t -s,@LTLIBOBJS@,$LTLIBOBJS,;t t -CEOF - -_ACEOF - - cat >>$CONFIG_STATUS <<\_ACEOF - # Split the substitutions into bite-sized pieces for seds with - # small command number limits, like on Digital OSF/1 and HP-UX. - ac_max_sed_lines=48 - ac_sed_frag=1 # Number of current file. - ac_beg=1 # First line for current file. - ac_end=$ac_max_sed_lines # Line after last line for current file. - ac_more_lines=: - ac_sed_cmds= - while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - else - sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - fi - if test ! -s $tmp/subs.frag; then - ac_more_lines=false - else - # The purpose of the label and of the branching condition is to - # speed up the sed processing (if there are no `@' at all, there - # is no need to browse any of the substitutions). - # These are the two extra sed commands mentioned above. - (echo ':t - /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" - else - ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" - fi - ac_sed_frag=`expr $ac_sed_frag + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_lines` - fi - done - if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +CYGPATH_W!$CYGPATH_W$ac_delim +PACKAGE!$PACKAGE$ac_delim +VERSION!$VERSION$ac_delim +ACLOCAL!$ACLOCAL$ac_delim +AUTOCONF!$AUTOCONF$ac_delim +AUTOMAKE!$AUTOMAKE$ac_delim +AUTOHEADER!$AUTOHEADER$ac_delim +MAKEINFO!$MAKEINFO$ac_delim +install_sh!$install_sh$ac_delim +STRIP!$STRIP$ac_delim +INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim +mkdir_p!$mkdir_p$ac_delim +AWK!$AWK$ac_delim +SET_MAKE!$SET_MAKE$ac_delim +am__leading_dot!$am__leading_dot$ac_delim +AMTAR!$AMTAR$ac_delim +am__tar!$am__tar$ac_delim +am__untar!$am__untar$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +DEPDIR!$DEPDIR$ac_delim +am__include!$am__include$ac_delim +am__quote!$am__quote$ac_delim +AMDEP_TRUE!$AMDEP_TRUE$ac_delim +AMDEP_FALSE!$AMDEP_FALSE$ac_delim +AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim +CCDEPMODE!$CCDEPMODE$ac_delim +am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim +am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim +CXX!$CXX$ac_delim +CXXFLAGS!$CXXFLAGS$ac_delim +ac_ct_CXX!$ac_ct_CXX$ac_delim +CXXDEPMODE!$CXXDEPMODE$ac_delim +am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim +am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim +LN_S!$LN_S$ac_delim +CPP!$CPP$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +POW_LIB!$POW_LIB$ac_delim +PERL!$PERL$ac_delim +PRINTCAP!$PRINTCAP$ac_delim +CUPS!$CUPS$ac_delim +CUPS_FILTERS!$CUPS_FILTERS$ac_delim +CUPS_BACKENDS!$CUPS_BACKENDS$ac_delim +PPR!$PPR$ac_delim +PPR_INTERFACES!$PPR_INTERFACES$ac_delim +PPR_LIB!$PPR_LIB$ac_delim +A2PS!$A2PS$ac_delim +ENSCRIPT!$ENSCRIPT$ac_delim +MPAGE!$MPAGE$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi -fi # test -n "$CONFIG_FILES" +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS <conf$$subs.sed +rm -f conf$$subs.sed +cat >>$CONFIG_STATUS <<_ACEOF +CEOF$ac_eof +_ACEOF + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +TEXTTOPS!$TEXTTOPS$ac_delim +FILECONVERTER!$FILECONVERTER$ac_delim +ECHO!$ECHO$ac_delim +EXECPATH!$EXECPATH$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 5; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end _ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS <conf$$subs.sed +rm -f conf$$subs.sed +cat >>$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + cat >>$CONFIG_STATUS <<\_ACEOF -for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case $ac_file in - - | *:- | *:-:* ) # input from stdin - cat >$tmp/stdin - ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - * ) ac_file_in=$ac_file.in ;; +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift - # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. - ac_dir=`(dirname "$ac_file") 2>/dev/null || + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p "$ac_dir" - else - as_dir="$ac_dir" + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } - ac_builddir=. -if test "$ac_dir" != .; then +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix case $srcdir in - .) # No --srcdir option. We are building in place. + .) # We are building in place. ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; -esac + case $ac_mode in + :F) + # + # CONFIG_FILE + # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac +_ACEOF - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - if test x"$ac_file" = x-; then - configure_input= - else - configure_input="$ac_file. " - fi - configure_input=$configure_input"Generated from `echo $ac_file_in | - sed 's,.*/,,'` by configure." - - # First look for the input files in the build tree, otherwise in the - # src tree. - ac_file_inputs=`IFS=: - for f in $ac_file_in; do - case $f in - -) echo $tmp/stdin ;; - [\\/$]*) - # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - echo "$f";; - *) # Relative - if test -f "$f"; then - # Build tree - echo "$f" - elif test -f "$srcdir/$f"; then - # Source tree - echo "$srcdir/$f" - else - # /dev/null tree - { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - fi;; - esac - done` || { (exit 1); exit 1; } +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= - if test x"$ac_file" != x-; then - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - rm -f "$ac_file" - fi +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s,@configure_input@,$configure_input,;t t -s,@srcdir@,$ac_srcdir,;t t -s,@abs_srcdir@,$ac_abs_srcdir,;t t -s,@top_srcdir@,$ac_top_srcdir,;t t -s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t -s,@builddir@,$ac_builddir,;t t -s,@abs_builddir@,$ac_abs_builddir,;t t -s,@top_builddir@,$ac_top_builddir,;t t -s,@abs_top_builddir@,$ac_abs_top_builddir,;t t -s,@INSTALL@,$ac_INSTALL,;t t -" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out - rm -f $tmp/stdin +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + :H) + # + # CONFIG_HEADER + # +_ACEOF + +# Transform confdefs.h into a sed script `conftest.defines', that +# substitutes the proper values into config.h.in to produce config.h. +rm -f conftest.defines conftest.tail +# First, append a space to every undef/define line, to ease matching. +echo 's/$/ /' >conftest.defines +# Then, protect against being on the right side of a sed subst, or in +# an unquoted here document, in config.status. If some macros were +# called several times there might be several #defines for the same +# symbol, which is useless. But do not sort them, since the last +# AC_DEFINE must be honored. +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +# NAME is the cpp macro being defined, VALUE is the value it is being given. +# PARAMS is the parameter list in the macro definition--in most cases, it's +# just an empty string. +ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +ac_dB='\\)[ (].*,\\1define\\2' +ac_dC=' ' +ac_dD=' ,' + +uniq confdefs.h | + sed -n ' + t rset + :rset + s/^[ ]*#[ ]*define[ ][ ]*// + t ok + d + :ok + s/[\\&,]/\\&/g + s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p + s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p + ' >>conftest.defines + +# Remove the space that was appended to ease matching. +# Then replace #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +# (The regexp can be short, since the line contains either #define or #undef.) +echo 's/ $// +s,^[ #]*u.*,/* & */,' >>conftest.defines + +# Break up conftest.defines: +ac_max_sed_lines=50 + +# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +# et cetera. +ac_in='$ac_file_inputs' +ac_out='"$tmp/out1"' +ac_nxt='"$tmp/out2"' + +while : +do + # Write a here document: + cat >>$CONFIG_STATUS <<_ACEOF + # First, check the format of the line: + cat >"\$tmp/defines.sed" <<\\CEOF +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +b +:def +_ACEOF + sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS + ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in + sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail + grep . conftest.tail >/dev/null || break + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines conftest.tail + +echo "ac_result=$ac_in" >>$CONFIG_STATUS +cat >>$CONFIG_STATUS <<\_ACEOF if test x"$ac_file" != x-; then - mv $tmp/out $ac_file + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f $ac_file + mv "$tmp/config.h" $ac_file + fi else - cat $tmp/out - rm -f $tmp/out + echo "/* $configure_input */" + cat "$ac_result" fi + rm -f "$tmp/out12" +# Compute $ac_file's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $ac_file | $ac_file:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $ac_file" >`$as_dirname -- $ac_file || +$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X$ac_file : 'X\(//\)[^/]' \| \ + X$ac_file : 'X\(//\)$' \| \ + X$ac_file : 'X\(/\)' \| . 2>/dev/null || +echo X$ac_file | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 +echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir=$dirpart/$fdir + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done done -_ACEOF + ;; + + esac +done # for ac_tag -cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF @@ -2852,6 +8962,7 @@ if test "$no_create" != yes; then fi +# Finished cat <<EOF Finished configuring. Type 'make' to build the package diff --git a/configure.ac b/configure.ac index a9ce275..a1eeffc 100644 --- a/configure.ac +++ b/configure.ac @@ -1,21 +1,50 @@ -dnl Process this file with autoconf to produce a configure script. -AC_INIT(foomatic-rip.in) +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. -dnl If the user didn't specify the $sysconfdir on the command line, let it -dnl be /etc, not /usr/local/etc or /usr/etc -dnl if [[ x$sysconfdir = 'x${prefix}/etc' ]]; then -dnl sysconfdir=/etc -dnl fi +AC_PREREQ(2.61) +AC_INIT(foomatic-rip, "4.0.0") +AM_INIT_AUTOMAKE([no-define]) +AC_CONFIG_SRCDIR([options.c]) -dnl Checks for programs. +AC_DEFINE_UNQUOTED(VERSION, "`cat VERSION.full 2> /dev/null`", [Foomatic version]) + + +# Checks for programs. +AC_PROG_CC +AC_PROG_CXX AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET +# Checks for libraries. +AC_CHECK_LIB(m, roundf) + +# Checks for header files. +AC_HEADER_STDC +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS([fcntl.h memory.h stddef.h stdlib.h string.h strings.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_TYPE_SSIZE_T +AC_STRUCT_TM + +# Checks for library functions. +AC_FUNC_FORK +AC_FUNC_MALLOC +AC_FUNC_REALLOC +AC_TYPE_SIGNAL +AC_FUNC_STRTOD +AC_FUNC_VPRINTF +AC_CHECK_FUNCS([dup2 getcwd gethostname regcomp setenv strcasecmp strchr strcspn strdup strncasecmp strndup strrchr strstr strtol]) + + ETCSEARCHPATH=${prefix}/etc:/usr/etc:/usr/local/etc -LIBSEARCHPATH=${prefix}/lib:/usr/lib:/usr/local/lib:${prefix}/libexec:/usr/libexec:/usr/local/libexec +LIBSEARCHPATH=${prefix}/lib:${prefix}/lib64:/usr/lib:/usr/lib64:/usr/local/lib:${prefix}/libexec:/usr/libexec:/usr/local/libexec -dnl Get the operating system and version number... uname=`uname` uversion=`uname -r | sed -e '1,$s/[[^0-9]]//g'` if test x$uname = xIRIX64; then @@ -34,34 +63,37 @@ if test -z "$PERL"; then AC_MSG_ERROR([Perl 5 is required to build and run]); fi -dnl Check for /etc/printcap +# Check for /etc/printcap AC_PATH_DIR(PRINTCAP,printcap,/etc/printcap,$ETCSEARCHPATH) -dnl Check for /usr/lib/cups +# Check for /usr/lib/cups AC_PATH_DIR(CUPS,cups,/usr/lib/cups,$LIBSEARCHPATH) -dnl Check for /usr/lib/cups/filter +# Check for /usr/lib/cups/filter AC_PATH_DIR(CUPS_FILTERS,cups/filter,/usr/lib/cups/filter,$LIBSEARCHPATH) -dnl Check for /usr/lib/cups/backend +# Check for /usr/lib/cups/backend AC_PATH_DIR(CUPS_BACKENDS,cups/backend,/usr/lib/cups/backend,$LIBSEARCHPATH) -dnl Check for /usr/lib/ppr +# Check for /usr/lib/ppr AC_PATH_DIR(PPR,ppr,/usr/lib/ppr,$LIBSEARCHPATH) -dnl Check for /usr/lib/ppr/interfaces +# Check for /usr/lib/ppr/interfaces AC_PATH_DIR(PPR_INTERFACES,ppr/interfaces,/usr/lib/ppr/interfaces,$LIBSEARCHPATH) -dnl Check for /usr/lib/ppr/lib +# Check for /usr/lib/ppr/lib AC_PATH_DIR(PPR_LIB,ppr/lib,/usr/lib/ppr/lib,$LIBSEARCHPATH) +AC_CHECK_HEADERS([ghostscript/ierrors.h ghostscript/iapi.h]) +AC_CHECK_LIB(gs, gsapi_new_instance) + AC_ARG_ENABLE(file-converter-check, [ --enable-file-converter-check check whether a file converter is installed [default=yes]], [if eval "test x${enableval} = xno"; then NOCONVERTERCHECK=1 AC_MSG_WARN([Absence of a file converter is ignored, package will be built anyway]) fi]) -dnl Check for a2ps, enscript, mpage +# Check for a2ps, enscript, mpage AC_PATH_PROG(A2PS,a2ps) AC_PATH_PROG(ENSCRIPT,enscript) AC_PATH_PROG(MPAGE,mpage) @@ -92,11 +124,11 @@ AC_ARG_WITH(execpath,[ --with-execpath=(path to various filters) AC_MSG_RESULT([Execpath: $EXECPATH]) AC_SUBST(EXECPATH) -AC_OUTPUT(Makefile beh \ - foomatic-rip foomatic-gswrapper \ - foomatic-rip.1 foomatic-gswrapper.1) +AC_CONFIG_FILES([Makefile beh foomatic-rip.1]) +AC_CONFIG_HEADER(config.h) +AC_OUTPUT -dnl Finished +# Finished cat <<EOF Finished configuring. Type 'make' to build the package diff --git a/debian/README.Debian b/debian/README.Debian deleted file mode 100644 index b867d92..0000000 --- a/debian/README.Debian +++ /dev/null @@ -1,19 +0,0 @@ -foomatic-filters for Debian ---------------------------- - -Note that the structure of the OpenPrinting (foomatic) printer -configuration system in Debian (and upstream) has changed from the 2.0 -series. There are now 3 core packages: - -* foomatic-db: Contains the foomatic printer database. - -* foomatic-db-engine: Contains the foomatic-configure script. - -* foomatic-filters (this package): Contains the filter scripts for - various backend printing systems. - -In addition, the new foomatic-db-hpijs package includes the database -entries for printers supported by the HPIJS print filter developed by -Hewlett-Packard for its consumer inkjet line of printers. - - -- Chris Lawrence <lawrencc@debian.org>, Wed Jul 20 03:23:50 2005 diff --git a/debian/changelog b/debian/changelog deleted file mode 100644 index 4a62d56..0000000 --- a/debian/changelog +++ /dev/null @@ -1,469 +0,0 @@ -foomatic-filters (3.0.2-20080211-3.2) unstable; urgency=low - - * Non-maintainer upload. - * Fix pending l10n bugs. Debconf translations: - - Swedish. Closes: #491416 - - Dutch. Closes: #500513 - * Remove extra debian/po.old directory (cruft left in previous NMU, sorry) - - -- Christian Perrier <bubulle@debian.org> Tue, 30 Sep 2008 07:21:15 +0200 - -foomatic-filters (3.0.2-20080211-3.1) unstable; urgency=low - - * Non-maintainer upload to fix pending l10n issues. - * Debconf translations: - - Russian was already complete. Closes: #467184, #467186 - - Basque. Closes: #469474 - - Turkish. Closes: #470786 - - Spanish. Closes: #472465 - - -- Christian Perrier <bubulle@debian.org> Tue, 13 May 2008 08:44:14 +0200 - -foomatic-filters (3.0.2-20080211-3) unstable; urgency=low - - * Incorporate all the template changes made during the templates rewrite. - - -- Chris Lawrence <lawrencc@debian.org> Thu, 28 Feb 2008 13:27:44 -0600 - -foomatic-filters (3.0.2-20080211-2) unstable; urgency=low - - * Fix the translations properly based on the debconf templates rewrite. - (Closes: #444654) - * I really can't type bug numbers correctly on a laptop. (Closes: #466616) - - -- Chris Lawrence <lawrencc@debian.org> Fri, 22 Feb 2008 01:10:09 -0600 - -foomatic-filters (3.0.2-20080211-1) unstable; urgency=low - - * New upstream release. (Closes: #461564, #446616) - * Fix(?) debian/watch. (Closes: #449615) - * Update translations. - - ca (Closes: #446389) - - cs (Closes: #446641) - - de (Closes: #447193) - - fi (Closes: #446406) - - fr (Closes: #445220) - - gl (Closes: #446478) - - it (Closes: #447050) - - ja (Closes: #445341) - - pt (Closes: #445272) - - pt_BR (Closes: #446941) - - ru (Closes: #446928, #432874) - - vi (Closes: #427022, #446892) - * Remove debconf handling of Ghostscript interpreter; no longer - necessary due to end of gs-* packages. (Closes: #447086) - - -- Chris Lawrence <lawrencc@debian.org> Thu, 21 Feb 2008 14:17:18 -0600 - -foomatic-filters (3.0.2-20061031-1.2) unstable; urgency=low - - * Non-maintainer upload to fix pending l10n issues. - * Debconf translations: - - Translation files converted to UTF-8 - - Czech. Closes: #408722 - - Portuguese. Closes: #409210 - - -- Christian Perrier <bubulle@debian.org> Fri, 2 Mar 2007 07:39:27 +0100 - -foomatic-filters (3.0.2-20061031-1.1) unstable; urgency=low - - * Non-maintainer upload to fix l10n issues - * Debconf translation updates/additions: - - German. Closes: #401469 - - French. Closes: #399364 - - Spanish. Closes: #401959 - - Brazilian Portuguese. Closes: #403830 - - Dutch. Closes: #406856 - - Galician. Closes: #407288 - - -- Christian Perrier <bubulle@debian.org> Sat, 20 Jan 2007 14:48:55 +0100 - -foomatic-filters (3.0.2-20061031-1) unstable; urgency=low - - * New upstream release. - * Make corrections to the debconf template pointed out by Erik Schanze - in private email. - * Update translations to fr, nl, pt. (Closes: #384390, #387656, #396639) - - -- Chris Lawrence <lawrencc@debian.org> Sat, 4 Nov 2006 19:11:37 -0600 - -foomatic-filters (3.0.2-20060712-3) unstable; urgency=low - - * Apply patch improving the translation of debconf templates. - (Closes: #378220) - - -- Chris Lawrence <lawrencc@debian.org> Mon, 21 Aug 2006 09:36:21 -0500 - -foomatic-filters (3.0.2-20060712-2) unstable; urgency=low - - * Update Japanese, French translations. (Closes: #378937, #379948) - * Add Portuguese, Swedish translations. (Closes: #381897, #381917) - - -- Chris Lawrence <lawrencc@debian.org> Mon, 21 Aug 2006 01:28:48 -0500 - -foomatic-filters (3.0.2-20060712-1) unstable; urgency=low - - * New upstream release. - - -- Chris Lawrence <lawrencc@debian.org> Wed, 12 Jul 2006 20:11:45 -0400 - -foomatic-filters (3.0.2-20060530-1) unstable; urgency=low - - * New upstream release. - - -- Chris Lawrence <lawrencc@debian.org> Tue, 30 May 2006 19:52:08 -0400 - -foomatic-filters (3.0.2-20060318-2) unstable; urgency=low - - * Remove /etc/foomatic/defaultspooler in purge. (Closes: #359322) - - -- Chris Lawrence <lawrencc@debian.org> Mon, 27 Mar 2006 17:25:02 -0500 - -foomatic-filters (3.0.2-20060318-1) unstable; urgency=low - - * The "gee, won't it be nice when I can upload amd64 packages instead of - using a jury-rigged i386 pbuilder" release. - * New upstream CVS pull (no changes recorded in ChangeLog, but better - safe than sorry). - * Force upgrade from gs << 8.0 or gs-aladdin << 8.0. - * Reprompt for gspath if it is gs-gnu or gs-aladdin. - (Closes: #354149, #352856) - * Add Czech translation. (Closes: #309020) - * Add Vietnamese translation. (Closes: #314179) - * Improve robustness of postinst, even though I think the specific problem - reported is long fixed. (Closes: #289363) - * Don't fail in postrm if ucf is missing (an error message will still - display, but postrm will exit 0). (Closes: #350474) - * Apply patch fixing typos in man page foomatic-rip(1). (Closes: #351421) - - -- Chris Lawrence <lawrencc@debian.org> Sat, 18 Mar 2006 22:56:52 -0500 - -foomatic-filters (3.0.2-20060113-1) unstable; urgency=low - - * New upstream release. - - -- Chris Lawrence <lawrencc@debian.org> Fri, 13 Jan 2006 18:24:58 -0500 - -foomatic-filters (3.0.2-20050720-1) unstable; urgency=low - - * New upstream release. - * Remove mention of foomatic-bin from README.Debian. - - -- Chris Lawrence <lawrencc@debian.org> Wed, 20 Jul 2005 03:24:28 -0500 - -foomatic-filters (3.0.2-20050705-1) unstable; urgency=low - - * New upstream release. - - -- Chris Lawrence <lawrencc@debian.org> Tue, 5 Jul 2005 01:53:28 -0500 - -foomatic-filters (3.0.2-20050403-1) unstable; urgency=low - - * New upstream release. - - -- Chris Lawrence <lawrencc@debian.org> Sun, 3 Apr 2005 23:03:31 -0500 - -foomatic-filters (3.0.2-20041204-1) unstable; urgency=low - - * New upstream release. - - -- Chris Lawrence <lawrencc@debian.org> Sat, 4 Dec 2004 11:38:53 -0600 - -foomatic-filters (3.0.2-3) unstable; urgency=low - - * Apply patch to French and Brazilian Portuguese translations to fix - encoding issues. (Closes: #277570) - - -- Chris Lawrence <lawrencc@debian.org> Fri, 22 Oct 2004 06:15:29 -0500 - -foomatic-filters (3.0.2-2) unstable; urgency=low - - * Apply file descriptor handing patch from Alexander Achenbach. - This will fix some incompatibilities with Ghostscript prefiltering, - etc. (Closes: #271519) - - -- Chris Lawrence <lawrencc@debian.org> Tue, 19 Oct 2004 01:07:45 -0500 - -foomatic-filters (3.0.2-1) unstable; urgency=high - - * New upstream release. (Released ahead of embargo date due to public - notice of vulnerability being posted at LinuxPrinting.org. Fix has - been in CVS since August 26th.) - * Fixes foomatic-rip vulnerability CAN-2004-0801, which allows arbitrary - commands to be run as the spooler's UID (possibly root). - - -- Chris Lawrence <lawrencc@debian.org> Tue, 14 Sep 2004 20:38:08 -0500 - -foomatic-filters (3.0.1-20040621-4) unstable; urgency=low - - * Update Brazilian Portuguese translation. (Closes: #264193) - - -- Chris Lawrence <lawrencc@debian.org> Sat, 7 Aug 2004 19:25:42 -0500 - -foomatic-filters (3.0.1-20040621-3) unstable; urgency=medium - - * Downgrade foomatic-filters/spooler to low priority; the autodetection - should be sufficiently good for most purposes. - * Update French translation. (Closes: #257550) - - -- Chris Lawrence <lawrencc@debian.org> Sun, 4 Jul 2004 07:49:15 -0500 - -foomatic-filters (3.0.1-20040621-2) unstable; urgency=low - - * Update German translation. (Closes: #256619) - * Update Japanese translation. (Closes: #256097) - - -- Chris Lawrence <lawrencc@debian.org> Mon, 28 Jun 2004 02:50:26 -0500 - -foomatic-filters (3.0.1-20040621-1) unstable; urgency=low - - * New upstream release. - - -- Chris Lawrence <lawrencc@debian.org> Mon, 21 Jun 2004 02:24:42 -0500 - -foomatic-filters (3.0.1-20040506-6) unstable; urgency=low - - * Fix handling of config file. (Closes: #254462, #254516, #254652) - * Updated Dutch translation. (Closes: #254582) - - -- Chris Lawrence <lawrencc@debian.org> Mon, 21 Jun 2004 02:19:54 -0500 - -foomatic-filters (3.0.1-20040506-5) unstable; urgency=low - - * Move parseconfig Perl fragment into its own file, so the syntax - highlighting is correct. - * Try to autodetect the spooler, and record this setting in - /etc/foomatic/defaultspooler to make foomatic-configure more friendly. - * Modify foomatic-filters.config to skip the filter question with CUPS, - and skip the PS accounting question unless CUPS is being used. - - -- Chris Lawrence <lawrencc@debian.org> Mon, 14 Jun 2004 03:05:54 -0500 - -foomatic-filters (3.0.1-20040506-4) unstable; urgency=low - - * Fix case of Foomatic in one spot in the debconf template. - * Eliminated all fuzziness from translations. - * Add German debconf translation. (Closes: #252823) - - -- Chris Lawrence <lawrencc@debian.org> Sun, 6 Jun 2004 21:06:10 -0500 - -foomatic-filters (3.0.1-20040506-3) unstable; urgency=low - - * Add Turkish and Dutch debconf translations. - (Closes: #246077, #251400) - - -- Chris Lawrence <lawrencc@debian.org> Fri, 28 May 2004 23:36:23 -0500 - -foomatic-filters (3.0.1-20040506-2) unstable; urgency=low - - * Updated French debconf translation. (Closes: #248662) - * Manually fixed Portuguese and Japanese translations. - - -- Chris Lawrence <lawrencc@debian.org> Fri, 14 May 2004 18:27:43 -0500 - -foomatic-filters (3.0.1-20040506-1) unstable; urgency=low - - * New upstream release. - * Changed gs-aladdin to gs-afpl in Debconf template. - - -- Chris Lawrence <lawrencc@debian.org> Thu, 6 May 2004 23:00:07 -0500 - -foomatic-filters (3.0.1-6) unstable; urgency=low - - * Updated French translation. (Closes: #238121) - * Ran debconf-updatepo manually, for good measure, even though it's - claimed in the form letter I received as part of #238121 that - dh_installdebconf automatically does this. - - -- Chris Lawrence <lawrencc@debian.org> Mon, 15 Mar 2004 19:03:27 -0600 - -foomatic-filters (3.0.1-5) unstable; urgency=low - - * Add Portguese translation of debconf templates. (Closes: #235469) - - -- Chris Lawrence <lawrencc@debian.org> Mon, 1 Mar 2004 16:10:07 -0600 - -foomatic-filters (3.0.1-4) unstable; urgency=low - - * Update Japanese translation. (Closes: #235094) - - -- Chris Lawrence <lawrencc@debian.org> Sat, 28 Feb 2004 03:16:15 -0600 - -foomatic-filters (3.0.1-3) unstable; urgency=low - - * Update French translation. (Closes: #228999) - - -- Chris Lawrence <lawrencc@debian.org> Thu, 26 Feb 2004 04:28:26 -0600 - -foomatic-filters (3.0.1-2) unstable; urgency=low - - * Add debconf configuration for the gspath variable. - * Remove all the ucf hackery, since ucf now supports debconf. We now - depend on the latest ucf. - * Remove the temporary file generated from the debconf data. - - -- Chris Lawrence <lawrencc@debian.org> Sun, 22 Feb 2004 19:43:05 -0600 - -foomatic-filters (3.0.1-1) unstable; urgency=low - - * New upstream release. No upstream changes since last CVS snapshot. - * Use DEBIAN_FRONTEND instead of DEBCONF_FRONTEND for the interactivity - test, and check the debconf database for the frontend setting too; - this should solve the buildd problems with packages that depend on - foomatic-filters. - - -- Chris Lawrence <lawrencc@debian.org> Fri, 20 Feb 2004 21:52:42 -0600 - -foomatic-filters (3.0.0-20040203-1) unstable; urgency=low - - * New upstream release. - * If DEBCONF_FRONTEND is "noninteractive", bypass ucf handling of - /etc/foomatic/filter.conf. (Closes: #231018) - - -- Chris Lawrence <lawrencc@debian.org> Tue, 3 Feb 2004 19:41:34 -0600 - -foomatic-filters (3.0.0-20040114-1) unstable; urgency=low - - * New upstream release. - * Update debconf translations. (Closes: #224193, #227127) - * Acknowledge NMU. (Closes: #223681) - - -- Chris Lawrence <lawrencc@debian.org> Wed, 14 Jan 2004 23:01:10 -0600 - -foomatic-filters (3.0.0-20031207-1) unstable; urgency=low - - * New upstream release. - * Handle filter.conf with ucf. - * Bypass the file converter check when calling configure. - (Closes: #223152) - - -- Chris Lawrence <lawrencc@debian.org> Sun, 7 Dec 2003 21:34:52 -0600 - -foomatic-filters (3.0.0-20031118-1) unstable; urgency=low - - * New upstream release. - * Note that texttops is used with CUPS by default in the template file. - (This will require minor po file updates.) - - -- Chris Lawrence <lawrencc@debian.org> Tue, 18 Nov 2003 15:32:03 -0600 - -foomatic-filters (3.0.0-20030919-3) unstable; urgency=low - - * New debconf translations. (Closes: #212496, #212723) - - -- Chris Lawrence <lawrencc@debian.org> Mon, 29 Sep 2003 09:12:16 -0500 - -foomatic-filters (3.0.0-20030919-2) unstable; urgency=low - - * Don't use the *dj variants of paper sizes, since a2ps seems to have - recently lost support for them. (Closes: #212259) - - -- Chris Lawrence <lawrencc@debian.org> Mon, 22 Sep 2003 19:54:47 -0500 - -foomatic-filters (3.0.0-20030919-1) unstable; urgency=low - - * New upstream release. - - -- Chris Lawrence <lawrencc@debian.org> Fri, 19 Sep 2003 20:35:00 -0500 - -foomatic-filters (3.0.0-20030907-2) unstable; urgency=low - - * Add French translation of debconf templates. (Closes: #211222) - * foomatic-rip now dies with a reasonable error message if unable to - open the log file. (Closes: #211345) - * Drop the debconf question on retaining the config file; the new - behavior is equivalent to "parse", which was the default behavior - anyway. (Closes: #200713) - * Change the default setting for the PostScript filter to "Automagic" - and lower the question priority to "low". - - -- Chris Lawrence <lawrencc@debian.org> Fri, 19 Sep 2003 20:30:37 -0500 - -foomatic-filters (3.0.0-20030907-1) unstable; urgency=low - - * New upstream release. - * Include Japanese translation of debconf templates. (Closes: #207513) - - -- Chris Lawrence <lawrencc@debian.org> Sun, 7 Sep 2003 12:07:18 -0500 - -foomatic-filters (3.0.0-20030628-2) unstable; urgency=low - - * Test whether /etc/foomatic/filter.conf.debconf-old exists before doing - file operations on it in the postinst. (Closes: #199777) - - -- Chris Lawrence <lawrencc@debian.org> Wed, 2 Jul 2003 22:53:05 -0500 - -foomatic-filters (3.0.0-20030628-1) unstable; urgency=low - - * New upstream release. - - -- Chris Lawrence <lawrencc@debian.org> Sat, 28 Jun 2003 17:08:02 -0500 - -foomatic-filters (3.0.0-5) unstable; urgency=low - - * Change conflicts line to not conflict with the forthcoming - cupsomatic-ppd transition package. - - -- Chris Lawrence <lawrencc@debian.org> Sat, 14 Jun 2003 19:06:39 -0500 - -foomatic-filters (3.0.0-4) unstable; urgency=low - - * Conflict/Replace with the massively obsolete cupsomatic-ppd. - (Closes: #195550) - - -- Chris Lawrence <lawrencc@debian.org> Tue, 10 Jun 2003 17:41:27 -0500 - -foomatic-filters (3.0.0-3) unstable; urgency=medium - - * Fiddle with dependencies to break the cycle keeping foomatic 3.x out - of testing. - - -- Chris Lawrence <lawrencc@debian.org> Tue, 27 May 2003 15:47:43 -0500 - -foomatic-filters (3.0.0-2) unstable; urgency=low - - * Include symbolic links for lpdomatic and directomatic for - backwards-compatibility with Foomatic 2.0. - - -- Chris Lawrence <lawrencc@debian.org> Sat, 3 May 2003 23:39:02 -0500 - -foomatic-filters (3.0.0-1) unstable; urgency=low - - * New upstream release. - - -- Chris Lawrence <lawrencc@debian.org> Sat, 3 May 2003 23:15:09 -0500 - -foomatic-filters (2.9-20030423-3) unstable; urgency=low - - * Straightened out foomatic-filters.config on first install, I think. - At least, it works here when the database entries are deleted and - /etc/foomatic/filter.conf is removed. (Closes: #190642) - - -- Chris Lawrence <lawrencc@debian.org> Tue, 29 Apr 2003 16:58:05 -0500 - -foomatic-filters (2.9-20030423-2) unstable; urgency=low - - * Upgraded foomatic-db-engine to a dependency. - - -- Chris Lawrence <lawrencc@debian.org> Thu, 24 Apr 2003 14:43:39 -0500 - -foomatic-filters (2.9-20030423-1) unstable; urgency=low - - * New upstream release. (Same as 3.0.0rc2) - - -- Chris Lawrence <lawrencc@debian.org> Wed, 23 Apr 2003 19:23:23 -0500 - -foomatic-filters (2.9-3.0.0rc1-2) unstable; urgency=low - - * Add a symbolic link in /usr/lib/cups/filter from cupsomatic to - foomatic-rip, for backwards-compatibility with Foomatic 2.x. - (Closes: #190106) - * Tried to clean up the description somewhat. - - -- Chris Lawrence <lawrencc@debian.org> Wed, 23 Apr 2003 19:15:20 -0500 - -foomatic-filters (2.9-3.0.0rc1-1) unstable; urgency=low - - * Initial Release. - - -- Chris Lawrence <lawrencc@debian.org> Sun, 13 Apr 2003 20:44:09 -0500 diff --git a/debian/compat b/debian/compat deleted file mode 100644 index b8626c4..0000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -4 diff --git a/debian/control b/debian/control deleted file mode 100644 index 22babf0..0000000 --- a/debian/control +++ /dev/null @@ -1,29 +0,0 @@ -Source: foomatic-filters -Section: text -Priority: optional -Maintainer: Chris Lawrence <lawrencc@debian.org> -Build-Depends: debhelper (>> 4), po-debconf -Homepage: http://www.openprinting.org/ -Standards-Version: 3.7.3 - -Package: foomatic-filters -Architecture: all -Pre-Depends: bash (>= 2.05) -Depends: ${perl:Depends}, ${misc:Depends}, ucf (>= 0.30) -Recommends: cupsys-client | lpr | lprng | pdq | rlpr, gs-esp | gs, cupsys | enscript | a2ps | mpage, foomatic-db-engine -Conflicts: foomatic-bin (<< 2.9), cupsomatic-ppd (<< 20030507), gs (<< 8.0), gs-aladdin (<< 8.0) -Replaces: foomatic-bin (<< 2.9), cupsomatic-ppd -Description: OpenPrinting printer support - filters - Foomatic is a printer database designed to make it easier to set up - common printers for use with UNIX-like other operating systems. - It provides the "glue" between a print spooler (like CUPS or lpr) and - the printer, by processing files sent to the printer. - . - This package consists of filter scripts used by the printer spoolers - to convert the incoming PostScript data into the printer's native - format using a printer-specific, but spooler-independent PPD file. - You will need to install the foomatic-db-engine package and its - dependencies for this package to be useful. - . - For use with CUPS, you will need both the cupsys and cupsys-client - packages installed on your system. diff --git a/debian/copyright b/debian/copyright deleted file mode 100644 index 4c6c8ae..0000000 --- a/debian/copyright +++ /dev/null @@ -1,27 +0,0 @@ -This package was debianized by Chris Lawrence <lawrencc@debian.org> on -Sun, 13 Apr 2003 20:44:09 -0500. - -It was downloaded from http://www.openprinting.org/download/foomatic/ - -Upstream Authors: - Original founder: Grant Taylor <gtaylor@picante.com> - Current maintainer: Till Kamppeter <till.kamppeter@gmail.com> - -Copyright: - - This package 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; version 2 dated June, 1991. - - This package 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 package; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - -On Debian systems, the complete text of the GNU General -Public License can be found in `/usr/share/common-licenses/GPL'. - diff --git a/debian/dirs b/debian/dirs deleted file mode 100644 index 84a4858..0000000 --- a/debian/dirs +++ /dev/null @@ -1,6 +0,0 @@ -etc/foomatic -usr/bin -usr/sbin -usr/share/foomatic -usr/share/man/man1 -usr/share/man/man8 diff --git a/debian/docs b/debian/docs deleted file mode 100644 index f0e1368..0000000 --- a/debian/docs +++ /dev/null @@ -1,3 +0,0 @@ -README -TODO -USAGE diff --git a/debian/foomatic-filters.config b/debian/foomatic-filters.config deleted file mode 100644 index 2e5bfd9..0000000 --- a/debian/foomatic-filters.config +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/bash -e -# -# Debconf configuration script for the foomatic-filters package -# - -. /usr/share/debconf/confmodule - -db_version 2.0 -db_capb backup -db_title Foomatic Printer Filter Configuration - -declare -i state=1 backup=0 - -function parseconfig -{ - if [ -e /usr/share/foomatic/parseconfig.pl ]; then - db_clear - eval $(/usr/bin/perl /usr/share/foomatic/parseconfig.pl) - db_set foomatic-filters/config_parsed true - else - db_set foomatic-filters/config_parsed false - fi -} - -################# -### Main loop ### -################# - -parseconfig - -if [ -f /etc/foomatic/defaultspooler ]; then - db_set foomatic-filters/spooler `cat /etc/foomatic/defaultspooler`; -else - # Try to detect from installed packages; use the one found first in - # the list - spooler=`dpkg-query --showformat='${Package} ${Status}' -W cupsys lpr lprng rlpr lpr-ppd pdq ppr 2>/dev/null | grep ' installed$' | cut -d' ' -f1 | head -1` - if [ "$spooler" = cupsys ]; then - spooler=cups - elif [ "$spooler" = lpr-ppd -o "$spooler" = lpr -o "$spooler" = rlpr ]; then - spooler=lpd - fi - if [ "$spooler" ]; then - db_set foomatic-filters/spooler $spooler - else - # This script may be run before dpkg gets around to installing - # a spooler if it is done in the same apt run, so see if anything - # is in the "install" state. - spooler=`dpkg-query --showformat='${Package} ${Status}' -W cupsys lpr lprng rlpr lpr-ppd pdq ppr 2>/dev/null | grep ' install ' | cut -d' ' -f1 | head -1` - if [ "$spooler" = "cupsys" ]; then - spooler=cups - elif [ "$spooler" = lpr-ppd -o "$spooler" = lpr -o "$spooler" = rlpr ]; then - spooler=lpd - fi - if [ "$spooler" ]; then - db_set foomatic-filters/spooler $spooler - fi - fi -fi - -while ((state)); do - case $state in - 1) - db_input low foomatic-filters/spooler || true - ;; - 2) - db_input low foomatic-filters/filter_debug || true - ;; - 3) - db_get foomatic-filters/spooler; - if [ "$RET" = cups ]; then - ((backup ? state-- : state++ )) || true - continue - else - db_input low foomatic-filters/textfilter || true - fi - ;; - 4) - db_get foomatic-filters/textfilter; - if [ "$RET" = Custom ]; then - db_input low foomatic-filters/custom_textfilter || true - else - ((backup ? state-- : state++)) || true - continue - fi - ;; - 5) - db_get foomatic-filters/spooler; - if [ "$RET" = cups ]; then - db_input low foomatic-filters/ps_accounting || true - else - ((backup ? state-- : state++)) || true - continue - fi - ;; - *) - break; - ;; - esac - backup=0 - db_go || backup=1 - ((backup ? state-- : state++)) -done - -db_stop - -### Local Variables: -### tab-width: 4 -### End: diff --git a/debian/foomatic-filters.postinst b/debian/foomatic-filters.postinst deleted file mode 100644 index bc30bff..0000000 --- a/debian/foomatic-filters.postinst +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/bash -e - -# Source debconf library. -. /usr/share/debconf/confmodule - -readonly FILTERCONF=/etc/foomatic/filter.conf -readonly FILTERBACK=$FILTERCONF.debconf-old -readonly tempfile=`tempfile -pfoomatic-filters-` - -function parseconfig -{ - db_clear - eval $(/usr/bin/perl /usr/share/foomatic/parseconfig.pl) -} - -db_get foomatic-filters/config_parsed -if [ $RET = false ]; then - parseconfig - db_set foomatic-filters/config_parsed true -fi - -db_get foomatic-filters/filter_debug -debug="debug: 0" -if [ $RET = true ]; then - debug="debug: 1" -fi - -db_get foomatic-filters/textfilter -if [ "$RET" = Automagic ]; then - textfilter="# textfilter:" -else - if [ "$RET" = Custom ]; then - db_get foomatic-filters/custom_textfilter - fi - textfilter="textfilter: $RET" -fi - -# Disable the whole customized Ghostscript stuff -gspath="# gspath: gs" - -db_get foomatic-filters/ps_accounting -if [ $RET = true ]; then - ps_accounting="ps_accounting: 1" -else - ps_accounting="ps_accounting: 0" -fi - -db_get foomatic-filters/spooler -echo "$RET" >| /etc/foomatic/defaultspooler - -cat <<EOF >| $tempfile -# This file allows you to configure the "foomatic-rip" filter. - -# You can force reconfiguration managed via debconf by running the -# following command: -# dpkg-reconfigure foomatic-filters -# You may need to change the lowest priority of questions to be presented -# using the switch "-p" to access some or any of these options. - -# Command for converting text files to PostScript. -# -# Priority low -$textfilter - -# Enable debug output into a logfile in /tmp/foomatic-rip.log. -# It will contain status from this filter, plus Ghostscript stderr output. -# -# WARNING: This logfile is a potential security hole; do not use in production. -# -# Priority low -$debug - -# Enable insertion of PostScript code for accounting into each printjob. -# Currently only supported with CUPS. (EXPERIMENTAL) -# -# NOTE: Enabling this option may cause extra pages to be printed after each -# job as well as after banner pages, especially with generic -# PostScript printers. -# -# Priority low -$ps_accounting - -# Path to the Ghostscript interpreter; will search the path for 'gs' if -# not specified. -# -# Priority low -$gspath - -EOF - -if [ -e $FILTERCONF ]; then - chmod --reference=$FILTERCONF $tempfile -else - chmod 0644 $tempfile -fi - -ucf --three-way --debconf-ok $tempfile $FILTERCONF - -db_stop - -# Remove the temporary file -rm -f $tempfile - -#DEBHELPER# - -### Local Variables: -### tab-width: 4 -### End: diff --git a/debian/foomatic-filters.postrm b/debian/foomatic-filters.postrm deleted file mode 100644 index 25c5dbd..0000000 --- a/debian/foomatic-filters.postrm +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -e - -case "$1" in - purge) - rm -f /etc/foomatic/filter.conf /etc/foomatic/defaultspooler - ucf --purge /etc/foomatic/filter.conf || true - ;; -esac - -#DEBHELPER# - -exit 0 diff --git a/debian/foomatic-filters.templates b/debian/foomatic-filters.templates deleted file mode 100644 index 2102be6..0000000 --- a/debian/foomatic-filters.templates +++ /dev/null @@ -1,76 +0,0 @@ -# These templates have been reviewed by the debian-l10n-english -# team -# -# If modifications/additions/rewording are needed, please ask -# debian-l10n-english@lists.debian.org for advice. -# -# Even minor modifications require translation updates and such -# changes should be coordinated with translators and reviewers. - -Template: foomatic-filters/filter_debug -Type: boolean -Default: false -_Description: Enable logging debug output into a log file (INSECURE)? - If you choose this option, the log file will be named /tmp/foomatic-rip.log. - . - This option is a potential security issue and should not be used - in production. However, if you are having trouble printing, you should - enable it and include the log file in bug reports. - -Template: foomatic-filters/textfilter -Type: select -#flag:translate:1,5 -__Choices: Automagic, a2ps, mpage, enscript, Custom -Default: Automagic -_Description: Command for converting text files to PostScript: - If you select 'Automagic', Foomatic will search for one of a2ps, - mpage, and enscript (in that order) each time the filter script is executed. - . - Please make sure that the selected command is actually available; otherwise - print jobs may get lost. - . - This setting is ignored when foomatic-filters is used with CUPS; - instead, the texttops program included in the cupsys package is - always used to convert jobs submitted as plain text to PostScript for - printing to raster devices. - -Template: foomatic-filters/custom_textfilter -Type: string -_Description: Command to convert standard input to PostScript: - Please enter the full command line of a command that converts text from - standard input to PostScript on standard output. - . - Please note that entering an invalid command line here may result in lost - print jobs. - -Template: foomatic-filters/ps_accounting -Type: boolean -Default: false -_Description: Enable PostScript accounting for CUPS? - You should choose this option if you want to insert PostScript code - for accounting into each print job. This is currently only useful - with CUPS. - . - When used with generic PostScript printers (and under certain - conditions with other printers) this causes an extra page to be - printed after each job. - -Template: foomatic-filters/spooler -Type: select -Choices: cups, lpd, lprng, pdq, ppr, direct -Default: direct -_Description: Printer spooler backend for Foomatic: - Foomatic normally requires a printer spooler (like CUPS or LPRng) to - handle communication with the printer and manage print jobs. If - no spooler is installed, you can use the 'direct' backend, but - this is only recommended for single-user systems. - . - The installation process may have already detected the correct - spooler; however, if this is the initial installation of this system, - or if more than one spooler is installed, - the detected spooler may be incorrect. - -Template: foomatic-filters/config_parsed -Type: boolean -Default: false -Description: (for internal use only) diff --git a/debian/parseconfig.pl b/debian/parseconfig.pl deleted file mode 100644 index b9854ee..0000000 --- a/debian/parseconfig.pl +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/perl - -my $configpath = "/etc/foomatic"; - -sub readConfFile -{ - my ($file) = @_; - - my %conf; - # Read config file if present - if (open CONF, "< $file") - { - while (<CONF>) - { - $conf{$1}="$2" if (m/^\s*([^\#\s]\S*)\s*:\s*(.*)\s*$/); - } - close CONF; - } - - return %conf; -} - -%conf = readConfFile("$configpath/filter.conf"); -print( 'db_set foomatic-filters/filter_debug ', - $conf{debug} > 0 ? 'true' : 'false', ";\n") if exists $conf{debug}; -if (exists $conf{textfilter}) -{ - if ($conf{textfilter} =~ m/^(a2ps|enscript|mpage)$/) - { - print "db_set foomatic-filters/textfilter $1;\n"; - } - elsif ($conf{textfilter} =~ m/^\s*$/) - { - print "db_set foomatic-filters/textfilter Automagic;\n"; - } - else - { - print "db_set foomatic-filters/textfilter Custom;\n"; - print "db_set foomatic-filters/custom_textfilter $conf{textfilter};\n"; - } -} -print( 'db_set foomatic-filters/ps_accounting ', - $conf{ps_accounting} ? 'true' : 'false', - "\n") if exists $conf{ps_accounting}; diff --git a/debian/po/POTFILES.in b/debian/po/POTFILES.in deleted file mode 100644 index 7e902a6..0000000 --- a/debian/po/POTFILES.in +++ /dev/null @@ -1 +0,0 @@ -[type: gettext/rfc822deb] foomatic-filters.templates diff --git a/debian/po/de.po b/debian/po/de.po deleted file mode 100644 index 1351536..0000000 --- a/debian/po/de.po +++ /dev/null @@ -1,239 +0,0 @@ -# translation of foomatic-filters_3.0.2-20061031-1.3_de.po to German -# -# Translators, if you are not familiar with the PO format, gettext -# documentation is worth reading, especially sections dedicated to -# this format, e.g. by running: -# info -n '(gettext)PO Files' -# info -n '(gettext)Header Entry' -# Some information specific to po-debconf are available at -# /usr/share/doc/po-debconf/README-trans -# or http://www.debian.org/intl/l10n/po-debconf/README-trans# -# Developers do not need to manually edit POT or PO files. -# -# Erik Schanze <eriks@debian.org>, 2004-2007. -msgid "" -msgstr "" -"Project-Id-Version: foomatic-filters_3.0.2-20061031-1.3_de\n" -"Report-Msgid-Bugs-To: foomatic-filters@packages.debian.org\n" -"POT-Creation-Date: 2008-02-28 13:25-0600\n" -"PO-Revision-Date: 2007-10-18 22:08+0200\n" -"Last-Translator: Erik Schanze <eriks@debian.org>\n" -"Language-Team: German <debian-l10n-german@lists.debian.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.11.4\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "Enable logging debug output into a log file (INSECURE)?" -msgstr "Debug-Ausgaben in eine Protokolldatei schreiben (UNSICHER)?" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "" -"If you choose this option, the log file will be named /tmp/foomatic-rip.log." -msgstr "" -"Wenn Sie hier zustimmen, wird die Protokolldatei /tmp/foomatic-rip.log " -"heißen." - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "" -"This option is a potential security issue and should not be used in " -"production. However, if you are having trouble printing, you should enable " -"it and include the log file in bug reports." -msgstr "" -"Diese Auswahl ist eine mögliche Sicherheitslücke und sollte nicht in " -"Produktivumgebungen benutzt werden. Falls Sie Probleme beim Drucken haben, " -"sollten Sie sie dennoch einschalten und die Protokolldatei Ihrem " -"Fehlerbericht beifügen." - -#. Type: select -#. Choices -#: ../foomatic-filters.templates:3001 -msgid "Automagic" -msgstr "Automatisch" - -#. Type: select -#. Choices -#: ../foomatic-filters.templates:3001 -msgid "Custom" -msgstr "Benutzerspezifisch" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "Command for converting text files to PostScript:" -msgstr "Kommando für die Umwandlung von Textdateien in PostScript:" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"If you select 'Automagic', Foomatic will search for one of a2ps, mpage, and " -"enscript (in that order) each time the filter script is executed." -msgstr "" -"Falls Sie »Automatisch« auswählen, sucht Foomatic bei jedem Aufruf des " -"Filterskripts eines der Programme a2ps, mpage und enscript (in dieser " -"Reihenfolge)." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"Please make sure that the selected command is actually available; otherwise " -"print jobs may get lost." -msgstr "" -"Stellen Sie sicher, dass das ausgewählte Kommando verfügbar ist, sonst " -"könnten Druckaufträge verloren gehen." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"This setting is ignored when foomatic-filters is used with CUPS; instead, " -"the texttops program included in the cupsys package is always used to " -"convert jobs submitted as plain text to PostScript for printing to raster " -"devices." -msgstr "" -"Diese Einstellung hat keine Wirkung, wenn Foomatic-filters mit CUPS " -"eingesetzt wird; statt dessen wandelt das im Paket Cupsys enthaltene " -"Programm texttops Druckaufträge von Klartext in PostScript um, damit sie mit " -"rasterbasierten Geräten ausgedruckt werden können." - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "Command to convert standard input to PostScript:" -msgstr "Kommando für Umwandlung von der Standardeingabe in PostScript:" - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "" -"Please enter the full command line of a command that converts text from " -"standard input to PostScript on standard output." -msgstr "" -"Bitte geben Sie die vollständige Kommandozeile es Befehls ein, der Text von " -"der Standardeingabe einliest und als PostScript auf der Standardausgabe " -"ausgibt." - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "" -"Please note that entering an invalid command line here may result in lost " -"print jobs." -msgstr "" -"Bitte beachten Sie, dass ein ungültiges Kommando zum Verlust von " -"Druckaufträgen führen kann." - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "Enable PostScript accounting for CUPS?" -msgstr "PostScript-Abrechnung (accounting) für CUPS einschalten?" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "" -"You should choose this option if you want to insert PostScript code for " -"accounting into each print job. This is currently only useful with CUPS." -msgstr "" -"Sie sollten hier zustimmen, wenn Sie PostScript-Kommandos für die Abrechnung " -"in jeden Druckauftrag einbauen lassen wollen. Das ist derzeit nur mit CUPS " -"sinnvoll." - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "" -"When used with generic PostScript printers (and under certain conditions " -"with other printers) this causes an extra page to be printed after each job." -msgstr "" -"Beim Einsatz von gewöhnlichen PostScript-Druckern (und manchmal auch bei " -"anderen Druckern), wird hierdurch nach jedem Druckauftrag eine zusätzliche " -"Seite ausgedruckt." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "Printer spooler backend for Foomatic:" -msgstr "Druckerwarteschlange für Foomatic:" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "" -"Foomatic normally requires a printer spooler (like CUPS or LPRng) to handle " -"communication with the printer and manage print jobs. If no spooler is " -"installed, you can use the 'direct' backend, but this is only recommended " -"for single-user systems." -msgstr "" -"Foomatic benötigt normalerweise eine Druckerwarteschlange (wie CUPS oder " -"LPRng) für die Übertragung zum Drucker und die Verwaltung der Druckaufträge. " -"Wenn kein Druckdienst installiert ist, können Sie die »direct«-Anbindung " -"nutzen, aber das wird nur für Einzelbenutzersysteme empfohlen." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "" -"The installation process may have already detected the correct spooler; " -"however, if this is the initial installation of this system, or if more than " -"one spooler is installed, the detected spooler may be incorrect." -msgstr "" -"Während der Installation sollte schon der richtige Druckdienst erkannt " -"worden sein. Bei der Erstinstallation dieses Systems oder falls mehr als ein " -"Druckdienst installiert ist, könnte die Erkennung aber fehlerhaft sein." - -#~ msgid "Ghostscript interpreter to be used by Foomatic:" -#~ msgstr "Ghostscript-Übersetzer, den Foomatic benutzt:" - -#~ msgid "" -#~ "For non-PostScript printers, print jobs are usually translated from " -#~ "PostScript to the printer's command language using the free Ghostscript " -#~ "interpreter." -#~ msgstr "" -#~ "Für Drucker, die kein PostScript verstehen, werden Druckaufträge " -#~ "normalerweise mit einem freien Ghostscript-Übersetzer von PostScript in " -#~ "die Kommando-Sprache des Druckers übersetzt." - -#~ msgid "" -#~ "There are a number of different versions of the Ghostscript interpreter " -#~ "available. Normally, Foomatic will use the default version (configured by " -#~ "the 'gs' alternative, which can be changed with 'update-alternatives --" -#~ "config gs'). However, you may want to use a different Ghostscript for " -#~ "screen display than for printing; 'gs-esp' is usually a good choice for " -#~ "printing." -#~ msgstr "" -#~ "Es gibt viele verschiedene Versionen von Ghostscript-Übersetzern. " -#~ "Normalerweise nutzt Foomatic den Standard-Übersetzer, der über das " -#~ "Alternativen-System für »gs« eingestellt ist. (Das können Sie durch das " -#~ "Kommando 'update-alternatives --config gs' ändern.) Vielleicht wollen Sie " -#~ "für das Drucken einen anderen Ghostscript-Übersetzer als für die Anzeige " -#~ "am Bildschirm verwenden; »gs-esp« ist meist eine gute Wahl für das Drucken." - -#~ msgid "" -#~ "You should use the Custom option if you have a locally-installed " -#~ "Ghostscript interpreter." -#~ msgstr "" -#~ "Sie sollten »Benutzerspezifisch« wählen, wenn Sie einen lokal " -#~ "installierten Ghostscript-Übersetzer verwenden wollen." - -#~ msgid "Custom Ghostscript interpreter path:" -#~ msgstr "Pfad zum benutzerspezifischen Ghostscript-Übersetzer:" - -#~ msgid "Please enter the full path to the custom Ghostscript interpreter." -#~ msgstr "" -#~ "Bitte geben Sie den vollständigen Pfad zum Ghostscript-Übersetzer für die " -#~ "Auswahl »Benutzerspezifisch« ein." - -#~ msgid "Example: /opt/artifex.com-ghostscript/bin/gs" -#~ msgstr "Beispiel: /opt/artifex.com-ghostscript/bin/gs" diff --git a/debian/po/fr.po b/debian/po/fr.po deleted file mode 100644 index d95650c..0000000 --- a/debian/po/fr.po +++ /dev/null @@ -1,243 +0,0 @@ -# translation of fr.po to French -# -# Translators, if you are not familiar with the PO format, gettext -# documentation is worth reading, especially sections dedicated to -# this format, e.g. by running: -# info -n '(gettext)PO Files' -# info -n '(gettext)Header Entry' -# -# Some information specific to po-debconf are available at -# /usr/share/doc/po-debconf/README-trans -# or http://www.debian.org/intl/l10n/po-debconf/README-trans -# -# Developers do not need to manually edit POT or PO files. -# -# Christian Perrier <bubulle@debian.org>, 2004, 2006, 2007. -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: foomatic-filters@packages.debian.org\n" -"POT-Creation-Date: 2008-02-28 13:25-0600\n" -"PO-Revision-Date: 2007-10-04 07:14+0200\n" -"Last-Translator: Christian Perrier <bubulle@debian.org>\n" -"Language-Team: French <debian-l10n-french@lists.debian.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.11.4\n" -"Plural-Forms: Plural-Forms: nplurals=2; plural=n>1;\n" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "Enable logging debug output into a log file (INSECURE)?" -msgstr "" -"Faut-il enregistrer les informations de débogage dans un fichier de " -"journalisation (DANGEREUX) ?" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "" -"If you choose this option, the log file will be named /tmp/foomatic-rip.log." -msgstr "" -"Si vous choisissez cette option, un fichier appelé /tmp/foomatic-rip.log " -"sera utilisé pour enregistrer les informations de débogage." - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "" -"This option is a potential security issue and should not be used in " -"production. However, if you are having trouble printing, you should enable " -"it and include the log file in bug reports." -msgstr "" -"ATTENTION : ce fichier de journalisation pose un problème de sécurité et ne " -"devrait pas être utilisé sur un serveur de production. Cependant, si vous " -"avez des difficultés pour imprimer, vous devriez activer cette option et " -"inclure ce fichier dans les rapports de bogue." - -#. Type: select -#. Choices -#: ../foomatic-filters.templates:3001 -msgid "Automagic" -msgstr "automatique" - -#. Type: select -#. Choices -#: ../foomatic-filters.templates:3001 -msgid "Custom" -msgstr "personnalisée" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "Command for converting text files to PostScript:" -msgstr "Commande de conversion des fichiers texte en PostScript :" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"If you select 'Automagic', Foomatic will search for one of a2ps, mpage, and " -"enscript (in that order) each time the filter script is executed." -msgstr "" -"Si vous choisissez « automatique », l'un des programmes a2ps, mpage ou " -"enscript sera recherché, dans cet ordre, à chaque exécution du filtre." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"Please make sure that the selected command is actually available; otherwise " -"print jobs may get lost." -msgstr "" -"Veuillez vérifier que la commande choisie est réellement disponible, sinon " -"des demandes d'impression peuvent être perdues." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"This setting is ignored when foomatic-filters is used with CUPS; instead, " -"the texttops program included in the cupsys package is always used to " -"convert jobs submitted as plain text to PostScript for printing to raster " -"devices." -msgstr "" -"Avec CUPS, ce réglage sera ignoré. Le programme texttops, inclus dans le " -"paquet cupsys, sera utilisé à la place : il convertit les travaux soumis en " -"format texte brut au format PostScript, pour utilisation avec les " -"périphériques « raster »." - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "Command to convert standard input to PostScript:" -msgstr "Commande de conversion de l'entrée standard en PostScript :" - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "" -"Please enter the full command line of a command that converts text from " -"standard input to PostScript on standard output." -msgstr "" -"Veuillez indiquer la ligne de commande complète qui convertira des données " -"texte vers l'entrée standard en données PostScript sur la sortie standard." - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "" -"Please note that entering an invalid command line here may result in lost " -"print jobs." -msgstr "" -"Veuillez noter qu'une commande invalide peut entraîner la perte des demandes " -"d'impression." - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "Enable PostScript accounting for CUPS?" -msgstr "Faut-il activer la comptabilité PostScript pour CUPS ?" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "" -"You should choose this option if you want to insert PostScript code for " -"accounting into each print job. This is currently only useful with CUPS." -msgstr "" -"Vous devriez choisir cette option pour insérer du code PostScript de " -"comptabilité dans chaque demande d'impression. Cette fonctionnalité n'est " -"utile qu'avec CUPS." - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "" -"When used with generic PostScript printers (and under certain conditions " -"with other printers) this causes an extra page to be printed after each job." -msgstr "" -"Lorsque cette option est utilisée avec des imprimantes PostScript génériques " -"(et, dans certaines conditions, avec d'autres imprimantes), elle provoque " -"l'impression d'une page supplémentaire après chaque impression." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "Printer spooler backend for Foomatic:" -msgstr "Gestionnaire d'impression interfacé avec Foomatic :" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "" -"Foomatic normally requires a printer spooler (like CUPS or LPRng) to handle " -"communication with the printer and manage print jobs. If no spooler is " -"installed, you can use the 'direct' backend, but this is only recommended " -"for single-user systems." -msgstr "" -"Il est usuellement nécessaire d'utiliser un gestionnaire d'impression tel " -"que CUPS ou LPRng pour gérer la communication avec l'imprimante et les " -"travaux d'impression. Si aucun gestionnaire n'est installé, vous pouvez " -"utiliser le choix « direct » qui n'est recommandé que pour des systèmes mono-" -"utilisateur." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "" -"The installation process may have already detected the correct spooler; " -"however, if this is the initial installation of this system, or if more than " -"one spooler is installed, the detected spooler may be incorrect." -msgstr "" -"La procédure d'installation a probablement détecté le gestionnaire " -"approprié. Cependant, s'il s'agit de votre première installation de ce " -"système ou si plus d'un gestionnaire est installé, celui qui est détecté " -"n'est peut-être pas le bon." - -#~ msgid "Ghostscript interpreter to be used by Foomatic:" -#~ msgstr "Interpréteur Ghostscript utilisé par Foomatic :" - -#~ msgid "" -#~ "For non-PostScript printers, print jobs are usually translated from " -#~ "PostScript to the printer's command language using the free Ghostscript " -#~ "interpreter." -#~ msgstr "" -#~ "Lors de l'utilisation d'imprimantes non-PostScript, les travaux " -#~ "d'impression sont généralement convertis de PostScript vers le langage de " -#~ "commande de l'imprimante avec l'interpréteur libre Ghostscript." - -#~ msgid "" -#~ "There are a number of different versions of the Ghostscript interpreter " -#~ "available. Normally, Foomatic will use the default version (configured by " -#~ "the 'gs' alternative, which can be changed with 'update-alternatives --" -#~ "config gs'). However, you may want to use a different Ghostscript for " -#~ "screen display than for printing; 'gs-esp' is usually a good choice for " -#~ "printing." -#~ msgstr "" -#~ "Il existe plusieurs versions différentes de l'interpréteur Ghostscript. " -#~ "Habituellement, Foomatic utilise la version par défaut (l'alternative " -#~ "« gs » configurée avec la commande « update-alternatives --config gs »). " -#~ "Cependant, il peut être recommandé d'utiliser un interpréteur Ghostscript " -#~ "différent pour l'affichage à l'écran et pour l'impression ; « gs-esp » est " -#~ "généralement recommandé pour l'impression." - -#~ msgid "" -#~ "You should use the Custom option if you have a locally-installed " -#~ "Ghostscript interpreter." -#~ msgstr "" -#~ "Vous pouvez choisir l'option « personnalisée » pour utiliser un " -#~ "interpréteur Ghostscript installé localement." - -#~ msgid "Custom Ghostscript interpreter path:" -#~ msgstr "Chemin d'accès de l'interpréteur Ghostscript personnalisé :" - -#~ msgid "Please enter the full path to the custom Ghostscript interpreter." -#~ msgstr "" -#~ "Veuillez indiquer le chemin d'accès complet vers l'interpréteur " -#~ "Ghostscript." - -#~ msgid "Example: /opt/artifex.com-ghostscript/bin/gs" -#~ msgstr "Exemple : /opt/artifex.com-ghostscript/bin/gs" diff --git a/debian/po/ja.po b/debian/po/ja.po deleted file mode 100644 index 35cd90f..0000000 --- a/debian/po/ja.po +++ /dev/null @@ -1,229 +0,0 @@ -# -# Translators, if you are not familiar with the PO format, gettext -# documentation is worth reading, especially sections dedicated to -# this format, e.g. by running: -# info -n '(gettext)PO Files' -# info -n '(gettext)Header Entry' -# -# Some information specific to po-debconf are available at -# /usr/share/doc/po-debconf/README-trans -# or http://www.debian.org/intl/l10n/po-debconf/README-trans -# -# Developers do not need to manually edit POT or PO files. -# -msgid "" -msgstr "" -"Project-Id-Version: foomatic-filters\n" -"Report-Msgid-Bugs-To: foomatic-filters@packages.debian.org\n" -"POT-Creation-Date: 2008-02-28 13:25-0600\n" -"PO-Revision-Date: 2007-10-05 14:54+0900\n" -"Last-Translator: Kenshi Muto <kmuto@debian.org>\n" -"Language-Team: Japanese <debian-japanese@lists.debian.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "Enable logging debug output into a log file (INSECURE)?" -msgstr "ログファイルへのデバッグ出力を有効にしますか (危険)?" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "" -"If you choose this option, the log file will be named /tmp/foomatic-rip.log." -msgstr "" -"この選択肢で「はい」と答えると、ログファイルは /tmp/foomatic-rip.log と名付け" -"られます。" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "" -"This option is a potential security issue and should not be used in " -"production. However, if you are having trouble printing, you should enable " -"it and include the log file in bug reports." -msgstr "" -"この選択は、潜在的なセキュリティ問題となり得るので、製品運用では利用すべきで" -"はありません。しかし、印刷時に問題があったときには、これを有効にして、バグリ" -"ポートにこのログファイルを含めるとよいでしょう。" - -#. Type: select -#. Choices -#: ../foomatic-filters.templates:3001 -msgid "Automagic" -msgstr "Automagic" - -#. Type: select -#. Choices -#: ../foomatic-filters.templates:3001 -msgid "Custom" -msgstr "カスタム" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "Command for converting text files to PostScript:" -msgstr "テキストファイルから PostScript への変換を行うコマンド:" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"If you select 'Automagic', Foomatic will search for one of a2ps, mpage, and " -"enscript (in that order) each time the filter script is executed." -msgstr "" -"'Automagic' を選ぶと、Foomatic はフィルタスクリプトが実行されるたびに、a2ps、" -"mpage、enscript の順に検索します。" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"Please make sure that the selected command is actually available; otherwise " -"print jobs may get lost." -msgstr "" -"選択されたコマンドが実際に利用可能であることを確認してください。さもないと、" -"印刷ジョブを失うことになります。" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"This setting is ignored when foomatic-filters is used with CUPS; instead, " -"the texttops program included in the cupsys package is always used to " -"convert jobs submitted as plain text to PostScript for printing to raster " -"devices." -msgstr "" -"foomatic-filters は CUPS と共に使うときには、この設定は無視されます。代わり" -"に cupsys パッケージに入っている texttops プログラムが常に、プレインテキスト" -"として与えられたジョブをラスターデバイスに印刷するための PostScript への変換" -"に使われます。" - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "Command to convert standard input to PostScript:" -msgstr "標準入力を PostScript に変換するコマンド:" - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "" -"Please enter the full command line of a command that converts text from " -"standard input to PostScript on standard output." -msgstr "" -"標準入力からのテキストを PostScript の標準出力として変換するコマンドの完全な" -"コマンドラインを入力してください。" - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "" -"Please note that entering an invalid command line here may result in lost " -"print jobs." -msgstr "" -"ここに誤ったコマンドラインを入力してしまうと、印刷ジョブを失うことに注意して" -"ください。" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "Enable PostScript accounting for CUPS?" -msgstr "CUPS の PostScript アカウンティングを有効にしますか?" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "" -"You should choose this option if you want to insert PostScript code for " -"accounting into each print job. This is currently only useful with CUPS." -msgstr "" -"各印刷ジョブにアカウンティングを行う PostScript コードを挿入したいなら、この" -"選択肢に「はい」と答えてください。これは現在のところ、CUPS 上でのみ動作しま" -"す。" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "" -"When used with generic PostScript printers (and under certain conditions " -"with other printers) this causes an extra page to be printed after each job." -msgstr "" -"一般の PostScript プリンタ (およびほかのプリンタでも正しい状態であれば) を" -"使っている場合、各ジョブのあとに余分なページが印刷されることになります。" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "Printer spooler backend for Foomatic:" -msgstr "Foomatic のプリンタスプーラバックエンド:" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "" -"Foomatic normally requires a printer spooler (like CUPS or LPRng) to handle " -"communication with the printer and manage print jobs. If no spooler is " -"installed, you can use the 'direct' backend, but this is only recommended " -"for single-user systems." -msgstr "" -"Foomatic は通常、プリンタとの相互通信や印刷ジョブの管理の面倒を見るプリンタス" -"プーラ (CUPS または LPRng など) を必要とします。スプーラを何もインストールし" -"ていなければ、'direct' バックエンドを使うこともできますが、これは単一ユーザの" -"システム以外にはお勧めしません。" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "" -"The installation process may have already detected the correct spooler; " -"however, if this is the initial installation of this system, or if more than " -"one spooler is installed, the detected spooler may be incorrect." -msgstr "" -"インストールプロセスはすでに正しいスプーラを検出しているはずです。しかし、こ" -"れがこのシステムの初期インストール段階であるか、あなたのシステムに 1 つ以上の" -"スプーラがあると、検出されたスプーラは誤っているかもしれません。" - -#~ msgid "Ghostscript interpreter to be used by Foomatic:" -#~ msgstr "Foomatic で使う Ghostscript インタプリタ:" - -#~ msgid "" -#~ "For non-PostScript printers, print jobs are usually translated from " -#~ "PostScript to the printer's command language using the free Ghostscript " -#~ "interpreter." -#~ msgstr "" -#~ "非 PostScript プリンタでは、印刷ジョブは通常 PostScript からプリンタコマン" -#~ "ド言語にフリーの Ghostscript インタプリタを使って変換されます。" - -#~ msgid "" -#~ "There are a number of different versions of the Ghostscript interpreter " -#~ "available. Normally, Foomatic will use the default version (configured by " -#~ "the 'gs' alternative, which can be changed with 'update-alternatives --" -#~ "config gs'). However, you may want to use a different Ghostscript for " -#~ "screen display than for printing; 'gs-esp' is usually a good choice for " -#~ "printing." -#~ msgstr "" -#~ "利用可能な異なるバージョンの Ghostscript インタプリタがあります。通常、" -#~ "Foomatic はデフォルトバージョン ('update-alternatives --config gs' で変更" -#~ "可能な、'gs' オルタナティブとして設定されるもの) を使います。しかし、印刷" -#~ "時と画面表示で異なる Ghostscript を使いたいこともあるでしょう。'gs-esp' が" -#~ "通常、印刷に最良の選択です。" - -#~ msgid "" -#~ "You should use the Custom option if you have a locally-installed " -#~ "Ghostscript interpreter." -#~ msgstr "" -#~ "(ローカルにインストールした Ghostscript インタプリタを持っているのであれ" -#~ "ば、「カスタム」を選ぶとよいでしょう。" - -#~ msgid "Custom Ghostscript interpreter path:" -#~ msgstr "カスタム Ghostscript インタプリタのパス:" - -#~ msgid "Please enter the full path to the custom Ghostscript interpreter." -#~ msgstr "カスタムの Ghostscript インタプリタの完全パスを入力してください。" - -#~ msgid "Example: /opt/artifex.com-ghostscript/bin/gs" -#~ msgstr "例: /opt/artifex.com-ghostscript/bin/gs" diff --git a/debian/po/nl.po b/debian/po/nl.po deleted file mode 100644 index 715fe23..0000000 --- a/debian/po/nl.po +++ /dev/null @@ -1,201 +0,0 @@ -# translation of foomatic-filters_3.0.2-20080211-3.2_nl.po to Dutch -# -# Translators, if you are not familiar with the PO format, gettext -# documentation is worth reading, especially sections dedicated to -# this format, e.g. by running: -# info -n '(gettext)PO Files' -# info -n '(gettext)Header Entry' -# -# Some information specific to po-debconf are available at -# /usr/share/doc/po-debconf/README-trans -# or http://www.debian.org/intl/l10n/po-debconf/README-trans -# -# Developers do not need to manually edit POT or PO files. -# -# -# This is an unofficial translation -# -# Luk Claes <luk.claes@ugent.be>, 2004. -# Kurt De Bree <kdebree@telenet.be>, 2006. -# Paul Gevers <paul@climbing.nl>, 2008. -msgid "" -msgstr "" -"Project-Id-Version: foomatic-filters_3.0.2-20080211-3.2_nl\n" -"Report-Msgid-Bugs-To: foomatic-filters@packages.debian.org\n" -"POT-Creation-Date: 2008-02-28 13:25-0600\n" -"PO-Revision-Date: 2008-09-28 18:27-0500\n" -"Last-Translator: Paul Gevers <paul@climbing.nl>\n" -"Language-Team: Dutch <debian-l10n-dutch@lists.debian.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.11.4\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "Enable logging debug output into a log file (INSECURE)?" -msgstr "Wilt u de debuguitvoer bijhouden in een logbestand (ONVEILIG)?" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "" -"If you choose this option, the log file will be named /tmp/foomatic-rip.log." -msgstr "" -"Indien u voor deze optie kiest, zal het logbestand /tmp/foomatic-rip.log " -"worden genoemd." - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "" -"This option is a potential security issue and should not be used in " -"production. However, if you are having trouble printing, you should enable " -"it and include the log file in bug reports." -msgstr "" -"Deze optie leidt tot een onveilige situatie en wordt afgeraden in een " -"productie-omgeving. Als u echter printproblemen hebt, kunt u deze optie " -"aanzetten en het logbestand toevoegen aan het bugrapport." - -#. Type: select -#. Choices -#: ../foomatic-filters.templates:3001 -msgid "Automagic" -msgstr "Automagisch" - -#. Type: select -#. Choices -#: ../foomatic-filters.templates:3001 -msgid "Custom" -msgstr "Aangepast" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "Command for converting text files to PostScript:" -msgstr "Commando om tekstbestanden te converteren naar PostScript:" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"If you select 'Automagic', Foomatic will search for one of a2ps, mpage, and " -"enscript (in that order) each time the filter script is executed." -msgstr "" -"Als u voor 'Automagisch' kiest, dan zal 'foomatic' zoeken naar één van de " -"volgende programma's: 'a2ps', 'mpage' of 'enscript' (in die volgorde). Dit " -"gebeurt dan elke keer dat het filterscript wordt uitgevoerd." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"Please make sure that the selected command is actually available; otherwise " -"print jobs may get lost." -msgstr "" -"Als het geselecteerde commando niet beschikbaar is, kunnen er " -"printopdrachten verloren gaan." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"This setting is ignored when foomatic-filters is used with CUPS; instead, " -"the texttops program included in the cupsys package is always used to " -"convert jobs submitted as plain text to PostScript for printing to raster " -"devices." -msgstr "" -"Indien u 'foomatic-filters' met CUPS gebruikt, wordt deze instelling " -"genegeerd. Om opdrachten die doorgegeven zijn als platte tekst te " -"converteren naar PostScript wordt in dat geval altijd het programma " -"'texttops' uit het pakket 'cupsys' gebruikt, als er naar een rasterapparaat " -"geprint wordt." - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "Command to convert standard input to PostScript:" -msgstr "Commando om standaardinvoer te converteren naar PostScript:" - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "" -"Please enter the full command line of a command that converts text from " -"standard input to PostScript on standard output." -msgstr "" -"Wat is de volledige commandoregel die gebruikt moet worden om tekst van de " -"standaardinvoer te converteren naar PostScript op de standaarduitvoer?" - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "" -"Please note that entering an invalid command line here may result in lost " -"print jobs." -msgstr "" -"Het ingeven van een ongeldige commandolijn kan resulteren in het verlies van " -"printopdrachten." - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "Enable PostScript accounting for CUPS?" -msgstr "PostScript-boekhouding activeren voor CUPS?" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "" -"You should choose this option if you want to insert PostScript code for " -"accounting into each print job. This is currently only useful with CUPS." -msgstr "" -"Het wordt aangeraden deze optie alleen te gebruiken als u wilt dat " -"PostScript-code voor boekhouding aan elke printopdracht wordt toegevoegd. Op " -"dit moment werkt dit enkel met CUPS." - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "" -"When used with generic PostScript printers (and under certain conditions " -"with other printers) this causes an extra page to be printed after each job." -msgstr "" -"Indien u deze optie gebruikt met generieke PostScript-printers (en onder " -"bepaalde omstandigheden met andere printers), zal er na elke opdracht een " -"extra pagina geprint worden." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "Printer spooler backend for Foomatic:" -msgstr "Printspooler backend voor 'foomatic':" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "" -"Foomatic normally requires a printer spooler (like CUPS or LPRng) to handle " -"communication with the printer and manage print jobs. If no spooler is " -"installed, you can use the 'direct' backend, but this is only recommended " -"for single-user systems." -msgstr "" -"'Foomatic' vereist normaal gesproken een printspooler (zoals CUPS of LPRng) " -"om met de printer te communiceren en om printopdrachten te beheren. Als u " -"geen printspooler heeft geïnstalleerd, dan kunt u de 'direct' backend " -"gebruiken, maar dat wordt enkel aangeraden voor één-gebruiker-systemen." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "" -"The installation process may have already detected the correct spooler; " -"however, if this is the initial installation of this system, or if more than " -"one spooler is installed, the detected spooler may be incorrect." -msgstr "" -"Het installatieproces heeft misschien reeds de correcte spooler " -"gedetecteerd. Als dit de initiële installatie van uw systeem is of als u " -"meer dan één spooler geïnstalleerd heeft, is het mogelijk dat de " -"gedetecteerde spooler niet correct is." diff --git a/debian/po/pt_BR.po b/debian/po/pt_BR.po deleted file mode 100644 index f7e97d0..0000000 --- a/debian/po/pt_BR.po +++ /dev/null @@ -1,257 +0,0 @@ -# am-utils Brazilian Portuguese translation -# Copyright (c) 2007 foomatic-filters's PACKAGE COPYRIGHT HOLDER -# This file is distributed under the same license as the foomatic-filters -# package. -# Felipe Augusto van de Wiel (faw) <faw@debian.org>, 2007. -# -msgid "" -msgstr "" -"Project-Id-Version: foomatic-filters\n" -"Report-Msgid-Bugs-To: foomatic-filters@packages.debian.org\n" -"POT-Creation-Date: 2008-02-28 13:25-0600\n" -"PO-Revision-Date: 2007-10-05 01:27-0300\n" -"Last-Translator: Felipe Augusto van de Wiel (faw) <faw@debian.org>\n" -"Language-Team: l10n portuguese <debian-l10n-portuguese@lists.debian.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"pt_BR utf-8\n" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "Enable logging debug output into a log file (INSECURE)?" -msgstr "" -"Habilitar o registro de log da saída de depuração em um arquivo de log " -"(INSEGURO)?" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "" -"If you choose this option, the log file will be named /tmp/foomatic-rip.log." -msgstr "" -"Se você escolher esta opção, o arquivo de log será nomeado como /tmp/" -"foomatic-rip.log." - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "" -"This option is a potential security issue and should not be used in " -"production. However, if you are having trouble printing, you should enable " -"it and include the log file in bug reports." -msgstr "" -"Esta opção é um problema de segurança em potencial e não deveria ser usado " -"em produção. No entanto, se você está tendo problemas com impressão, você " -"deveria habilitá-lo e incluir este arquivo de log em seus relatórios de bug." - -#. Type: select -#. Choices -#: ../foomatic-filters.templates:3001 -msgid "Automagic" -msgstr "Automágico" - -#. Type: select -#. Choices -#: ../foomatic-filters.templates:3001 -msgid "Custom" -msgstr "Personalizado" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "Command for converting text files to PostScript:" -msgstr "Comando para converter arquivos texto para PostScript:" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"If you select 'Automagic', Foomatic will search for one of a2ps, mpage, and " -"enscript (in that order) each time the filter script is executed." -msgstr "" -"Se você selecionar 'Automágico', o Foomatic procurará por um dos comandos " -"a2ps, mpage e enscript (nesta ordem) a cada vez que o script de filtro for " -"executado." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"Please make sure that the selected command is actually available; otherwise " -"print jobs may get lost." -msgstr "" -"Por favor, certifique-se de que o comando selecionado está realmente " -"disponível; caso contrário seus trabalhos de impressão podem ser perdidos." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"This setting is ignored when foomatic-filters is used with CUPS; instead, " -"the texttops program included in the cupsys package is always used to " -"convert jobs submitted as plain text to PostScript for printing to raster " -"devices." -msgstr "" -"Esta configuração é ignorada quando o foomatic-filters é usado com o CUPS; " -"ao invés desta configuração, o programa texttops incluído no pacote cupsys " -"será sempre usado para converter trabalhos enviados como texto puro para " -"PostScript para impressão em dispositivos raster." - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "Command to convert standard input to PostScript:" -msgstr "Comando para converter a entrada padrão para PostScript:" - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "" -"Please enter the full command line of a command that converts text from " -"standard input to PostScript on standard output." -msgstr "" -"Por favor, informe a linha de comando completa de um comando que converta da " -"entrada padrão para PostScript na saída padrão." - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "" -"Please note that entering an invalid command line here may result in lost " -"print jobs." -msgstr "" -"Por favor, note que informar uma linha de comando inválida poderá resultar " -"em trabalhos de impressão perdidos." - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "Enable PostScript accounting for CUPS?" -msgstr "Habilitar a contabilidade PostScript para o CUPS?" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "" -"You should choose this option if you want to insert PostScript code for " -"accounting into each print job. This is currently only useful with CUPS." -msgstr "" -"Você deveria escolher esta opção se você quer inserir código PostScript para " -"contabilidade em cada trabalho de impressão. Atualmente, isto só é útil com " -"o CUPS." - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "" -"When used with generic PostScript printers (and under certain conditions " -"with other printers) this causes an extra page to be printed after each job." -msgstr "" -"Quando usado com impressoras PostScript genéricas (e sob certas condições " -"com outras impressoras) isto faz com que uma página extra seja impressa a " -"cada trabalho." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "Printer spooler backend for Foomatic:" -msgstr "\"Backend\" do \"spooler\" de impressão para o Foomatic:" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "" -"Foomatic normally requires a printer spooler (like CUPS or LPRng) to handle " -"communication with the printer and manage print jobs. If no spooler is " -"installed, you can use the 'direct' backend, but this is only recommended " -"for single-user systems." -msgstr "" -"O Foomatic normalmente requer um \"spooler\" de impressão (como o CUPS ou o " -"LPRng) para manipular a comunicação com a impressora e gerenciar os " -"trabalhos de impressão. Se não há um \"spooler\" instalado você pode usar o " -"\"backend 'direct'\", mas isto é recomendado somente para sistemas com " -"apenas um único usuário." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "" -"The installation process may have already detected the correct spooler; " -"however, if this is the initial installation of this system, or if more than " -"one spooler is installed, the detected spooler may be incorrect." -msgstr "" -"O processo de instalação pode já ter detectado o \"spooler\" correto; no " -"entanto, se esta é a instalação inicial do sistema, ou se há mais de um " -"\"spooler\" instalado, o \"spooler\" detectado pode estar incorreto." - -#~ msgid "Ghostscript interpreter to be used by Foomatic:" -#~ msgstr "Interpretador Ghostscript a ser usado pelo Foomatic:" - -#~ msgid "" -#~ "For non-PostScript printers, print jobs are usually translated from " -#~ "PostScript to the printer's command language using the free Ghostscript " -#~ "interpreter." -#~ msgstr "" -#~ "Para impressoras não-PostScript, os trabalhos de impressão são " -#~ "normalmente traduzidos de PostScript para a linguagem de comandos da " -#~ "impressora usando o interpretador livre Ghostscript." - -#~ msgid "" -#~ "There are a number of different versions of the Ghostscript interpreter " -#~ "available. Normally, Foomatic will use the default version (configured by " -#~ "the 'gs' alternative, which can be changed with 'update-alternatives --" -#~ "config gs'). However, you may want to use a different Ghostscript for " -#~ "screen display than for printing; 'gs-esp' is usually a good choice for " -#~ "printing." -#~ msgstr "" -#~ "Há diversas versões diferentes do interpretador Ghostscript disponíveis. " -#~ "Normalmente, o Foomatic utilizará a versão padrão (configurada pela " -#~ "alternativa 'gs', a qual pode ser modificada com o comando 'update-" -#~ "alternatives --config gs'). No entanto, você pode desejar usar um " -#~ "Ghostscript para exibição diferente do usado para impressão; 'gs-esp' é " -#~ "normalmente uma boa escolha para impressão." - -#~ msgid "" -#~ "You should use the Custom option if you have a locally-installed " -#~ "Ghostscript interpreter." -#~ msgstr "" -#~ "Você deveria usar a opção Personalizado se você tem um interpretador " -#~ "Ghostscript instalado localmente." - -#~ msgid "Custom Ghostscript interpreter path:" -#~ msgstr "Caminho do interpretador Ghostscript personalizado:" - -#~ msgid "Please enter the full path to the custom Ghostscript interpreter." -#~ msgstr "" -#~ "Por favor, informe o caminho completo para o interpretador Ghostscript " -#~ "personalizado." - -#~ msgid "Example: /opt/artifex.com-ghostscript/bin/gs" -#~ msgstr "Exemplo: /opt/artifex.com-ghostscript/bin/gs" - -#~ msgid "If in doubt, you should simply accept the default option (gs)." -#~ msgstr "" -#~ "Em caso de dúvidas, você deverá simplesmente aceitar a opção padrão (gs)." - -#~ msgid "" -#~ "You should enter the full path to your preferred Ghostscript interpreter; " -#~ "e.g. `/opt/artifex.com-ghostscript/bin/gs'." -#~ msgstr "" -#~ "Informe o caminho completo para o intepretador Ghostscript preferido; por " -#~ "exemplo, `/opt/artifex.com-ghostscript/bin/gs'." - -#~ msgid "" -#~ "There are some special tags available usable on the filter command line. " -#~ "See the filter.conf manpage for details." -#~ msgstr "" -#~ "Existem algums tags especiais disponíveis que podem ser usadas na linha " -#~ "de comando do filtro. Consulte a página de manual filter.conf para " -#~ "maiores detalhes." - -#~ msgid "Automagic, a2ps, mpage, enscript, Custom" -#~ msgstr "Automagic, a2ps, mpage, enscript, Personalizado" - -#~ msgid "gs, gs-gnu, gs-esp, gs-afpl, Custom" -#~ msgstr "gs, gs-gnu, gs-esp, gs-afpl, Personalizado" diff --git a/debian/po/templates.pot b/debian/po/templates.pot deleted file mode 100644 index 0c519e4..0000000 --- a/debian/po/templates.pot +++ /dev/null @@ -1,152 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: foomatic-filters@packages.debian.org\n" -"POT-Creation-Date: 2008-02-28 13:25-0600\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "Enable logging debug output into a log file (INSECURE)?" -msgstr "" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "" -"If you choose this option, the log file will be named /tmp/foomatic-rip.log." -msgstr "" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "" -"This option is a potential security issue and should not be used in " -"production. However, if you are having trouble printing, you should enable " -"it and include the log file in bug reports." -msgstr "" - -#. Type: select -#. Choices -#: ../foomatic-filters.templates:3001 -msgid "Automagic" -msgstr "" - -#. Type: select -#. Choices -#: ../foomatic-filters.templates:3001 -msgid "Custom" -msgstr "" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "Command for converting text files to PostScript:" -msgstr "" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"If you select 'Automagic', Foomatic will search for one of a2ps, mpage, and " -"enscript (in that order) each time the filter script is executed." -msgstr "" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"Please make sure that the selected command is actually available; otherwise " -"print jobs may get lost." -msgstr "" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"This setting is ignored when foomatic-filters is used with CUPS; instead, " -"the texttops program included in the cupsys package is always used to " -"convert jobs submitted as plain text to PostScript for printing to raster " -"devices." -msgstr "" - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "Command to convert standard input to PostScript:" -msgstr "" - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "" -"Please enter the full command line of a command that converts text from " -"standard input to PostScript on standard output." -msgstr "" - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "" -"Please note that entering an invalid command line here may result in lost " -"print jobs." -msgstr "" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "Enable PostScript accounting for CUPS?" -msgstr "" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "" -"You should choose this option if you want to insert PostScript code for " -"accounting into each print job. This is currently only useful with CUPS." -msgstr "" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "" -"When used with generic PostScript printers (and under certain conditions " -"with other printers) this causes an extra page to be printed after each job." -msgstr "" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "Printer spooler backend for Foomatic:" -msgstr "" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "" -"Foomatic normally requires a printer spooler (like CUPS or LPRng) to handle " -"communication with the printer and manage print jobs. If no spooler is " -"installed, you can use the 'direct' backend, but this is only recommended " -"for single-user systems." -msgstr "" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "" -"The installation process may have already detected the correct spooler; " -"however, if this is the initial installation of this system, or if more than " -"one spooler is installed, the detected spooler may be incorrect." -msgstr "" diff --git a/debian/po/tr.po b/debian/po/tr.po deleted file mode 100644 index 3446396..0000000 --- a/debian/po/tr.po +++ /dev/null @@ -1,225 +0,0 @@ -# Turkish translation of foomatic-filters. -# This file is distributed under the same license as the foomatic-filters package. -# Gürkan Aslan <gurkan@iaslan.com>, 2004. -# -msgid "" -msgstr "" -"Project-Id-Version: foomatic-filters\n" -"Report-Msgid-Bugs-To: foomatic-filters@packages.debian.org\n" -"POT-Creation-Date: 2008-02-28 13:25-0600\n" -"PO-Revision-Date: 2008-03-13 19:26+0200\n" -"Last-Translator: Mert Dirik <mertdirik@gmail.com>\n" -"Language-Team: Turkish <debian-l10n-turkish@lists.debian.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "Enable logging debug output into a log file (INSECURE)?" -msgstr "Günlük dosyası içine hata ayıklama çıktısı etkinleştir (GÜVENSİZ)?" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "" -"If you choose this option, the log file will be named /tmp/foomatic-rip.log." -msgstr "" -"Eğer bu seçeneği seçerseniz, günlük dosyası /tmp/foomatik-rip.log olarak " -"adlandırılacak." - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:2001 -msgid "" -"This option is a potential security issue and should not be used in " -"production. However, if you are having trouble printing, you should enable " -"it and include the log file in bug reports." -msgstr "" -"Bu seçenek potansiyel bir güvenlik açığıdır ve üretim ortamında " -"kullanılmamalıdır. Bununla birlikte, eğer yazdırma sorununuz varsa, bunu " -"etkinleştirmeli ve günlük dosyasını bildirilecek hata raporuna eklemelisiniz." - -#. Type: select -#. Choices -#: ../foomatic-filters.templates:3001 -msgid "Automagic" -msgstr "Otomatik" - -#. Type: select -#. Choices -#: ../foomatic-filters.templates:3001 -msgid "Custom" -msgstr "Özel" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "Command for converting text files to PostScript:" -msgstr "Metin dosyalarını PostScript'e dönüştürecek komut:" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"If you select 'Automagic', Foomatic will search for one of a2ps, mpage, and " -"enscript (in that order) each time the filter script is executed." -msgstr "" -"Eğer 'Otomatik'i seçtiyseniz, süzgeç betiği her çalıştırıldığında a2ps, " -"mpage ve enscript (bu sırayla) Foomatic tarafından aranacaktır." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"Please make sure that the selected command is actually available; otherwise " -"print jobs may get lost." -msgstr "" -"Lütfen seçili komutun gerçekten uygun olduğuna emin olun, aksi taktirde " -"yazdırma görevleri kaybolabilir." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:3002 -msgid "" -"This setting is ignored when foomatic-filters is used with CUPS; instead, " -"the texttops program included in the cupsys package is always used to " -"convert jobs submitted as plain text to PostScript for printing to raster " -"devices." -msgstr "" -"Bu ayarlar, foomatic-filters CUPS tarafından kullanıldığında " -"önemsenmeyecektir. Bunun yerine, cupsys paketi içinde bulunan texttops " -"programı düz metin halinde gönderilen görevleri tarama aygıtlarında " -"yazdırmak amacıyla PostScript'e dönüştürecektir." - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "Command to convert standard input to PostScript:" -msgstr "Standart girdiyi PostScript'e dönüştürme komutu:" - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "" -"Please enter the full command line of a command that converts text from " -"standard input to PostScript on standard output." -msgstr "" -"Lütfen standart girdiden gelen metni standart çıktıda Postscript'e " -"dönüştürmekte kullanılacak komutu tam olarak girin." - -#. Type: string -#. Description -#: ../foomatic-filters.templates:4001 -msgid "" -"Please note that entering an invalid command line here may result in lost " -"print jobs." -msgstr "" -"Burada girilecek geçersiz bir komutun yazdırma görevlerinin kaybolmasına yol " -"açabileceğini lütfen unutmayın." - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "Enable PostScript accounting for CUPS?" -msgstr "CUPS için PostScript muhasebesini etkinleştirilsin mi?" - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "" -"You should choose this option if you want to insert PostScript code for " -"accounting into each print job. This is currently only useful with CUPS." -msgstr "" -"Eğer yazdırma muhasebesinde kullanılmak üzere her yazdırma görevine " -"PostScript kodu eklemek istiyorsanız bu seçeneği seçmelisiniz. Bu seçenek şu " -"anda sadece CUPS ile çalışıyor." - -#. Type: boolean -#. Description -#: ../foomatic-filters.templates:5001 -msgid "" -"When used with generic PostScript printers (and under certain conditions " -"with other printers) this causes an extra page to be printed after each job." -msgstr "" -"Bu özellik genel amaçlı PostScript yazıcılarla (ve belirli durumlarda diğer " -"bazı yazıcılarla) kullanıldığında her görevden sonra ek bir sayfanın " -"bastırılmasına neden olacaktır." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "Printer spooler backend for Foomatic:" -msgstr "Foomatic için yazıcı kuyruğu arka ucu:" - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "" -"Foomatic normally requires a printer spooler (like CUPS or LPRng) to handle " -"communication with the printer and manage print jobs. If no spooler is " -"installed, you can use the 'direct' backend, but this is only recommended " -"for single-user systems." -msgstr "" -"Foomatic normalde yazıcı ile iletişimi sağlamak ve yazdırma işlerini " -"yönetmek için (CUPS ya da LPRng gibi) bir yazıcı kuyruğu gerektirir. Eğer " -"herhangi bir kuyruk yüklü değilse, \"doğrudan\" arka ucunu " -"kullanabilirsiniz, fakat bu sadece tek kullanıcılı sistemlerde önerilir." - -#. Type: select -#. Description -#: ../foomatic-filters.templates:6001 -msgid "" -"The installation process may have already detected the correct spooler; " -"however, if this is the initial installation of this system, or if more than " -"one spooler is installed, the detected spooler may be incorrect." -msgstr "" -"Yükleme süreci zaten doğru kuyruğu algılamış olabilir, bununla birlikte, " -"eğer bu sistemin ilk yüklemesiyse, ya da birden fazla kuyruk yüklüyse, " -"algılanmış kuyruklayıcı doğru olmayabilir." - -#~ msgid "Ghostscript interpreter to be used by Foomatic:" -#~ msgstr "Foomatic ile beraber kullanılacak Ghostscript yorumlayıcısı:" - -#~ msgid "" -#~ "For non-PostScript printers, print jobs are usually translated from " -#~ "PostScript to the printer's command language using the free Ghostscript " -#~ "interpreter." -#~ msgstr "" -#~ "PostScript olmayan yazıcılar için, yazdırma görevleri genellikle özgür " -#~ "Ghostscript yorumlayıcısı kullanılarak PostScript'ten yazıcınızın komut " -#~ "diline dönüştürülür." - -#~ msgid "" -#~ "There are a number of different versions of the Ghostscript interpreter " -#~ "available. Normally, Foomatic will use the default version (configured by " -#~ "the 'gs' alternative, which can be changed with 'update-alternatives --" -#~ "config gs'). However, you may want to use a different Ghostscript for " -#~ "screen display than for printing; 'gs-esp' is usually a good choice for " -#~ "printing." -#~ msgstr "" -#~ "Debian sistemlerinde her biri farklı sürümlerde bir kaç farklı " -#~ "Ghostscript yorumlayıcısı mevcuttur. Normalde, Foomatic (`update-" -#~ "alternatives --config gs' komutuyla değiştirilebilecek 'gs' " -#~ "alternatifinin gösterdiği) öntanımlı sürümü kullanacaktır. Bununla " -#~ "birlikte, ekran gösterimi için yazdırma işleminde kullanılanın dışında " -#~ "bir Ghostscript kullanmak isteyebilirsiniz. 'gs-esp' genellikle yazdırma " -#~ "için iyi bir seçimdir." - -#~ msgid "" -#~ "You should use the Custom option if you have a locally-installed " -#~ "Ghostscript interpreter." -#~ msgstr "" -#~ "Eğer yerel olarak yüklenmiş bir Ghostscript yorumlayıcınız varsa Özel " -#~ "seçeneğini kullanmalısınız." - -#~ msgid "Custom Ghostscript interpreter path:" -#~ msgstr "Özel Ghostscript yorumlayıcısına ait dosya yolu:" - -#~ msgid "Please enter the full path to the custom Ghostscript interpreter." -#~ msgstr "Lütfen özel Ghostscript yorumlayıcısına ait yolu girin." - -#~ msgid "Example: /opt/artifex.com-ghostscript/bin/gs" -#~ msgstr "Örnek: /opt/artifex.com-ghostscript/bin/gs" diff --git a/debian/rules b/debian/rules deleted file mode 100755 index 8211f6b..0000000 --- a/debian/rules +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/make -f -# Sample debian/rules that uses debhelper. -# GNU copyright 1997 to 1999 by Joey Hess. - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - - -# These are used for cross-compiling and for saving the configure script -# from having to guess our platform (since we know it already) -DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) -DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) - - -CFLAGS = -Wall -g - -ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) - CFLAGS += -O0 -else - CFLAGS += -O2 -endif -ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) - INSTALL_PROGRAM += -s -endif - -config.status: configure - dh_testdir - # Add here commands to configure the package. -ifneq "$(wildcard /usr/share/misc/config.sub)" "" - cp -f /usr/share/misc/config.sub config.sub -endif -ifneq "$(wildcard /usr/share/misc/config.guess)" "" - cp -f /usr/share/misc/config.guess config.guess -endif - ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --sysconfdir=/etc --disable-file-converter-check - - -build: build-stamp - -build-stamp: config.status - dh_testdir - - # Add here commands to compile the package. - $(MAKE) - - touch build-stamp - -clean: - dh_testdir - dh_testroot - rm -f build-stamp config.sub config.guess tests/Makefile - - # Add here commands to clean up after the build process. - -$(MAKE) distclean - chmod -x filter.conf - debconf-updatepo - - dh_clean - -install: build - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs - - # Add here commands to install the package into debian/foomatic-filters. - $(MAKE) install DESTDIR=$(CURDIR)/debian/foomatic-filters - rm -f $(CURDIR)/debian/foomatic-filters/etc/foomatic/filter.conf* - cp -p debian/parseconfig.pl $(CURDIR)/debian/foomatic-filters/usr/share/foomatic - chmod +x $(CURDIR)/debian/foomatic-filters/usr/share/foomatic/parseconfig.pl - -# Build architecture-dependent files here. -binary-arch: build install -# We have nothing to do by default. - -# Build architecture-independent files here. -binary-indep: build install - dh_testdir - dh_testroot - dh_installchangelogs ChangeLog - dh_installdocs - dh_installexamples filter.conf -# dh_install -# dh_installmenu - dh_installdebconf -# dh_installlogrotate -# dh_installemacsen -# dh_installpam -# dh_installmime -# dh_installinit -# dh_installcron -# dh_installinfo - dh_installman - (cd $(CURDIR)/debian/foomatic-filters/usr/lib/ppr/lib; ln -s foomatic-rip ppromatic) - (cd $(CURDIR)/debian/foomatic-filters/usr/lib/ppr/interfaces; ln -s foomatic-rip ppromatic) - (cd $(CURDIR)/debian/foomatic-filters/usr/lib/cups/filter; ln -s foomatic-rip cupsomatic) - (cd $(CURDIR)/debian/foomatic-filters/usr/sbin; ln -s ../bin/foomatic-rip lpdomatic) - (cd $(CURDIR)/debian/foomatic-filters/usr/bin; ln -s foomatic-rip directomatic) - (cd $(CURDIR)/debian/foomatic-filters/usr/share/man/man8; ln -s ../man1/foomatic-rip.1.gz lpdomatic.8.gz; cd ../man1; ln -s foomatic-rip.1.gz directomatic.1.gz) - dh_link - dh_strip - dh_compress - dh_fixperms - dh_perl -# dh_python -# dh_makeshlibs - dh_installdeb - dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install @@ -0,0 +1,530 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2005-07-09.11 + +# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. + +# 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>. + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to <bug-automake@gnu.org>. +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + stat=$? + + if test -f "$tmpdepfile"; then : + else + stripped=`echo "$stripped" | sed 's,^.*/,,'` + tmpdepfile="$stripped.u" + fi + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + outname="$stripped.o" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mecanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/fileconverter.c b/fileconverter.c new file mode 100644 index 0000000..f5e4da4 --- /dev/null +++ b/fileconverter.c @@ -0,0 +1,248 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <signal.h> +#include <unistd.h> + +#include "foomaticrip.h" +#include "options.h" +#include "process.h" + + +/* + * One of these fileconverters is used if the 'textfilter' option in the config file + * is not set. (Except if the spooler is CUPS, then 'texttops' is used + */ +const char *fileconverters[][2] = { + { "a2ps", "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- -" }, + { NULL, NULL } +}; + +char fileconverter[PATH_MAX] = ""; + +void set_fileconverter(const char *fc) +{ + int i; + for (i = 0; fileconverters[i][0]; i++) { + if (!strcmp(fc, fileconverters[i][0])) + strlcpy(fileconverter, fileconverters[i][1], PATH_MAX); + } + if (!fileconverters[i][0]) + strlcpy(fileconverter, fc, PATH_MAX); +} + +int guess_fileconverter() +{ + int i; + for (i = 0; fileconverters[i][0]; i++) { + if (find_in_path(fileconverters[i][0], getenv("PATH"), NULL)) { + strlcpy(fileconverter, fileconverters[i][1], PATH_MAX); + return 1; + } + } + return 0; +} + +/* + * Replace @@...@@PAGESIZE@@ and @@...@@JOBTITLE@@ with 'pagesize' and + * 'jobtitle' (if they are are not NULL). Returns a newly malloced string. + */ +char * fileconverter_from_template(const char *fileconverter, + const char *pagesize, const char *jobtitle) +{ + char *templstart, *templname; + const char *last = fileconverter; + char *res; + size_t len; + + len = strlen(fileconverter) + + (pagesize ? strlen(pagesize) : 0) + + (jobtitle ? strlen(jobtitle) : 0) +1; + res = malloc(len); + res[0] = '\0'; + + while ((templstart = strstr(last, "@@"))) { + strncat(res, last, templstart - last); + templstart += 2; + templname = strstr(templstart, "@@"); + if (!templname) + break; + if (startswith(templname, "@@PAGESIZE@@") && pagesize) { + strncat(res, templstart, templname - templstart); + strcat(res, pagesize); + last = templname + 12; + } + else if (startswith(templname, "@@JOBTITLE@@") && jobtitle) { + strncat(res, templstart, templname - templstart); + strcat(res, jobtitle); + while (templstart != templname) { + if (*templstart == '\"') { + strcat(res, "\""); + break; + } + templstart++; + } + last = templname + 12; + } + else + last += strlen(res); + } + strlcat(res, last, len); + + return res; +} + +int exec_kid2(FILE *in, FILE *out, void *user_arg) +{ + int n; + const char *alreadyread = (const char *)user_arg; + char tmp[1024]; + + /* child, first part of the pipe, reading in the data from standard input + * and stuffing it into the file converter after putting in the already + * read data (in alreadyread) */ + + _log("kid2: writing alreadyread\n"); + + /* At first pass the data which we already read to the filter */ + fwrite(alreadyread, 1, strlen(alreadyread), out); + + _log("kid2: Then read the rest from standard input\n"); + /* Then read the rest from standard input */ + while ((n = fread(tmp, 1, 1024, stdin)) > 0) + fwrite(tmp, 1, n, out); + + _log("kid2: Close out and stdin\n"); + fclose(out); + fclose(stdin); + + _log("kid2 finished\n"); + return EXIT_PRINTED; +} + +typedef struct { + const char *fileconv; + const char *alreadyread; +} kid1_userdata_t; + +int exec_kid1(FILE *in, FILE *out, void *user_arg) +{ + int kid2; + FILE *kid2out; + int status; + const char *fileconv = ((kid1_userdata_t *)user_arg)->fileconv; + const char *alreadyread = ((kid1_userdata_t *)user_arg)->alreadyread; + + kid2 = start_process("kid2", exec_kid2, (void *)alreadyread, NULL, &kid2out); + if (kid2 < 0) + return EXIT_PRNERR_NORETRY_BAD_SETTINGS; + + if (spooler != SPOOLER_CUPS) + _log("file converter command: %s\n", fileconv); + + if (dup2(fileno(kid2out), fileno(stdin)) < 0) { + _log("kid1: Could not dup stdin\n"); + fclose(kid2out); + return EXIT_PRNERR_NORETRY_BAD_SETTINGS; + } + if (dup2(fileno(out), fileno(stdout)) < 0) { + _log("kid1: Could not dup stdout\n"); + fclose(kid2out); + return EXIT_PRNERR_NORETRY_BAD_SETTINGS; + } + if (debug && !redirect_log_to_stderr()) { + _log("Could not dup logh to stderr\n"); + fclose(kid2out); + return EXIT_PRNERR_NORETRY_BAD_SETTINGS; + } + + /* Actually run the thing... */ + status = run_system_process("fileconverter", fileconv); + fclose(out); + fclose(kid2out); + fclose(stdin); + fclose(stdout); + + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) == 0) { + wait_for_process(kid2); + _log("kid1 finished\n"); + return EXIT_PRINTED; + } + } + else if (WIFSIGNALED(status)) { + switch (WTERMSIG(status)) { + case SIGUSR1: return EXIT_PRNERR; + case SIGUSR2: return EXIT_PRNERR_NORETRY; + case SIGTTIN: return EXIT_ENGAGED; + } + } + return EXIT_PRNERR; +} + + +/* + * This function is only used when the input data is not PostScript. Then it + * runs a filter which converts non-PostScript files into PostScript. The user + * can choose which filter he wants to use. The filter command line is + * provided by 'fileconverter'. + */ +void get_fileconverter_handle(const char *alreadyread, FILE **fd, pid_t *pid) +{ + pid_t kid1; + FILE *kid1out; + const char *pagesize; + char *fileconv; + kid1_userdata_t kid1_userdata; + + _log("\nStarting converter for non-PostScript files\n"); + + if (isempty(fileconverter) && !guess_fileconverter()) + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "Cannot convert file to " + "Postscript (missing fileconverter)."); + + /* Use wider margins so that the pages come out completely on every printer + * model (especially HP inkjets) */ + pagesize = option_get_value(find_option("PageSize"), optionset("header")); + if (pagesize && startswith(fileconverter, "a2ps")) { + if (!strcasecmp(pagesize, "letter")) + pagesize = "Letterdj"; + else if (!strcasecmp(pagesize, "a4")) + pagesize = "A4dj"; + } + + if (do_docs) + snprintf(get_current_job()->title, 128, "Documentation for the %s", printer_model); + + fileconv = fileconverter_from_template(fileconverter, pagesize, get_current_job()->title); + + kid1_userdata.fileconv = fileconv; + kid1_userdata.alreadyread = alreadyread; + kid1 = start_process("kid1", exec_kid1, &kid1_userdata, NULL, &kid1out); + if (kid1 < 0) + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "Cannot convert file to " + "Postscript (Cannot fork for kid1!)\n"); + + *fd = kid1out; + *pid = kid1; + + free(fileconv); +} + +int close_fileconverter_handle(FILE *fileconverter_handle, pid_t fileconverter_pid) +{ + int status; + + _log("\nClosing file converter\n"); + fclose(fileconverter_handle); + + status = wait_for_process(fileconverter_pid); + if (WIFEXITED(status)) + return WEXITSTATUS(status); + else + return EXIT_PRNERR_NORETRY_BAD_SETTINGS; +} + diff --git a/fileconverter.h b/fileconverter.h new file mode 100644 index 0000000..1b96a10 --- /dev/null +++ b/fileconverter.h @@ -0,0 +1,13 @@ + +#ifndef fileconverter_h +#define fileconverter_h + +#include <unistd.h> + +void set_fileconverter(const char *fc); + +int close_fileconverter_handle(FILE *fileconverter_handle, pid_t fileconverter_pid); +void get_fileconverter_handle(const char *alreadyread, FILE **fd, pid_t *pid); + +#endif + diff --git a/foomatic-gswrapper.1.in b/foomatic-gswrapper.1.in deleted file mode 100644 index fd95941..0000000 --- a/foomatic-gswrapper.1.in +++ /dev/null @@ -1,31 +0,0 @@ -.\" This -*- nroff -*- source file is part of foomatic. -.\" -.TH FOOMATIC-GSWRAPPER 1 "2001-05-07" "Foomatic Project" -.SH NAME -foomatic-gswrapper \- foomatic wrapper for ghostscript -.SH SYNOPSIS -.B foomatic-gswrapper -[\fB gs option \fR] ... - - -This is a little Ghostscript regularization script. It massages -arguments to make Ghostscript execute properly as a filter, with -output on stdout and errors etc on stderr. - -.\".SH SEE ALSO -.\".IR foomatic-XXX (1), - -.SH EXIT STATUS -.B foomatic-gswrapper -returns 0 on success. - -.SH AUTHOR -Manfred Wassmann <\fImanolo@NCC-1701.B.Shuttle.de\fR> for the foomatic -project using output from the associated binary. - -.SH BUGS -None so far. - -Please send bug reports to the Foomatic mailing list: - -http://lists.freestandards.org/mailman/listinfo/printing-foomatic diff --git a/foomatic-gswrapper.in b/foomatic-gswrapper.in deleted file mode 100644 index d314c6a..0000000 --- a/foomatic-gswrapper.in +++ /dev/null @@ -1,98 +0,0 @@ -#!@PERL@ -# -*- perl -*- -# $Revision$ - -# This is a little Ghostscript regularization script. It massages -# arguments to make Ghostscript execute properly as a filter, with -# output on stdout and errors etc on stderr. - -# Arbitrary other option processing could happen here, too. - -# IT WOULD BE WRONG to have this file do any processing of the input -# or output data. Such job transforms belong in actual filters, or -# inside Ghostscript itself. - -my $prefix = "@prefix@"; -my $configpath = "@sysconfdir@/foomatic"; -# Read config file if present -%conf = readConfFile("$configpath/filter.conf"); - -# Set Ghostscript path -my $gspath = "gs"; -$gspath = $conf{gspath} if defined(%conf) and defined $conf{gspath}; -my $execpath = "@EXECPATH@"; -# Get execution path from config file -$execpath = $conf{execpath} if defined(%conf) and defined $conf{execpath}; -$ENV{'PATH'} = $execpath; - -# Check whether we have a Ghostscript version with redirection of the -# standard output of the PostScript programs via '-sstdout=%stderr' -my $gswithstdoutredirection = 0; -if (`$gspath -dQUIET -dPARANOIDSAFER -dNOPAUSE -dBATCH -dNOMEDIAATTRS -sDEVICE=pswrite -sstdout=%stderr -sOutputFile=/dev/null -c '(hello\n) print flush' 2>&1` =~ /hello/) { - $gswithstdoutredirection = 1; -} - -grep (m!\-sOutputFile=\-! - && do { - # If Ghostscript does not support redirecting the standard output - # of the PostScript program to standard error with - # '-sstdout=%stderr', sen the job output data to fd 3; errors - # will be on 2(stderr) and job ps program interpreter output on - # 1(stdout). - $_ = ($gswithstdoutredirection ? - '-sOutputFile=%stdout' : '-sOutputFile=/dev/fd/3'); - # quoted properly below... - }, @ARGV); - -grep (((m!^\-$!) || (m!^\-_$!) || (m!^/dev/fd/0$!)) - && do { - # Use always buffered input. This works around a Ghostscript - # bug which prevents printing encrypted PDF files with Adobe - # Reader 8.1.1 and Ghostscript built as shared library - # (Ghostscript bug #689577, Ubuntu bug #172264) - $_ = "-_"; - }, @ARGV); - -# Turn *off* -q (quiet!); now that stderr is useful! :) -my @myargs = grep (! m!^\-q$!, @ARGV); - -# Escape any quotes, and then quote everything just to be sure... - -# Escaping a single quote inside single quotes is a bit complex as the shell -# takes everything literal there. So we have to assemble it by concatinating -# different quoted strings. -# Finally we get e.g.: 'x'"'"'y' or ''"'"'xy' or 'xy'"'"'' or ... -grep (s/\'/\'\"\'\"\'/g, @myargs); -my $args = "'" . join("' '", @myargs) . "'"; - -# Execute Ghostscript, with both job and gs errors on stderr, and job -# output on stdout... - -if ($gswithstdoutredirection) { - $args = "'-sstdout=\%stderr' $args"; - print STDERR "foomatic-gswrapper: $gspath $args\n"; - exec "$gspath $args"; -} else { - print STDERR "foomatic-gswrapper: $gspath $args 3>&1 1>&2\n"; - exec "$gspath $args 3>&1 1>&2"; -} - -die "Failed to execute Ghostscript?!"; - -# Read the config file - -sub readConfFile { - my ($file) = @_; - - my %conf; - # Read config file if present - if (open CONF, "< $file") { - while (<CONF>) - { - $conf{$1}="$2" if (m/^\s*([^\#\s]\S*)\s*:\s*(.*?)\s*$/); - } - close CONF; - } - - return %conf; -} diff --git a/foomatic-rip.1.in b/foomatic-rip.1.in index 7c86fd6..95891bc 100644 --- a/foomatic-rip.1.in +++ b/foomatic-rip.1.in @@ -55,7 +55,7 @@ input to the printer's native language (usually put to standard output). .Topic -The translation is done with an external renderer, usually GhostScript +The translation is done with an external renderer, usually Ghostscript (\fBgs(1)\fR). If no translation is needed (PostScript printer) the renderer's command line reduces to \fBcat(1)\fR. The way how this translation is done is described in a \fBPPD file\fR. 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 <gtaylor@picante.com> -# & Till Kamppeter <till.kamppeter@gmail.com> -# & Helge Blischke <h.blischke@srz.de> -# -# 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=<file>" appends the data to the <file>, -# "--genpdq=<file>" creates/overwrites <file> 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 = <FILE>) { - # 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 = <CONFIG>) { - 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 <name>\") " . - "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 = ("<STDIN>"); -} - -# Check file list -my $file; -my $filecnt = 0; -for $file (@filelist) { - if ($file ne "<STDIN>") { - 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(<PPD>) { - # foomatic-rip should also work with PPD file downloaded under Windows. - $_ = undossify($_); - # Parse keywords - if (m!^\*NickName:\s*\"(.*)$!) { - # "*NickName: <code>" - 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 = <PPD>; - chomp $line; - } - $line =~ m!^([^\"]*)\"!; - $cmd .= $1; - $model = unhtmlify($cmd); - } elsif (m!^\*FoomaticIDs:\s*\"?\s*(\S+?)\s+(\S+?)\s*\"?\s*$!) { - # "*FoomaticIDs: <printer ID> <driver ID>" - my $id = $1; - my $driver = $2; - # Store the values - $dat->{'id'} = $id; - $dat->{'driver'} = $driver; - } elsif (m!^\*FoomaticRIPPostPipe:\s*\"(.*)$!) { - # "*FoomaticRIPPostPipe: <code>" - 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 = <PPD>; - chomp $line; - } - $line =~ m!^([^\"]*)\"!; - $cmd .= $1; - $postpipe = unhtmlify($cmd); - } elsif (m!^\*FoomaticRIPCommandLine:\s*\"(.*)$!) { - # "*FoomaticRIPCommandLine: <code>" - 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 = <PPD>; - chomp $line; - } - $line =~ m!^([^\"]*)\"!; - $cmd .= $1; - $dat->{'cmd'} = unhtmlify($cmd); - } elsif (m!^\*FoomaticNoPageAccounting:\s*\"?\s*(\S+?)\s*\"?\s*$!) { - # "*FoomaticRIPNoPageAccounting: <boolean value>" - 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: <code>" - 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 = <PPD>; - 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: <code>" - 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 = <PPD>; - 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 *<option>[/<translation>]: <type>" - my $argnametrans = $2; - my $argtype = $3; - my $argname; - my $translation = ""; - if ($argnametrans =~ m!^([^:/\s]+)/([^:]*)$!) { - $argname = $1; - $translation = $2; - } else { - $argname = $argnametrans; - } - # Make sure that the argument is in the data structure - checkarg ($dat, $argname); - # Store the values - $dat->{'args_byname'}{$argname}{'comment'} = $translation; - # Set the argument type only if not defined yet, a - # definition in "*FoomaticRIPOption" has priority - if ( !($dat->{'args_byname'}{$argname}{'type'}) ) { - if ($argtype eq "PickOne") { - $dat->{'args_byname'}{$argname}{'type'} = 'enum'; - } elsif ($argtype eq "PickMany") { - $dat->{'args_byname'}{$argname}{'type'} = 'pickmany'; - } elsif ($argtype eq "Boolean") { - $dat->{'args_byname'}{$argname}{'type'} = 'bool'; - } - } - # Mark in which argument we are currently, so that we can find - # the entries for the choices - $currentargument = $argname; - } elsif (m!^\*(JCL|)CloseUI:\s+\*([^:/\s]+)\s*$!) { - # "*[JCL]CloseUI *<option>" - my $argname = $2; - # Unmark the current argument to do not mis-interpret any keywords - # as choices - $currentargument = ""; - } elsif ((m!^\*FoomaticRIPOption ([^/:\s]+):\s*\"?\s*(\S+?)\s+(\S+)\s+(\S)\s*\"?\s*$!) || - (m!^\*FoomaticRIPOption ([^/:\s]+):\s*\"?\s*(\S+?)\s+(\S+)\s+(\S)\s+(\S+?)\s*\"?\s*$!)){ - # "*FoomaticRIPOption <option>: <type> <style> <spot> [<order>]" - # <order> only used for 1-choice enum options - my $argname = $1; - my $argtype = $2; - my $argstyle = $3; - my $spot = $4; - my $order = $5; - # Make sure that the argument is in the data structure - checkarg ($dat, $argname); - # Store the values - $dat->{'args_byname'}{$argname}{'type'} = $argtype; - if ($argstyle eq "PS") { - $dat->{'args_byname'}{$argname}{'style'} = 'G'; - } elsif ($argstyle eq "CmdLine") { - $dat->{'args_byname'}{$argname}{'style'} = 'C'; - } elsif ($argstyle eq "JCL") { - $dat->{'args_byname'}{$argname}{'style'} = 'J'; - $dat->{'jcl'} = 1; - } elsif ($argstyle eq "Composite") { - $dat->{'args_byname'}{$argname}{'style'} = 'X'; - } - $dat->{'args_byname'}{$argname}{'spot'} = $spot; - # $order only defined here for 1-choice enum options - if ($order) { - $dat->{'args_byname'}{$argname}{'order'} = $order; - } - } elsif (m!^\*FoomaticRIPOptionPrototype\s+([^/:\s]+):\s*\"(.*)$!) { - # "*FoomaticRIPOptionPrototype <option>: <code>" - # Used for numerical and string options only - my $argname = $1; - my $line = $2; - # Make sure that the argument is in the data structure - checkarg ($dat, $argname); - # Store the value - # Code string can have multiple lines, read all of them - my $proto = ""; - while ($line !~ m!\"!) { - if ($line =~ m!&&$!) { - # line continues in next line - $proto .= substr($line, 0, -2); - } else { - # line ends here - $proto .= "$line\n"; - } - # Read next line - $line = <PPD>; - chomp $line; - } - $line =~ m!^([^\"]*)\"!; - $proto .= $1; - $dat->{'args_byname'}{$argname}{'proto'} = unhtmlify($proto); - } elsif (m!^\*FoomaticRIPOptionRange\s+([^/:\s]+):\s*\"?\s*(\S+?)\s+(\S+?)\s*\"?\s*$!) { - # "*FoomaticRIPOptionRange <option>: <min> <max>" - # Used for numerical options only - my $argname = $1; - my $min = $2; - my $max = $3; - # Make sure that the argument is in the data structure - checkarg ($dat, $argname); - # Store the values - $dat->{'args_byname'}{$argname}{'min'} = $min; - $dat->{'args_byname'}{$argname}{'max'} = $max; - } elsif (m!^\*FoomaticRIPOptionMaxLength\s+([^/:\s]+):\s*\"?\s*(\S+?)\s*\"?\s*$!) { - # "*FoomaticRIPOptionMaxLength <option>: <length>" - # Used for string options only - my $argname = $1; - my $maxlength = $2; - # Make sure that the argument is in the data structure - checkarg ($dat, $argname); - # Store the value - $dat->{'args_byname'}{$argname}{'maxlength'} = $maxlength; - } elsif (m!^\*FoomaticRIPOptionAllowedChars\s+([^/:\s]+):\s*\"(.*)$!) { - # "*FoomaticRIPOptionAllowedChars <option>: <code>" - # Used for string options only - my $argname = $1; - my $line = $2; - # 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 = <PPD>; - chomp $line; - } - $line =~ m!^([^\"]*)\"!; - $code .= $1; - # Make sure that the argument is in the data structure - checkarg ($dat, $argname); - # Store the value - $dat->{'args_byname'}{$argname}{'allowedchars'} = unhtmlify($code); - } elsif (m!^\*FoomaticRIPOptionAllowedRegExp\s+([^/:\s]+):\s*\"(.*)$!) { - # "*FoomaticRIPOptionAllowedRegExp <option>: <code>" - # Used for string options only - my $argname = $1; - my $line = $2; - # 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 = <PPD>; - chomp $line; - } - $line =~ m!^([^\"]*)\"!; - $code .= $1; - # Make sure that the argument is in the data structure - checkarg ($dat, $argname); - # Store the value - $dat->{'args_byname'}{$argname}{'allowedregexp'} = - unhtmlify($code); - } elsif (m!^\*OrderDependency:\s*(\S+)\s+(\S+)\s+\*([^:/\s]+)\s*$!) { - # "*OrderDependency: <order> <section> *<option>" - my $order = $1; - my $section = $2; - my $argname = $3; - # Make sure that the argument is in the data structure - checkarg ($dat, $argname); - # Store the values - $dat->{'args_byname'}{$argname}{'order'} = $order; - $dat->{'args_byname'}{$argname}{'section'} = $section; - } elsif (m!^\*Default([^/:\s]+):\s*([^/:\s]+)\s*$!) { - # "*Default<option>: <value>" - my $argname = $1; - my $default = $2; - # Make sure that the argument is in the data structure - checkarg ($dat, $argname); - # Store the value - $dat->{'args_byname'}{$argname}{'default'} = $default; - } elsif (m!^\*FoomaticRIPDefault([^/:\s]+):\s*\"?\s*([^/:\s]+?)\s*\"?\s*$!) { - # "*FoomaticRIPDefault<option>: <value>" - # Used for numerical options only - my $argname = $1; - my $default = $2; - # Make sure that the argument is in the data structure - checkarg ($dat, $argname); - # Store the value - $dat->{'args_byname'}{$argname}{'fdefault'} = $default; - } elsif (m!^\*$currentargument\s+([^:]+):\s*\"(.*)$!) { - # "*<option> <choice>[/<translation>]: <code>" - my $settingtrans = $1; - my $line = $2; - my $translation = ""; - my $setting = ""; - if ($settingtrans =~ m!^([^:/\s]+)/([^:]*)$!) { - $setting = $1; - $translation = $2; - } else { - $setting = $settingtrans; - } - # Make sure that the argument is in the data structure - checkarg ($dat, $currentargument); - # Make sure that the setting is in the data structure (enum options) - my $bool = - ($dat->{'args_byname'}{$currentargument}{'type'} eq 'bool'); - if ($bool) { - if (lc($setting) eq "true") { - if (!$dat->{'args_byname'}{$currentargument}{'comment'}) { - $dat->{'args_byname'}{$currentargument}{'comment'} = - $translation; - } - $dat->{'args_byname'}{$currentargument}{'comment_true'} = - $translation; - } else { - $dat->{'args_byname'}{$currentargument}{'comment_false'} = - $translation; - } - } else { - checksetting ($dat, $currentargument, $setting); - # Make sure that this argument has a default setting, even if - # none is defined in this PPD file - if (!defined ($dat->{'args_byname'}{$currentargument}{'default'})) { - $dat->{'args_byname'}{$currentargument}{'default'} = $setting; - } - $dat->{'args_byname'}{$currentargument}{'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 = <PPD>; - chomp $line; - } - $line =~ m!^([^\"]*)\"!; - $code .= $1; - if ($code !~ m!^%% FoomaticRIPOptionSetting!) { - if ($bool) { - if (lc($setting) eq "true") { - $dat->{'args_byname'}{$currentargument}{'proto'} = $code; - } else { - $dat->{'args_byname'}{$currentargument}{'protof'} = $code; - } - } else { - $dat->{'args_byname'}{$currentargument}{'vals_byname'}{$setting}{'driverval'} = $code; - } - } - } elsif ((m!^\*FoomaticRIPOptionSetting\s+([^/:=\s]+)=([^/:=\s]+):\s*\"(.*)$!) || - (m!^\*FoomaticRIPOptionSetting\s+([^/:=\s]+):\s*\"(.*)$!)) { - # "*FoomaticRIPOptionSetting <option>[=<choice>]: <code>" - # For boolean options <choice> is not given - my $argname = $1; - my $setting = $2; - my $line = $3; - my $bool = 0; - if (!$line) { - $line = $setting; - $bool = 1; - } - # Make sure that the argument is in the data structure - checkarg ($dat, $argname); - # Make sure that the setting is in the data structure (enum options) - if (!$bool) { - checksetting ($dat, $argname, $setting); - # Make sure that this argument has a default setting, even if - # none is defined in this PPD file - if (!defined ($dat->{'args_byname'}{$argname}{'default'})) { - $dat->{'args_byname'}{$argname}{'default'} = $setting; - } - } - # 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 = <PPD>; - chomp $line; - } - $line =~ m!^([^\"]*)\"!; - $code .= $1; - if ($bool) { - $dat->{'args_byname'}{$argname}{'proto'} = unhtmlify($code); - } else { - $dat->{'args_byname'}{$argname}{'vals_byname'}{$setting}{'driverval'} = unhtmlify($code); - } - } elsif (m!^\*(Foomatic|)JCL(Begin|ToPSInterpreter|End|Prefix):\s*\"(.*)$!) { - # "*(Foomatic|)JCL(Begin|ToPSInterpreter|End|Prefix): <code>" - # The printer supports PJL/JCL when there is such a line - $dat->{'jcl'} = 1; - my $item = $2; - my $line = $3; - # 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 = <PPD>; - chomp $line; - } - $line =~ m!^([^\"]*)\"!; - $code .= $1; - if ($item eq 'Begin') { - $jclbegin = unhexify($code); - $jclprefix = "" if (!$jclprefixset) && ($jclbegin !~ /PJL/s); - } elsif ($item eq 'ToPSInterpreter') { - $jcltointerpreter = unhexify($code); - } elsif ($item eq 'End') { - $jclend = unhexify($code); - } elsif ($item eq 'Prefix') { - $jclprefix = unhexify($code); - $jclprefixset = 1; - } - } elsif (m!^\*\% COMDATA \#(.*)$!) { - # If we have an old Foomatic 2.0.x PPD file, collect its Perl data - push (@datablob, $1); - } -} -close PPD; - -# If we have an old Foomatic 2.0.x PPD file use its Perl data structure -if ($#datablob >= 0) { - print $logh "${added_lf}You are using an old Foomatic 2.0 PPD file, consider " . - "upgrading.${added_lf}\n"; - my $VAR1; - if (eval join('',@datablob)) { - # Overtake default settings from the main structure of the PPD file - for my $arg (@{$dat->{'args'}}) { - if ($arg->{'default'}) { - $VAR1->{'argsbyname'}{$arg->{'name'}}{'default'} = - $arg->{'default'}; - } - } - undef $dat; - $dat = $VAR1; - $dat->{'jcl'} = $dat->{'pjl'}; - } else { - # Perl structure broken - print $logh "${added_lf}Unable to evaluate datablob, print job may come " . - "out incorrectly or not at all.${added_lf}\n"; - } -} - - - -## We do not need to parse the PostScript job when we don't have -## any options. If we have options, we must check whether the -## default settings from the PPD file are valid and correct them -## if nexessary. - -my $dontparse = 0; -if ((!defined(@{$dat->{'args'}})) || - ($#{$dat->{'args'}} < 0)) { - # We don't have any options, so we do not need to parse the - # PostScript data - $dontparse = 1; -} else { - # Let the default value of a boolean option being 0 or 1 instead of - # "True" or "False", range-check the defaults of all options and - # issue warnings if the values are not valid - checkoptions($dat, 'default'); - - # Adobe's PPD specs do not support numerical - # options. Therefore the numerical options are mapped to - # enumerated options in the PPD file and their characteristics - # as a numerical option are stored in "*Foomatic..." - # keywords. A default must be between the enumerated - # fixed values. The default - # value must be given by a "*FoomaticRIPDefault<option>: - # <value>" line in the PPD file. But this value is only valid - # if the "official" default given by a "*Default<option>: - # <value>" line (it must be one of the enumerated values) - # points to the enumerated value which is closest to this - # value. This way a user can select a default value with a - # tool only supporting PPD files but not Foomatic extensions. - # This tool only modifies the "*Default<option>: <value>" line - # and if the "*FoomaticRIPDefault<option>: <value>" had always - # priority, the user's change in "*Default<option>: <value>" - # would have no effect. - - for my $arg (@{$dat->{'args'}}) { - if ($arg->{'fdefault'}) { - if ($arg->{'default'}) { - if ($arg->{'type'} =~ /^(int|float)$/) { - if ($arg->{'fdefault'} < $arg->{'min'}) { - $arg->{'fdefault'} = $arg->{'min'}; - } - if ($arg->{'fdefault'} > $arg->{'max'}) { - $arg->{'fdefault'} = $arg->{'max'}; - } - if ($arg->{'type'} eq 'int') { - $arg->{'fdefault'} = POSIX::floor($arg->{'fdefault'}); - } - my $mindiff = abs($arg->{'max'} - $arg->{'min'}); - my $closestvalue; - for my $val (@{$arg->{'vals'}}) { - if (abs($arg->{'fdefault'} - $val->{'value'}) < - $mindiff) { - $mindiff = - abs($arg->{'fdefault'} - $val->{'value'}); - $closestvalue = $val->{'value'}; - } - } - if (($arg->{'default'} == $closestvalue) || - (abs($arg->{'default'} - $closestvalue) / - $closestvalue < 0.001)) { - $arg->{'default'} = $arg->{'fdefault'}; - } - } - } else { - $arg->{'default'} = $arg->{'fdefault'}; - } - } - } -} - -# Is our PPD for a CUPS raster driver -if (my $cupsfilter = $dat->{'cupsfilter'}{"application/vnd.cups-raster"}) { - - # Search filter in cupsfilterpath - # The %Y is a placeholder for the option settings - my $havefilter = 0; - for (split(':', $cupsfilterpath)) { - if (-x "$_/$cupsfilter") { - $havefilter=1; - $cupsfilter = "$_/$cupsfilter 0 '' '' 0 '%Y%X'"; - last; - } - } - - if (!$havefilter) { - - # We do not have the required filter, so we assume that - # rendering this job is supposed to be done on a remote - # server. So we do not define a renderer command line and - # embed only the option settings (as we had a PostScript - # printer). This way the settings are # taken into account - # when the job is rendered on the server. - print $logh "${added_lf}CUPS filter for this PPD file not found " . - "assuming that job will be rendered on a remote server. Only " . - "the PostScript of the options will be inserted into the " . - "PostScript data stream.${added_lf}\n"; - - } else { - - # use pstoraster script if available, otherwise run GhostScript - # directly - my $pstoraster = "pstoraster"; - my $havepstoraster = 0; - for (split(':', $cupsfilterpath)) { - if (-x "$_/$pstoraster") { - $havepstoraster=1; - $pstoraster = "$_/$pstoraster 0 '' '' 0 '%X'"; - last; - } - } - - if (!$havepstoraster) { - - # Build GhostScript command line - $pstoraster = "gs -dQUIET -dDEBUG -dPARANOIDSAFER -dNOPAUSE -dBATCH -dNOMEDIAATTRS -sDEVICE=cups -sOutputFile=-%W -" - - } - - # build GhostScript/CUPS driver command line - $dat->{'cmd'} = "$pstoraster | $cupsfilter"; - - # Set environment variables - $ENV{'PPD'} = $ppdfile; - - } -} - -# Was the RIP command line defined in the PPD file? If not, we assume a -# PostScript printer and do not render/translate the input data -if (!defined($dat->{'cmd'})) { - $dat->{'cmd'} = "cat%A%B%C%D%E%F%G%H%I%J%K%L%M%Z"; - if ($dontparse) { - # No command line, no options, we have a raw queue, don't check - # whether the input is PostScript and ignore the "docs" option, - # simply pass the input data to the backend. - $dontparse = 2; - $model = "Raw queue"; - } -} - - - -## Summary for debugging -print $logh "${added_lf}Parameter Summary\n"; -print $logh "-----------------${added_lf}\n"; -print $logh "Spooler: $spooler\n"; -print $logh "Printer: $printer\n"; -print $logh "Shell: $modern_shell\n"; -print $logh "PPD file: $ppdfile\n"; -print $logh "ATTR file: $attrpath\n"; -print $logh "Printer model: $model\n"; -# Print the options string only in debug mode, Mac OS X adds very many -# options so that CUPS cannot handle the output of the option string -# 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 "Options: $optstr\n"; -} -print $logh "Job title: $jobtitle\n"; -print $logh "File(s) to be printed: ${added_lf}@filelist${added_lf}\n"; -print $logh "GhostScript extra search path ('GS_LIB'): $ENV{'GS_LIB'}\n" - if $ENV{'GS_LIB'}; - - - -## Parse options from command line ($optstr) - -# Before we start, save the defaults for printing documentation pages - -copyoptions($dat, 'default', 'userval'); - - -# The options are "foo='bar nut'", "foo", "nofoo", "'bar nut'", or -# "foo:'bar nut'" (when GPR was used) all with spaces between... -# In addition they can be preceeded by page ranges, separated with a -# colon. - -my @opts; - -# Variable for PPR's backend interface name (parallel, tcpip, atalk, ...) - -my $backend = ""; - -# Array to collect unknown options so that they can get passed to the -# backend interface of PPR. For other spoolers we ignore them. - -my @backendoptions = (); - -# "foo='bar nut'" -while ($optstr =~ s!(((even|odd|[\d,-]+):|)\w+=[\'\"].*?[\'\"]) ?!!i) { - push (@opts, $1); -} - -# "foo:'bar nut'" (GPR separates option and setting with a colon ":") -while ($optstr =~ s!(((even|odd|[\d,-]+):|)\w+:[\'\"].*?[\'\"]) ?!!i) { -#while ($optstr =~ s!(\w+=[\'\"].*?[\'\"])!!i) { - push (@opts, $1); -} - -# "'bar nut'", "'foo=bar nut'", "'foo:bar nut'" -while ($optstr =~ s!([\'\"].+?[\'\"]) ?!!) { - my $opt = $1; - $opt =~ s/[\'\"]//g; # Make only sure that we didn't quote - # the option for a second time when we read - # rge options from the command line or - # environment variable - push (@opts, $opt); - -} - -# "foo", "nofoo" -push(@opts, split(/ /,$optstr)); - -# Now actually process those pesky options... - -for (@opts) { - print $logh "Pondering option '$_'\n"; - - # "docs" option to print help page - if ((lc($_) =~ /^\s*docs\s*$/) || - (lc($_) =~ /^\s*docs\s*=\s*true\s*$/)) { - # The second one is necessary becuase CUPS 1.1.15 or newer sees - # "docs" as boolean option and modifies it to "docs=true" - $do_docs = 1; - next; - } - - # "profile" option to supply a color correction profile to a - # CUPS raster driver - if (lc($_) =~ /^\s*profile=(\S+)\s*$/) { - $cupscolorprofile=$1; - $dat->{'cmd'} =~ s!\%X!profile=$cupscolorprofile!g; - $dat->{'cmd'} =~ s!\%W! -c\"<</cupsProfile($cupscolorprofile)>>setpagedevice\"!g; - next; - } - - # Is the command line option limited to certain page ranges? If so, - # mark the setting with a hash key containing the ranges - my $optionset; - if (s/^(even|odd|[\d,-]+)://i) { - $optionset = "pages:$1"; - } else { - $optionset = 'userval'; - } - - # Solaris options that have no reason to be - if (/^nobanner$/ || /^dest=.+$/ || /^protocol=.+$/) { - next; - } - - my $arg; - if ((m!([^=]+)=\'?(.*)\'?!) || (m!([^=:]+):\'?(.*)\'?!)) { - my ($aname, $avalue) = ($1, $2); - - if (($optionset =~ /pages/) && - ($arg = argbyname($aname)) && - ((!defined($arg->{'section'})) || - ($arg->{'section'} !~ /^(Any|Page)Setup/))) { - print $logh "This option is not a \"PageSetup\" or " . - "\"AnySetup\" option, so it cannot be restricted to " . - "a page range.\n"; - next; - } - - # At first look for the "backend" option to determine the PPR - # backend to use - if (($aname =~ m!^backend$!i) && ($spooler eq 'ppr_int')) { - # Backend interface name - $backend = $avalue; - } elsif ($aname =~ m!^media$!i) { - - # Standard arguments? - # media=x,y,z - # sides=one|two-sided-long|short-edge - - # Rummage around in the media= option for known media, source, - # etc types. - # We ought to do something sensible to make the common manual - # boolean option work when specified as a media= tray thing. - # - # Note that this fails miserably when the option value is in - # fact a number; they all look alike. It's unclear how many - # drivers do that. We may have to standardize the verbose - # names to make them work as selections, too. - - my @values = split(',',$avalue); - for (@values) { - my $val; - if ($dat->{'args_byname'}{'PageSize'} and - $val=valbyname($dat->{'args_byname'}{'PageSize'},$_)) { - $dat->{'args_byname'}{'PageSize'}{$optionset} = - $val->{'value'}; - # Keep "PageRegion" in sync - if ($dat->{'args_byname'}{'PageRegion'} and - $val=valbyname($dat->{'args_byname'}{'PageRegion'}, - $_)) { - $dat->{'args_byname'}{'PageRegion'}{$optionset} = - $val->{'value'}; - } - } elsif ($dat->{'args_byname'}{'PageSize'} - and /^Custom/) { - $dat->{'args_byname'}{'PageSize'}{$optionset} = $_; - # Keep "PageRegion" in sync - if ($dat->{'args_byname'}{'PageRegion'}) { - $dat->{'args_byname'}{'PageRegion'}{$optionset} = - $_; - } - } elsif ($dat->{'args_byname'}{'MediaType'} and - $val=valbyname($dat->{'args_byname'}{'MediaType'}, - $_)) { - $dat->{'args_byname'}{'MediaType'}{$optionset} = - $val->{'value'}; - } elsif ($dat->{'args_byname'}{'InputSlot'} and - $val=valbyname($dat->{'args_byname'}{'InputSlot'}, - $_)) { - $dat->{'args_byname'}{'InputSlot'}{$optionset} = - $val->{'value'}; - } elsif (lc($_) eq 'manualfeed') { - # Special case for our typical boolean manual - # feeder option if we didn't match an InputSlot above - if (defined($dat->{'args_byname'}{'ManualFeed'})) { - $dat->{'args_byname'}{'ManualFeed'}{$optionset} = 1; - } - } else { - print $logh "Unknown \"media\" component: \"$_\".\n"; - } - } - } elsif ($aname =~ m!^sides$!i) { - # Handle the standard duplex option, mostly - if ($avalue =~ m!^two-sided!i) { - if (defined($dat->{'args_byname'}{'Duplex'})) { - # Default to long-edge binding here, for the case that - # there is no binding setting - $dat->{'args_byname'}{'Duplex'}{$optionset} = - 'DuplexNoTumble'; - # Check the binding: "long edge" or "short edge" - if ($avalue =~ m!long-edge!i) { - if (defined($dat->{'args_byname'}{'Binding'})) { - $dat->{'args_byname'}{'Binding'}{$optionset} = - $dat->{'args_byname'}{'Binding'}{'vals_byname'}{'LongEdge'}{'value'}; - } else { - $dat->{'args_byname'}{'Duplex'}{$optionset} = - 'DuplexNoTumble'; - } - } elsif ($avalue =~ m!short-edge!i) { - if (defined($dat->{'args_byname'}{'Binding'})) { - $dat->{'args_byname'}{'Binding'}{$optionset} = - $dat->{'args_byname'}{'Binding'}{'vals_byname'}{'ShortEdge'}{'value'}; - } else { - $dat->{'args_byname'}{'Duplex'}{$optionset} = - 'DuplexTumble'; - } - } - } - } elsif ($avalue =~ m!^one-sided!i) { - if (defined($dat->{'args_byname'}{'Duplex'})) { - $dat->{'args_byname'}{'Duplex'}{$optionset} = 'None'; - } - } - - # We should handle the other half of this option - the - # BindEdge bit. Also, are there well-known ipp/cups - # options for Collate and StapleLocation? These may be - # here... - - } else { - # Various non-standard printer-specific options - if ($arg = argbyname($aname)) { - if (defined(my $newvalue = - checkoptionvalue($dat, $aname, $avalue, 0))) { - # If the choice is valid, use it, otherwise - # ignore it. - $arg->{$optionset} = $newvalue; - # If this argument is PageSize or PageRegion, - # also set the other - syncpagesize($dat, $aname, $avalue, $optionset); - } else { - # Invalid choice, make log entry - print $logh "Invalid choice $aname=$avalue.\n"; - } - } elsif ($spooler eq 'ppr_int') { - # Unknown option, pass it to PPR's backend interface - push (@backendoptions, "$aname=$avalue"); - } else { - # Unknown option, make log entry - print $logh "Unknown option $aname=$avalue.\n"; - } - } - } elsif (m!^([\d\.]+)x([\d\.]+)([A-Za-z]*)$!) { - my ($w, $h, $u) = ($1, $2, $3); - # Custom paper size - if (($w != 0) && ($h != 0) && - ($arg=argbyname("PageSize")) && - (defined($arg->{'vals_byname'}{'Custom'}))) { - $arg->{$optionset} = "Custom.${w}x${h}${u}"; - # Keep "PageRegion" in sync - if ($dat->{'args_byname'}{'PageRegion'}) { - $dat->{'args_byname'}{'PageRegion'}{$optionset} = - $arg->{$optionset}; - } - } - } elsif ((m!^\s*no(.+)\s*$!i) and ($arg=argbyname($1))) { - # standard bool args: - # landscape; what to do here? - # duplex; we should just handle this one OK now? - $arg->{$optionset} = 0; - } elsif (m!^\s*(.+)\s*$!) { - if ($arg=argbyname($1)) { - $arg->{$optionset} = 1; - } else { - print $logh "Unknown boolean option \"$1\".\n"; - } - } -} -$do_docs = 1 if( $show_docs ); - - -## Were we called to build the PDQ driver declaration file? -my @pdqfile; -if ($genpdqfile) { - @pdqfile = buildpdqdriver($dat, 'userval'); - 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; -} - - - -## Set the $postpipe - -# $postpipe when running as a PPR RIP -if ($spooler eq 'ppr') { - # The PPR RIP sends the data output to /dev/fd/3 instead of to STDOUT - if (-w "/dev/fd/3") { - $postpipe = "| cat - > /dev/fd/3"; - } else { - $postpipe = "| cat - >&3"; - } -} - -# Set up PPR backend (if we run as a PPR interface). -if ($spooler eq 'ppr_int') { - - # Is the chosen backend installed and executable - if (!-x "interfaces/$backend") { - my $pwd = cwd; - print $logh "The backend interface $pwd/interfaces/$backend " . - "does not exist/is not executable!\n"; - rip_die ("The backend interface $pwd/interfaces/$backend " . - "does not exist/is not executable!", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - - # foomatic-rip cannot use foomatic-rip as backend - if ($backend eq "foomatic-rip") { - print $logh "\"foomatic-rip\" cannot use itself as backend " . - "interface!\n"; - ppr_die ($ppr_printer, - "\"foomatic-rip\" cannot use itself as backend interface!", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - - # Put the backend interface into the $postpipe - $postpipe = "| ( interfaces/$backend \"$ppr_printer\" ". - "\"$ppr_address\" \"" . join(" ",@backendoptions) . - "\" \"$ppr_jobbreak\" \"$ppr_feedback\" " . - "\"$ppr_codes\" \"$ppr_jobname\" \"$ppr_routing\" " . - "\"$ppr_for\" \"\" )"; - -} - -# CUPS and PDQ have their own backends, they do not need a $postpipe -if (($spooler eq 'cups') || ($spooler eq 'pdq')) { - # No $postpipe for CUPS or PDQ, even if one is defined in the PPD file - $postpipe = ""; -} - -# CPS needs always a $postpipe, set the default one for local printing -# if none is set -if (($spooler eq 'cps') && !$postpipe) { - $postpipe = "| cat - > \$LPDDEV"; -} - -if ($postpipe) { - print $logh "${added_lf}Output will be redirected to:\n$postpipe${added_lf}\n"; -} - - - -## Print documentation page when asked for -my ($docgeneratorhandle, $docgeneratorpid,$retval); -if ($do_docs) { - # Don't print the supplied files, STDIN will be redirected to the - # documentation page generator - @filelist = ("<STDIN>"); - # Start the documentation page generator - ($docgeneratorhandle, $docgeneratorpid) = - getdocgeneratorhandle($dat); - if ($retval != $EXIT_PRINTED) { - rip_die ("Error opening documentation page generator", - $retval); - } - # Read the further data from the documentation page generator and - # not from STDIN - if (!close STDIN && $! != $ESPIPE) { - rip_die ("Couldn't close STDIN", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - if (!open (STDIN, "<&$docgeneratorhandle")) { - rip_die ("Couldn't dup \$docgeneratorhandle", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - if( $show_docs ){ - while( <$docgeneratorhandle> ){ - print; - } - exit(0); - } -} - - - - -## In debug mode save the data supposed to be fed into the -## renderer also into a file, reset the file here - -if ($debug) { - modern_system("> ${logfile}.ps"); -} - - - -## From here on we have to repeat all the rest of the program for -## every file to print - -for $file (@filelist) { - - print $logh -"${added_lf}================================================\n${added_lf}". -"File: $file\n${added_lf}" . -"================================================\n${added_lf}"; - - - - ## If we do not print standard input, open the file to print - if ($file ne "<STDIN>") { - if (! -r $file) { - print $logh "File $file missing or not readable, skipping.\n"; - next; - } - close STDIN; - open STDIN, "< $file" || do { - print $logh "Cannot open $file, skipping.\n"; - next; - } - } - - - - ## Do we have a raw queue - if ($dontparse == 2) { - # Raw queue, simply pass the input into the $postpipe (or to STDOUT - # when there is no $postpipe) - print $logh "Raw printing, executing \"cat $postpipe\"${added_lf}\n"; - modern_system("cat $postpipe"); - next; - } - - - - ## First, for arguments with a default, stick the default in as - ## the initial value for the "header" option set, this option set - ## consists of the PPD defaults, the options specified on the - ## command line, and the options set in the header part of the - ## PostScript file (all before the first page begins). - - copyoptions($dat, 'userval', 'header'); - - - - ## Next, examine the PostScript job for traces of command-line and - ## JCL options. PPD-aware applications and spoolers stuff option - ## settings directly into the file, they do not necessarily send - ## PPD options by the command line. Also stuff in PostScript code - ## to apply option settings given by the command line and to set - ## the defaults given in the PPD file. - - # Examination strategy: read lines from STDIN until the first - # %%Page: comment appears and save them as @psheader. This is the - # page-independent header part of the PostScript file. The - # PostScript interpreter (renderer) must execute this part once - # before rendering any assortment of pages. Then pages can be - # printed in any arbitrary selection or order. All option - # settings we find here will be collected in the default option - # set for the RIP command line. - - # Now the pages will be read and sent to the renderer, one after - # the other. Every page is read into memory until the - # %%EndPageSetup comment appears (or a certain amount of lines was - # read). So we can get option settings only valid for this - # page. If we have such settings we set them in the modified - # command set for this page. - - # If the renderer is not running yet (first page) we start it with - # the command line built from the current modified command set and - # send the first page to it, in the end we leave the renderer - # running and keep input and output pipes open, so that it can - # accept further pages. If the renderer is still running from - # the previous page and the current modified command set is the - # same as the one for the previous page, we send the page. If - # the command set is different, we close the renderer, re-start - # it with the command line built from the new modified command - # set, send the header again, and then the page. - - # After the last page the trailer (%%Trailer) is sent. - - # The output pipe of this program stays open all the time so that - # the spooler does not assume that the job has finished when the - # renderer is re-started. - - # Non DSC-conforming documents will be read until a certain line - # number is reached. Command line or JCL options inserted later - # will be ignored. - - # If options are implemented by PostScript code supposed to be - # stuffed into the job's PostScript data we stuff the code for all - # these options into our job data, So all default settings made in - # the PPD file (the user can have edited the PPD file to change - # them) are taken care of and command line options get also - # applied. To give priority to settings made by applications we - # insert the options's code in the beginnings of their respective - # sections, so that sommething, which is already inserted, gets - # executed after our code. Missing sections are automatically - # created. In non-DSC-conforming files we insert the option code - # in the beginning of the file. This is the same policy as used by - # the "pstops" filter of CUPS. - - # If CUPS is the spooler, the option settings were already - # inserted by the "pstops" filter, so we don't insert them - # again. The only thing we do is correcting settings of numerical - # options when they were set to a value not available as choice in - # the PPD file, As "pstops" does not support "real" numerical - # options, it sees these settings as an invalid choice and stays - # with the default setting. In this case we correct the setting in - # the first occurence of the option's code, as this one is the one - # added by CUPS, later occurences come from applications and - # should not be touched. - - # If the input is not PostScript (if there is no "%!" after - # $maxlinestopsstart lines) a file conversion filter will - # automatically be applied to the incoming data, so that we will - # process the resulting PostScript here. This way we have always - # PostScript data here and so we can apply the printer/driver - # features described in the PPD file. - - # Supported file conversion filters are "a2ps", "enscript", - # "mpage", and spooler-specific filters. All filters convert - # plain text to PostScript, "a2ps" also other formats. The - # conversion filter is always used when one prints the - # documentation pages, as they are created as plain text, - # when CUPS is the spooler "pstops" is executed after the - # filter so that the default option settings from the PPD file - # and CUPS-specific options as N-up get applied. On regular - # printouts one gets always PostScript when CUPS or PPR is - # the spooler, so the filter is only used for regular - # printouts under LPD, LPRng, GNUlpr or without spooler. - - my $maxlines = 1000; # Maximum number of lines to be read - # when the documenent is not - # DSC-conforming. "$maxlines = 0" - # means that all will be read - # and examined. If it is - # discovered that the input file - # is DSC-conforming, this will - # be set to 0. - - my $maxlinestopsstart = 200; # That many lines are allowed until the - # "%!" indicating PS comes. These - # additional lines in the - # beginning are usually JCL - # commands. The lines will be - # ignored by our parsing but - # passed through. - - my $maxlinesforpageoptions=200; # Unfortunately, CUPS does not bracket - # "PageSetup" option with - # "%%BeginPageSetup" and - # "%%EndPageSetup", so the options - # can simply stand after the - # page header and before the - # page code, without special - # marking. So buffer this amount - # of lines before printing the - # page to check for options. - - my $maxnondsclinesinheader=1000; # If there is a block of more lines - # than this in the document - # header which is not in the - # "%%BeginProlog...%%EndProlog" - # or - # "%%BeginSetup...%%EndSetup" - # sections, the document is not - # considered as DSC-conforming - # and the rest gets passed - # through to the renderer without - # further parsing for options. - - my $nondsclines = 0; # Amount of lines found which are not in - # a section (see - # $maxnondsclinesinheader). - - my $nonpslines = 0; # lines before "%!" found yet. - - my $more_stuff = 1; # there is more stuff in stdin. - - my $linect = 0; # how many lines have we examined? - - my $onelinebefore = ""; # The line before the current line - # (Non-DSC comments are ignored) - - my $twolinesbefore = ""; # The line two lines before the current - # line (Non-DSC comments are ignored) - - my $linesafterlastbeginfeature = ""; # All code lines after the last - # "%%BeginFeature:" - - my @psheader = (); # The header of the PostScript file, - # to be sent after each start of the - # renderer - - my @psfifo = (); # The input FIFO, data which we have - # pulled from stdin for examination, - # but not sent to the renderer yet. - - my $passthru = 0; # 0: write data into @psfifo; 1: pass - # data directly to the renderer - - my $isdscjob = 0; # Is the job DSC conforming - - my $inheader = 1; # Are we still in the header, before - # first "%%Page:" comment? - - my $optionset = 'header'; # Where do the option settings, which - # we have found, go? - - my $optionsalsointoheader = 0; # 1: We are in a "%%BeginSetup... - # %%EndSetup" section after the first - # "%%Page:..." line (OpenOffice.org - # does this and intends the options here - # apply to the whole document and not - # only to the current page). We have to - # add all lines also to the end of the - # @psheader now and we have to set - # non-PostScript options also in the - # "header" optionset. 0: otherwise. - - my $nestinglevel = 0; # Are we in the main document (0) or - # in an embedded document bracketed by - # "%%BeginDocument" and "%%EndDocument" - # (>0) We do not parse the PostScript - # in an embedded document. - - my $inpageheader = 0; # Are we in the header of a page, - # between "%%BeginPageSetup" and - # "%%EndPageSetup" (1) or not (0). - - my $lastpassthru = 0; # State of $passthru in previous line - # (to allow debug output when $passthru - # switches. - - my $ignorepageheader = 0; # Will be set to 1 as soon as active - # code (not between "%%BeginPageSetup" - # and "%%EndPageSetup") appears after a - # "%%Page:" comment. In this case - # "%%BeginPageSetup" and - # "%%EndPageSetup" is not allowed any - # more on this page and will be ignored. - # Will be set to 0 when a new "%%Page:" - # comment appears. - - my $printprevpage = 0; # We set this when encountering - # "%%Page:" and the previous page is not - # printed yet. Then it will be printed and - # the new page will be prepared in the - # next run of the loop (we don't read a - # new line and don't increase the - # $linect then). - - $fileconverterhandle = undef; # File handle to the fileconverter process - - $fileconverterpid = 0; # PID of the fileconverter process - - $rendererhandle = undef; # File handle to the renderer process - - $rendererpid = 0; # PID of the renderer process - - my $prologfound = 0; # Did we find the - # "%%BeginProlog...%%EndProlog" section? - - my $setupfound = 0; # Did we find the - # "%%BeginSetup...%%EndSetup" section? - - my $pagesetupfound = 0; # special page setup handling needed - - my $inprolog = 0; # We are between "%%BeginProlog" and - # "%%EndProlog". - - my $insetup = 0; # We are between "%%BeginSetup" and - # "%%EndSetup". - - my $infeature = 0; # We are between "%%BeginFeature" and - # "%%EndFeature". - - my $postscriptsection = 'jclsetup'; # In which section of the PostScript - # file are we currently? - - $nondsclines = 0; # Number of subsequent lines found which - # are at a non-DSC-conforming place, - # between the sections of the header. - - my $optionreplaced = 0; # Will be set to 1 when we are in an - # option ("%%BeginFeature... - # %%EndFeature") which we have replaced. - - $jobhasjcl = 0; # When the job does not start with - # PostScript directly, but is a - # PostScript job, we set this to 1 - # to avoid adding the JCL options - # for the second time. - - my $insertoptions = 1; # If we find out that a file with - # a DSC magic string - # ("%!PS-Adobe-") is not really - # DSC-conforming, we insert the - # options directly after the line - # with the magic string. We use - # this variable to store the - # number of the line with the - # magic string. - - my $currentpage = 0; # The page which we are currently - # printing. - - my $ooo110 = 0; # Flag to work around an application - # bug. - - my $saved = 0; # DSC line not processed yet - - if ($dontparse) { - # We do not parse the PostScript to find Foomatic options, we check - # only whether we have PostScript. - $maxlines = 1; - } - - print $logh "Reading PostScript input ...\n"; - - my $line; # Line to be read from stdin - do { - my $ignoreline = 0; # Comment line to be ignored when - # determining the last active line - # and the one before the last - - if (($printprevpage) || ($saved) || ($line=<STDIN>)) { - $saved = 0; - - if ($linect == $nonpslines) { - # In the beginning should be the postscript leader, - # sometimes after some JCL commands - if ($line !~ m/^.?%!/) { # There can be a Windows control - # character before "%!" - $nonpslines ++; - if ($maxlines == $nonpslines) { - $maxlines ++; - } - $jobhasjcl = 1; - if ($nonpslines > $maxlinestopsstart) { - # This is not a PostScript job, we must convert it - print $logh "${added_lf}Job does not start with \"%!\", " . - "is it PostScript?\n" . - "Starting file converter\n"; - # Reset all variables but conserve the data which - # we have already read. - $jobhasjcl = 0; - $linect = 0; - $nonpslines = 1; # Take into account that the line - # of this run of the loop will be - # put into @psheader, so the - # first line read by the file - # converter is already the second - # line. - $maxlines = 1001; - $onelinebefore = ""; - $twolinesbefore = ""; - my $alreadyread = join('', @psheader, @psfifo) . - $line; - $line = ""; - @psheader = (); - @psfifo = (); - # Start the file conversion filter - if (!$fileconverterpid) { - ($fileconverterhandle, $fileconverterpid) = - getfileconverterhandle - ($dat, $alreadyread); - if ($retval != $EXIT_PRINTED) { - rip_die ("Error opening file converter", - $retval); - } - } else { - rip_die("File conversion filter probably " . - "crashed", - $EXIT_JOBERR); - } - # Read the further data from the file converter and - # not from STDIN - if (!close STDIN && $! != $ESPIPE) { - rip_die ("Couldn't close STDIN", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - if (!open (STDIN, "<&$fileconverterhandle")) { - rip_die ("Couldn't dup \$fileconverterhandle", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - } - } else { - # Do we have a DSC-conforming document? - if ($line =~ m/^.?%!PS-Adobe-/) { - # Do not stop parsing the document - if (!$dontparse) { - $maxlines = 0; - $isdscjob = 1; - $insertoptions = $linect + 1; - # We have written into @psfifo before, - # now we continue in @psheader and move - # over the data which is already in @psfifo - push (@psheader, @psfifo); - @psfifo = (); - } - print $logh - "--> This document is DSC-conforming!\n"; - } else { - # Job is not DSC-conforming, stick in all PostScript - # option settings in the beginning - $line .= makeprologsection($dat, $optionset, 1); - $line .= makesetupsection($dat, $optionset, 1); - $line .= makepagesetupsection($dat, $optionset, 1); - $prologfound = 1; - $setupfound = 1; - $pagesetupfound = 1; - } - } - } else { - if ($line =~ /^\%\%/) { - if ($line =~ m/^\s*\%\%BeginDocument[: ]/) { - # Beginning of an embedded document - # Note that Adobe Acrobat has a bug and so uses - # "%%BeginDocument " instead of "%%BeginDocument:" - $nestinglevel ++; - print $logh "Embedded document, " . - "nesting level now: $nestinglevel\n"; - } elsif (($line =~ m/^\s*\%\%EndDocument/) && - ($nestinglevel > 0)) { - # End of an embedded document - $nestinglevel --; - print $logh "End of Embedded document, " . - "nesting level now: $nestinglevel\n"; - } elsif (($line =~ m/^\s*\%\%Creator[: ](.*)$/) && - ($nestinglevel == 0)) { - # Here we set flags to treat particular bugs of the - # PostScript produced by certain applications - my $creator = $1; - if ($creator =~ /^\s*OpenOffice.org\s+1.1.\d+\s*$/) { - # OpenOffice.org 1.1.x - # The option settings supposed to affect the - # whole document are put into the "%%PageSetup" - # section of the first page - print $logh "Document created with " . - "OpenOffice.org 1.1.x\n"; - $ooo110 = 1; - } - } elsif (($line =~ m/^\%\%BeginProlog/) && - ($nestinglevel == 0)) { - # Note: Below is another place where a "Prolog" - # section start will be considered. There we assume - # start of the "Prolog" if the job is DSC-Conformimg, - # but an arbitrary comment starting with "%%Begin", but - # not a comment explicitly treated here, is found. This - # is done because many "dvips" (TeX/LaTeX) files miss - # the "%%BeginProlog" comment. - # Beginning of Prolog - print $logh "${added_lf}-----------\nFound: \%\%BeginProlog\n"; - $inprolog = 1; - $postscriptsection = 'prolog' if $inheader; - $nondsclines = 0; - # Insert options for "Prolog" - if (!$prologfound) { - $line .= makeprologsection($dat, $optionset, 0); - } - $prologfound = 1; - } elsif (($line =~ m/^\%\%EndProlog/) && - ($nestinglevel == 0)) { - # End of Prolog - print $logh "Found: \%\%EndProlog\n"; - $inprolog = 0; - $insertoptions = $linect + 1; - } elsif (($line =~ m/^\%\%BeginSetup/) && - ($nestinglevel == 0)) { - # Beginning of Setup - print $logh "${added_lf}-----------\nFound: \%\%BeginSetup\n"; - $insetup = 1; - # We need to distinguish with the $inheader variable - # here whether we are in the header or on a page, as - # OpenOffice.org inserts a "%%BeginSetup...%%EndSetup" - # section after the first "%%Page:..." line and assumes - # this section to be valid for all pages. - $postscriptsection = 'setup' if $inheader; - $nondsclines = 0; - if ($inheader) { - # If there was no "Prolog" but there are - # options for the "Prolog", push a "Prolog" - # with these options onto the @psfifo here - if (!$prologfound) { - # "Prolog" missing, insert it here - $line = - makeprologsection($dat, $optionset, 1) . - $line; - # Now we have a "Prolog" - $prologfound = 1; - } - # Insert options for "DocumentSetup" or "AnySetup" - if ($spooler ne 'cups') { - # For non-CUPS spoolers or no spooler at all, - # we leave everything as it is. - if (!$setupfound) { - $line .= - makesetupsection($dat, $optionset, 0); - } - $setupfound = 1; - } - } else { - # Found option settings must be stuffed into both - # the header and the currrent page now. They will - # be written into both the "header" and the - # "currentpage" optionsets and the PostScript code - # lines of this section will not only go into the - # output stream, but also added to the end of the - # @psheader, so that they get repeated (to preserve - # the embedded PostScript option settings) on a - # restart of the renderer due to command line - # option changes - $optionsalsointoheader = 1; - print $logh "\"%%BeginSetup\" in page header\n"; - } - } elsif (($line =~ m/^\%\%EndSetup/) && - ($nestinglevel == 0)) { - # End of Setup - print $logh "Found: \%\%EndSetup\n"; - $insetup = 0; - if ($inheader) { - if ($spooler eq 'cups') { - # In case of CUPS, we must insert the - # accounting stuff just before the - # %%EndSetup comment in order to leave any - # EndPage procedures that have been - # defined by either the pstops filter or - # the PostScript job itself fully - # functional. - if (!$setupfound) { - $line = makesetupsection($dat, - $optionset, 0) . - $line; - } - $setupfound = 1; - } - $insertoptions = $linect + 1; - } else { - # The "%%BeginSetup...%%EndSetup" which - # OpenOffice.org has inserted after the first - # "%%Page:..." line ends here, so the following - # options go only onto the current page again - $optionsalsointoheader = 0; - } - } elsif (($line =~ m/^\%\%Page:(.*)$/) && - ($nestinglevel == 0)) { - if ((!$lastpassthru) && (!$inheader)) { - # In the last line we were not in passthru mode, - # so the last page is not printed. Prepare to do - # it now. - $printprevpage = 1; - # Print the previous page - $passthru = 1; - print $logh "New page found but previous not " . - "printed, print it now.\n"; - } else { - # The previous page is printed, so we can prepare - # the current one - $printprevpage = 0; - print $logh "${added_lf}-----------\nNew page: $1\n"; - # Count pages - $currentpage ++; - # We consider the beginning of the page already as - # page setup section, as some apps do not use - # "%%PageSetup" tags. - $postscriptsection = 'pagesetup'; - # Save PostScript state before beginning the page - #$line .= "/foomatic-saved-state save def\n"; - # Here begins a new page - if ($inheader) { - # Here we add some stuff which still belongs - # into the header - my $stillforheader; - # If there was no "Setup" but there are - # options for the "Setup", push a "Setup" - # with these options onto the @psfifo here - if (!$setupfound) { - # "Setup" missing, insert it here - $stillforheader = - makesetupsection($dat, $optionset, 1) . - $stillforheader; - # Now we have a "Setup" - $setupfound = 1; - } - # If there was no "Prolog" but there are - # options for the "Prolog", push a "Prolog" - # with these options onto the @psfifo here - if (!$prologfound) { - # "Prolog" missing, insert it here - $stillforheader = - makeprologsection($dat, $optionset, - 1) . - $stillforheader; - # Now we have a "Prolog" - $prologfound = 1; - } - # Now we push this onto the header - push (@psheader, $stillforheader); - # The first page starts, so the header ends - $inheader = 0; - $nondsclines = 0; - # Option setting should go into the - # page-specific option set now - $optionset = 'currentpage'; - } else { - # Restore PostScript state after completing the - # previous page: - # - # foomatic-saved-state restore - # %%Page: ... - # /foomatic-saved-state save def - # - # Print this directly, so that if we need to - # restart the renderer for this page due to - # a command line change this is done under the - # old instance of the renderer - #print $rendererhandle - # "foomatic-saved-state restore\n"; - - # Save the option settings of the previous page - copyoptions($dat, 'currentpage', - 'previouspage'); - deleteoptions($dat, 'currentpage'); - } - # Initialize the option set - copyoptions($dat, 'header', 'currentpage'); - # Set command line options which apply only - # given pages - setoptionsforpage($dat, 'currentpage', $currentpage); - $pagesetupfound = 0; - if ($spooler eq 'cups') { - # Remove the "notfirst" flag from all options - # forseen for the "PageSetup" section, because - # when these are numerical options for CUPS. - # they have to be set to the correct value - # for every page - for my $arg (@{$dat->{'args'}}) { - if (($arg->{'section'} eq 'PageSetup') && - (defined($arg->{'notfirst'}))) { - delete($arg->{'notfirst'}); - } - } - } - # Insert PostScript option settings - # (options for section "PageSetup". - if ($isdscjob) { - $line .= - makepagesetupsection($dat, $optionset, - 0); - $pagesetupfound = 1; - } - # Now the page header comes, so buffer the data, - # because we must perhaps shut down and restart - # the renderer - $passthru = 0; - $ignorepageheader = 0; - $optionsalsointoheader = 0; - } - } elsif (($line =~ m/^\%\%BeginPageSetup/) && - ($nestinglevel == 0) && - (!$ignorepageheader)) { - # Start of the page header, up to %%EndPageSetup - # nothing of the page will be drawn, page-specific - # option settngs (as letter-head paper for page 1) - # go here - print $logh "${added_lf}Found: \%\%BeginPageSetup\n"; - $passthru = 0; - $inpageheader = 1; - $postscriptsection = 'pagesetup'; - if (($ooo110) && ($currentpage == 1)) { - $optionsalsointoheader = 1; - } else { - $optionsalsointoheader = 0; - } - } elsif (($line =~ m/^\%\%EndPageSetup/) && - ($nestinglevel == 0) && - (!$ignorepageheader)) { - # End of the page header, the page is ready to be - # printed - print $logh "Found: \%\%EndPageSetup\n"; - print $logh "End of page header\n"; - # We cannot for sure say that the page header ends here - # OpenOffice.org puts (due to a bug) a "%%BeginSetup... - # %%EndSetup" section after the first "%%Page:...". It - # is possible that CUPS inserts a "%%BeginPageSetup... - # %%EndPageSetup" before this section, which means that - # the options in the "%%BeginSetup...%%EndSetup" - # section are after the "%%EndPageSetup", so we - # continue for searching options up to the buffer size - # limit $maxlinesforpageoptions. - $passthru = 0; - $inpageheader = 0; - $optionsalsointoheader = 0; - } elsif ((($line =~ m/^\%\%(BeginFeature):\s*\*?([^\*\s=]+)\s+()(\S[^\r\n]*)\r?\n?$/) || - ($line =~ m/^\s*\%\%\s*(FoomaticRIPOptionSetting):\s*([^\*\s=]+)\s*=\s*(\@?)([^\@\s][^\r\n]*)\r?\n?$/)) && - ($nestinglevel == 0) && - (!$optionreplaced) && - ((!$passthru) || (!$isdscjob))) { - my ($linetype, $option, $fromcomposite, $value) = - ($1, $2, $3, $4); - - # Mark that we are in a "Feature" section - if ($linetype eq 'BeginFeature') { - $infeature = 1; - $linesafterlastbeginfeature = ""; - } - - # OK, we have an option. If it's not a - # *ostscript-style option (ie, it's command-line or - # JCL) then we should note that fact, since the - # attribute-to-filter option passing in CUPS is kind of - # funky, especially wrt boolean options. - - print $logh "Found: $line"; - if (my $arg=argbyname($option)) { - print $logh " Option: $option=" . - ($fromcomposite ? "From" : "") . $value; - if (($spooler eq 'cups') && - ($linetype eq 'BeginFeature') && - (!defined($arg->{'notfirst'})) && - ($arg->{$optionset} ne $value) && - (($inheader) || - ($arg->{section} eq 'PageSetup'))) { - - # We have the first occurence of an option - # setting and the spooler is CUPS, so this - # setting is inserted by "pstops" or - # "imagetops". The value from the command - # line was not inserted by "pstops" or - # "imagetops" so it seems to be not under - # the choices in the PPD. Possible - # reasons: - # - # - "pstops" and "imagetops" ignore settings - # of numerical or string options which are - # not one of the choices in the PPD file, - # and inserts the default value instead. - # - # - On the command line an option was applied - # only to selected pages: - # "-o <page ranges>:<option>=<values> - # This is not supported by CUPS, so not - # taken care of by "pstops". - # - # We must fix this here by replacing the - # setting inserted by "pstops" or "imagetops" - # with the exact setting given on the command - # line. - - # $arg->{$optionset} is already - # range-checked, so do not check again here - # Insert DSC comment - my $dest = ((($inheader) && ($isdscjob)) ? - \@psheader : \@psfifo); - my $val; - if ($arg->{'style'} eq 'G') { - # PostScript option, insert the code - if ($arg->{'type'} eq 'bool') { - # Boolean option - push(@{$dest}, - "%%BeginFeature: *$option " . - ($arg->{$optionset} == 1 ? - "True" : "False") . "\n"); - if (defined($arg->{$optionset}) && - $arg->{$optionset} == 1) { - push(@{$dest}, $arg->{'proto'} . - "\n"); - } elsif ($arg->{'protof'}) { - push(@{$dest}, $arg->{'protof'} . - "\n"); - } - } elsif ((($arg->{'type'} eq 'enum') || - ($arg->{'type'} eq 'string') || - ($arg->{'type'} eq - 'password')) && - (defined($val = - $arg->{'vals_byname'}{$arg->{$optionset}}))) { - # Enumerated choice of string or enum - # option - push(@{$dest}, - "%%BeginFeature: " . - "*$option $arg->{$optionset}\n"); - push(@{$dest}, $val->{'driverval'} . "\n"); - } elsif ((($arg->{'type'} eq 'string') || - ($arg->{'type'} eq - 'password')) && - ($arg->{$optionset} eq 'None')) { - # 'None' is mapped to the empty string - # in string options - push(@{$dest}, - "%%BeginFeature: " . - "*$option $arg->{$optionset}\n"); - my $driverval = $arg->{'proto'}; - $driverval =~ s/\%s//g; - push(@{$dest}, $driverval . "\n"); - } else { - # Setting for numerical or string - # option which is not under the - # enumerated choices - push(@{$dest}, - "%%BeginFeature: " . - "*$option $arg->{$optionset}\n"); - my $sprintfproto = $arg->{'proto'}; - $sprintfproto =~ s/\%(?!s)/\%\%/g; - push(@{$dest}, - sprintf($sprintfproto, - $arg->{$optionset}) . - "\n"); - } - } else { - # Command line or JCL option - push(@{$dest}, - "%% FoomaticRIPOptionSetting: " . - "$option=$arg->{$optionset}\n"); - } - print $logh " --> Correcting numerical/string " . - "option to $option=$arg->{$optionset}" . - " (Command line argument)\n"; - # We have replaced this option on the - # FIFO - $optionreplaced = 1; - } - # Mark that we have already found this option - $arg->{'notfirst'} = 1; - if (!$optionreplaced) { - if ($arg->{'style'} ne 'G') { - # "Controlled by '<Composite>'" setting of - # a member option of a composite option - if ($fromcomposite) { - $value = "From$value"; - } - # Non-PostScript option - # Check whether it is valid - if (defined(my $newvalue = - checkoptionvalue($dat, $option, - $value, 0))) { - print $logh " --> Setting option\n"; - # Valid choice, set it. - $arg->{$optionset} = $newvalue; - if ($optionsalsointoheader) { - $arg->{'header'} = $newvalue; - } - if (($arg->{'type'} eq 'enum') && - (($option eq 'PageSize') || - ($option eq 'PageRegion')) && - ($newvalue =~ /^Custom/) && - ($linetype eq - 'FoomaticRIPOptionSetting')) { - # Custom page size - $linesafterlastbeginfeature =~ - /^[\s\r\n]*([\d\.]+)[\s\r\n]+([\d\.]+)[\s\r\n]+/s; - my ($w, $h) = ($1, $2); - if (($w) && ($h) && - ($w != 0) && ($h != 0)) { - $newvalue = - "$newvalue.${w}x$h"; - $arg->{$optionset} = $newvalue; - if ($optionsalsointoheader) { - $arg->{'header'} = - $newvalue; - } - } - } - # For a composite option insert the - # code from the member options with - # current setting "From<composite>" - # The code from the member options - # is chosen according to the setting - # of the composite option. - if (($arg->{'style'} eq 'X') && - ($linetype eq - 'FoomaticRIPOptionSetting')) { - buildcommandline($dat, $optionset); - $line .= - $arg->{$postscriptsection}; - } - # If this argument is PageSize or - # PageRegion, also set the other - syncpagesize($dat, $option, $newvalue, - $optionset); - if ($optionsalsointoheader) { - syncpagesize($dat, $option, - $newvalue, 'header'); - } - } else { - # Invalid option, log it. - print $logh " --> Invalid option " . - "setting found in job\n"; - } - } elsif ($fromcomposite) { - # PostScript option, but we have to look up - # the PostScript code to be inserted from - # the setting of a composite option, as - # this option is set to "Controlled by - # '<Composite>'". - # Set the option - if (defined(my $newvalue = - checkoptionvalue - ($dat, $option, - "From$value", 0))) { - print $logh " --> Looking up setting " . - "in composite option '$value'\n"; - # Valid choice, set it. - $arg->{$optionset} = $newvalue; - if ($optionsalsointoheader) { - $arg->{'header'} = $newvalue; - } - # Update composite options - buildcommandline($dat, $optionset); - # Substitute PostScript comment by - # the real code - $line = $arg->{'compositesubst'}; - } else { - # Invalid option, log it. - print $logh " --> Invalid option " . - "setting found in job\n"; - } - } else { - # it is a PostScript style option with - # the code readily inserted, no option - # for the renderer command line/JCL to set, - # no lookup of a composite option needed, - # so nothing to do here... - print $logh - " --> Option will be set by " . - "PostScript interpreter\n"; - } - } - } else { - # This option is unknown to us. WTF? - print $logh "Unknown option $option=$value found " . - "in the job\n"; - } - } elsif (($line =~ m/^\%\%EndFeature/) && - ($nestinglevel == 0)) { - # End of Feature - $infeature = 0; - # If the option setting was replaced, it ends here, - # too, and the next option is not necessarily also - # replaced. - $optionreplaced = 0; - $linesafterlastbeginfeature = ""; - } elsif (($line =~ m/^\%\%Begin/) && - ($isdscjob) && - (!$prologfound) && - ($nestinglevel == 0)) { - # In some PostScript files (especially when generated - # by "dvips" of TeX/LaTeX) the "%%BeginProlog" is - # missing, so assume that it was before the current - # line (the first line starting with "%%Begin". - print $logh "Job claims to be DSC-conforming, but " . - "\"%%BeginProlog\" was missing before first " . - "line with another \"%%Begin...\" comment " . - "(is this a TeX/LaTeX/dvips-generated PostScript " . - "file?). Assuming start of \"Prolog\" here.\n"; - # Beginning of Prolog - $inprolog = 1; - $nondsclines = 0; - # Insert options for "Prolog" before the current line - if (!$prologfound) { - $line = - "%%BeginProlog\n" . - makeprologsection($dat, $optionset, 0) . - $line; - } - $prologfound = 1; - } elsif (($line =~ m/^\s*\%/) || ($line =~ m/^\s*$/)) { - # This is an unknown PostScript comment or a blank - # line, no active code - $ignoreline = 1; - } - } else { - # This line is active PostScript code - if ($infeature) { - # Collect coe in a "%%BeginFeature: ... %%EndFeature" - # section, to get the values for a custom option - # setting - $linesafterlastbeginfeature .= $line; - } - if ($inheader) { - if ((!$inprolog) && (!$insetup)) { - # Outside the "Prolog" and "Setup" section - # a correct DSC-conforming document has no - # active PostScript code, so consider the - # file as non-DSC-conforming when there are - # too many of such lines. - $nondsclines ++; - if ($nondsclines > $maxnondsclinesinheader) { - # Consider document as not DSC-conforming - print $logh "This job seems not to be " . - "DSC-conforming, DSC-comment for " . - "next section not found, stopping " . - "to parse the rest, passing it " . - "directly to the renderer.\n"; - # Stop scanning for further option settings - $maxlines = 1; - $isdscjob = 0; - # Insert defaults and command line settings - # in the beginning of the job or after the - # last valid section - splice(@psheader, $insertoptions, 0, - ($prologfound ? () : - makeprologsection($dat, $optionset, - 1)), - ($setupfound ? () : - makesetupsection($dat, $optionset, - 1)), - ($pagesetupfound ? () : - makepagesetupsection($dat, - $optionset, - 1))); - $prologfound = 1; - $setupfound = 1; - $pagesetupfound = 1; - } - } - } else { - if (!$inpageheader) { - # PostScript code inside a page, but not between - # "%%BeginPageSetup" and "%%EndPageSetup", so - # we are perhaps already drawing onto a page now - if ($onelinebefore =~ m/^\%\%Page:/) { - print $logh "No page header or page " . - "header not DSC-conforming\n"; - } - # Stop buffering lines to search for options - # placed not DSC-conforming - if (scalar(@psfifo) >= - $maxlinesforpageoptions) { - print $logh "Stopping search for " . - "page header options\n"; - $passthru = 1; - # If there comes a page header now, ignore - # it - $ignorepageheader = 1; - $optionsalsointoheader = 0; - } - } - } - } - } - - # Debug info - if ($lastpassthru != $passthru) { - if ($passthru) { - print $logh "Found: $line" . - " --> Output goes directly to the renderer now.\n${added_lf}"; - } else { - print $logh "Found: $line" . - " --> Output goes to the FIFO buffer now.${added_lf}\n"; - } - } - - # We are in an option which was replaced, do not output - # the current line. - if ($optionreplaced) { - $line = ""; - } - - # If we are in a "%%BeginSetup...%%EndSetup" section after - # the first "%%Page:..." and the current line belongs to - # an option setting, we have to copy the line also to the - # @psheader. - if (($optionsalsointoheader) && - (($infeature) || ($line =~ m/^\%\%EndFeature/))) { - push (@psheader, $line); - } - - # Store or send the current line - if (($inheader) && ($isdscjob)) { - # We are still in the PostScript header, collect all lines - # in @psheader - push (@psheader, $line); - } else { - if (($passthru) && ($isdscjob)) { - if (!$lastpassthru) { - # We enter passthru mode with this line, so the - # command line can have changed, check it and - # close the renderer if needed - if (($rendererpid) && - (!optionsequal($dat, 'currentpage', - 'previouspage', 0))) { - print $logh "Command line/JCL options " . - "changed, restarting renderer\n"; - $retval = closerendererhandle - ($rendererhandle, $rendererpid); - if ($retval != $EXIT_PRINTED) { - rip_die ("Error closing renderer", - $retval); - } - $rendererpid = 0; - } - } - # Flush @psfifo and send line directly to the renderer - if (!$rendererpid) { - # No renderer running, start it - ($rendererhandle, $rendererpid) = - getrendererhandle - ($dat, join('', @psheader, @psfifo)); - if ($retval != $EXIT_PRINTED) { - rip_die ("Error opening renderer", - $retval); - } - # @psfifo is sent out, flush it. - @psfifo = (); - } - if ($#psfifo >= 0) { - # Send @psfifo to renderer - print $rendererhandle join('', @psfifo); - # flush @psfifo - @psfifo = (); - } - # Send line to renderer - if (!$printprevpage) { - print $rendererhandle $line; - - while ($line=<STDIN>) - { - if ($line =~ /^\%\%[A-Za-z\s]{3,}/) { - print $logh "Found: $line" . - " --> Continue DSC parsing now.${added_lf}\n"; - $saved = 1; - last; - } else { - print $rendererhandle $line; - $linect++; - } - } - } - } else { - # Push the line onto the stack for later spitting up... - push (@psfifo, $line); - } - } - - if (!$printprevpage) { - $linect++; - } - - } else { - # EOF! - $more_stuff = 0; - # No PostScript header in the whole file? Then it's not - # PostScript, convert it. - # We open the file converter here when the file has less - # lines than the amount which we search for the PostScript - # header ($maxlinestopsstart). - if ($linect <= $nonpslines) { - # This is not a PostScript job, we must convert it - print $logh "${added_lf}Job does not start with \"%!\", " . - "is it PostScript?\n" . - "Starting file converter\n"; - # Reset all variables but conserve the data which - # we have already read. - $jobhasjcl = 0; - $linect = 0; - $nonpslines = 0; - $maxlines = 1000; - $onelinebefore = ""; - $twolinesbefore = ""; - my $alreadyread = join('', @psheader, @psfifo); - @psheader = (); - @psfifo = (); - $line = ""; - # Start the file conversion filter - if (!$fileconverterpid) { - ($fileconverterhandle, $fileconverterpid) = - getfileconverterhandle($dat, $alreadyread); - if ( defined($retval) and $retval != $EXIT_PRINTED) { - rip_die ("Error opening file converter", - $retval); - } - } else { - rip_die("File conversion filter probably " . - "crashed", - $EXIT_JOBERR); - } - # Read the further data from the file converter and - # not from STDIN - if (!close STDIN && $! != $ESPIPE) { - rip_die ("Couldn't close STDIN", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - if (!open (STDIN, "<&$fileconverterhandle")) { - rip_die ("Couldn't dup \$fileconverterhandle", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - # Now we have new (converted) stuff in STDIN, so - # continue in the loop - $more_stuff = 1; - } - } - - $lastpassthru = $passthru; - - if ((!$ignoreline) && (!$printprevpage)) { - $twolinesbefore = $onelinebefore; - $onelinebefore = $line; - } - - } while ((($maxlines == 0) or ($linect < $maxlines)) and - ($more_stuff != 0)); - - # Some buffer still containing data? Send it out to the renderer. - if (($more_stuff != 0) || ($inheader) || ($#psfifo >= 0)) { - # Flush @psfifo and send the remaining data to the renderer, this - # only happens with non-DSC-conforming jobs or non-Foomatic PPDs - if ($more_stuff) { - print $logh "Stopped parsing the PostScript data, ". - "sending rest directly to renderer.\n"; - } else { - print $logh "Flushing FIFO.\n"; - } - if ($inheader) { - # No page initialized yet? Copy the "header" option set into the - # "currentpage" option set, so that the renderer will find the - # options settings. - copyoptions($dat, 'header', 'currentpage'); - $optionset = 'currentpage'; - # If not done yet, insert defaults and command line settings - # in the beginning of the job or after the last valid section - splice(@psheader, $insertoptions, 0, - ($prologfound ? () : - makeprologsection($dat, $optionset, 1)), - ($setupfound ? () : - makesetupsection($dat, $optionset, 1)), - ($pagesetupfound ? () : - makepagesetupsection($dat, $optionset, 1))); - $prologfound = 1; - $setupfound = 1; - $pagesetupfound = 1; - } - if (($rendererpid) && - (!optionsequal($dat, 'currentpage', - 'previouspage', 0))) { - print $logh "Command line/JCL options " . - "changed, restarting renderer\n"; - $retval = closerendererhandle - ($rendererhandle, $rendererpid); - if ($retval != $EXIT_PRINTED) { - rip_die ("Error closing renderer", - $retval); - } - $rendererpid = 0; - } - if (!$rendererpid) { - ($rendererhandle, $rendererpid) = - getrendererhandle($dat, join('', @psheader, @psfifo)); - if ($retval != $EXIT_PRINTED) { - rip_die ("Error opening renderer", - $retval); - } - # We have sent @psfifo now - @psfifo = (); - } - if ($#psfifo >= 0) { - # Send @psfifo to renderer - print $rendererhandle join('', @psfifo); - # flush @psfifo - @psfifo = (); - } - # Print the rest of the input data - if ($more_stuff) { - while (<STDIN>) { - print $rendererhandle $_; - } - } - } - - # At every "%%Page:..." comment we have saved the PostScript state - # and we have increased the page number. So if the page number is - # non-zero we had at least one "%%Page:..." comment and so we have - # to give a restore the PostScript state. - #if ($currentpage > 0) { - # print $rendererhandle "foomatic-saved-state restore\n"; - #} - - # Close the renderer - if ($rendererpid) { - $retval = closerendererhandle ($rendererhandle, $rendererpid); - if ($retval != $EXIT_PRINTED) { - rip_die ("Error closing renderer", - $retval); - } - $rendererpid = 0; - } - - # Close the file converter (if it was used) - if ($fileconverterpid) { - $retval = closefileconverterhandle - ($fileconverterhandle, $fileconverterpid); - if ($retval != $EXIT_PRINTED) { - rip_die ("Error closing file converter", - $retval); - } - $fileconverterpid = 0; - } -} - - -## Close the documentation page generator -if ($docgeneratorpid) { - $retval = closedocgeneratorhandle - ($docgeneratorhandle, $docgeneratorpid); - if ($retval != $EXIT_PRINTED) { - rip_die ("Error closing documentation page generator", - $retval); - } - $docgeneratorpid = 0; -} - - - -## Close last input file -close STDIN; - - - -## Only for debugging -if ($debug && 1) { - use Data::Dumper; - local $Data::Dumper::Purity=1; - local $Data::Dumper::Indent=1; - print $logh Dumper($dat); -} - - - -## The End -print $logh "${added_lf}Closing foomatic-rip.\n"; -close $logh; - -exit $retval; - - - -## Functions to let foomatic-rip fork to do several tasks in parallel. - -# To do the filtering without loading the whole file into memory we work -# on a data stream, we read the data line by line analyse it to decide what -# filters to use and start the filters if we have found out which we need. -# We buffer the data only as long as we didn't determing which filters to -# use for this piece of data and with which options. There are no temporary -# files used. - -# foomatic-rip splits into up to 6 parallel processes to do the whole -# filtering (listed in the order of the data flow): - -# KID0: Generate documentation pages (only jobs with "docs" option) -# KID2: Put together already read data and current input stream for -# feeding into the file conversion filter (only non-PostScript -# and "docs" jobs) -# KID1: Run the file conversion filter to convert non-PostScript -# input into PostScript (only non-PostScript and "docs" jobs) -# MAIN: Prepare the job auto-detecting the spooler, reading the PPD, -# extracting the options from the command line, and parsing -# the job data itself. It analyses the job data to check -# whether it is PostScript and starts KID1/KID2 if not, it -# also stuffs PostScript code from option settings into the -# PostScript data stream. It starts the renderer (KID3/KID4) -# as soon as it knows its command line and restarts it when -# page-specific option settings need another command line -# or different JCL commands. -# KID3: The rendering process. In most cases GhostScript, "cat" -# for native PostScript printers with their manufacturer's -# PPD files. -# KID4: Put together the JCL commands and the renderer's output -# and send all that either to STDOUT or pipe it into the -# command line defined with $postpipe. - -## This function runs the renderer command line (and if defined also -## the postpipe) and returns a file handle for stuffing in the -## PostScript data. -sub getrendererhandle { - - my ($dat, $prepend) = @_; - - print $logh "${added_lf}Starting renderer\n"; - - # Catch signals - $retval = $EXIT_PRINTED; - use sigtrap qw(handler set_exit_prnerr USR1 - handler set_exit_prnerr_noretry USR2 - handler set_exit_engaged TTIN); - - # Variables for the kid processes reporting their state - - # Set up a pipe for the kids to pass their exit stat to the main process - pipe KID_MESSAGE, KID_MESSAGE_IN; - - # When one kid fails put the exit stat here - $kidfailed = 0; - - # When a kid exits successfully, mark it here - $kid3finished = 0; - $kid4finished = 0; - - # Build the command line and get the JCL commands - buildcommandline($dat, 'currentpage'); - my $commandline = $dat->{'currentcmd'}; - my @jclprepend = @{$dat->{'jclprepend'}} if defined $dat->{'jclprepend'}; - my @jclappend = @{$dat->{'jclappend'}} if defined $dat->{'jclappend'}; - - use IO::Handle; - pipe KID3_IN, KID3; - KID3->autoflush(1); - $kid3 = fork(); - if (!defined($kid3)) { - close KID3; - close KID3_IN; - print $logh "$0: cannot fork for kid3!\n"; - rip_die ("can't fork for kid3", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - if ($kid3) { - - # we are the parent; return a glob to the filehandle - close KID3_IN; - - # Feed in the PostScript header and the FIFO contents - print KID3 $prepend; - - KID3->flush(); - return ( *KID3, $kid3 ); - - } else { - close KID3; - - pipe KID4_IN, KID4; - KID4->autoflush(1); - $kid4 = fork(); - if (!defined($kid4)) { - close KID4; - close KID4_IN; - print $logh "$0: cannot fork for kid4!\n"; - close KID_MESSAGE; - print KID_MESSAGE_IN "3 $EXIT_PRNERR_NORETRY_BAD_SETTINGS\n"; - close KID_MESSAGE_IN; - rip_die ("can't fork for kid4", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - - if ($kid4) { - # parent, child of primary task; we are |commandline| - close KID4_IN; - - print $logh "renderer PID kid4=$kid4\n"; - print $logh "renderer command: $commandline\n"; - - if (!close STDIN && $! != $ESPIPE) { - close KID3_IN; - close KID4; - close KID_MESSAGE; - print KID_MESSAGE_IN - "3 $EXIT_PRNERR_NORETRY_BAD_SETTINGS\n"; - close KID_MESSAGE_IN; - rip_die ("Couldn't close STDIN in $kid4", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - if (!open (STDIN, "<&KID3_IN")) { - close KID3_IN; - close KID4; - close KID_MESSAGE; - print KID_MESSAGE_IN - "3 $EXIT_PRNERR_NORETRY_BAD_SETTINGS\n"; - close KID_MESSAGE_IN; - rip_die ("Couldn't dup KID3_IN", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - if (!close STDOUT) { - close KID3_IN; - close KID4; - close KID_MESSAGE; - print KID_MESSAGE_IN - "3 $EXIT_PRNERR_NORETRY_BAD_SETTINGS\n"; - close KID_MESSAGE_IN; - rip_die ("Couldn't close STDOUT in $kid4", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - if (!open (STDOUT, ">&KID4")) { - close KID3_IN; - close KID4; - close KID_MESSAGE; - print KID_MESSAGE_IN - "3 $EXIT_PRNERR_NORETRY_BAD_SETTINGS\n"; - close KID_MESSAGE_IN; - rip_die ("Couldn't dup KID4", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - if ($debug) { - if (!open (STDERR, ">&$logh")) { - close KID3_IN; - close KID4; - close KID_MESSAGE; - print KID_MESSAGE_IN - "3 $EXIT_PRNERR_NORETRY_BAD_SETTINGS\n"; - close KID_MESSAGE_IN; - rip_die ("Couldn't dup logh to stderr", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - } - - # Massage commandline to execute foomatic-gswrapper - my $havewrapper = 0; - for (split(':', $ENV{'PATH'})) { - if (-x "$_/foomatic-gswrapper") { - $havewrapper=1; - last; - } - } - if ($havewrapper) { - $commandline =~ s!^\s*gs\s!foomatic-gswrapper !g; - $commandline =~ s!(\|\s*)gs\s!\|foomatic-gswrapper !g; - $commandline =~ s!(;\s*)gs\s!; foomatic-gswrapper !g; - } - - # If the renderer command line contains the "echo" - # command, replace the "echo" by the user-chosen $myecho - # (important for non-GNU systems where GNU echo is in a - # special path - $commandline =~ s!^\s*echo\s!$myecho !g; - $commandline =~ s!(\|\s*)echo\s!\|$myecho !g; - $commandline =~ s!(;\s*)echo\s!; $myecho !g; - - # In debug mode save the data supposed to be fed into the - # renderer also into a file - if ($debug) { - $commandline = "tee -a ${logfile}.ps | ( $commandline )"; - } - - # Actually run the thing... - modern_system("$commandline"); - if ($? != 0) { - my $rendererretval = $? >> 8; - print $logh "renderer return value: $rendererretval\n"; - my $renderersignal = $? & 127; - print $logh "renderer received signal: $rendererretval\n"; - close STDOUT; - close KID4; - close STDIN; - close KID3_IN; - # Handle signals - if ($renderersignal == SIGUSR1) { - $retval = $EXIT_PRNERR; - } elsif ($renderersignal == SIGUSR2) { - $retval = $EXIT_PRNERR_NORETRY; - } elsif ($renderersignal == SIGTTIN) { - $retval = $EXIT_ENGAGED; - } - if ($retval != $EXIT_PRINTED) { - close KID_MESSAGE; - print KID_MESSAGE_IN "3 $retval\n"; - close KID_MESSAGE_IN; - exit $retval; - } - # Evaluate renderer result - if ($rendererretval == 0) { - # Success, exit with 0 and inform main process - close KID_MESSAGE; - print KID_MESSAGE_IN "3 $EXIT_PRINTED\n"; - close KID_MESSAGE_IN; - exit $EXIT_PRINTED; - } elsif ($rendererretval == 1) { - # Syntax error? PostScript error? - close KID_MESSAGE; - print KID_MESSAGE_IN "3 $EXIT_JOBERR\n"; - close KID_MESSAGE_IN; - rip_die ("Possible error on renderer command line or PostScript error. Check options.", - $EXIT_JOBERR); - } elsif ($rendererretval == 139) { - # Seems to indicate a core dump - close KID_MESSAGE; - print KID_MESSAGE_IN "3 $EXIT_JOBERR\n"; - close KID_MESSAGE_IN; - rip_die ("The renderer may have dumped core.", - $EXIT_JOBERR); - } elsif ($rendererretval == 141) { - # Broken pipe, presumably additional filter interface - # exited. - close KID_MESSAGE; - print KID_MESSAGE_IN "3 $EXIT_PRNERR\n"; - close KID_MESSAGE_IN; - rip_die ("A filter used in addition to the renderer" . - " itself may have failed.", - $EXIT_PRNERR); - } elsif (($rendererretval == 243) || ($retval == 255)) { - # PostScript error? - close KID_MESSAGE; - print KID_MESSAGE_IN "3 $EXIT_JOBERR\n"; - close KID_MESSAGE_IN; - exit $EXIT_JOBERR; - } else { - # Unknown error - close KID_MESSAGE; - print KID_MESSAGE_IN "3 $EXIT_PRNERR\n"; - close KID_MESSAGE_IN; - rip_die ("The renderer command line returned an" . - " unrecognized error code $rendererretval.", - $EXIT_PRNERR); - } - } - close STDOUT; - close KID4; - close STDIN; - close KID3_IN; - # When arrived here the renderer command line was successful - # So exit with zero exit value here and inform the main process - close KID_MESSAGE; - print KID_MESSAGE_IN "3 $EXIT_PRINTED\n"; - close KID_MESSAGE_IN; - # Wait for postpipe/output child - waitpid($kid4, 0); - print $logh "KID3 finished\n"; - exit $EXIT_PRINTED; - } else { - # child, trailing task on the pipe; we write jcl stuff - close KID4; - close KID3_IN; - - my $fileh = *STDOUT; - - # Do we have a $postpipe, if yes, launch the command(s) and - # point our output into it/them - if ($postpipe) { - if (!open PIPE,$postpipe) { - close KID4_IN; - close KID_MESSAGE; - print KID_MESSAGE_IN - "4 $EXIT_PRNERR_NORETRY_BAD_SETTINGS\n"; - close KID_MESSAGE_IN; - rip_die ("cannot execute postpipe $postpipe", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - $fileh = *PIPE; - } - - # Debug output - print $logh "JCL: " . join("", @jclprepend) . "<job data> ${added_lf}" . - join("", @jclappend) . "\n"; - - # wrap the JCL around the job data, if there are any - # options specified... - # Should the driver already have inserted JCL commands we merge - # our JCL header with the one from the driver - my $driverjcl = 0; - if ( @jclprepend > 1 ) { - # JCL header read from renderer output - my @jclheader = (); - # Determine magic string of JCL in use (usually "@PJL") - # For that we take the first part of the second JCL line up - # to the first space - if ($jclprepend[1] =~ /^(\S+)/) { - my $jclstr = $1; - # Read from the renderer output until the first non-JCL - # line appears - while (my $line = <KID4_IN>) { - push(@jclheader, $line); - last if ($line !~ /$jclstr/); - } - # If we had read at least two lines, at least one is - # a JCL header, so do the merging - if (@jclheader > 1) { - $driverjcl = 1; - # Discard the first and the last entry of the - # @jclprepend array, we only need the option settings - # to merge them in - pop(@jclprepend); - shift(@jclprepend); - # Line after which we insert new JCL commands in the - # JCL header of the job - my $insert = 1; - # Go through every JCL command in @jclprepend - for my $line (@jclprepend) { - # Search the command in the JCL header from the - # driver. As search term use only the string from - # the beginning of the line to the "=", so the - # command will also be found when it has another - # value - $line =~ /^([^=]+)/; - my $cmd = $1; - $cmd =~ s/^\s*(.*?)\s*$/$1/; - my $cmdfound = 0; - for (@jclheader) { - # If the command is there, replace it - $_ =~ s/$cmd\b.*(\r\n|\n|\r)/$line/ and - $cmdfound = 1; - } - if (!$cmdfound) { - # If the command is not found, insert it - if (@jclheader > 2) { - # @jclheader has more than one line, - # insert the new command beginning - # right after the first line and continuing - # after the previous inserted command - splice(@jclheader, $insert, 0, $line); - $insert ++; - } else { - # If we have only one line of JCL it - # is probably something like the - # "@PJL ENTER LANGUAGE=..." line - # which has to be in the end, but - # it also contains the - # "<esc>%-12345X" which has to be in the - # beginning of the job. So we split the - # line right before the $jclstr and - # append our command to the end of the - # first part and let the second part - # be a second JCL line. - $jclheader[0] =~ - /^(.*?)($jclstr.*(\r\n|\n|\r))/; - my $first = "$1$line"; - my $second = "$2"; - my $third = $jclheader[1]; - @jclheader = ($first, $second, $third); - } - } - } - # Now pass on the merged JCL header - print $fileh @jclheader; - } else { - # The driver didn't create a JCL header, simply - # prepend ours and then pass on the line which we - # already have read - print $fileh @jclprepend, @jclheader; - } - } else { - # No merging of JCL header possible, simply prepend it - print $fileh @jclprepend; - } - } - - # The rest of the job data - my $buf; - while (read(KID4_IN, $buf, 1024)) { - print $fileh $buf; - } - - # A JCL trailer - if (( @jclprepend > 1 ) && (!$driverjcl)) { - print $fileh @jclappend; - } - - if (!close $fileh) { - close KID4_IN; - close KID_MESSAGE; - print KID_MESSAGE_IN - "4 $EXIT_PRNERR_NORETRY_BAD_SETTINGS\n"; - close KID_MESSAGE_IN; - rip_die ("error closing $fileh", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - close KID4_IN; - - print $logh "tail process done writing data to STDOUT\n"; - - # Handle signals of the backend interface - if ($retval != $EXIT_PRINTED) { - close KID_MESSAGE; - print KID_MESSAGE_IN "4 $retval\n"; - close KID_MESSAGE_IN; - exit $retval; - } - - # Successful exit, inform main process - close KID_MESSAGE; - print KID_MESSAGE_IN "4 $EXIT_PRINTED\n"; - close KID_MESSAGE_IN; - - print $logh "KID4 finished\n"; - exit($EXIT_PRINTED); - } - } -} - - - -## Close the renderer process and wait until all kid processes finish. - -sub closerendererhandle { - - my ($rendererhandle, $rendererpid) = @_; - - print $logh "${added_lf}Closing renderer\n"; - - # Do it! - close $rendererhandle; - - # Wait for all kid processes to finish or one kid process to fail - close KID_MESSAGE_IN; - while ((!$kidfailed) && - !(($kid3finished) && - ($kid4finished))) { - my $message = <KID_MESSAGE>; - chomp $message; - if ($message =~ /(\d+)\s+(\d+)/) { - my $kid_id = $1; - my $exitstat = $2; - print $logh "KID$kid_id exited with status $exitstat\n"; - if ($exitstat > 0) { - $kidfailed = $exitstat; - } elsif ($kid_id == 3) { - $kid3finished = 1; - } elsif ($kid_id == 4) { - $kid4finished = 1; - } - } - } - - close KID_MESSAGE; - - # If a kid failed, return the exit stat of this kid - if ($kidfailed != 0) { - $retval = $kidfailed; - } - - print $logh "Renderer exit stat: $retval\n"; - # Wait for renderer child - waitpid($rendererpid, 0); - print $logh "Renderer process finished\n"; - return ($retval); -} - - - -## This function is only used when the input data is not -## PostScript. Then it runs a filter which converts non-PostScript -## files into PostScript. The user can choose which filter he wants -## to use. The filter command line is provided by $fileconverter. - -sub getfileconverterhandle { - - # Already read data must be converted, too - my ($dat, $alreadyread) = @_; - - print $logh "${added_lf}Starting converter for non-PostScript files\n"; - - # Determine with which command non-PostScript files are converted - # to PostScript - if ($fileconverter eq "") { - if ($spoolerfileconverters->{$spooler}) { - $fileconverter = $spoolerfileconverters->{$spooler}; - } else { - for my $c (@fileconverters) { - ($c =~ m/^\s*(\S+)\s+/) || ($c = m/^\s*(\S+)$/); - my $command = $1; - if( -x $command ){ - $fileconverter = $command; - } else { - for (split(':', $ENV{'PATH'})) { - if (-x "$_/$command") { - $fileconverter = $c; - last; - } - } - } - if ($fileconverter ne "") { - last; - } - } - } - if ($fileconverter eq "") { - $fileconverter = "echo \"Cannot convert file to " . - "PostScript!\" 1>&2"; - } - } - - # Insert the page size into the $fileconverter - if ($fileconverter =~ /\@\@([^@]+)\@\@PAGESIZE\@\@/) { - # We always use the "header" option swt here, with a - # non-PostScript file we have no "currentpage" - my $optstr = $1; - my $arg; - my $sizestr = (($arg = $dat->{'args_byname'}{'PageSize'}) - ? $arg->{'header'} - : ""); - if ($sizestr) { - # Use wider margins so that the pages come out completely on - # every printer model (especially HP inkjets) - if ($fileconverter =~ /^\s*(a2ps)\s+/) { - if (lc($sizestr) eq "letter") { - $sizestr = "Letterdj"; - } elsif (lc($sizestr) eq "a4") { - $sizestr = "A4dj"; - } - } - $optstr .= $sizestr; - } else { - $optstr = ""; - } - $fileconverter =~ s/\@\@([^@]+)\@\@PAGESIZE\@\@/$optstr/; - } - - # Insert the job title into the $fileconverter - if ($fileconverter =~ /\@\@([^@]+)\@\@JOBTITLE\@\@/) { - if ($do_docs) { - $jobtitle = - "Documentation for the $model"; - } - my $titlearg = $1; - my ($arg, $optstr); - ($arg = $jobtitle) =~ s/\"/\\\"/g; - if (($titlearg =~ /\"/) || $arg) { - $optstr = $titlearg . ($titlearg =~ /\"/ ? '' : '"') . - ($arg ? "$arg\"" : '"'); - } else { - $optstr = ""; - } - $fileconverter =~ s/\@\@([^@]+)\@\@JOBTITLE\@\@/$optstr/; - } - - # Apply "pstops" when having used a file converter under CUPS, so - # CUPS can stuff the default settings into the PostScript output - # of the file converter (so all CUPS settings get also applied when - # one prints the documentation pages (all other files we get - # already converted to PostScript by CUPS). - if ($spooler eq 'cups') { - $fileconverter .= - " | ${programdir}pstops '$rargs[0]' '$rargs[1]' '$rargs[2]' " . - "'$rargs[3]' '$rargs[4]'"; - } - - # Variables for the kid processes reporting their state - - # Set up a pipe for the kids to pass their exit stat to the main process - pipe KID_MESSAGE_CONV, KID_MESSAGE_CONV_IN; - - # When one kid fails put the exit stat here - $convkidfailed = 0; - - # When a kid exits successfully, mark it here - $kid1finished = 0; - $kid2finished = 0; - - use IO::Handle; - pipe KID1_IN, KID1; - KID1->autoflush(1); - my $kid1 = fork(); - if (!defined($kid1)) { - close KID1; - close KID1_IN; - print $logh "$0: cannot fork for kid1!\n"; - rip_die ("can't fork for kid1", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - - if ($kid1) { - - # we are the parent; return a glob to the filehandle - close KID1; - - return ( *KID1_IN, $kid1 ); - - } else { - # We go on reading the job data and stuff it into the file - # converter - close KID1_IN; - - pipe KID2_IN, KID2; - KID2->autoflush(1); - $kid2 = fork(); - if (!defined($kid2)) { - print $logh "$0: cannot fork for kid2!\n"; - close KID1; - close KID2; - close KID2_IN; - close KID_MESSAGE_CONV; - print KID_MESSAGE_CONV_IN - "1 $EXIT_PRNERR_NORETRY_BAD_SETTINGS\n"; - rip_die ("can't fork for kid2", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - - if ($kid2) { - # parent, child of primary task; we are |$fileconverter| - close KID2; - - print $logh "file converter PID kid2=$kid2\n"; - if (($debug) || ($spooler ne 'cups')) { - print $logh "file converter command: $fileconverter\n"; - } - - if (!close STDIN && $! != $ESPIPE) { - close KID1; - close KID2_IN; - close KID_MESSAGE_CONV; - print KID_MESSAGE_CONV_IN - "1 $EXIT_PRNERR_NORETRY_BAD_SETTINGS\n"; - close KID_MESSAGE_CONV_IN; - rip_die ("Couldn't close STDIN in $kid2", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - if (!open (STDIN, "<&KID2_IN")) { - close KID1; - close KID2_IN; - close KID_MESSAGE_CONV; - print KID_MESSAGE_CONV_IN - "1 $EXIT_PRNERR_NORETRY_BAD_SETTINGS\n"; - close KID_MESSAGE_CONV_IN; - rip_die ("Couldn't dup KID2_IN", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - if (!close STDOUT) { - close KID1; - close KID2_IN; - close KID_MESSAGE_CONV; - print KID_MESSAGE_CONV_IN - "1 $EXIT_PRNERR_NORETRY_BAD_SETTINGS\n"; - close KID_MESSAGE_CONV_IN; - rip_die ("Couldn't close STDOUT in $kid2", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - if (!open (STDOUT, ">&KID1")) { - close KID1; - close KID2_IN; - close KID_MESSAGE_CONV; - print KID_MESSAGE_CONV_IN - "1 $EXIT_PRNERR_NORETRY_BAD_SETTINGS\n"; - close KID_MESSAGE_CONV_IN; - rip_die ("Couldn't dup KID1", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - if ($debug) { - if (!open (STDERR, ">&$logh")) { - close KID1; - close KID2_IN; - close KID_MESSAGE_CONV; - print KID_MESSAGE_CONV_IN - "1 $EXIT_PRNERR_NORETRY_BAD_SETTINGS\n"; - close KID_MESSAGE_CONV_IN; - rip_die ("Couldn't dup logh to stderr", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - } - - # Actually run the thing... - modern_system("$fileconverter"); - if ($? != 0) { - my $fileconverterretval = $? >> 8; - print $logh "file converter return value: " . - "$fileconverterretval\n"; - my $fileconvertersignal = $? & 127; - print $logh "file converter received signal: ". - "$fileconverterretval\n"; - close STDOUT; - close KID1; - close STDIN; - close KID2_IN; - # Handle signals - if ($fileconvertersignal == SIGUSR1) { - $retval = $EXIT_PRNERR; - } elsif ($fileconvertersignal == SIGUSR2) { - $retval = $EXIT_PRNERR_NORETRY; - } elsif ($fileconvertersignal == SIGTTIN) { - $retval = $EXIT_ENGAGED; - } - if ($retval != $EXIT_PRINTED) { - close KID_MESSAGE_CONV; - print KID_MESSAGE_CONV_IN "1 $retval\n"; - close KID_MESSAGE_CONV_IN; - exit $retval; - } - # Evaluate fileconverter result - if ($fileconverterretval == 0) { - # Success, exit with 0 and inform main process - close KID_MESSAGE_CONV; - print KID_MESSAGE_CONV_IN "1 $EXIT_PRINTED\n"; - close KID_MESSAGE_CONV_IN; - exit $EXIT_PRINTED; - } else { - # Unknown error - close KID_MESSAGE_CONV; - print KID_MESSAGE_CONV_IN "1 $EXIT_PRNERR\n"; - close KID_MESSAGE_CONV_IN; - rip_die ("The file converter command line returned " . - "an unrecognized error code " . - "$fileconverterretval.", - $EXIT_PRNERR); - } - } - close STDOUT; - close KID1; - close STDIN; - close KID2_IN; - # When arrived here the fileconverter command line was - # successful. - # So exit with zero exit value here and inform the main process - close KID_MESSAGE_CONV; - print KID_MESSAGE_CONV_IN "1 $EXIT_PRINTED\n"; - close KID_MESSAGE_CONV_IN; - # Wait for input child - waitpid($kid1, 0); - print $logh "KID1 finished\n"; - exit $EXIT_PRINTED; - } else { - # child, first part of the pipe, reading in the data from - # standard input and stuffing it into the file converter - # after putting in the already read data (in $alreadyread) - close KID1; - close KID2_IN; - - # At first pass the data which we have already read to the - # filter - print KID2 $alreadyread; - # Then read the rest from standard input - my $buf; - while (read(STDIN, $buf, 1024)) { - print KID2 $buf; - } - - if (!close STDIN && $! != $ESPIPE) { - close KID2; - close KID_MESSAGE_CONV; - print KID_MESSAGE_CONV_IN - "2 $EXIT_PRNERR_NORETRY_BAD_SETTINGS\n"; - close KID_MESSAGE_CONV_IN; - rip_die ("error closing STDIN", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - close KID2; - - print $logh "tail process done reading data from STDIN\n"; - - # Successful exit, inform main process - close KID_MESSAGE_CONV; - print KID_MESSAGE_CONV_IN "2 $EXIT_PRINTED\n"; - close KID_MESSAGE_CONV_IN; - - print $logh "KID2 finished\n"; - exit($EXIT_PRINTED); - } - } -} - - - -## Close the file conversion process and wait until all kid processes -## finish. - -sub closefileconverterhandle { - - my ($fileconverterhandle, $fileconverterpid) = @_; - - print $logh "${added_lf}Closing file converter\n"; - - # Do it! - close $fileconverterhandle; - - # Wait for all kid processes to finish or one kid process to fail - close KID_MESSAGE_CONV_IN; - while ((!$convkidfailed) && - !(($kid1finished) && - ($kid2finished))) { - my $message = <KID_MESSAGE_CONV>; - chomp $message; - if ($message =~ /(\d+)\s+(\d+)/) { - my $kid_id = $1; - my $exitstat = $2; - print $logh "KID$kid_id exited with status $exitstat\n"; - if ($exitstat > 0) { - $convkidfailed = $exitstat; - } elsif ($kid_id == 1) { - $kid1finished = 1; - } elsif ($kid_id == 2) { - $kid2finished = 1; - } - } - } - - close KID_MESSAGE_CONV; - - # If a kid failed, return the exit stat of this kid - if ($convkidfailed != 0) { - $retval = $convkidfailed; - } - - print $logh "File converter exit stat: $retval\n"; - # Wait for fileconverter child - waitpid($fileconverterpid, 0); - print $logh "File converter process finished\n"; - return ($retval); -} - - - -## Generate the documentation page and return a filehandle to get it - -sub getdocgeneratorhandle { - - # The data structure with the options - my ($dat) = @_; - - print $logh "${added_lf}Generating documentation page for the $model\n"; - - # Printer queue name - my $printerstr; - if ($printer) { - $printerstr = $printer; - } else { - $printerstr = "<printer>"; - } - - # Spooler-specific differences - my ($command, - $enumopt, $enumoptleft, $enumoptequal, $enumoptright, - $boolopt, $booloptfalseprefix, $booloptleft, $booloptequal, - $booloptright, - $numopt, $numoptleft, $numoptequal, $numoptright, - $stropt, $stroptleft, $stroptequal, $stroptright, - $optsep, $trailer, $custompagesize); - if ($spooler eq 'cups') { - ($command, - $enumopt, $enumoptleft, $enumoptequal, $enumoptright, - $boolopt, $booloptfalseprefix, $booloptleft, $booloptequal, - $booloptright, - $numopt, $numoptleft, $numoptequal, $numoptright, - $stropt, $stroptleft, $stroptequal, $stroptright, - $optsep, $trailer, $custompagesize) = - ("lpr -P $printerstr ", - "-o ", "", "=", "", - "-o ", "no", "", "=", "", - "-o ", "", "=", "", - "-o ", "", "=", "", - " "," <file>", - "\n Custom size: -o PageSize=Custom." . - "<width>x<height>[<unit>]\n" . - " Units: pt (default), in, cm, mm\n" . - " Example: -o PageSize=Custom.4.0x6.0in\n"); - } elsif ($spooler eq 'lpd') { - ($command, - $enumopt, $enumoptleft, $enumoptequal, $enumoptright, - $boolopt, $booloptfalseprefix, $booloptleft, $booloptequal, - $booloptright, - $numopt, $numoptleft, $numoptequal, $numoptright, - $stropt, $stroptleft, $stroptequal, $stroptright, - $optsep, $trailer, $custompagesize) = - ("lpr -P $printerstr -J \"", - "", "", "=", "", - "", "", "", "=", "", - "", "", "=", "", - "", "", "=", "", - " ", "\" <file>", - "\n Custom size: PageSize=Custom." . - "<width>x<height>[<unit>]\n" . - " Units: pt (default), in, cm, mm\n" . - " Example: PageSize=Custom.4.0x6.0in\n"); - } elsif ($spooler eq 'gnulpr') { - ($command, - $enumopt, $enumoptleft, $enumoptequal, $enumoptright, - $boolopt, $booloptfalseprefix, $booloptleft, $booloptequal, - $booloptright, - $numopt, $numoptleft, $numoptequal, $numoptright, - $stropt, $stroptleft, $stroptequal, $stroptright, - $optsep, $trailer, $custompagesize) = - ("lpr -P $printerstr ", - "-o ", "", "=", "", - "-o ", "", "", "=", "", - "-o ", "", "=", "", - "-o ", "", "=", "", - " "," <file>", - "\n Custom size: -o PageSize=Custom." . - "<width>x<height>[<unit>]\n" . - " Units: pt (default), in, cm, mm\n" . - " Example: -o PageSize=Custom.4.0x6.0in\n"); - } elsif ($spooler eq 'lprng') { - ($command, - $enumopt, $enumoptleft, $enumoptequal, $enumoptright, - $boolopt, $booloptfalseprefix, $booloptleft, $booloptequal, - $booloptright, - $numopt, $numoptleft, $numoptequal, $numoptright, - $stropt, $stroptleft, $stroptequal, $stroptright, - $optsep, $trailer, $custompagesize) = - ("lpr -P $printerstr ", - "-Z ", "", "=", "", - "-Z ", "", "", "=", "", - "-Z ", "", "=", "", - "-Z ", "", "=", "", - " "," <file>", - "\n Custom size: -Z PageSize=Custom." . - "<width>x<height>[<unit>]\n" . - " Units: pt (default), in, cm, mm\n" . - " Example: -Z PageSize=Custom.4.0x6.0in\n"); - } elsif ($spooler eq 'ppr') { - ($command, - $enumopt, $enumoptleft, $enumoptequal, $enumoptright, - $boolopt, $booloptfalseprefix, $booloptleft, $booloptequal, - $booloptright, - $numopt, $numoptleft, $numoptequal, $numoptright, - $stropt, $stroptleft, $stroptequal, $stroptright, - $optsep, $trailer, $custompagesize) = - ("ppr -d $printerstr --ripopts \"", - "", "", "=", "", - "", "", "", "=", "", - "", "", "=", "", - "", "", "=", "", - " ","\" <file>", - "\n Custom size: PageSize=Custom." . - "<width>x<height>[<unit>]\n" . - " Units: pt (default), in, cm, mm\n" . - " Example: PageSize=Custom.4.0x6.0in\n"); - } elsif ($spooler eq 'ppr-int') { - ($command, - $enumopt, $enumoptleft, $enumoptequal, $enumoptright, - $boolopt, $booloptfalseprefix, $booloptleft, $booloptequal, - $booloptright, - $numopt, $numoptleft, $numoptequal, $numoptright, - $stropt, $stroptleft, $stroptequal, $stroptright, - $optsep, $trailer, $custompagesize) = - ("ppr -d $printerstr -i \"", - "", "", "=", "", - "", "", "", "=", "", - "", "", "=", "", - "", "", "=", "", - " ","\" <file>", - "\n Custom size: PageSize=Custom." . - "<width>x<height>[<unit>]\n" . - " Units: pt (default), in, cm, mm\n" . - " Example: PageSize=Custom.4.0x6.0in\n"); - } elsif ($spooler eq 'cps') { - ($command, - $enumopt, $enumoptleft, $enumoptequal, $enumoptright, - $boolopt, $booloptfalseprefix, $booloptleft, $booloptequal, - $booloptright, - $numopt, $numoptleft, $numoptequal, $numoptright, - $stropt, $stroptleft, $stroptequal, $stroptright, - $optsep, $trailer, $custompagesize) = - ("lpr -P $printerstr ", - "-o ", "", "=", "", - "-o ", "", "", "=", "", - "-o ", "", "=", "", - "-o ", "", "=", "", - " "," <file>", - "\n Custom size: -o PageSize=Custom." . - "<width>x<height>[<unit>]\n" . - " Units: pt (default), in, cm, mm\n" . - " Example: -o PageSize=Custom.4.0x6.0in\n"); - } elsif ($spooler eq 'direct') { - ($command, - $enumopt, $enumoptleft, $enumoptequal, $enumoptright, - $boolopt, $booloptfalseprefix, $booloptleft, $booloptequal, - $booloptright, - $numopt, $numoptleft, $numoptequal, $numoptright, - $stropt, $stroptleft, $stroptequal, $stroptright, - $optsep, $trailer, $custompagesize) = - ("$programname -P $printerstr ", - "-o ", "", "=", "", - "-o ", "", "", "=", "", - "-o ", "", "=", "", - "-o ", "", "=", "", - " "," <file>", - "\n Custom size: -o PageSize=Custom." . - "<width>x<height>[<unit>]\n" . - " Units: pt (default), in, cm, mm\n" . - " Example: -o PageSize=Custom.4.0x6.0in\n"); - } elsif ($spooler eq 'pdq') { - ($command, - $enumopt, $enumoptleft, $enumoptequal, $enumoptright, - $boolopt, $booloptfalseprefix, $booloptleft, $booloptequal, - $booloptright, - $numopt, $numoptleft, $numoptequal, $numoptright, - $stropt, $stroptleft, $stroptequal, $stroptright, - $optsep, $trailer, $custompagesize) = - ("pdq -P $printerstr ", - "-o", "", "_", "", - "-o", "no", "", "_", "", - "-a", "", "=", "", - "-a", "", "=", "", - " "," <file>", - "\n" . - "Option 'PageWidth':\n". - " Page Width (for \"Custom\" page size)\n" . - " A floating point number argument\n" . - " Range: 0 <= x <= 100000\n" . - " Example: -aPageWidth=123.4\n" . - "\n" . - "Option 'PageHeight':\n" . - " Page Height (for \"Custom\" page size)\n" . - " A floating point number argument\n" . - " Range: 0 <= x <= 100000\n" . - " Example: -aPageHeight=234.5\n" . - "\n" . - "Option 'PageSizeUnit':\n" . - " Unit (for \"Custom\" page size)\n" . - " An enumerated choice argument\n" . - " Possible choices:\n" . - " o -oPageSizeUnit_pt: Points (1/72 inch)\n" . - " o -oPageSizeUnit_in: Inches\n" . - " o -oPageSizeUnit_cm: cm\n" . - " o -oPageSizeUnit_mm: mm\n" . - " Example: -oPageSizeUnit_mm\n"); - } - - # Variables for the kid processes reporting their state - - # Set up a pipe for the kids to pass their exit stat to the main process - pipe KID_MESSAGE_DOC, KID_MESSAGE_DOC_IN; - - # When the kid fails put the exit stat here - $dockidfailed = 0; - - # When the kid exits successfully, mark it here - $kid0finished = 0; - - use IO::Handle; - pipe KID0_IN, KID0; - KID0->autoflush(1); - my $kid0 = fork(); - if (!defined($kid0)) { - close KID0; - close KID0_IN; - print $logh "$0: cannot fork for kid0!\n"; - rip_die ("can't fork for kid0", - $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - - if ($kid0) { - # we are the parent; return a glob to the filehandle - close KID0; - print $logh "Documentation page generator PID kid0=$kid0\n"; - return ( *KID0_IN, $kid0 ); - } - - # we are the kid; we generate the documentation page - - close KID0_IN; - - # Kill data on STDIN to satisfy PPR - if (($spooler eq 'ppr_int') || ($spooler eq 'ppr')) { - while (my $dummy = <STDIN>) {}; - } - close STDIN - or print $logh "Error closing STDIN for docs print\n"; - - # write the job into KID0 - select KID0; - - print "\nInvokation summary for the $model\n\n"; - print "Use the following command line:\n\n"; - if ($booloptfalseprefix) { - # I think that what you want to indicate is that the prefix for a false - # boolean has this form: xxx [no]<switch> or something similar - print " ${command}${enumopt}${enumoptleft}<option>" . - "${enumoptequal}<choice>${enumoptright}${optsep}" . - "${boolopt}${booloptleft}\[${booloptfalseprefix}\]<switch>" . - "${booloptright}${optsep}" . - "${numopt}${numoptleft}<num. option>${numoptequal}" . - "<value>${numoptright}${optsep}" . - "${stropt}${stroptleft}<string option>${stroptequal}" . - "<string>${stroptright}" . - "${trailer}\n\n"; - } else { - print " ${command}${enumopt}${enumoptleft}<option>" . - "${enumoptequal}<choice>${enumoptright}${optsep}" . - "${boolopt}${booloptleft}<switch>${booloptequal}" . - "<True/False>${booloptright}${optsep}" . - "${numopt}${numoptleft}<num. option>${numoptequal}" . - "<value>${numoptright}${optsep}" . - "${stropt}${stroptleft}<string option>${stroptequal}" . - "<string>${stroptright}" . - "${trailer}\n\n"; - } - - print "The following options are available for this printer:\n\n"; - - for my $arg (@{$dat->{'args'}}) { - my ($name, - $type, - $comment, - $spot, - $default) = ($arg->{'name'}, - $arg->{'type'}, - $arg->{'comment'}, - $arg->{'spot'}, - $arg->{'default'}); - - # Is this really an option? Otherwise skip it. - next if (!$type); - - # We don't need "PageRegion", we have "PageSize" - next if ($name eq "PageRegion"); - - # Skip enumerated choice options with only one choice - next if (($type eq 'enum') && ($#{$arg->{'vals'}} < 1)); - - my $commentstr = ""; - if ($comment) { - $commentstr = " $comment\n"; - } - - my $typestr; - if ($type eq "enum") { - $typestr = "An enumerated choice"; - } elsif ($type eq "bool") { - $typestr = "A boolean"; - } elsif ($type eq "int") { - $typestr = "An integer number"; - } elsif ($type eq "float") { - $typestr = "A floating point number"; - } elsif (($type eq "string") || ($type eq "password")) { - $typestr = "A string"; - } - - print "Option '$name':\n$commentstr $typestr argument\n"; - print " This options corresponds to a JCL command\n" if ($arg->{'style'} eq 'J'); - - if ($type eq 'bool') { - print " Possible choices:\n"; - if ($booloptfalseprefix) { - print " o $name: $arg->{'comment_true'}\n"; - print " o $booloptfalseprefix$name: " . - "$arg->{'comment_false'}\n"; - if (defined($default)) { - my $defstr = ($default ? "" : "$booloptfalseprefix"); - print " Default: $defstr$name\n"; - } - print " Example: ${boolopt}${booloptleft}${name}" . - "${booloptright}\n"; - } else { - print " o True: $arg->{'comment_true'}\n"; - print " o False: $arg->{'comment_false'}\n"; - if (defined($default)) { - my $defstr = ($default ? "True" : "False"); - print " Default: $defstr\n"; - } - print " Example: ${boolopt}${booloptleft}${name}" . - "${booloptequal}True${booloptright}\n"; - } - } elsif ($type eq 'enum') { - print " Possible choices:\n"; - my $exarg; - my $havecustomsize = 0; - for (@{$arg->{'vals'}}) { - my ($choice, $comment) = ($_->{'value'}, $_->{'comment'}); - print " o $choice: $comment\n"; - if (($name eq "PageSize") && ($choice eq "Custom")) { - $havecustomsize = 1; - } - $exarg=$choice; - } - if (defined($default)) { - print " Default: $default\n"; - } - print " Example: ${enumopt}${enumoptleft}${name}" . - "${enumoptequal}${exarg}${enumoptright}\n"; - if ($havecustomsize) { - print $custompagesize; - } - } elsif ($type eq 'int' or $type eq 'float') { - my ($max, $min) = ($arg->{'max'}, $arg->{'min'}); - my $exarg; - if (defined($max)) { - print " Range: $min <= x <= $max\n"; - $exarg=$max; - } - if (defined($default)) { - print " Default: $default\n"; - $exarg=$default; - } - if (!$exarg) { $exarg=0; } - print " Example: ${numopt}${numoptleft}${name}" . - "${numoptequal}${exarg}${numoptright}\n"; - } elsif ($type eq 'string' or $type eq 'password') { - my $maxlength = $arg->{'maxlength'}; - if (defined($maxlength)) { - print " Maximum length: $maxlength characters\n"; - } - if (defined($default)) { - print " Default: $default\n"; - } - print " Examples/special settings:\n"; - for (@{$arg->{'vals'}}) { - my ($value, $comment, $driverval, $proto) = - ($_->{'value'}, $_->{'comment'}, $_->{'driverval'}, - $arg->{'proto'}); - # Retrieve the original string from the prototype - # and the driverval - my $string; - if ($proto) { - my $s = index($proto, '%s'); - my $l = length($driverval) - length($proto) + 2; - if (($s < 0) || ($l < 0)) { - $string = $driverval; - } else { - $string = substr($driverval, $s, $l); - } - } else { - $string = $driverval; - } - print " o ${stropt}${stroptleft}${name}" . - "${stroptequal}${value}${stroptright}"; - if (($value ne $string) || ($comment ne $value)) { - print " ("; - } - if ($value ne $string) { - if ($string eq '') { - print "blank string"; - } else { - print "\"$string\""; - } - } - if (($value ne $string) && ($comment ne $value)) { - print ", "; - } - if ($value ne $comment) { - print "$comment"; - } - if (($value ne $string) || ($comment ne $value)) { - print ")"; - } - print "\n"; - } - } - - print "\n"; - } - - select STDOUT; - close KID0 - or print $logh "Error closing KID0 for docs print\n"; - close STDOUT - or print $logh "Error closing STDOUT for docs print\n"; - - # Finished successfully, inform main process - close KID_MESSAGE_DOC; - print KID_MESSAGE_DOC_IN "0 $EXIT_PRINTED\n"; - close KID_MESSAGE_DOC_IN; - - print $logh "KID0 finished\n"; - exit($EXIT_PRINTED); - -} - - - -## Close the documentation page generation process and wait until the -## kid process finishes. - -sub closedocgeneratorhandle { - - my ($handle, $pid) = @_; - - print $logh "${added_lf}Closing documentation page generator\n"; - - # Do it! - close $handle; - - # Wait for the kid process to finish or the kid process to fail - close KID_MESSAGE_DOC_IN; - while ((!$dockidfailed) && - (!$kid0finished)) { - my $message = <KID_MESSAGE_DOC>; - chomp $message; - if ($message =~ /(\d+)\s+(\d+)/) { - my $kid_id = $1; - my $exitstat = $2; - print $logh "KID$kid_id exited with status $exitstat\n"; - if ($exitstat > 0) { - $dockidfailed = $exitstat; - } elsif ($kid_id eq "0") { - $kid0finished = 1; - } - } - } - - close KID_MESSAGE_DOC; - - # If the kid failed, return the exit stat of the kid - if ($dockidfailed != 0) { - $retval = $dockidfailed; - } - - print $logh "Documentation page generator exit stat: $retval\n"; - # Wait for fileconverter child - waitpid($pid, 0); - print $logh "Documentation page generator process finished\n"; - return ($retval); -} - - - -# Find an argument by name in a case-insensitive way -sub argbyname { - my $name = $_[0]; - - for my $arg (@{$dat->{'args'}}) { - return $arg if (lc($name) eq lc($arg->{'name'})); - } - - return undef; -} - -sub valbyname { - my ($arg,$name) = @_; - - for my $val (@{$arg->{'vals'}}) { - return $val if (lc($name) eq lc($val->{'value'})); - } - - return undef; -} - -# Write a Good-Bye letter and clean up before committing suicide (send -# error message to caller) - -sub rip_die { - my ($message, $exitstat) = @_; - my $errmsg = "$!"; - my $errcod = $! + 0; - - # Close the documentation page generator (if it was used) - if ($docgeneratorpid) { - if ($kid0) { - print $logh "Killing process $kid0 (KID0)\n"; - kill(9, $kid0); - } - $docgeneratorpid = 0; - } - - # Close the file converter (if it was used) - if ($fileconverterpid) { - if ($kid2) { - print $logh "Killing process $kid2 (KID2)\n"; - kill(9, $kid2); - } - if ($kid1) { - print $logh "Killing process $kid1 (KID1)\n"; - kill(9, $kid1); - } - $fileconverterpid = 0; - } - - # Close the renderer - if ($rendererpid) { - if ($kid4) { - print $logh "Killing process $kid4 (KID4)\n"; - kill(9, $kid4); - } - if ($kid3) { - print $logh "Killing process $kid3 (KID3)\n"; - kill(9, $kid3); - } - $rendererpid = 0; - } - - print $logh "Process dying with \"$message\", exit stat: $exitstat\n\terror: $errmsg ($errcod)\n"; - if ($spooler eq 'ppr_int') { - # Special error handling for PPR intefaces - $message =~ s/\\/\\\\/; - $message =~ s/\"/\\\"/; - my @messagelines = split("\n", $message); - my $firstline = "TRUE"; - for my $line (@messagelines) { - modern_system("lib/alert $printer $firstline \"$line\""); - $firstline = "FALSE"; - } - } else { - print STDERR $message . "\n"; - } - if ($debug) { - use Data::Dumper; - local $Data::Dumper::Purity=1; - local $Data::Dumper::Indent=1; - print $logh Dumper($dat); - } - exit $exitstat; -} - -# Signal handling routines - -sub set_exit_prnerr { - $retval = $EXIT_PRNERR; -} - -sub set_exit_prnerr_noretry { - $retval = $EXIT_PRNERR_NORETRY; -} - -sub set_exit_engaged { - $retval = $EXIT_ENGAGED; -} - -# Read the config file - -sub readConfFile { - my ($file) = @_; - - my %conf; - # Read config file if present - if (open CONF, "< $file") { - while (<CONF>) - { - $conf{$1}="$2" if (m/^\s*([^\#\s]\S*)\s*:\s*(.*?)\s*$/); - } - close CONF; - } - - return %conf; -} - -sub removeunprintables { - # Remove unprintable characters - my $str = $_[0]; - $str =~ s/[\x00-\x1f]//g; - return $str; -} - -sub removeshellescapes { - # Remove shell escape characters - my $str = $_[0]; - $str =~ s/[\|<>&!\$\'\"\#\*\?\(\)\[\]\{\}]//g; - return $str; -} - -sub removespecialchars { - # Remove unprintable and shell escape characters - return removeshellescapes(removeunprintables($_[0])); -} - -sub unhtmlify { - my $str = $_[0]; - - # Replace HTML/XML entities by the original characters - $str =~ s/\'/\'/g; - $str =~ s/\"/\"/g; - $str =~ s/\>/\>/g; - $str =~ s/\</\</g; - $str =~ s/\&/\&/g; - - # Replace special entities by job data - $str =~ s/\&job;/$jobid/g; - $str =~ s/\&user;/$jobuser/g; - $str =~ s/\&host;/$jobhost/g; - $str =~ s/\&title;/$jobtitle/g; - $str =~ s/\&copies;/$copies/g; - $str =~ s/\&options;/$optstr/g; - - my ($sec, $min, $hour, $mday, $mon, $year) = (localtime)[0..5]; - my $yearstr = sprintf("%04d", $year + 1900); - my $monstr = sprintf("%02d", $mon + 1); - my $mdaystr = sprintf("%02d", $mday); - my $hourstr = sprintf("%02d", $hour); - my $minstr = sprintf("%02d", $min); - my $secstr = sprintf("%02d", $sec); - - $str =~ s/\&year;/$yearstr/g; - $str =~ s/\&month;/$monstr/g; - $str =~ s/\&date;/$mdaystr/g; - $str =~ s/\&hour;/$hourstr/g; - $str =~ s/\&min;/$minstr/g; - $str =~ s/\&sec;/$secstr/g; - - return $str; -} - -sub unhexify { - # Replace hex notation for unprintable characters in PPD files - # by the actual characters ex: "<0A>" --> chr(hex("0A")) - my ($input) = @_; - my $output = ""; - my $hexmode = 0; - my $firstdigit = ""; - for (my $i = 0; $i < length($input); $i ++) { - my $c = substr($input, $i, 1); - if ($hexmode) { - if ($c eq ">") { - # End of hex string - $hexmode = 0; - } elsif ($c =~ /^[0-9a-fA-F]$/) { - # Hexadecimal digit, two of them give a character - if ($firstdigit ne "") { - $output .= chr(hex("$firstdigit$c")); - $firstdigit = ""; - } else { - $firstdigit = $c; - } - } - } else { - if ($c eq "<") { - # Beginning of hex string - $hexmode = 1; - } else { - # Normal character - $output .= $c; - } - } - } - return $output; -} - -sub undossify( $ ) { - # Remove "dossy" line ends ("\r\n") from a string - my $str = $_[0]; - $str =~ s/\r\n/\n/gs; - $str =~ s/\r$//s; - return( $str ); -} - -sub checkarg { - # Check if there is already an argument record $argname in $dat, if not, - # create one - my ($dat, $argname) = @_; - return if defined($dat->{'args_byname'}{$argname}); - # argument record - my $rec; - $rec->{'name'} = $argname; - # Insert record in 'args' array for browsing all arguments - push(@{$dat->{'args'}}, $rec); - # 'args_byname' hash for looking up arguments by name - $dat->{'args_byname'}{$argname} = $dat->{'args'}[$#{$dat->{'args'}}]; - # Default execution style is 'G' (PostScript) since all arguments for - # which we don't find "*Foomatic..." keywords are usual PostScript - # options - $dat->{'args_byname'}{$argname}{'style'} = 'G'; - # Default prototype for code to insert, used by enum options - $dat->{'args_byname'}{$argname}{'proto'} = '%s'; - # stop Perl nattering about undefined to string comparisons - $dat->{'args_byname'}{$argname}{'type'} = ''; - print $logh "Added option $argname\n"; -} - -sub checksetting { - # Check if there is already an choice record $setting in the $argname - # argument in $dat, if not, create one - my ($dat, $argname, $setting) = @_; - return if - defined($dat->{'args_byname'}{$argname}{'vals_byname'}{$setting}); - # setting record - my $rec; - $rec->{'value'} = $setting; - # Insert record in 'vals' array for browsing all settings - push(@{$dat->{'args_byname'}{$argname}{'vals'}}, $rec); - # 'vals_byname' hash for looking up settings by name - $dat->{'args_byname'}{$argname}{'vals_byname'}{$setting} = - $dat->{'args_byname'}{$argname}{'vals'}[$#{$dat->{'args_byname'}{$argname}{'vals'}}]; -} - -sub removearg { - # remove the argument record $argname from $dat - my ($dat, $argname) = @_; - return if !defined($dat->{'args_byname'}{$argname}); - # Remove 'args_byname' hash for looking up arguments by name - delete $dat->{'args_byname'}{$argname}; - # Remove argument itself - for (my $i = 0; $i <= $#{$dat->{'args'}}; $i ++) { - if ($dat->{'args'}[$i]{'name'} eq $argname) { - print $logh "Removing option " . - $argname . "\n"; - splice(@{$dat->{'args'}}, $i, 1); - last; - } - } -} - -sub removepsargs { - # remove all records of PostScript arguments from $dat - my ($dat) = @_; - return if !defined($dat); - for (my $i = 0; $i <= $#{$dat->{'args'}}; $i ++) { - if ($dat->{'args'}[$i]{'style'} eq 'G') { - print $logh "Removing PostScript option " . - $dat->{'args'}[$i]{'name'} . "\n"; - # Remove 'args_byname' hash for looking up arguments by name - delete $dat->{'args_byname'}{$dat->{'args'}[$i]{'name'}}; - # Remove argument itself - splice(@{$dat->{'args'}}, $i, 1); - $i --; - } - } -} - -sub checkoptionvalue { - - ## This function checks whether a given value is valid for a given - ## option. If yes, it returns a cleaned value (e. g. always 0 or 1 - ## for boolean options), otherwise "undef". If $forcevalue is set, - ## we always determine a corrected value to insert (we never return - ## "undef"). - - # Is $value valid for the option named $argname? - my ($dat, $argname, $value, $forcevalue) = @_; - - # Record for option $argname - my $arg = $dat->{'args_byname'}{$argname}; - $arg->{'type'} = '' if not defined $arg->{'type'}; - - if ($arg->{'type'} eq 'bool') { - my $lcvalue = lc($value); - if ((($lcvalue) eq 'true') || - (($lcvalue) eq 'on') || - (($lcvalue) eq 'yes') || - (($lcvalue) eq '1')) { - return 1; - } elsif ((($lcvalue) eq 'false') || - (($lcvalue) eq 'off') || - (($lcvalue) eq 'no') || - (($lcvalue) eq '0')) { - return 0; - } elsif ($forcevalue) { - # This maps Unknown to mean False. Good? Bad? - # It was done so in Foomatic 2.0.x, too. - my $name = $arg->{'name'}; - print $logh - "The value $value for $name is not a " . - "choice!\n" . - " --> Using False instead!\n"; - return 0; - } - } elsif ($arg->{'type'} eq 'enum') { - if ($value =~ /^None$/i) { - return 'None'; - } elsif (defined($arg->{'vals_byname'}{$value})) { - return $value; - } elsif ((($arg->{'name'} eq "PageSize") || - ($arg->{'name'} eq "PageRegion")) && - (defined($arg->{'vals_byname'}{'Custom'})) && - ($value =~ m!^Custom\.([\d\.]+)x([\d\.]+)([A-Za-z]*)$!)) { - # Custom paper size - return $value; - } elsif ($forcevalue) { - # wtf!? that's not a choice! - my $name = $arg->{'name'}; - # Return the first entry of the list - my $firstentry = $arg->{'vals'}[0]{'value'}; - print $logh - "The value $value for $name is not a " . - "choice!\n" . - " --> Using $firstentry instead!\n"; - return $firstentry; - } - } elsif (($arg->{'type'} eq 'int') || - ($arg->{'type'} eq 'float')) { - if (($value <= $arg->{'max'}) && - ($value >= $arg->{'min'})) { - if ($arg->{'type'} eq 'int') { - return POSIX::floor($value); - } else { - return $value; - } - } elsif ($forcevalue) { - my $name = $arg->{'name'}; - my $newvalue; - if ($value > $arg->{'max'}) { - $newvalue = $arg->{'max'} - } elsif ($value < $arg->{'min'}) { - $newvalue = $arg->{'min'} - } - print $logh - "The value $value for $name is out of " . - "range!\n" . - " --> Using $newvalue instead!\n"; - return $newvalue; - } - } elsif (($arg->{'type'} eq 'string') || - ($arg->{'type'} eq 'password')) { - if (defined($arg->{'vals_byname'}{$value})) { - my $name = $arg->{'name'}; - print $logh - "The value $value for $name is a predefined choice\n"; - return $value; - } elsif (stringvalid($dat, $argname, $value)) { - # Check whether the string is one of the enumerated choices - my $sprintfproto = $arg->{'proto'}; - $sprintfproto =~ s/\%(?!s)/\%\%/g; - my $driverval = sprintf($sprintfproto, $value); - for my $val (@{$arg->{'vals'}}) { - if (($val->{'driverval'} eq $driverval) || - ($val->{'driverval'} eq $value)) { - my $name = $arg->{'name'}; - print $logh - "The string $value for $name is the predefined " . - "choice $val->{value}\n"; - return $val->{value}; - } - } - # "None" is mapped to the empty string - if ($value eq 'None') { - my $name = $arg->{'name'}; - print $logh - "Option $name: 'None' is the mapped to the " . - "empty string\n"; - return ''; - } - # No matching choice? Return the original string - return $value; - } elsif ($forcevalue) { - my $name = $arg->{'name'}; - my $str = substr($value, 0, $arg->{'maxlength'}); - if (stringvalid($dat, $argname, $str)) { - print $logh - "The string $value for $name is longer than " . - "$arg->{'maxlength'}, string shortened to $str\n"; - return $str; - } elsif ($#{$arg->{'vals'}} >= 0) { - # First list item - my $firstentry = $arg->{'vals'}[0]{'value'}; - print $logh - "The string $value for $name contains forbidden " . - "characters or does not match the regular expression " . - "defined for this option, using predefined choice " . - "$firstentry instead\n"; - return $firstentry; - } else { - # We should not get here - rip_die("Option $name incorrectly defined in the " . - "PPD file!\n", $EXIT_PRNERR_NORETRY_BAD_SETTINGS); - } - } - } - return undef; -} - -sub stringvalid { - - ## Checks whether a user-supplied value for a string option is valid - ## It must be within the length limit, should only contain allowed - ## characters and match the given regexp - - # Option and string - my ($dat, $argname, $value) = @_; - - my $arg = $dat->{'args_byname'}{$argname}; - - # Maximum length - return 0 if (defined($arg->{'maxlength'}) && - (length($value) > $arg->{'maxlength'})); - - # Allowed characters - if ($arg->{'allowedchars'}) { - my $chars = $arg->{'allowedchars'}; - # Quote the slashes (if a slash is preceeded by an even number of - # backslashes, it is not already quoted) - $chars =~ s/(?<!\\)((\\\\)*)\//$2\\\//g; - return 0 if $value !~ /^[$chars]*$/; - } - - # Regular expression - if ($arg->{'allowedregexp'}) { - my $regexp = $arg->{'allowedregexp'}; - # Quote the slashes (if a slash is preceeded by an even number of - # backslashes, it is not already quoted) - $regexp =~ s/(?<!\\)((\\\\)*)\//$2\\\//g; - return 0 if $value !~ /$regexp/; - } - - # All checks passed - return 1; -} - -sub checkoptions { - - ## Let the values of a boolean option being 0 or 1 instead of - ## "True" or "False", range-check the defaults of all options and - ## issue warnings if the values are not valid - - # Option set to be examined - my ($dat, $optionset) = @_; - - for my $arg (@{$dat->{'args'}}) { - if (defined($arg->{$optionset})) { - $arg->{$optionset} = - checkoptionvalue - ($dat, $arg->{'name'}, $arg->{$optionset}, 1); - } - } - - # If the settings for "PageSize" and "PageRegion" are different, - # set the one for "PageRegion" to the one for "PageSize" and issue - # a warning. - if ($dat->{'args_byname'}{'PageSize'}{$optionset} ne - $dat->{'args_byname'}{'PageRegion'}{$optionset}) { - print $logh "Settings for \"PageSize\" and \"PageRegion\" are " . - "different:\n" . - " PageSize: $dat->{'args_byname'}{'PageSize'}{$optionset}\n" . - " PageRegion: ". - "$dat->{'args_byname'}{'PageRegion'}{$optionset}\n" . - "Using the \"PageSize\" value " . - "\"$dat->{'args_byname'}{'PageSize'}{$optionset}\"," . - " for both.\n"; - $dat->{'args_byname'}{'PageRegion'}{$optionset} = - $dat->{'args_byname'}{'PageSize'}{$optionset}; - } -} - -# If the PageSize or PageRegion was changed, also change the other - -sub syncpagesize { - - # Name and value of the option we set, and the option set where we - # did the change - my ($dat, $name, $value, $optionset) = @_; - - # Don't do anything if we were called with an option other than - # "PageSize" or "PageRegion" - return if (($name ne "PageSize") && ($name ne "PageRegion")); - - # Don't do anything if not both "PageSize" and "PageRegion" exist - return if ((!defined($dat->{'args_byname'}{'PageSize'})) || - (!defined($dat->{'args_byname'}{'PageRegion'}))); - - my $dest; - - # "PageSize" --> "PageRegion" - if ($name eq "PageSize") { - $dest = "PageRegion"; - } - - # "PageRegion" --> "PageSize" - if ($name eq "PageRegion") { - $dest = "PageSize"; - } - - # Do it! - my $val; - if ($val=valbyname($dat->{'args_byname'}{$dest}, $value)) { - # Standard paper size - $dat->{'args_byname'}{$dest}{$optionset} = $val->{'value'}; - } elsif ($val=valbyname($dat->{'args_byname'}{$dest}, "Custom")) { - # Custom paper size - $dat->{'args_byname'}{$dest}{$optionset} = $value; - } -} - -sub copyoptions { - - ## Copy one option set into another one - - # Source and destination option sets - my ($dat, $srcoptionset, $destoptionset) = @_; - - for my $arg (@{$dat->{'args'}}) { - if (defined($arg->{$srcoptionset})) { - $arg->{$destoptionset} = $arg->{$srcoptionset}; - } - } -} - -sub deleteoptions { - - ## Delete an option set - - # option set to be removed - my ($dat, $optionset) = @_; - - for my $arg (@{$dat->{'args'}}) { - if (defined($arg->{$optionset})) { - delete($arg->{$optionset}); - } - } -} - -sub optionsequal { - - ## Compare two option sets, if they are equal, return 1, otherwise 0 - - # Option sets to be compared, flag to compare only command line and JCL - # options - my ($dat, $firstoptionset, $secondoptionset, $exceptPS) = @_; - - for my $arg (@{$dat->{'args'}}) { - next if ($exceptPS && ($arg->{'style'} eq 'G')); - if ((defined($arg->{$firstoptionset})) && - (defined($arg->{$secondoptionset}))) { - # Both entries exist - return 0 if $arg->{$firstoptionset} ne $arg->{$secondoptionset}; - } elsif ((defined($arg->{$firstoptionset})) || - (defined($arg->{$secondoptionset}))) { - # One entry exists - return 0; - } - # If no entry exists, the non-existing entries are considered as - # equal - } - return 1; -} - -sub makeprologsection { - - # option set to be used, - # $comments = 1: Add "%%BeginProlog...%%EndProlog" - my ($dat, $optionset, $comments) = @_; - - # Collect data to be inserted here - my @output; - - # Start comment - if ($comments) { - print $logh "\"Prolog\" section is missing, inserting it.\n"; - push(@output, "%%BeginProlog\n"); - } - - # Generate the option code (not necessary when CUPS is spooler) - if ($spooler ne 'cups') { - print $logh "Inserting option code into \"Prolog\" section.\n"; - buildcommandline ($dat, $optionset); - push(@output, @{$dat->{'prologprepend'}}); - } - - # End comment - if ($comments) { - push(@output, "%%EndProlog\n"); - } - - return join('', @output); -} - -sub makesetupsection { - - # option set to be used, $comments = 1: Add "%%BeginSetup...%%EndSetup" - my ($dat, $optionset, $comments) = @_; - - # Collect data to be inserted here - my @output; - - # Start comment - if ($comments) { - print $logh "\"Setup\" section is missing, inserting it.\n"; - push(@output, "%%BeginSetup\n"); - } - - # PostScript code to generate accounting messages for CUPS - if ($spooler eq 'cups') { - print $logh "Inserting PostScript code for CUPS' page accounting\n"; - push(@output, $accounting_prolog); - } - - # Generate the option code (not necessary when CUPS is spooler) - if ($spooler ne 'cups') { - print $logh "Inserting option code into \"Setup\" section.\n"; - buildcommandline ($dat, $optionset); - push(@output, @{$dat->{'setupprepend'}}); - } - - # End comment - if ($comments) { - push(@output, "%%EndSetup\n"); - } - - return join('', @output); -} - -sub makepagesetupsection { - - # option set to be used, - # $comments = 1: Add "%%BeginPageSetup...%%EndPageSetup" - my ($dat, $optionset, $comments) = @_; - - # Collect data to be inserted here - my @output; - - # Start comment - if ($comments) { - push(@output, "%%BeginPageSetup\n"); - print $logh "\"PageSetup\" section is missing, inserting it.\n"; - } - - # Generate the option code (not necessary when CUPS is spooler) - print $logh "Inserting option code into \"PageSetup\" section.\n"; - buildcommandline ($dat, $optionset); - if ($spooler ne 'cups') { - push(@output, @{$dat->{'pagesetupprepend'}}); - } else { - push(@output, @{$dat->{'cupspagesetupprepend'}}); - } - - # End comment - if ($comments) { - push(@output, "%%EndPageSetup\n"); - } - - return join('', @output); -} - -sub parsepageranges { - - ## Parse a string containing page ranges and either check whether a - ## given page is in the ranges or, if the given page number is zero, - ## determine the score how specific this page range string is. - - # String with page ranges and number of current page (0 for score) - my ($ranges, $page) = @_; - - my $currentnumber = 0; - my $rangestart = 0; - my $currentkeyword = ''; - my $invalidrange = 0; - my $totalscore = 0; - my $pageinside = 0; - my $currentrange = ''; - - my $evaluaterange = sub { - # evaluate the current range: determine its score and whether the - # current page is member of it. - if ($invalidrange) { - # Range is invalid, issue a warning - print $logh " Invalid range: $currentrange\n"; - } else { - # We have a valid range, evaluate it - if ($currentkeyword) { - if ($currentkeyword =~ /^even/i) { - # All even-numbered pages - $totalscore += 50000; - $pageinside = 1 if (($page % 2) == 0); - } elsif ($currentkeyword =~ /^odd/i) { - # All odd-numbered pages - $totalscore += 50000; - $pageinside = 1 if (($page % 2) == 1); - } else { - # Invalid range - print $logh " Invalid range: $currentrange\n"; - } - } elsif (($rangestart == 0) && ($currentnumber > 0)) { - # Page range is a single page - $totalscore += 1; - $pageinside = 1 if ($page == $currentnumber); - } elsif (($rangestart > 0) && ($currentnumber > 0)) { - # Page range is a sequence of pages - $totalscore += (abs($currentnumber - $rangestart) + 1); - if ($currentnumber < $rangestart) { - my $tmp = $currentnumber; - $currentnumber = $rangestart; - $rangestart = $tmp; - } - $pageinside = 1 if (($page <= $currentnumber) && - ($page >= $rangestart)); - } elsif ($rangestart > 0) { - # Page range goes to the end of the document - $totalscore += 100000; - $pageinside = 1 if ($page >= $rangestart); - } else { - # Invalid range - print $logh " Invalid range: $currentrange\n"; - } - } - # Range is evaluated, remove all recordings of the current range - $rangestart = 0; - $currentnumber = 0; - $currentkeyword = ''; - $invalidrange = 0; - $currentrange = ''; - }; - - for (my $i = 0; $i < length($ranges); $i ++) { - my $c = substr($ranges, $i, 1); - if (!$invalidrange) { - if ($c =~ /\d/) { - # Digit - if ($currentkeyword) { - # Add to keyword - $currentkeyword .= $c; - } else { - # Build a page number - $currentnumber *= 10; - $currentnumber += $c; - } - } elsif ($c =~ /[a-z_]/i) { - # Letter or underscore - if (($rangestart > 0) || ($currentnumber > 0)) { - # Keyword not allowed after a page number or a - # page range - $invalidrange = 1; - } else { - # Build a keyword - $currentkeyword .= $c; - } - } elsif ($c eq '-') { - # Page range - if (($rangestart > 0) || ($currentkeyword)) { - # Keyword or two '-' not allowed in page range - $invalidrange = 1; - } else { - # Save start of range, reset page number - $rangestart = $currentnumber; - if ($rangestart == 0) { - $rangestart = 1; - } - $currentnumber = 0; - } - } - } - if ($c eq ',') { - # End of a range - &$evaluaterange(); - } else { - # Make a string of the current range, for warnings - $currentrange .= $c; - } - } - # End of input string - &$evaluaterange(); - # Return value - if (($page == 0) || ($pageinside)) { - return $totalscore; - } else { - return 0; - } -} - -sub setoptionsforpage { - - ## Set the options for a given page - - # Foomatic data, name of the option set where to apply the options, and - # number of the page - my ($dat, $optionset, $page) = @_; - - my $value; - for my $arg (@{$dat->{'args'}}) { - $value = ''; - my $bestscore = 10000000; - for my $key (keys %{$arg}) { - next if $key !~ /^pages:(.*)$/; - my $pageranges = $1; - if (my $score = parsepageranges($pageranges, $page)) { - if ($score <= $bestscore) { - $bestscore = $score; - $value = $arg->{$key}; - } - } - } - if ($value) { - $arg->{$optionset} = $value; - } - } -} - -sub buildcommandline { - - ## Build a renderer command line, based on the given option set - - # Foomatic data and name of the option set to apply - my ($dat, $optionset) = @_; - - # Construct the proper command line. - $dat->{'currentcmd'} = $dat->{'cmd'}; - my @prologprepend; - my @setupprepend; - my @pagesetupprepend; - my @cupspagesetupprepend; - my @jclprepend; - my @jclappend; - - # At first search for composite options and determine how they - # set their member options - for my $arg (@{$dat->{'args'}}) { $arg->{'order'} = 0 if !defined $arg->{'order'}; } - for my $arg (sort { $a->{'order'} <=> $b->{'order'} } - @{$dat->{'args'}}) { - - # Here we are only interested in composite options, skip the others - next if $arg->{'style'} ne 'X'; - - my $name = $arg->{'name'}; - # Check whether this composite option is controlled by another - # composite option, so nested composite options are possible. - my $userval = ($arg->{'fromcomposite'} ? - $arg->{'fromcomposite'} : $arg->{$optionset}); - - # Get the current setting - my $v = $arg->{'vals_byname'}{$userval}; - my @settings = split(/\s+/s, $v->{'driverval'}); - for my $s (@settings) { - my ($key, $value); - if ($s =~ /^([^=]+)=(.+)$/) { - $key = $1; - $value = $2; - } elsif ($s =~ /^no([^=]+)$/) { - $key = $1; - $value = 0; - } elsif ($s =~ /^([^=]+)$/) { - $key = $1; - $value = 1; - } - $a = $dat->{'args_byname'}{$key}; - if ($a->{$optionset} eq "From$name") { - # We must set this option according to the - # composite option - $a->{'fromcomposite'} = $value; - # Mark the option telling by which composite option - # it is controlled - $a->{'controlledby'} = $name; - } else { - $a->{'fromcomposite'} = ""; - } - } - # Remove PostScript code to be inserted after an appearance of the - # Composite option in the PostScript code. - undef $arg->{'jclsetup'}; - undef $arg->{'prolog'}; - undef $arg->{'setup'}; - undef $arg->{'pagesetup'}; - } - - for my $arg (sort { $a->{'order'} <=> $b->{'order'} } - @{$dat->{'args'}}) { - - # Composite options have no direct influence on the command - # line, skip them here - next if $arg->{'style'} eq 'X'; - - my $name = $arg->{'name'}; - my $spot = $arg->{'spot'}; - my $cmd = $arg->{'proto'}; - my $cmdf = $arg->{'protof'}; - my $type = ($arg->{'type'} || ""); - my $section = $arg->{'section'}; - my $userval = ($arg->{'fromcomposite'} ? - $arg->{'fromcomposite'} : $arg->{$optionset}); - my $cmdvar = ""; - - # If we have both "PageSize" and "PageRegion" options, we kept - # them all the time in sync, so we don't need to insert the settings - # of both options. So skip "PageRegion". - next if (($name eq "PageRegion") && - (defined($dat->{'args_byname'}{'PageSize'})) && - (defined($dat->{'args_byname'}{'PageRegion'}))); - - # Build the command line snippet/PostScript/JCL code for the current - # option - if ($type eq 'bool') { - - # If true, stick the proto into the command line, if false - # and we have a proto for false, stick that in - if (defined($userval) && $userval == 1) { - $cmdvar = $cmd; - } elsif ($cmdf) { - $userval = 0; - $cmdvar = $cmdf; - } - - } elsif ($type eq 'int' or $type eq 'float') { - - # If defined, process the proto and stick the result into - # the command line or postscript queue. - if (defined($userval)) { - my $min = $arg->{'min'}; - my $max = $arg->{'max'}; - # We have already range-checked, correct only - # floating point inaccuricies here - if ($userval < $min) { - $userval = $min; - } - if ($userval > $max) { - $userval = $max; - } - my $sprintfcmd = $cmd; - $sprintfcmd =~ s/\%(?!s)/\%\%/g; - $cmdvar = sprintf($sprintfcmd, - ($type eq 'int' - ? sprintf("%d", $userval) - : sprintf("%f", $userval))); - } else { - $userval = 'None'; - } - - } elsif ($type eq 'enum') { - - # If defined, stick the selected value into the proto and - # thence into the commandline - if (defined($userval)) { - # CUPS assumes that options with the choices "Yes", "No", - # "On", "Off", "True", or "False" are boolean options and - # maps "-o Option=On" to "-o Option" and "-o Option=Off" - # to "-o noOption", which foomatic-rip maps to "0" and "1". - # So when "0" or "1" is unavailable in the option, we try - # "Yes", "No", "On", "Off", "True", and "False". - my $val; - my $found = 0; - if ($val=valbyname($arg,$userval)) { - $found = 1; - } elsif ($userval =~ /^Custom\.[\d\.]+x[\d\.]+[A-Za-z]*$/) { - # Custom paper size - $val = valbyname($arg,"Custom"); - $found = 1; - } elsif ($userval =~ /^(0|No|Off|False)$/i) { - foreach (qw(0 No Off False None)) { - if ($val=valbyname($arg,$_)) { - $userval = $_; - $arg->{$optionset} = $userval; - $found = 1; - last; - } - } - } elsif ($userval =~ /^(1|Yes|On|True)$/i) { - foreach (qw(1 Yes On True)) { - if ($val=valbyname($arg,$_)) { - $userval = $_; - $arg->{$optionset} = $userval; - $found = 1; - last; - } - } - } elsif ($userval =~ /^(LongEdge|DuplexNoTumble)$/i) { - # Handle different names for the choices of the - # "Duplex" option - foreach (qw(LongEdge DuplexNoTumble)) { - if ($val=valbyname($arg,$_)) { - $userval = $_; - $arg->{$optionset} = $userval; - $found = 1; - last; - } - } - } elsif ($userval =~ /^(ShortEdge|DuplexTumble)$/i) { - foreach (qw(ShortEdge DuplexTumble)) { - if ($val=valbyname($arg,$_)) { - $userval = $_; - $arg->{$optionset} = $userval; - $found = 1; - last; - } - } - } - if ($found) { - my $sprintfcmd = $cmd; - $sprintfcmd =~ s/\%(?!s)/\%\%/g; - $cmdvar = sprintf($sprintfcmd, - (defined($val->{'driverval'}) - ? $val->{'driverval'} - : $val->{'value'})); - # Custom paper size - if ($userval =~ /^Custom\.([\d\.]+)x([\d\.]+)([A-Za-z]*)$/) { - my $width = $1; - my $height = $2; - my $unit = $3; - # convert width and height to PostScript points - if (lc($unit) eq "in") { - $width *= 72.0; - $height *= 72.0; - } elsif (lc($unit) eq "cm") { - $width *= (72.0/2.54); - $height *= (72.0/2.54); - } elsif (lc($unit) eq "mm") { - $width *= (72.0/25.4); - $height *= (72.0/25.4); - } - # Round width and height - $width =~ s/\.[0-4].*$// or - $width =~ s/\.[5-9].*$// and $width += 1; - $height =~ s/\.[0-4].*$// or - $height =~ s/\.[5-9].*$// and $height += 1; - # Insert width and height into the prototype - if ($cmdvar =~ /^\s*pop\W/s) { - # Custom page size for PostScript printers - $cmdvar = "$width $height 0 0 0\n$cmdvar"; - } else { - # Custom page size for Foomatic/Gutenprint/ - # Gimp-Print - $cmdvar =~ s/\%0/$width/ or - $cmdvar =~ s/(\W)0(\W)/$1$width$2/ or - $cmdvar =~ s/^0(\W)/$width$1/m or - $cmdvar =~ s/(\W)0$/$1$width/m or - $cmdvar =~ s/^0$/$width/m; - $cmdvar =~ s/\%1/$height/ or - $cmdvar =~ s/(\W)0(\W)/$1$height$2/ or - $cmdvar =~ s/^0(\W)/$height$1/m or - $cmdvar =~ s/(\W)0$/$1$height/m or - $cmdvar =~ s/^0$/$height/m; - } - } - } else { - # User gave unknown value? - $userval = 'None'; - print $logh "Value $userval for $name is not a valid choice.\n"; - } - } else { - $userval = 'None'; - } - - } elsif (($type eq 'string') || ($type eq 'password')) { - # Stick the entered value into the proto and - # thence into the commandline - if (defined($userval)) { - my $val; - if ($val=valbyname($arg,$userval)) { - $userval = $val->{'value'}; - $cmdvar = (defined($val->{'driverval'}) - ? $val->{'driverval'} - : $val->{'value'}); - } else { - my $sprintfcmd = $cmd; - $sprintfcmd =~ s/\%(?!s)/\%\%/g; - $cmdvar = sprintf($sprintfcmd, $userval); - } - } else { - $userval = 'None'; - } - - } else { - # Ignore unknown option types silently - } - - # Insert the built snippet at the correct place - if ($arg->{'style'} eq 'G') { - # Place this Postscript command onto the prepend queue - # for the appropriate section. - if ($cmdvar) { - my $open = "[{\n%%BeginFeature: *$name "; - if ($type eq 'bool') { - $open .= ($userval == 1 ? "True" : "False") . "\n"; - } else { - $open .= "$userval\n"; - } - my $close = "\n%%EndFeature\n} stopped cleartomark\n"; - if ($section eq "Prolog") { - push (@prologprepend, "$open$cmdvar$close"); - my $a = $arg; - while ($a->{'controlledby'}) { - # Collect option PostScript code to be inserted when - # the composite option which controls this option - # is found in the PostScript code - $a = $dat->{'args_byname'}{$a->{'controlledby'}}; - $a->{'prolog'} .= "$cmdvar\n"; - } - } elsif ($section eq "AnySetup") { - if ($optionset ne 'currentpage') { - push (@setupprepend, "$open$cmdvar$close"); - } elsif ($arg->{'header'} ne $userval) { - push (@pagesetupprepend, "$open$cmdvar$close"); - push (@cupspagesetupprepend, "$open$cmdvar$close"); - } - my $a = $arg; - while ($a->{'controlledby'}) { - # Collect option PostScript code to be inserted when - # the composite option which controls this option - # is found in the PostScript code - $a = $dat->{'args_byname'}{$a->{'controlledby'}}; - $a->{'setup'} .= "$cmdvar\n"; - $a->{'pagesetup'} .= "$cmdvar\n"; - } - } elsif ($section eq "DocumentSetup") { - push (@setupprepend, "$open$cmdvar$close"); - my $a = $arg; - while ($a->{'controlledby'}) { - # Collect option PostScript code to be inserted when - # the composite option which controls this option - # is found in the PostScript code - $a = $dat->{'args_byname'}{$a->{'controlledby'}}; - $a->{'setup'} .= "$cmdvar\n"; - } - } elsif ($section eq "PageSetup") { - push (@pagesetupprepend, "$open$cmdvar$close"); - my $a = $arg; - while ($a->{'controlledby'}) { - # Collect option PostScript code to be inserted when - # the composite option which controls this option - # is found in the PostScript code - $a = $dat->{'args_byname'}{$a->{'controlledby'}}; - $a->{'pagesetup'} .= "$cmdvar\n"; - } - } elsif ($section eq "JCLSetup") { - # PJL/JCL argument - $dat->{'jcl'} = 1; - push (@jclprepend, unhexify($cmdvar)); - my $a = $arg; - while ($a->{'controlledby'}) { - # Collect option PostScript code to be inserted when - # the composite option which controls this option - # is found in the PostScript code - $a = $dat->{'args_byname'}{$a->{'controlledby'}}; - $a->{'jclsetup'} .= "$cmdvar\n"; - } - } else { - push (@setupprepend, "$open$cmdvar$close"); - my $a = $arg; - while ($a->{'controlledby'}) { - # Collect option PostScript code to be inserted when - # the composite option which controls this option - # is found in the PostScript code - $a = $dat->{'args_byname'}{$a->{'controlledby'}}; - $a->{'setup'} .= "$cmdvar\n"; - } - } - } - # Do we have an option which is set to "Controlled by - # '<Composite>'"? Then make PostScript code available - # for substitution of "%% FoomaticRIPOptionSetting: ..." - if ($arg->{'fromcomposite'}) { - $arg->{'compositesubst'} = "$cmdvar\n"; - } - } elsif ($arg->{'style'} eq 'J') { - # JCL argument - $dat->{'jcl'} = 1; - # put JCL commands onto JCL stack... - push (@jclprepend, "$jclprefix$cmdvar\n") if $cmdvar; - } elsif ($arg->{'style'} eq 'C') { - # command-line argument - - # Insert the processed argument in the commandline - # just before every occurance of the spot marker. - $dat->{'currentcmd'} =~ s!\%$spot!$cmdvar\%$spot!g; - } - # Insert option into command line of CUPS raster driver - if ($dat->{'currentcmd'} =~ m!\%Y!) { - next if !defined($userval) or $userval eq ""; - $dat->{'currentcmd'} =~ s!\%Y!$name=$userval \%Y!g; - } - # Remove the marks telling that this option is currently controlled - # by a composite option (setting "From<composite>") - undef $arg->{'fromcomposite'}; - undef $arg->{'controlledby'}; - } - - - ### Tidy up after computing option statements for all of P, J, and - ### C types: - - ## C type finishing - # Pluck out all of the %n's from the command line prototype - my @letters = qw/A B C D E F G H I J K L M W X Y Z/; - for my $spot (@letters) { - # Remove the letter markers from the commandline - $dat->{'currentcmd'} =~ s!\%$spot!!g; - } - - ## J type finishing - # Compute the proper stuff to say around the job - - if ((defined($dat->{'jcl'})) && (!$jobhasjcl)) { - - # Stick beginning of job cruft on the front of the jcl stuff... - unshift (@jclprepend, $jclbegin); - - # Command to switch to the interpreter - push (@jclprepend, $jcltointerpreter); - - # Arrange for JCL RESET command at end of job - push (@jclappend, $jclend); - - # Put the JCL stuff into the data structure - @{$dat->{'jclprepend'}} = @jclprepend; - @{$dat->{'jclappend'}} = @jclappend; - } - - ## G type finishing - # Save PostScript options - @{$dat->{'prologprepend'}} = @prologprepend; - @{$dat->{'setupprepend'}} = @setupprepend; - @{$dat->{'pagesetupprepend'}} = @pagesetupprepend; - @{$dat->{'cupspagesetupprepend'}} = @cupspagesetupprepend; -} - -sub buildpdqdriver { - - # Build a PDQ driver description file to use the given PPD file - # together with foomatic-rip with the PDQ printing system - - # Foomatic data and name of the option set for the default settings - my ($dat, $optionset) = @_; - - # Construct structure with driver information - my @pdqdriver = (); - - # Construct option list - my @driveropts = (); - - # Do we have a "Custom" setting for the page size? - # Then we have to insert the following into the "filter_exec" script. - my @setcustompagesize = (); - - # Fata for a custom page size, to allow a custom size as default - my $pagewidth = 612; - my $pageheight = 792; - my $pageunit = "pt"; - - - - ## First, compute the various option/value clauses - for my $arg (@{$dat->{'args'}}) { - - if ($arg->{'type'} eq "enum") { - - # Option with only one choice, omit it, foomatic-rip will set - # this choice anyway. - next if ($#{$arg->{'vals'}} < 1); - - my $nam = $arg->{'name'}; - - # Omit "PageRegion" option, it does the same as "PageSize". - next if $nam eq "PageRegion"; - - my $com = $arg->{'comment'}; - - # Assure that the comment is not empty - if (!$com) { - $com = $nam; - } - - my $def = $arg->{$optionset}; - $arg->{'varname'} = "$nam"; - $arg->{'varname'} =~ s![\-\/\.]!\_!g; - my $varn = $arg->{'varname'}; - - # 1, if setting "PageSize=Custom" was found - # Then we must add options for page width and height - my $custompagesize = 0; - - # If the default is a custom size we have to set also - # defaults for the width, height, and units of the page - if (($nam eq "PageSize") && - ($def =~ /^Custom\.([\d\.]+)x([\d\.]+)([A-Za-z]*)$/)) { - $def = "Custom"; - $pagewidth = $1; - $pageheight = $2; - $pageunit = $3; - } - - # No quotes, thank you. - $com =~ s!\"!\\\"!g; - - push(@driveropts, - " option {\n", - " var = \"$varn\"\n", - " desc = \"$com\"\n"); - - # get enumeration values for each enum arg - my ($ev, @vals, @valstmp); - for $ev (@{$arg->{'vals'}}) { - my $choiceshortname = $ev->{'value'}; - my $choicename = "${nam}_${choiceshortname}"; - my $val = " -o ${nam}=${choiceshortname}"; - my $com = $ev->{'comment'}; - - # Assure that the comment is not empty - if (!$com) { - $com = $choiceshortname; - } - - # stick another choice on driveropts - push(@valstmp, - " choice \"$choicename\" {\n", - " desc = \"$com\"\n", - " value = \"$val\"\n", - " }\n"); - if (($nam eq "PageSize") && - ($choiceshortname eq "Custom")) { - $custompagesize = 1; - if ($#setcustompagesize < 0) { - push(@setcustompagesize, - " # Custom page size settings\n", - " # We aren't really checking for " . - "legal vals.\n", - " if [ \"x\${$varn}\" = 'x$val' ]; " . - "then\n", - " $varn=\"\${$varn}.\${PageWidth}" . - "x\${PageHeight}\${PageSizeUnit}\"\n", - " fi\n\n"); - } - } - } - - push(@driveropts, - " default_choice \"" . $nam . "_" . $def . "\"\n", - @valstmp, - " }\n\n"); - - if ($custompagesize) { - # Add options to set the custom page size - push(@driveropts, - " argument {\n", - " var = \"PageWidth\"\n", - " desc = \"Page Width (for \\\"Custom\\\" page " . - "size)\"\n", - " def_value \"$pagewidth\"\n", - " help = \"Minimum value: 0, Maximum value: " . - "100000\"\n", - " }\n\n", - " argument {\n", - " var = \"PageHeight\"\n", - " desc = \"Page Height (for \\\"Custom\\\" page " . - "size)\"\n", - " def_value \"$pageheight\"\n", - " help = \"Minimum value: 0, Maximum value: " . - "100000\"\n", - " }\n\n", - " option {\n", - " var = \"PageSizeUnit\"\n", - " desc = \"Unit (for \\\"Custom\\\" page size)\"\n", - " default_choice \"PageSizeUnit_$pageunit\"\n", - " choice \"PageSizeUnit_pt\" {\n", - " desc = \"Points (1/72 inch)\"\n", - " value = \"pt\"\n", - " }\n", - " choice \"PageSizeUnit_in\" {\n", - " desc = \"Inches\"\n", - " value = \"in\"\n", - " }\n", - " choice \"PageSizeUnit_cm\" {\n", - " desc = \"cm\"\n", - " value = \"cm\"\n", - " }\n", - " choice \"PageSizeUnit_mm\" {\n", - " desc = \"mm\"\n", - " value = \"mm\"\n", - " }\n", - " }\n\n"); - } - - } elsif ($arg->{'type'} eq 'int' or $arg->{'type'} eq 'float') { - - my $nam = $arg->{'name'}; - my $com = $arg->{'comment'}; - - # Assure that the comment is not empty - if (!$com) { - $com = $nam; - } - - my $def = $arg->{$optionset}; - my $max = $arg->{'max'}; - my $min = $arg->{'min'}; - $arg->{'varname'} = "$nam"; - $arg->{'varname'} =~ s![\-\/\.]!\_!g; - my $varn = $arg->{'varname'}; - my $legal = $arg->{'legal'} = - "Minimum value: $min, Maximum value: $max"; - - my $defstr = ""; - if ($def) { - $defstr = sprintf(" def_value \"%s\"\n", $def); - } - - push(@driveropts, - " argument {\n", - " var = \"$varn\"\n", - " desc = \"$com\"\n", - $defstr, - " help = \"$legal\"\n", - " }\n\n"); - - } elsif ($arg->{'type'} eq 'bool') { - - my $nam = $arg->{'name'}; - my $com = $arg->{'comment'}; - - # Assure that the comment is not empty - if (!$com) { - $com = $nam; - } - - my $tcom = $arg->{'comment_true'}; - my $fcom = $arg->{'comment_false'}; - my $def = $arg->{$optionset}; - $arg->{'legal'} = "Value is a boolean flag"; - $arg->{'varname'} = "$nam"; - $arg->{'varname'} =~ s![\-\/\.]!\_!g; - my $varn = $arg->{'varname'}; - - my $defstr = ""; - if ($def) { - $defstr = sprintf(" default_choice \"%s\"\n", - $def ? "$nam" : "no$nam"); - } else { - $defstr = sprintf(" default_choice \"%s\"\n", "no$nam"); - } - push(@driveropts, - " option {\n", - " var = \"$varn\"\n", - " desc = \"$com\"\n", - $defstr, - " choice \"$nam\" {\n", - " desc = \"$tcom\"\n", - " value = \" -o $nam=True\"\n", - " }\n", - " choice \"no$nam\" {\n", - " desc = \"$fcom\"\n", - " value = \" -o $nam=False\"\n", - " }\n", - " }\n\n"); - - } elsif ($arg->{'type'} eq 'string' or $arg->{'type'} eq 'password') { - - my $nam = $arg->{'name'}; - my $com = $arg->{'comment'}; - - # Assure that the comment is not empty - if (!$com) { - $com = $nam; - } - - my $def = $arg->{$optionset}; - my $maxlength = $arg->{'maxlength'}; - my $proto = $arg->{'proto'}; - $arg->{'varname'} = "$nam"; - $arg->{'varname'} =~ s![\-\/\.]!\_!g; - my $varn = $arg->{'varname'}; - - my $legal; - if (defined($maxlength)) { - $legal .= "Maximum length: $maxlength characters, "; - } - $legal .= "Examples/special settings: "; - for (@{$arg->{'vals'}}) { - my ($value, $comment, $driverval) = - ($_->{'value'}, $_->{'comment'}, $_->{'driverval'}); - # Retrieve the original string from the prototype - # and the driverval - my $string; - if ($proto) { - my $s = index($proto, '%s'); - my $l = length($driverval) - length($proto) + 2; - if (($s < 0) || ($l < 0)) { - $string = $driverval; - } else { - $string = substr($driverval, $s, $l); - } - } else { - $string = $driverval; - } - if ($value ne $string) { - $legal .= "${value}: \\\"$string\\\""; - } else { - $legal .= "\\\"$value\\\""; - } - if ($comment && ($value ne $comment) && - ($string ne $comment) && - (($value ne 'None') || ($comment ne '(None)'))) { - $legal .= " ($comment)"; - } - $legal .= "; "; - } - $legal =~ s/; $//; - - $arg->{'legal'} = $legal; - - my $defstr = ""; - if ($def) { - $defstr = sprintf(" def_value \"%s\"\n", $def); - } - - push(@driveropts, - " argument {\n", - " var = \"$varn\"\n", - " desc = \"$com\"\n", - $defstr, - " help = \"$legal\"\n", - " }\n\n"); - - } - - } - - - - ## Define the "docs" option to print the driver documentation page - - push(@driveropts, - " option {\n", - " var = \"DRIVERDOCS\"\n", - " desc = \"Print driver usage information\"\n", - " default_choice \"nodocs\"\n", - " choice \"docs\" {\n", - " desc = \"Yes\"\n", - " value = \" -o docs\"\n", - " }\n", - " choice \"nodocs\" {\n", - " desc = \"No\"\n", - " value = \"\"\n", - " }\n", - " }\n\n"); - - - - ## Build the "foomatic-rip" command line - my $commandline = "foomatic-rip --pdq"; - if ($printer) { - $commandline .= " -P $printer"; - } else { - # Make sure that the PPD file is entered with an absolute path - if ($ppdfile !~ m!^/!) { - my $pwd = cwd; - $ppdfile = "$pwd/$ppdfile"; - } - $commandline .= " --ppd=$ppdfile"; - } - for my $arg (@{$dat->{'args'}}) { - if ($arg->{'varname'}) { - $commandline .= "\${$arg->{'varname'}}"; - } - } - $commandline .= "\${DRIVERDOCS} \$INPUT > \$OUTPUT"; - - - - ## Now we generate code to build the command line snippets for the - ## numerical options - - my @psfilter; - for my $arg (@{$dat->{'args'}}) { - - # Only numerical and string options need to be treated here - next if (($arg->{'type'} ne 'int') && - ($arg->{'type'} ne 'float') && - ($arg->{'type'} ne 'string') && - ($arg->{'type'} ne 'password')); - - my $comment = $arg->{'comment'}; - my $name = $arg->{'name'}; - my $varname = $arg->{'varname'}; - - # If the option's variable is non-null, put in the - # argument. Otherwise this option is the empty - # string. Error checking? - - push(@psfilter, - " # $comment\n", - (($arg->{'type'} eq 'int') || ($arg->{'type'} eq 'float') ? - (" # We aren't really checking for max/min,\n", - " # this is done by foomatic-rip\n", - " if [ \"x\${$varname}\" != 'x' ]; then\n ") : ""), - #" $varname=`echo \${$varname} | perl -p -e \"s/'/'\\\\\\\\\\\\\\\\''/g\"`\n", - " $varname=\" -o $name='\${$varname}'\"\n", - (($arg->{'type'} eq 'int') || ($arg->{'type'} eq 'float') ? - " fi\n" : ""), - "\n"); - } - - # Command execution - - push(@psfilter, - " if ! test -e \$INPUT.ok; then\n", - " sh -c \"$commandline\"\n", - " if ! test -e \$OUTPUT; then \n", - " echo 'Error running foomatic-rip; no output!'\n", - " exit 1\n", - " fi\n", - " else\n", - " ln -s \$INPUT \$OUTPUT\n", - " fi\n\n"); - - my $version = time(); - my $name = "$model-$version"; - $name =~ s/\W/\-/g; - $name =~ s/\-+/\-/g; - - my $pname = $model; - - push (@pdqdriver, - "driver \"$name\" {\n\n", - " # This PDQ driver declaration file was generated " . - "automatically by\n", - " # foomatic-rip from information in the file $ppdfile.\n", - " # It allows printing with PDQ on the $pname.\n", - "\n", - " requires \"foomatic-rip\"\n\n", - @driveropts, - " language_driver all {\n", - " # We accept all file types and pass them to foomatic-rip\n", - " # (invoked in \"filter_exec {}\" section) without\n", - " # pre-filtering\n", - " filetype_regx \"\"\n", - " convert_exec {\n", - " ln -s \$INPUT \$OUTPUT\n", - " }\n", - " }\n\n", - " filter_exec {\n", - @setcustompagesize, - @psfilter, - " }\n", - "}\n"); - - return @pdqdriver; - -} - -# -# Convert lp or ipp based attribute names (and values) to something that matches# PPD file options. -# -sub option_to_ppd { - my ($ipp_attribute) = @_; - my ($key, $value, $result) = (); - - if (/([^=]+)=[\'\"]?(.*}[\'\"]?)/) { # key=value - ($key, $value) = ($1, $2); - } elsif (/no(.+)/) { # BOOLEAN: no{key} (false) - ($key, $value) = ($1, 'false'); - } else { # BOOLEAN: {key} (true) - ($key, $value) = ($1, 'true'); - } - - if (($key =~ /^job-/) || ($key =~ /^copies/) || - ($key =~ /^multiple-document-handling/) || ($key =~ /^number-up/) || - ($key =~ /^orientation-requested/) || - ($key =~ /^dest/) || ($key =~ /^protocol/) || ($key =~ /^banner/) || - ($key =~ /^page-ranges/)) { - # Ignored: - # job-*, multiple-document-handling are not supported by this - # filter - # dest, protocol, banner, number-up, orientation-requested are - # handled by the LP filtering or interface script - # NOTE - page-ranges should probably be handled here, but - # ignore it until we decide how to handle it. - } elsif (/^printer-resolution/) { - # value match on "123, 457" or on "123, 457, 8" - if (/([\d]+),([\s]*)([\d]+)((,([\s]*)([\d]+))??)/) { - $result = '$1x$2$3 '; # (width)x(height)(units) - } - } elsif (/^print-quality/) { - ($value == 3) && - ($result = 'PrintoutMode=Draft'); - ($value == 4) && - ($result = 'PrintoutMode=Normal'); - ($value == 5) && - ($result = 'PrintoutMode=High'); - } else { - # NOTE - if key == 'media', we may need to convert the values at some - # point. (see RFC2911, Section 14 for values) - $result = '$key=\"$value\"'; - } - - return ($result); -} - -# -# Read the attributes file containing the various job meta-data, including -# requested capabilities -# -sub read_attribute_file { - my ($file) = @_; - my $result = ""; - - open (AFP, "<$file") || - (print $logh "Unable to open IPP Attribute file ".$file.", ignored: ".$!); - - while(<AFP>) { - $result .= option_to_ppd($_); - } - - close (AFP); - - return ($result); -} - -sub modern_system { - my (@list) = @_; - - if (($modern_shell =~ /.+/) && ($modern_shell ne '/bin/sh')) { - # a "modern" shell other than the default shell was specified - my $pid = fork(); - - ($pid < 0) && die "failed to fork()"; - - if ($pid == 0) { # child, execute the commands under a modern shell - exec($modern_shell, "-c", @list); - die "exec($modern_shell, \"-c\", @list);"; - } else { # parent, wait for the child - waitpid($pid, 0); - } - } else { # the system shell is "modern" enough. - system(@list); - } -} - -# Emacs tabulator/indentation - -### Local Variables: -### tab-width: 8 -### perl-indent-level: 4 -### End: diff --git a/foomaticrip.c b/foomaticrip.c new file mode 100644 index 0000000..37d0822 --- /dev/null +++ b/foomaticrip.c @@ -0,0 +1,1570 @@ + +#include "foomaticrip.h" +#include "util.h" +#include "options.h" +#include "pdf.h" +#include "postscript.h" +#include "process.h" +#include "spooler.h" +#include "renderer.h" +#include "fileconverter.h" + +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <errno.h> +#include <memory.h> +#include <ctype.h> +#include <stdarg.h> +#include <assert.h> +#include <unistd.h> +#include <sys/wait.h> +#include <math.h> +#include <signal.h> +#include <pwd.h> + + +/* Logging */ +FILE* logh = NULL; + +void _logv(const char *msg, va_list ap) +{ + if (!logh) + return; + vfprintf(logh, msg, ap); + fflush(logh); +} + +void _log(const char* msg, ...) +{ + va_list ap; + va_start(ap, msg); + _logv(msg, ap); + va_end(ap); +} + +void close_log() +{ + if (logh && logh != stderr) + fclose(logh); +} + +int redirect_log_to_stderr() +{ + if (dup2(fileno(logh), fileno(stderr)) < 0) { + _log("Could not dup logh to stderr\n"); + return 0; + } + return 1; +} + +void rip_die(int status, const char *msg, ...) +{ + va_list ap; + + _log("Process is dying with \""); + va_start(ap, msg); + _logv(msg, ap); + va_end(ap); + _log("\", exit stat %d\n", status); + + _log("Cleaning up...\n"); + kill_all_processes(); + + exit(status); +} + + +jobparams_t *job = NULL; + +jobparams_t * get_current_job() +{ + assert(job); + return job; +} + + +dstr_t *postpipe; /* command into which the output of this filter should be piped */ +FILE *postpipe_fh = NULL; + +FILE * open_postpipe() +{ + const char *p; + + if (postpipe_fh) + return postpipe_fh; + + if (isempty(postpipe->data)) + return stdout; + + /* Delete possible '|' symbol in the beginning */ + p = skip_whitespace(postpipe->data); + if (*p && *p == '|') + p += 1; + + if (start_system_process("postpipe", p, &postpipe_fh, NULL) < 0) + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, + "Cannot execute postpipe %s\n", postpipe->data); + + return postpipe_fh; +} + + +char printer_model[256] = ""; +const char *accounting_prolog = NULL; +char attrpath[256] = ""; + + +int spooler = SPOOLER_DIRECT; +int do_docs = 0; +int dontparse = 0; +int jobhasjcl; +int pdfconvertedtops; + +/* Variable for PPR's backend interface name (parallel, tcpip, atalk, ...) */ +char backend [64]; + +/* Array to collect unknown options so that they can get passed to the +backend interface of PPR. For other spoolers we ignore them. */ +dstr_t *backendoptions = NULL; + +/* These variables were in 'dat' before */ +char colorprofile [128]; +char cupsfilter[256]; +char **jclprepend = NULL; +dstr_t *jclappend; + +/* Set debug to 1 to enable the debug logfile for this filter; it will appear + * as defined by LOG_FILE. 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. */ +int debug = 0; + +/* Path to the GhostScript which foomatic-rip shall use */ +char gspath[PATH_MAX] = "gs"; + +/* 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. */ +char echopath[PATH_MAX] = "echo"; + +/* CUPS raster drivers are searched here */ +char cupsfilterpath[PATH_MAX] = "/usr/local/lib/cups/filter:" + "/usr/local/libexec/cups/filter:" + "/opt/cups/filter:" + "/usr/lib/cups/filter"; + +char modern_shell[64] = "/bin/bash"; + +void config_set_option(const char *key, const char *value) +{ + if (strcmp(key, "debug") == 0) + debug = atoi(value); + + /* 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. */ + else if (strcmp(key, "execpath") == 0 && !isempty(value)) + setenv("PATH", value, 1); + + else if (strcmp(key, "cupsfilterpath") == 0) + strlcpy(cupsfilterpath, value, PATH_MAX); + else if (strcmp(key, "preferred_shell") == 0) + strlcpy(modern_shell, value, 32); + else if (strcmp(key, "textfilter") == 0) + set_fileconverter(value); + else if (strcmp(key, "gspath") == 0) + strlcpy(gspath, value, PATH_MAX); + else if (strcmp(key, "echo") == 0) + strlcpy(echopath, value, PATH_MAX); +} + +void config_from_file(const char *filename) +{ + FILE *fh; + char line[256]; + char *key, *value; + + fh = fopen(filename, "r"); + if (fh == NULL) + return; /* no error here, only read config file if it is present */ + + while (fgets(line, 256, fh) != NULL) + { + key = strtok(line, " :\t\r\n"); + if (key == NULL || key[0] == '#') + continue; + value = strtok(NULL, " \t\r\n#"); + config_set_option(key, value); + } + fclose(fh); +} + +const char * get_modern_shell() +{ + return modern_shell; +} + +/* returns position in 'str' after the option */ +char * extract_next_option(char *str, char **pagerange, char **key, char **value) +{ + char *p = str; + char quotechar; + + *pagerange = NULL; + *key = NULL; + *value = NULL; + + if (!str) + return NULL; + + /* skip whitespace and commas */ + while (*p && (isspace(*p) || *p == ',')) p++; + + if (!*p) + return NULL; + + /* read the pagerange if we have one */ + if (prefixcmp(p, "even:") == 0 || prefixcmp(p, "odd:") == 0 || isdigit(*p)) { + *pagerange = p; + p = strchr(p, ':'); + if (!p) + return NULL; + *p = '\0'; + p++; + } + + /* read the key */ + if (*p == '\'' || *p == '\"') { + quotechar = *p; + *key = p +1; + p = strchr(*key, quotechar); + if (!p) + return NULL; + } + else { + *key = p; + while (*p && *p != ':' && *p != '=' && *p != ' ') p++; + } + + if (*p != ':' && *p != '=') { /* no value for this option */ + if (!*p) + return NULL; + else if (isspace(*p)) { + *p = '\0'; + return p +1; + } + return p; + } + + *p++ = '\0'; /* remove the separator sign */ + + if (*p == '\"' || *p == '\'') { + quotechar = *p; + *value = p +1; + p = strchr(*value, quotechar); + if (!p) + return NULL; + *p = '\0'; + p++; + } + else { + *value = p; + while (*p && *p != ' ' && *p != ',') p++; + if (*p == '\0') + return NULL; + *p = '\0'; + p++; + } + + return *p ? p : NULL; +} + +/* processes job->optstr */ +void process_cmdline_options() +{ + char *p, *nextopt, *pagerange, *key, *value; + option_t *opt, *opt2; + int optset; + char tmp [256]; + + for (nextopt = extract_next_option(job->optstr->data, &pagerange, &key, &value); + key; + nextopt = extract_next_option(nextopt, &pagerange, &key, &value)) + { + if (value) + _log("Pondering option '%s=%s'\n", key, value); + else + _log("Pondering option '%s'\n", key); + + /* "docs" option to print help page */ + if (!strcasecmp(key, "docs")) { + do_docs = 1; + continue; + } + /* "profile" option to supply a color correction profile to a CUPS raster driver */ + if (!strcmp(key, "profile")) { + strlcpy(colorprofile, value, 128); + continue; + } + /* Solaris options that have no reason to be */ + if (!strcmp(key, "nobanner") || !strcmp(key, "dest") || !strcmp(key, "protocol")) + continue; + + if (pagerange) { + snprintf(tmp, 256, "pages:%s", pagerange); + optset = optionset(tmp); + + opt = find_option(key); + if (opt && (option_get_section(opt) != SECTION_ANYSETUP && + option_get_section(opt) != SECTION_PAGESETUP)) { + _log("This option (%s) is not a \"PageSetup\" or \"AnySetup\" option, so it cannot be restricted to a page range.\n", key); + continue; + } + } + else + optset = optionset("userval"); + + if (value) { + /* At first look for the "backend" option to determine the PPR backend to use */ + if (spooler == SPOOLER_PPR_INT && !strcasecmp(key, "backend")) { + /* backend interface name */ + strlcpy(backend, value, 64); + } + else if (strcasecmp(key, "media") == 0) { + /* Standard arguments? + media=x,y,z + sides=one|two-sided-long|short-edge + + Rummage around in the media= option for known media, source, + etc types. + We ought to do something sensible to make the common manual + boolean option work when specified as a media= tray thing. + + Note that this fails miserably when the option value is in + fact a number; they all look alike. It's unclear how many + drivers do that. We may have to standardize the verbose + names to make them work as selections, too. */ + + p = strtok(value, ","); + do { + if ((opt = find_option("PageSize")) && option_accepts_value(opt, p)) + option_set_value(opt, optset, p); + else if ((opt = find_option("MediaType")) && option_has_choice(opt, p)) + option_set_value(opt, optset, p); + else if ((opt = find_option("InputSlot")) && option_has_choice(opt, p)) + option_set_value(opt, optset, p); + else if (!strcasecmp(p, "manualfeed")) { + /* Special case for our typical boolean manual + feeder option if we didn't match an InputSlot above */ + if ((opt = find_option("ManualFeed"))) + option_set_value(opt, optset, "1"); + } + else + _log("Unknown \"media\" component: \"%s\".\n", p); + + } while ((p = strtok(NULL, ","))); + } + else if (!strcasecmp(key, "sides")) { + /* Handle the standard duplex option, mostly */ + if (!prefixcasecmp(value, "two-sided")) { + if ((opt = find_option("Duplex"))) { + /* Default to long-edge binding here, for the case that + there is no binding setting */ + option_set_value(opt, optset, "DuplexNoTumble"); + + /* Check the binding: "long edge" or "short edge" */ + if (strcasestr(value, "long-edge")) { + if ((opt2 = find_option("Binding"))) + option_set_value(opt2, optset, "LongEdge"); + else + option_set_value(opt, optset, "DuplexNoTumble"); + } + else if (strcasestr(value, "short-edge")) { + if ((opt2 = find_option("Binding"))) + option_set_value(opt2, optset, "ShortEdge"); + else + option_set_value(opt, optset, "DuplexNoTumble"); + } + } + } + else if (!prefixcasecmp(value, "one-sided")) { + if ((opt = find_option("Duplex"))) + option_set_value(opt, optset, "0"); + } + + /* TODO + We should handle the other half of this option - the + BindEdge bit. Also, are there well-known ipp/cups options + for Collate and StapleLocation? These may be here... + */ + } + else { + /* Various non-standard printer-specific options */ + if ((opt = find_option(key))) { + if (!option_set_value(opt, optset, value)) { + _log(" invalid choice \"%s\", using \"%s\" instead\n", + value, option_get_value(opt, optset)); + } + } + else if (spooler == SPOOLER_PPR_INT) { + /* Unknown option, pass it to PPR's backend interface */ + if (!backendoptions) + backendoptions = create_dstr(); + dstrcatf(backendoptions, "%s=%s ", key, value); + } + else + _log("Unknown option %s=%s.\n", key, value); + } + } + /* Custom paper size */ + else if ((opt = find_option("PageSize")) && option_set_value(opt, optset, key)) { + /* do nothing, if the value could be set, it has been set */ + } + /* Standard bool args: + landscape; what to do here? + duplex; we should just handle this one OK now? */ + else if (!prefixcasecmp(key, "no") && (opt = find_option(&key[2]))) + option_set_value(opt, optset, "0"); + else if ((opt = find_option(key))) + option_set_value(opt, optset, "1"); + else + _log("Unknown boolean option \"%s\".\n", key); + } +} + +/* checks whether a pdq driver declaration file should be build + and returns an opened file handle if so */ +FILE * check_pdq_file(list_t *arglist) +{ + /* "--appendpdq=<file>" appends the data to the <file>, + "--genpdq=<file>" creates/overwrites <file> for the data, and + "--genpdq" writes to standard output */ + + listitem_t *i; + char filename[256]; + FILE *handle; + char *p; + int raw, append; + + if ((i = arglist_find_prefix(arglist, "--genpdq"))) { + raw = 0; + append = 0; + } + else if ((i = arglist_find_prefix(arglist, "--genrawpdq"))) { + raw = 1; + append = 0; + } + else if ((i = arglist_find_prefix(arglist, "--appendpdq"))) { + raw = 0; + append = 1; + } + else if ((i = arglist_find_prefix(arglist, "--appendrawpdq"))) { + raw = 1; + append = 1; + } + + if (!i) + return NULL; + + p = strchr((char*)i->data, '='); + if (p) { + strncpy_omit(filename, p +1, 256, omit_shellescapes); + handle = fopen(filename, append ? "a" : "w"); + if (!handle) + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "Cannot write PDQ driver declaration file.\n"); + } + else if (!append) + handle = stdout; + else + return NULL; + + /* remove option from args */ + list_remove(arglist, i); + + /* Do we have a pdq driver declaration for a raw printer */ + if (raw) { + fprintf(handle, + "driver \"Raw-Printer-%u\" {\n" + " # This PDQ driver declaration file was generated automatically by\n" + " # foomatic-rip to allow raw (filter-less) printing.\n" + " language_driver all {\n" + " # We accept all file types and pass them through without any changes\n" + " filetype_regx \"\"\n" + " convert_exec {\n" + " ln -s $INPUT $OUTPUT\n" + " }\n" + " }\n" + " filter_exec {\n" + " ln -s $INPUT $OUTPUT\n" + " }\n" + "}", (unsigned int)job->time); + if (handle != stdout) { + fclose(handle); + handle = NULL; + } + exit(EXIT_PRINTED); + } + + return handle; +} + + +/* Build a PDQ driver description file to use the given PPD file + together with foomatic-rip with the PDQ printing system + and output it into 'pdqfile' */ +void print_pdq_driver(FILE *pdqfile, int optset) +{ +} +#if 0 + option_t *opt; + value_t *val; + setting_t *setting, *setting_true, *setting_false; + + /* Construct option list */ + dstr_t *driveropts = create_dstr(); + + /* Do we have a "Custom" setting for the page size? + Then we have to insert the following into the filter_exec script. */ + dstr_t *setcustompagesize = create_dstr(); + + dstr_t *tmp = create_dstr(); + dstr_t *cmdline = create_dstr(); + dstr_t *psfilter = create_dstr(); + + + /* 1, if setting "PageSize=Custom" was found + Then we must add options for page width and height */ + int custompagesize = 0; + + /* Data for a custom page size, to allow a custom size as default */ + int pagewidth = 612; + int pageheight = 792; + char pageunit[2] = "pt"; + + char def [128]; + + def[0] = '\0'; + + for (opt = optionlist; opt; opt = opt->next) { + if (opt->type == TYPE_ENUM) { + /* Option with only one choice, omit it, foomatic-rip will set + this choice anyway */ + if (option_setting_count(opt) <= 1) + continue; + + /* Omit "PageRegion" option, it does the same as "PageSize" */ + if (!strcmp(opt->name, "PageRegion")) + continue; + + /* 1, if setting "PageSize=Custom" was found + Then we must add options for page width and height */ + custompagesize = 0; + + if ((val = option_get_value(opt, optset))) + strlcpy(def, val->value, 128); + +#if 0 TODO not used ?! + /* If the default is a custom size we have to set also + defaults for the width, height, and units of the page */ + if (!strcmp(opt->name, "PageSize") && val && value_has_custom_setting(val)) + strcpy(def, "Custom"); +#endif + + dstrcatf(driveropts, + " option {\n" + " var = \"%s\"\n" + " desc = \"%s\"\n", opt->varname, option_text(opt)); + + /* get enumeration values for each enum arg */ + dstrclear(tmp); + for (setting = opt->settinglist; setting; setting = setting->next) { + dstrcatf(tmp, + " choice \"%s_%s\" {\n" + " desc = \"%s\"\n" + " value = \" -o %s=%s\"\n" + " }\n", + opt->name, setting->value, + isempty(setting->comment) ? setting->value : setting->comment, + opt->name, setting->value); + + if (!strcmp(opt->name, "PageSize") && !strcmp(setting->value, "Custom")) { + custompagesize = 1; + if (isempty(setcustompagesize->data)) { + dstrcatf(setcustompagesize, + " # Custom page size settings\n" + " # We aren't really checking for legal vals.\n" + " if [ \"x${%s}\" = 'x -o %s=%s' ]; then\n" + " %s=\"${%s}.${PageWidth}x${PageHeight}${PageSizeUnit}\"\n" + " fi\n\n", + opt->varname, opt->varname, setting->value, opt->varname, opt->varname); + } + } + } + + dstrcatf(driveropts, " default_choice \"%s_%s\"\n", opt->name, def); + dstrcatf(driveropts, tmp->data); + dstrcatf(driveropts, " }\n\n"); + + if (custompagesize) { + /* Add options to set the custom page size */ + dstrcatf(driveropts, + " argument {\n" + " var = \"PageWidth\"\n" + " desc = \"Page Width (for \\\"Custom\\\" page size)\"\n" + " def_value \"%d\"\n" /* pagewidth */ + " help = \"Minimum value: 0, Maximum value: 100000\"\n" + " }\n\n" + " argument {\n" + " var = \"PageHeight\"\n" + " desc = \"Page Height (for \\\"Custom\\\" page size)\"\n" + " def_value \"%d\"\n" /* pageheight */ + " help = \"Minimum value: 0, Maximum value: 100000\"\n" + " }\n\n" + " option {\n" + " var = \"PageSizeUnit\"\n" + " desc = \"Unit (for \\\"Custom\\\" page size)\"\n" + " default_choice \"PageSizeUnit_%.2s\"\n" /* pageunit */ + " choice \"PageSizeUnit_pt\" {\n" + " desc = \"Points (1/72 inch)\"\n" + " value = \"pt\"\n" + " }\n" + " choice \"PageSizeUnit_in\" {\n" + " desc = \"Inches\"\n" + " value = \"in\"\n" + " }\n" + " choice \"PageSizeUnit_cm\" {\n" + " desc = \"cm\"\n" + " value = \"cm\"\n" + " }\n" + " choice \"PageSizeUnit_mm\" {\n" + " desc = \"mm\"\n" + " value = \"mm\"\n" + " }\n" + " }\n\n", + pagewidth, pageheight, pageunit); + } + } + else if (opt->type == TYPE_INT || opt->type == TYPE_FLOAT) { + /* Assure that the comment is not emtpy */ + if (isempty(opt->comment)) + strcpy(opt->comment, opt->name); + + if ((val = option_get_value(opt, optset))) + strlcpy(def, val->value, 128); + + strcpy(opt->varname, opt->name); + strrepl(opt->varname, "-/.", '_'); + + + dstrcatf(driveropts, + " argument {\n" + " var = \"%s\"\n" + " desc = \"%s\"\n" + " def_value \"%s\"\n" + " help = \"Minimum value: %s, Maximum value: %s\"\n" + " }\n\n", + opt->varname, opt->comment, def, opt->min, opt->max); + } + else if (opt->type == TYPE_BOOL) { + /* Assure that the comment is not emtpy */ + if (isempty(opt->comment)) + strcpy(opt->comment, opt->name); + + if ((val = option_get_value(opt, optset))) + strlcpy(def, val->value, 128); + strcpy(opt->varname, opt->name); + strrepl(opt->varname, "-/.", '_'); + setting_true = option_find_setting(opt, "true"); + setting_false = option_find_setting(opt, "false"); + + dstrcatf(driveropts, + " option {\n" + " var = \"%s\"\n" + " desc = \"%s\"\n", opt->varname, opt->comment); + + if (!isempty(def) && !strcasecmp(def, "true")) + dstrcatf(driveropts, " default_choice \"%s\"\n", def); + else + dstrcatf(driveropts, " default_choice \"no%s\"\n", def); + + dstrcatf(driveropts, + " choice \"%s\" {\n" + " desc = \"%s\"\n" + " value = \" -o %s=True\"\n" + " }\n" + " choice \"no%s\" {\n" + " desc = \"%s\"\n" + " value = \" -o %s=False\"\n" + " }\n" + " }\n\n", + opt->name, setting_true->comment, opt->name, + opt->name, setting_false->comment, opt->name); + } + else if (opt->type == TYPE_STRING) { + /* Assure that the comment is not emtpy */ + if (isempty(opt->comment)) + strcpy(opt->comment, opt->name); + + if ((val = option_get_value(opt, optset))) + strlcpy(def, val->value, 128); + strcpy(opt->varname, opt->name); + strrepl_nodups(opt->varname, "-/.", '_'); + + dstrclear(tmp); + if (opt->maxlength) + dstrcatf(tmp, "Maximum Length: %s characters, ", opt->maxlength); + + dstrcatf(tmp, "Examples/special settings: "); + for (setting = opt->settinglist; setting; setting = setting->next) { + /* Retrieve the original string from the prototype and the driverval */ + /* TODO perl code for this part doesn't make sense to me */ + } + } + } + + /* Define the "docs" option to print the driver documentation page */ + dstrcatf(driveropts, + " option {\n" + " var = \"DRIVERDOCS\"\n" + " desc = \"Print driver usage information\"\n" + " default_choice \"nodocs\"\n" + " choice \"docs\" {\n" + " desc = \"Yes\"\n" + " value = \" -o docs\"\n" + " }\n" + " choice \"nodocs\" {\n" + " desc = \"No\"\n" + " value = \"\"\n" + " }\n" + " }\n\n"); + + /* Build the foomatic-rip command line */ + dstrcatf(cmdline, "foomatic-rip --pdq"); + if (!isempty(printer)) { + dstrcatf(cmdline, " -P %s", printer); + } + else { + /* Make sure that the PPD file is entered with an absolute path */ + make_absolute_path(job->ppdfile, 256); + dstrcatf(cmdline, " --ppd=%s", job->ppdfile); + } + + for (opt = optionlist; opt; opt = opt->next) { + if (!isempty(opt->varname)) + dstrcatf(cmdline, "${%s}", opt->varname); + } + dstrcatf(cmdline, "${DRIVERDOCS} $INPUT > $OUTPUT"); + + + /* Now we generate code to build the command line snippets for the numerical options */ + for (opt = optionlist; opt; opt = opt->next) { + /* Only numerical and string options need to be treated here */ + if (opt->type != TYPE_INT && + opt->type != TYPE_FLOAT && + opt->type != TYPE_STRING) + continue; + + /* If the option's variable is non-null, put in the + argument. Otherwise this option is the empty + string. Error checking? */ + dstrcatf(psfilter, " # %s\n", opt->comment); + if (opt->type == TYPE_INT || opt->type == TYPE_FLOAT) { + dstrcatf(psfilter, + " # We aren't really checking for max/min,\n" + " # this is done by foomatic-rip\n" + " if [ \"x${%s}\" != 'x' ]; then\n ", opt->varname); + } + + dstrcatf(psfilter, " %s=\" -o %s='${%s}'\"\n", opt->varname, opt->name, opt->varname); + + if (opt->type == TYPE_INT || opt->type == TYPE_FLOAT) + dstrcatf(psfilter, " fi\n"); + dstrcatf(psfilter, "\n"); + } + + /* Command execution */ + dstrcatf(psfilter, + " if ! test -e $INPUT.ok; then\n" + " sh -c \"%s\"\n" + " if ! test -e $OUTPUT; then \n" + " echo 'Error running foomatic-rip; no output!'\n" + " exit 1\n" + " fi\n" + " else\n" + " ln -s $INPUT $OUTPUT\n" + " fi\n\n", cmdline->data); + + + dstrclear(tmp); + dstrcatf(tmp, "%s", printer_model); + strrepl_nodups(tmp->data, " \t\n.,;/()[]{}+*", '-'); + tmp->len = strlen(tmp->data); /* length could have changed */ + if (tmp->data[tmp->len -1] == '-') { + tmp->data[--tmp->len] = '\0'; + } + + + fprintf(pdqfile, + "driver \"%s-%u\" {\n\n" + " # This PDQ driver declaration file was generated automatically by\n" + " # foomatic-rip from information in the file %s.\n" /* ppdfile */ + " # It allows printing with PDQ on the %s.\n" /* model */ + "\n" + " requires \"foomatic-rip\"\n\n" + "%s" /* driveropts */ + " language_driver all {\n" + " # We accept all file types and pass them to foomatic-rip\n" + " # (invoked in \"filter_exec {}\" section) without\n" + " # pre-filtering\n" + " filetype_regx \"\"\n" + " convert_exec {\n" + " ln -s $INPUT $OUTPUT\n" + " }\n" + " }\n\n" + " filter_exec {\n" + "%s" /* setcustompagesize */ + "%s" /* psfilter */ + " }\n" + "}\n", + tmp->data, /* cleaned printer_model */ (unsigned int)job->time, job->ppdfile, printer_model, + driveropts->data, setcustompagesize->data, psfilter->data); + + + free_dstr(setcustompagesize); + free_dstr(driveropts); + free_dstr(tmp); + free_dstr(cmdline); + free_dstr(psfilter); +} +#endif + +/* Functions to let foomatic-rip fork to do several tasks in parallel. + +To do the filtering without loading the whole file into memory we work +on a data stream, we read the data line by line analyse it to decide what +filters to use and start the filters if we have found out which we need. +We buffer the data only as long as we didn't determing which filters to +use for this piece of data and with which options. There are no temporary +files used. + +foomatic-rip splits into up to 6 parallel processes to do the whole +filtering (listed in the order of the data flow): + + KID0: Generate documentation pages (only jobs with "docs" option) + KID2: Put together already read data and current input stream for + feeding into the file conversion filter (only non-PostScript + and "docs" jobs) + KID1: Run the file conversion filter to convert non-PostScript + input into PostScript (only non-PostScript and "docs" jobs) + MAIN: Prepare the job auto-detecting the spooler, reading the PPD, + extracting the options from the command line, and parsing + the job data itself. It analyses the job data to check + whether it is PostScript and starts KID1/KID2 if not, it + also stuffs PostScript code from option settings into the + PostScript data stream. It starts the renderer (KID3/KID4) + as soon as it knows its command line and restarts it when + page-specific option settings need another command line + or different JCL commands. + KID3: The rendering process. In most cases Ghostscript, "cat" + for native PostScript printers with their manufacturer's + PPD files. + KID4: Put together the JCL commands and the renderer's output + and send all that either to STDOUT or pipe it into the + command line defined with $postpipe. */ + + + +void write_output(void *data, size_t len) +{ + const char *p = (const char *)data; + size_t left = len; + FILE *postpipe = open_postpipe(); + + /* Remove leading whitespace */ + while (isspace(*p++) && left-- > 0) + ; + + fwrite((void *)p, left, 1, postpipe); + fflush(postpipe); +} + +enum FileType { + UNKNOWN_FILE, + PDF_FILE, + PS_FILE +}; + +int guess_file_type(const char *begin, size_t len, int *startpos) +{ + const char * p; + + p = memchr(begin, '%', len); + if (!p) + return UNKNOWN_FILE; + *startpos = p - begin; + if (!memcmp(p, "%!", 2)) + return PS_FILE; + else if (!memcmp(p, "%PDF-1.", 7)) + return PDF_FILE; + *startpos = 0; + return UNKNOWN_FILE; +} + +/* + * Prints 'filename'. If 'convert' is true, the file will be converted if it is + * not postscript or pdf + */ +int print_file(const char *filename, int convert) +{ + FILE *file; + char buf[8192]; + int type; + int startpos; + size_t n; + FILE *fchandle = NULL; + int fcpid = 0, ret; + + if (!strcasecmp(filename, "<STDIN>")) + file = stdin; + else { + file = fopen(filename, "r"); + if (!file) { + _log("Could not open \"%s\" for reading\n", filename); + return 0; + } + } + + n = fread(buf, 1, sizeof(buf), file); + buf[n] = '\0'; + type = guess_file_type(buf, n, &startpos); + if (startpos > 0) { + jobhasjcl = 1; + write_output(buf, startpos); + } + if (file != stdin) + rewind(file); + + if (convert) pdfconvertedtops = 0; + + switch (type) { + case PDF_FILE: + _log("Filetype: PDF\n"); + + if (!ppd_supports_pdf()) + { + char pdf2ps_cmd[PATH_MAX]; + FILE *out, *in; + int renderer_pid; + + _log("Driver does not understand PDF input, " + "converting to PostScript\n"); + + pdfconvertedtops = 1; + snprintf(pdf2ps_cmd, PATH_MAX, + "gs -q -sstdout=%%stderr -sDEVICE=pswrite -sOutputFile=- " + "-dBATCH -dNOPAUSE -dPARANOIDSAFER %s", + file == stdin ? "-" : filename); + + renderer_pid = start_system_process("pdf-to-ps", pdf2ps_cmd, &in, &out); + + if (file == stdin) + { + fwrite(buf, 1, n, in); + while ((n = fread(buf, 1, sizeof(buf), file))) + fwrite(buf, 1, n, in); + fclose(in); + } + + if (dup2(fileno(out), fileno(stdin)) < 0) + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, + "Couldn't dup stdout of pdf-to-ps\n"); + + ret = print_file("<STDIN>", 0); + + wait_for_process(renderer_pid); + return ret; + } + + if (file == stdin) + return print_pdf(stdin, buf, n, filename, startpos); + else + return print_pdf(file, NULL, 0, filename, startpos); + + case PS_FILE: + _log("Filetype: PostScript\n"); + if (file == stdin) + return print_ps(stdin, buf, n, filename); + else + return print_ps(file, NULL, 0, filename); + + case UNKNOWN_FILE: + if (spooler == SPOOLER_CUPS) { + _log("Cannot process \"%s\": Unknown filetype.\n", filename); + return 0; + } + + _log("Filetype unknown, trying to convert ...\n"); + get_fileconverter_handle(buf, &fchandle, &fcpid); + + /* Read further data from the file converter and not from STDIN */ + if (dup2(fileno(fchandle), fileno(stdin)) < 0) + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "Couldn't dup fileconverterhandle\n"); + + ret = print_file("<STDIN>", 0); + + if (close_fileconverter_handle(fchandle, fcpid) != EXIT_PRINTED) + rip_die(ret, "Error closing file converter\n"); + return ret; + } + + fclose(file); + return 1; +} + +void signal_terminate(int signal) +{ + rip_die(EXIT_PRINTED, "Caught termination signal: Job canceled\n"); +} + +jobparams_t * create_job() +{ + jobparams_t *job = calloc(1, sizeof(jobparams_t)); + struct passwd *passwd; + + job->optstr = create_dstr(); + job->time = time(NULL); + strcpy(job->copies, "1"); + gethostname(job->host, 128); + passwd = getpwuid(getuid()); + if (passwd) + strlcpy(job->user, passwd->pw_name, 128); + snprintf(job->title, 128, "%s@%s", job->user, job->host); + + return job; +} + +void free_job(jobparams_t *job) +{ + free_dstr(job->optstr); + free(job); +} + +int main(int argc, char** argv) +{ + int i; + int verbose = 0, quiet = 0, showdocs = 0; + const char* str; + char *p, *filename; + const char *path; + FILE *genpdqfile = NULL; + FILE *ppdfh = NULL; + char tmp[1024], pstoraster[256]; + int havefilter, havepstoraster; + dstr_t *filelist; + list_t * arglist; + + arglist = list_create_from_array(argc -1, (void**)&argv[1]); + + if (argc == 2 && (arglist_find(arglist, "--version") || arglist_find(arglist, "--help") || + arglist_find(arglist, "-v") || arglist_find(arglist, "-h"))) { + printf("foomatic rip version "VERSION"\n"); + printf("\"man foomatic-rip\" for help.\n"); + list_free(arglist); + return 0; + } + + filelist = create_dstr(); + job = create_job(); + + jclprepend = NULL; + jclappend = create_dstr(); + postpipe = create_dstr(); + + options_init(); + + signal(SIGTERM, signal_terminate); + signal(SIGINT, signal_terminate); + + + config_from_file(CONFIG_PATH "/filter.conf"); + + /* Command line options for verbosity */ + if (arglist_remove_flag(arglist, "-v")) + verbose = 1; + if (arglist_remove_flag(arglist, "-q")) + quiet = 1; + if (arglist_remove_flag(arglist, "-d")) + showdocs = 1; + if (arglist_remove_flag(arglist, "--debug")) + debug = 1; + + if (debug) + logh = fopen(LOG_FILE ".log", "w"); /* insecure, use for debugging only */ + else if (quiet && !verbose) + logh = NULL; /* Quiet mode, do not log */ + else + logh = stderr; /* Default: log to 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. */ + _log("foomatic-rip version "VERSION" 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 (spooler != SPOOLER_CUPS) { + _log("called with arguments: "); + for (i = 1; i < argc -1; i++) + _log("\'%s\', ", argv[i]); + _log("\'%s\'\n", argv[i]); + } + } + + if (getenv("PPD")) { + strncpy(job->ppdfile, getenv("PPD"), 256); + spooler = SPOOLER_CUPS; + } + + if (getenv("SPOOLER_KEY")) { + spooler = SPOOLER_SOLARIS; + /* set the printer name from the ppd file name */ + strncpy_omit(job->ppdfile, getenv("PPD"), 256, omit_specialchars); + file_basename(job->printer, job->ppdfile, 256); + /* TODO read attribute file*/ + } + + if (getenv("PPR_VERSION")) + spooler = SPOOLER_PPR; + + if (getenv("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. */ + dstrcatf(job->optstr, "%s ", getenv("PPR_RIPOPTS")); + spooler = SPOOLER_PPR; + } + + if (getenv("LPOPTS")) { /* "LPOPTS": Option settings for some LPD implementations (ex: GNUlpr) */ + spooler = SPOOLER_GNULPR; + dstrcatf(job->optstr, "%s ", getenv("LPOPTS")); + } + + /* Check for LPRng first so we do not pick up bogus ppd files by the -ppd option */ + if (arglist_remove_flag(arglist, "--lprng")) + spooler = SPOOLER_LPRNG; + + /* 'PRINTCAP_ENTRY' environment variable is : LPRng + the :ppd=/path/to/ppdfile printcap entry should be used */ + if (getenv("PRINTCAP_ENTRY")) { + spooler = SPOOLER_LPRNG; + if ((str = strstr(getenv("PRINTCAP_ENTRY"), "ppd="))) + str += 4; + else if ((str = strstr(getenv("PRINTCAP_ENTRY"), "ppdfile="))); + str += 8; + if (str) { + while (isspace(*str)) str++; + p = job->ppdfile; + while (*str != '\0' && !isspace(*str) && *str != '\n') { + if (isprint(*str) && strchr(shellescapes, *str) == NULL) + *p++ = *str; + str++; + } + } + } + + /* PPD file name given via the command line + allow duplicates, and use the last specified one */ + if (spooler != SPOOLER_LPRNG) { + while ((str = arglist_get_value(arglist, "-p"))) { + strncpy(job->ppdfile, str, 256); + arglist_remove(arglist, "-p"); + } + } + while ((str = arglist_get_value(arglist, "--ppd"))) { + strncpy(job->ppdfile, str, 256); + arglist_remove(arglist, "--ppd"); + } + + /* 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 ((str = arglist_get_value(arglist, "-h"))) { + if (spooler != SPOOLER_GNULPR && spooler != SPOOLER_LPRNG) + spooler = SPOOLER_LPD; + strncpy(job->host, str, 127); + job->host[127] = '\0'; + arglist_remove(arglist, "-h"); + } + if ((str = arglist_get_value(arglist, "-n"))) { + if (spooler != SPOOLER_GNULPR && spooler != SPOOLER_LPRNG) + spooler = SPOOLER_LPD; + + strncpy(job->user, str, 127); + job->user[127] = '\0'; + arglist_remove(arglist, "-n"); + } + if (arglist_remove(arglist, "-w") || + arglist_remove(arglist, "-l") || + arglist_remove(arglist, "-x") || + arglist_remove(arglist, "-y") || + arglist_remove(arglist, "-i") || + arglist_remove_flag(arglist, "-c")) { + if (spooler != SPOOLER_GNULPR && spooler != SPOOLER_LPRNG) + spooler = SPOOLER_LPD; + } + /* LPRng delivers the option settings via the "-Z" argument */ + if ((str = arglist_get_value(arglist, "-Z"))) { + spooler = SPOOLER_LPRNG; + dstrcatf(job->optstr, "%s ", str); + arglist_remove(arglist, "-Z"); + } + /* Job title and options for stock LPD */ + if ((str = arglist_get_value(arglist, "-j")) || (str = arglist_get_value(arglist, "-J"))) { + strncpy_omit(job->title, str, 128, omit_shellescapes); + if (spooler == SPOOLER_LPD) + dstrcatf(job->optstr, "%s ", job->title); + if (!arglist_remove(arglist, "-j")) + arglist_remove(arglist, "-J"); + } + /* Check for CPS */ + if (arglist_remove_flag(arglist, "--cps") > 0) + spooler = SPOOLER_CPS; + + /* Options for spooler-less printing, CPS, or PDQ */ + while ((str = arglist_get_value(arglist, "-o"))) { + strncpy_omit(tmp, str, 1024, omit_shellescapes); + dstrcatf(job->optstr, "%s ", tmp); + arglist_remove(arglist, "-o"); + /* If we don't print as PPR RIP or as CPS filter, we print + without spooler (we check for PDQ later) */ + if (spooler != SPOOLER_PPR && spooler != SPOOLER_CPS) + spooler = SPOOLER_DIRECT; + } + + /* Printer for spooler-less printing or PDQ */ + if ((str = arglist_get_value(arglist, "-d"))) { + strncpy_omit(job->printer, str, 256, omit_shellescapes); + arglist_remove(arglist, "-d"); + } + + /* Printer for spooler-less printing, PDQ, or LPRng */ + if ((str = arglist_get_value(arglist, "-P"))) { + strncpy_omit(job->printer, str, 256, omit_shellescapes); + arglist_remove(arglist, "-P"); + } + + /* Were we called from a PDQ wrapper? */ + if (arglist_remove_flag(arglist, "--pdq")) + spooler = SPOOLER_PDQ; + + /* Were we called to build the PDQ driver declaration file? */ + genpdqfile = check_pdq_file(arglist); + if (genpdqfile) + spooler = SPOOLER_PDQ; + + /* spooler specific initialization */ + switch (spooler) { + case SPOOLER_PPR: + init_ppr(arglist, job); + break; + + case SPOOLER_CUPS: + init_cups(arglist, filelist, job); + break; + + case SPOOLER_LPD: + case SPOOLER_LPRNG: + case SPOOLER_GNULPR: + /* Get PPD file name as the last command line argument */ + if (arglist->last) + strncpy(job->ppdfile, (char*)arglist->last->data, 256); + break; + + case SPOOLER_DIRECT: + case SPOOLER_CPS: + case SPOOLER_PDQ: + init_direct_cps_pdq(arglist, filelist, job); + break; + } + + /* Files to be printed (can be more than one for spooler-less printing) */ + /* Empty file list -> print STDIN */ + dstrtrim(filelist); + if (filelist->len == 0) + dstrcpyf(filelist, "<STDIN>"); + + /* Check filelist */ + p = strtok(filelist->data, " "); + while (p) { + if (strcmp(p, "<STDIN>") != 0) { + if (p[0] == '-') + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "Invalid argument: %s", p); + else if (access(p, R_OK) != 0) { + _log("File %s does not exist/is not readable\n", p); + strclr(p); + } + } + p = strtok(NULL, " "); + } + + /* 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 == SPOOLER_DIRECT || spooler == SPOOLER_CPS || genpdqfile) && !verbose && !debug) { + if (logh && logh != stderr) + fclose(logh); + logh = NULL; + } + + /* If we are in debug mode, we do this earlier. */ + if (!debug) { + _log("foomatic-rip version " VERSION " 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 (spooler != SPOOLER_CUPS) { + _log("called with arguments: "); + for (i = 1; i < argc -1; i++) + _log("\'%s\', ", argv[i]); + _log("\'%s\'\n", argv[i]); + } + } + + /* PPD File */ + /* Load the PPD file and build a data structure for the renderer's + command line and the options */ + if (!(ppdfh = fopen(job->ppdfile, "r"))) + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "Unable to open PPD file %s\n", job->ppdfile); + + read_ppd_file(job->ppdfile); + + /* We do not need to parse the PostScript job when we don't have + any options. If we have options, we must check whether the + default settings from the PPD file are valid and correct them + if nexessary. */ + if (option_count() == 0) { + /* We don't have any options, so we do not need to parse the + PostScript data */ + dontparse = 1; + } + + /* Is our PPD for a CUPS raster driver */ + if (!isempty(cupsfilter)) { + /* Search the filter in cupsfilterpath + The %Y is a placeholder for the option settings */ + havefilter = 0; + path = cupsfilterpath; + while ((path = strncpy_tochar(tmp, path, 1024, ":"))) { + strlcat(tmp, "/", 1024); + strlcat(tmp, cupsfilter, 1024); + if (access(tmp, X_OK) == 0) { + havefilter = 1; + strlcpy(cupsfilter, tmp, 256); + strlcat(cupsfilter, " 0 '' '' 0 '%Y%X'", 256); + break; + } + } + + if (!havefilter) { + /* We do not have the required filter, so we assume that + rendering this job is supposed to be done on a remote + server. So we do not define a renderer command line and + embed only the option settings (as we had a PostScript + printer). This way the settings are taken into account + when the job is rendered on the server.*/ + _log("CUPS filter for this PPD file not found - assuming that job will " + "be rendered on a remote server. Only the PostScript of the options" + "will be inserted into the PostScript data stream.\n"); + } + else { + /* use pstoraster script if available, otherwise run Ghostscript directly */ + havepstoraster = 0; + path = cupsfilterpath; + while ((path = strncpy_tochar(tmp, path, 1024, ":"))) { + strlcat(tmp, "/pstoraster", 1024); + if (access(tmp, X_OK) == 0) { + havepstoraster = 1; + strlcpy(pstoraster, tmp, 256); + strlcat(pstoraster, " 0 '' '' 0 '%X'", 256); + break; + } + } + if (!havepstoraster) { + strcpy(pstoraster, "gs -dQUIET -dDEBUG -dPARANOIDSAFER -dNOPAUSE -dBATCH -dNOMEDIAATTRS -sDEVICE=cups -sOutputFile=-%W -"); + } + + /* build Ghostscript/CUPS driver command line */ + snprintf(cmd, 1024, "%s | %s", pstoraster, cupsfilter); + + /* Set environment variables */ + setenv("PPD", job->ppdfile, 1); + } + } + + /* Was the RIP command line defined in the PPD file? If not, we assume a PostScript printer + and do not render/translate the input data */ + if (isempty(cmd)) { + strcpy(cmd, "cat%A%B%C%D%E%F%G%H%I%J%K%L%M%Z"); + if (dontparse) { + /* No command line, no options, we have a raw queue, don't check + whether the input is PostScript and ignore the "docs" option, + simply pass the input data to the backend.*/ + dontparse = 2; + strcpy(printer_model, "Raw queue"); + } + } + + /* Summary for debugging */ + _log("\nParameter Summary\n" + "-----------------\n\n" + "Spooler: %s\n" + "Printer: %s\n" + "Shell: %s\n" + "PPD file: %s\n" + "ATTR file: %s\n" + "Printer model: %s\n", + spooler_name(spooler), job->printer, get_modern_shell(), job->ppdfile, attrpath, printer_model); + /* Print the options string only in debug mode, Mac OS X adds very many + options so that CUPS cannot handle the output of the option string + 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 != SPOOLER_CUPS) + _log("Options: %s\n", job->optstr->data); + _log("Job title: %s\n", job->title); + _log("File(s) to be printed:\n"); + _log("%s\n\n", filelist->data); + if (getenv("GS_LIB")) + _log("Ghostscript extra search path ('GS_LIB'): %s\n", getenv("GS_LIB")); + + /* Process options from command line, + but save the defaults for printing documentation pages first */ + optionset_copy_values(optionset("default"), optionset("userval")); + process_cmdline_options(); + + /* Were we called to build the PDQ driver declaration file? */ + if (genpdqfile) { + print_pdq_driver(genpdqfile, optionset("userval")); + fclose(genpdqfile); + exit(EXIT_PRINTED); + } + + if (spooler == SPOOLER_PPR_INT) { + snprintf(tmp, 1024, "interfaces/%s", backend); + if (access(tmp, X_OK) != 0) + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "The backend interface " + "/interfaces/%s does not exist/ is not executable!\n", backend); + + /* foomatic-rip cannot use foomatic-rip as backend */ + if (!strcmp(backend, "foomatic-rip")) + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "\"foomatic-rip\" cannot " + "use itself as backend interface!\n"); + + /* Put the backend interface into the postpipe */ + /* TODO + $postpipe = "| ( interfaces/$backend \"$ppr_printer\" ". + "\"$ppr_address\" \"" . join(" ",@backendoptions) . + "\" \"$ppr_jobbreak\" \"$ppr_feedback\" " . + "\"$ppr_codes\" \"$ppr_jobname\" \"$ppr_routing\" " . + "\"$ppr_for\" \"\" )"; + */ + } + + /* no postpipe for CUPS or PDQ, even if one is defined in the PPD file */ + if (spooler == SPOOLER_CUPS || spooler == SPOOLER_PDQ) + dstrclear(postpipe); + + /* CPS always needs a postpipe, set the default one for local printing if none is set */ + if (spooler == SPOOLER_CPS && !postpipe->len) + dstrcpy(postpipe, "| cat - > $LPDDEV"); + + if (postpipe->len) + _log("Ouput will be redirected to:\n%s\n", postpipe); + + + /* Print documentation page when asked for */ + if (do_docs) { + /* Don't print the supplied files, STDIN will be redirected to the + documentation page generator */ + dstrcpyf(filelist, "<STDIN>"); + + /* Start the documentation page generator */ + /* TODO tbd */ + } + + /* In debug mode save the data supposed to be fed into the + renderer also into a file, reset the file here */ + if (debug) + run_system_process("reset-file", "> " LOG_FILE ".ps"); + + filename = strtok_r(filelist->data, " ", &p); + while (filename) { + _log("\n================================================\n\n" + "File: %s\n\n" + "================================================\n\n", filename); + + /* Do we have a raw queue? */ + if (dontparse == 2) { + /* Raw queue, simply pass the input into the postpipe (or to STDOUT + when there is no postpipe) */ + _log("Raw printing, executing \"cat %s\"\n\n"); + snprintf(tmp, 1024, "cat %s", postpipe->data); + run_system_process("raw-printer", tmp); + continue; + } + + /* First, for arguments with a default, stick the default in as + the initial value for the "header" option set, this option set + consists of the PPD defaults, the options specified on the + command line, and the options set in the header part of the + PostScript file (all before the first page begins). */ + optionset_copy_values(optionset("userval"), optionset("header")); + + print_file(filename, 1); + filename = strtok_r(NULL, " ", &p); + } + + /* Close documentation page generator */ + /* if (docgenerator_pid) { + retval = close_docgenerator_handle(dogenerator_handle, docgenerator_pid); + if (!retval != EXIT_PRINTED) { + _log("Error closing documentation page generator\n"); + exit(retval); + } + docgenerator_pid = 0; + } */ + + /* Close the last input file */ + fclose(stdin); + + /* TODO dump everything in $dat when debug is turned on (necessary?) */ + + _log("\nClosing foomatic-rip.\n"); + + + /* Cleanup */ + free_job(job); + if (genpdqfile && genpdqfile != stdout) + fclose(genpdqfile); + free_dstr(filelist); + options_free(); + close_log(); + + argv_free(jclprepend); + free_dstr(jclappend); + if (backendoptions) + free_dstr(backendoptions); + + list_free(arglist); + + return 0; +} + diff --git a/foomaticrip.h b/foomaticrip.h new file mode 100644 index 0000000..f91570d --- /dev/null +++ b/foomaticrip.h @@ -0,0 +1,115 @@ + +#ifndef foomatic_h +#define foomatic_h + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include "config.h" + +#include <stddef.h> +#include <stdio.h> +#include <time.h> + +/* 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". + */ +#ifndef LOG_FILE +#define LOG_FILE "/tmp/foomatic-rip" +#endif + + +/* 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. + */ +#define EXIT_PRINTED 0 /* file was printed normally */ +#define EXIT_PRNERR 1 /* printer error occured */ +#define EXIT_PRNERR_NORETRY 2 /* printer error with no hope of retry */ +#define EXIT_JOBERR 3 /* job is defective */ +#define EXIT_SIGNAL 4 /* terminated after catching signal */ +#define EXIT_ENGAGED 5 /* printer is otherwise engaged (connection refused) */ +#define EXIT_STARVED = 6; /* starved for system resources */ +#define EXIT_PRNERR_NORETRY_ACCESS_DENIED 7 /* bad password? bad port permissions? */ +#define EXIT_PRNERR_NOT_RESPONDING 8 /* just doesn't answer at all (turned off?) */ +#define EXIT_PRNERR_NORETRY_BAD_SETTINGS 9 /* interface settings are invalid */ +#define EXIT_PRNERR_NO_SUCH_ADDRESS 10 /* address lookup failed, may be transient */ +#define EXIT_PRNERR_NORETRY_NO_SUCH_ADDRESS 11 /* address lookup failed, not transient */ +#define EXIT_INCAPABLE 50 /* printer wants (lacks) features or resources */ + + +/* 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 + */ +#define SPOOLER_CUPS 1 +#define SPOOLER_SOLARIS 2 +#define SPOOLER_LPD 3 +#define SPOOLER_LPRNG 4 +#define SPOOLER_GNULPR 5 +#define SPOOLER_PPR 6 +#define SPOOLER_PPR_INT 7 +#define SPOOLER_CPS 8 +#define SPOOLER_PDQ 9 +#define SPOOLER_DIRECT 10 + +/* The spooler from which foomatic-rip was called. set in main() */ +extern int spooler; + + +#define PATH_MAX 1024 + +typedef struct { + char printer[256]; + char id[128]; + char user[128]; + char host[128]; + char title[128]; + char ppdfile[256]; + char copies[128]; + int rbinumcopies; + struct dstr *optstr; + time_t time; +} jobparams_t; + + +jobparams_t * get_current_job(); + +void _log(const char* msg, ...); +int redirect_log_to_stderr(); +void rip_die(int status, const char *msg, ...); + +const char * get_modern_shell(); +FILE * open_postpipe(); + +extern struct dstr *currentcmd; +extern struct dstr *jclappend; +extern char **jclprepend; +extern int jobhasjcl; +extern const char *accounting_prolog; +extern char fileconverter[PATH_MAX]; +extern char cupsfilterpath[PATH_MAX]; +extern int debug; +extern int do_docs; +extern char printer_model[]; +extern int dontparse; +extern int pdfconvertedtops; +extern char gspath[PATH_MAX]; +extern char echopath[PATH_MAX]; + +#endif + diff --git a/make_configure b/make_configure index 2664dee..9955254 100755 --- a/make_configure +++ b/make_configure @@ -1,3 +1,15 @@ +#!/bin/sh +autoheader aclocal autoconf -perl -p -i -e "s=\#include <xmlversion.h>=\#include <libxml/xmlversion.h>=g" configure
\ No newline at end of file +automake -ac + +REVNO=`bzr revno 2> /dev/null` +if [ -z $REVNO ]; then + echo `cat VERSION` > VERSION.full +else + echo `cat VERSION`.$REVNO > VERSION.full +fi + + +#perl -p -i -e "s=\#include <xmlversion.h>=\#include <libxml/xmlversion.h>=g" configure @@ -0,0 +1,360 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2005-06-08.21 + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. + +# 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Send bug reports to <bug-automake@gnu.org>." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). +case "$1" in + lex|yacc) + # Not GNU programs, they don't have --version. + ;; + + tar) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/options.c b/options.c new file mode 100644 index 0000000..e39bf1e --- /dev/null +++ b/options.c @@ -0,0 +1,2073 @@ + +#include "foomaticrip.h" +#include "options.h" +#include "util.h" +#include <stdlib.h> +#include <ctype.h> +#include <assert.h> +#include <regex.h> +#include <string.h> +#include <math.h> + + +/* Values from foomatic keywords in the ppd file */ +char printer_model [256]; +char printer_id [128]; +char driver [128]; +char cmd [1024]; +char cmd_pdf [1024]; +dstr_t *postpipe = NULL; /* command into which the output of this + filter should be piped */ +int ps_accounting = 1; +char cupsfilter [256]; + +/* JCL prefix to put before the JCL options + (Can be modified by a "*JCLBegin:" keyword in the ppd file): */ +char jclbegin[256] = "\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): */ +char jcltointerpreter[256] = ""; + +/* JCL command to close a print job + (Can be modified by a "*JCLEnd:" keyword in the PPD file): */ +char jclend[256] = "\033%-12345X@PJL RESET\n"; + +/* Prefix for starting every JCL command + (Can be modified by "*FoomaticJCLPrefix:" keyword in the PPD file): */ +char jclprefix[256] = "@PJL "; +int jclprefixset = 0; + +dstr_t *prologprepend; +dstr_t *setupprepend; +dstr_t *pagesetupprepend; + + + +option_t *optionlist = NULL; +option_t *optionlist_sorted_by_order = NULL; + +int optionset_alloc, optionset_count; +char **optionsets; + + + + +const char * type_name(int type) +{ + switch (type) { + case TYPE_NONE: + return "none"; + case TYPE_ENUM: + return "enum"; + case TYPE_PICKMANY: + return "pickmany"; + case TYPE_BOOL: + return "bool"; + case TYPE_INT: + return "int"; + case TYPE_FLOAT: + return "float"; + case TYPE_STRING: + return "string"; + }; + _log("type '%d' does not exist\n", type); + return NULL; +} + +int type_from_string(const char *typestr) +{ + int type = TYPE_NONE; + + /* Official PPD options */ + if (!strcmp(typestr, "PickOne")) + type = TYPE_ENUM; + else if (!strcmp(typestr, "PickMany")) + type = TYPE_PICKMANY; + else if (!strcmp(typestr, "Boolean")) + type = TYPE_BOOL; + + /* FoomaticRIPOption */ + else if (strcasecmp(typestr, "enum") == 0) + type = TYPE_ENUM; + else if (strcasecmp(typestr, "pickmany") == 0) + type = TYPE_PICKMANY; + else if (strcasecmp(typestr, "bool") == 0) + type = TYPE_BOOL; + else if (strcasecmp(typestr, "int") == 0) + type = TYPE_INT; + else if (strcasecmp(typestr, "float") == 0) + type = TYPE_FLOAT; + else if (strcasecmp(typestr, "string") == 0) + type = TYPE_STRING; + else if (strcasecmp(typestr, "password") == 0) + type = TYPE_PASSWORD; + + return type; +} + +char style_from_string(const char *style) +{ + char r = '\0'; + if (strcmp(style, "PS") == 0) + r = 'G'; + else if (strcmp(style, "CmdLine") == 0) + r = 'C'; + else if (strcmp(style, "JCL") == 0) + r = 'J'; + else if (strcmp(style, "Composite") == 0) + r = 'X'; + return r; +} + +int section_from_string(const char *value) +{ + if (!strcasecmp(value, "AnySetup")) + return SECTION_ANYSETUP; + else if (!strcasecmp(value, "PageSetup")) + return SECTION_PAGESETUP; + else if (!strcasecmp(value, "Prolog")) + return SECTION_PROLOG; + else if (!strcasecmp(value, "DocumentSetup")) + return SECTION_DOCUMENTSETUP; + else if (!strcasecmp(value, "JCLSetup")) + return SECTION_JCLSETUP; + + _log("Unknown section: \"%s\"\n", value); + return 0; +} + +void options_init() +{ + optionset_alloc = 8; + optionset_count = 0; + optionsets = calloc(optionset_alloc, sizeof(char *)); + + prologprepend = create_dstr(); + setupprepend = create_dstr(); + pagesetupprepend = create_dstr(); +} + +static void free_param(param_t *param) +{ + if (param->allowedchars) { + regfree(param->allowedchars); + free(param->allowedchars); + } + + if (param->allowedregexp) { + regfree(param->allowedregexp); + free(param->allowedregexp); + } + + free(param); +} + +/* + * Values + */ + +static void free_value(value_t *val) +{ + if (val->value) + free(val->value); + free(val); +} + + +/* + * Options + */ +static void free_option(option_t *opt) +{ + choice_t *choice; + param_t *param; + value_t *value; + + free(opt->custom_command); + free(opt->proto); + + while (opt->valuelist) { + value = opt->valuelist; + opt->valuelist = opt->valuelist->next; + free_value(value); + } + while (opt->choicelist) { + choice = opt->choicelist; + opt->choicelist = opt->choicelist->next; + free(choice); + } + while (opt->paramlist) { + param = opt->paramlist; + opt->paramlist = opt->paramlist->next; + free_param(param); + } + if (opt->foomatic_param) + free_param(opt->foomatic_param); + + free(opt); +} + +void options_free() +{ + option_t *opt; + int i; + + for (i = 0; i < optionset_count; i++) + free(optionsets[i]); + free(optionsets); + optionsets = NULL; + optionset_alloc = 0; + optionset_count = 0; + + while (optionlist) { + opt = optionlist; + optionlist = optionlist->next; + free_option(opt); + } + + if (postpipe) + free_dstr(postpipe); + + free_dstr(prologprepend); + free_dstr(setupprepend); + free_dstr(pagesetupprepend); +} + +size_t option_count() +{ + option_t *opt; + size_t cnt = 0; + + for (opt = optionlist; opt; opt = opt->next) + cnt++; + return cnt; +} + +option_t * find_option(const char *name) +{ + option_t *opt; + + /* PageRegion and PageSize are the same options, just store one of them */ + if (!strcasecmp(name, "PageRegion")) + return find_option("PageSize"); + + for (opt = optionlist; opt; opt = opt->next) { + if (!strcasecmp(opt->name, name)) + return opt; + } + return NULL; +} + +option_t * assure_option(const char *name) +{ + option_t *opt, *last; + + if ((opt = find_option(name))) + return opt; + + opt = calloc(1, sizeof(option_t)); + + /* PageRegion and PageSize are the same options, just store one of them */ + if (!strcmp(name, "PageRegion")) + strlcpy(opt->name, "PageSize", 128); + else + strlcpy(opt->name, name, 128); + + /* set varname */ + strcpy(opt->varname, opt->name); + strrepl(opt->varname, "-/.", '_'); + + /* Default execution style is 'G' (PostScript) since all arguments for + which we don't find "*Foomatic..." keywords are usual PostScript options */ + opt->style = 'G'; + + opt->type = TYPE_NONE; + + /* append opt to optionlist */ + if (optionlist) { + for (last = optionlist; last->next; last = last->next); + last->next = opt; + } + else + optionlist = opt; + + /* prepend opt to optionlist_sorted_by_order + (0 is always at the beginning) */ + if (optionlist_sorted_by_order) { + opt->next_by_order = optionlist_sorted_by_order; + optionlist_sorted_by_order = opt; + } + else { + optionlist_sorted_by_order = opt; + } + + _log("Added option %s\n", opt->name); + return opt; +} + +/* This functions checks if "opt" is named "name", or if it has any + alternative names "name" (e.g. PageSize / PageRegion) */ +int option_has_name(option_t *opt, const char *name) +{ + if (!strcmp(opt->name, name)) + return 1; + + if (!strcmp(opt->name, "PageSize") && !strcmp(name, "PageRegion")) + return 1; + + return 0; +} + +int option_is_composite(option_t *opt) +{ + return opt ? (opt->style == 'X') : 0; +} + +int option_is_ps_command(option_t *opt) +{ + return opt->style == 'G'; +} + +int option_is_jcl_arg(option_t *opt) +{ + return opt->style == 'J'; +} + +int option_is_commandline_arg(option_t *opt) +{ + return opt->style == 'C'; +} + +int option_get_section(option_t *opt) +{ + return opt->section; +} + +static value_t * option_find_value(option_t *opt, int optionset) +{ + value_t *val; + + if (!opt) + return NULL; + + for (val = opt->valuelist; val; val = val->next) { + if (val->optionset == optionset) + return val; + } + return NULL; +} + +static value_t * option_assure_value(option_t *opt, int optionset) +{ + value_t *val, *last; + val = option_find_value(opt, optionset); + if (!val) { + val = calloc(1, sizeof(value_t)); + val->optionset = optionset; + + /* append to opt->valuelist */ + if (opt->valuelist) { + for (last = opt->valuelist; last->next; last = last->next); + last->next = val; + } + else + opt->valuelist = val; + } + return val; +} + +static param_t * option_find_param_index(option_t *opt, const char *name, int *idx) +{ + param_t *param; + int i; + for (param = opt->paramlist, i = 0; param; param = param->next, i += 1) { + if (!strcasecmp(param->name, name)) { + if (idx) + *idx = i; + return param; + } + } + if (idx) + *idx = -1; + return 0; +} + +static choice_t * option_find_choice(option_t *opt, const char *name) +{ + choice_t *choice; + assert(opt && name); + for (choice = opt->choicelist; choice; choice = choice->next) { + if (!strcasecmp(choice->value, name)) + return choice; + } + return NULL; +} + +void free_paramvalues(option_t *opt, char **paramvalues) +{ + int i; + if (!paramvalues) + return; + for (i = 0; i < opt->param_count; i++) + free(paramvalues[i]); + free(paramvalues); +} + +char * get_valid_param_string(option_t *opt, param_t *param, const char *str) +{ + char *result; + int i, imin, imax; + float f, fmin, fmax; + size_t len; + + switch (param->type) { + case TYPE_INT: + i = atoi(str); + imin = !isempty(param->min) ? atoi(param->min) : -999999; + imax = !isempty(param->max) ? atoi(param->max) : 1000000; + if (i < imin) { + _log("Value \"%s\" for option \"%s.%s\" is smaller than the minimum value \"%d\"\n", + str, opt->name, param->name, imin); + return NULL; + } + else if (i > imax) { + _log("Value \"%s\" for option \"%s.%s\" is larger than the maximum value \"%d\"\n", + str, opt->name, param->name, imax); + return NULL; + } + result = malloc(32); + snprintf(result, 32, "%d", i); + return result; + + case TYPE_FLOAT: + case TYPE_CURVE: + case TYPE_INVCURVE: + case TYPE_POINTS: + f = atof(str); + fmin = !isempty(param->min) ? atof(param->min) : -999999.0; + fmax = !isempty(param->max) ? atof(param->max) : 1000000.0; + if (f < fmin) { + _log("Value \"%s\" for option \"%s.%s\" is smaller than the minimum value \"%d\"\n", + str, opt->name, param->name, fmin); + return NULL; + } + else if (f > fmax) { + _log("Value \"%s\" for option \"%s.%s\" is larger than the maximum value \"%d\"\n", + str, opt->name, param->name, fmax); + return NULL; + } + result = malloc(32); + snprintf(result, 32, "%f", f); + return result; + + case TYPE_STRING: + case TYPE_PASSWORD: + case TYPE_PASSCODE: + if (param->allowedchars && + regexec(param->allowedchars, str, 0, NULL, 0) != 0) { + _log("Custom string \"%s\" for \"%s.%s\" contains illegal characters.\n", + str, opt->name, param->name); + return NULL; + } + if (param->allowedregexp && + regexec(param->allowedregexp, str, 0, NULL, 0) != 0) { + _log("Custom string \"%s\" for \"%s.%s\" does not match the allowed regexp.\n", + str, opt->name, param->name); + return NULL; + } + len = strlen(str); + if (!isempty(param->min) && len < atoi(param->min)) { + _log("Custom value \"%s\" is too short for \"%s.%s\".\n", + str, opt->name, param->name); + return NULL; + } + if (!isempty(param->max) && len > atoi(param->max)) { + _log("Custom value \"%s\" is too long for \"%s.%s\".\n", + str, opt->name, param->name); + return NULL; + } + return strdup(str); + } + return NULL; +} + +char * get_valid_param_string_int(option_t *opt, param_t *param, int value) +{ + char str[20]; + snprintf(str, 20, "%d", value); + return get_valid_param_string(opt, param, str); +} + +char * get_valid_param_string_float(option_t *opt, param_t *param, float value) +{ + char str[20]; + snprintf(str, 20, "%f", value); + return get_valid_param_string(opt, param, str); +} + +float convert_to_points(float f, const char *unit) +{ + if (!strcasecmp(unit, "pt")) + return roundf(f); + if (!strcasecmp(unit, "in")) + return roundf(f * 72.0); + if (!strcasecmp(unit, "cm")) + return roundf(f * 72.0 / 2.54); + if (!strcasecmp(unit, "mm")) + return roundf(f * 72.0 / 25.4); + + _log("Unknown unit: \"%s\"\n", unit); + return roundf(f); +} + +static char ** paramvalues_from_string(option_t *opt, const char *str) +{ + char ** paramvalues; + int n, i; + param_t *param; + char *copy, *cur, *p; + float width, height; + char unit[3]; + + if (!strcmp(opt->name, "PageSize")) + { + if (startswith(str, "Custom.")) + str = &str[7]; + /* 'unit' is optional, if it is not given, 'pt' is assumed */ + n = sscanf(str, "%fx%f%2s", &width, &height, unit); + if (n > 1) { + if (n == 3) { + width = convert_to_points(width, unit); + height = convert_to_points(height, unit); + } + paramvalues = calloc(opt->param_count, sizeof(char*)); + for (param = opt->paramlist, i = 0; param; param = param->next, i++) { + if (!strcasecmp(param->name, "width")) + paramvalues[i] = get_valid_param_string_int(opt, param, (int)width); + else if (!strcasecmp(param->name, "height")) + paramvalues[i] = get_valid_param_string_int(opt, param, (int)height); + else + paramvalues[i] = get_valid_param_string(opt, param, "0"); + if (!paramvalues[i]) { + free_paramvalues(opt, paramvalues); + return NULL; + } + } + return paramvalues; + } + } + + if (opt->param_count == 1) { + paramvalues = malloc(sizeof(char*)); + paramvalues[0] = get_valid_param_string(opt, opt->paramlist, + startswith(str, "Custom.") ? &str[7] : str); + if (!paramvalues[0]) { + free(paramvalues); + return NULL; + } + } + else { + if (!(p = strchr(str, '{'))) + return NULL; + paramvalues = calloc(opt->param_count, sizeof(char*)); + copy = strdup(p +1); + for (cur = strtok(copy, " \t}"); cur; cur = strtok(NULL, " \t}")) { + p = strchr(cur, '='); + if (!p) + continue; + *p++ = '\0'; + if ((param = option_find_param_index(opt, cur, &i))) + paramvalues[i] = get_valid_param_string(opt, param, p); + else + _log("Could not find param \"%s\" for option \"%s\"\n", + cur, opt->name); + } + free(copy); + + /* check if all params have been set */ + for (i = 0; i < opt->param_count; i++) { + if (!paramvalues[i]) { + free_paramvalues(opt, paramvalues); + return NULL; + } + } + } + return paramvalues; +} + +char * paramvalues_to_string(option_t *opt, char **paramvalues) +{ + int i; + param_t *param; + dstr_t *res = create_dstr(); + char *data; + + if (opt->param_count < 1) + return NULL; + + if (opt->param_count == 1) { + param = opt->paramlist; + dstrcpyf(res, "Custom.%s", paramvalues[0]); + } + else { + dstrcpyf(res, "{%s=%s", opt->paramlist->name, paramvalues[0]); + param = opt->paramlist->next; + i = 1; + while (param) { + dstrcatf(res, " %s=%s", param->name, paramvalues[i]); + i++; + param = param->next; + } + dstrcat(res, "}"); + } + /* only free dstr struct, NOT the string data */ + data = res->data; + free(res); + return data; +} + +char * get_valid_value_string(option_t *opt, const char *value) +{ + char *res; + choice_t *choice; + char **paramvalues; + + if (!value) + return NULL; + + if (startswith(value, "From") && option_is_composite(find_option(&value[4]))) + return strdup(value); + + if (opt->type == TYPE_BOOL) { + if (is_true_string(value)) + return strdup("1"); + else if (is_false_string(value)) + return strdup("0"); + else { + _log("Could not interpret \"%s\" as boolean value for option \"%s\".\n", value, opt->name); + return NULL; + } + } + + /* Check if "value" is a predefined choice (except for "Custom", which is + * not really a predefined choice, but an error if used without further + * parameters) */ + if (strcmp(value, "Custom") != 0 && (choice = option_find_choice(opt, value))) + return strdup(choice->value); + + if (opt->type == TYPE_ENUM) { + if (!strcasecmp(value, "none")) + return strdup("None"); + + /* + * CUPS assumes that options with the choices "Yes", "No", "On", "Off", + * "True", or "False" are boolean options and maps "-o Option=On" to + * "-o Option" and "-o Option=Off" to "-o noOption", which foomatic-rip + * maps to "0" and "1". So when "0" or "1" is unavailable in the + * option, we try "Yes", "No", "On", "Off", "True", and "False". + */ + if (is_true_string(value)) { + for (choice = opt->choicelist; choice; choice = choice->next) { + if (is_true_string(choice->value)) + return strdup(choice->value); + } + } + else if (is_false_string(value)) { + for (choice = opt->choicelist; choice; choice = choice->next) { + if (is_false_string(choice->value)) + return strdup(choice->value); + } + } + } + + /* Custom value */ + if (opt->paramlist) { + paramvalues = paramvalues_from_string(opt, value); + if (paramvalues) { + res = paramvalues_to_string(opt, paramvalues); + free(paramvalues); + return (startswith(res, "Custom.") ? strdup(&res[7]) : strdup(res)); + } + } + else if (opt->foomatic_param) + return get_valid_param_string(opt, opt->foomatic_param, + startswith(value, "Custom.") ? &value[7] : value); + + /* Return the default value */ + return NULL; +} + +/* Returns the current value for 'opt' in 'optionset'. */ +const char * option_get_value(option_t *opt, int optionset) +{ + value_t *val = option_find_value(opt, optionset); + return val ? val->value : NULL; +} + +/* Returns non-zero if the foomatic prototype should be used for that + * optionset, otherwise the custom_command will be used */ +int option_use_foomatic_prototype(option_t *opt) +{ + /* Only PostScript and JCL options can be CUPS custom options */ + if (!option_is_ps_command(opt) && !option_is_jcl_arg(opt)) + return 1; + + /* if only one of them exists, take that one */ + if (opt->custom_command && !opt->proto) + return 0; + if (!opt->custom_command && opt->proto) + return 1; + return 0; +} + +void build_foomatic_custom_command(dstr_t *cmd, option_t *opt, const char *values) +{ + if (!opt->proto && !strcmp(opt->name, "PageSize")) + { + choice_t *choice = option_find_choice(opt, "Custom"); + char ** paramvalues = paramvalues_from_string(opt, values); + char width[30], height[20]; + int pos; + + assert(choice); + + /* Get rid of the trailing ".00000", it confuses ghostscript */ + snprintf(width, 20, "%d", atoi(paramvalues[0])); + snprintf(height, 20, "%d", atoi(paramvalues[1])); + + dstrcpy(cmd, choice->command); + + if ((pos = dstrreplace(cmd, "%0", width, 0)) < 0) + pos = dstrreplace(cmd, "0", width, 0); + + if ((pos = dstrreplace(cmd, "%1", height, pos) < 0)) + dstrreplace(cmd, "0", height, pos); + + free_paramvalues(opt, paramvalues); + } + else + { + dstrcpy(cmd, opt->proto); + /* use replace instead of printf-style because opt->proto could contain + other format strings */ + dstrreplace(cmd, "%s", values, 0); + } +} + +void build_cups_custom_ps_command(dstr_t *cmd, option_t *opt, const char *values) +{ + param_t *param; + int i; + char **paramvalues = paramvalues_from_string(opt, values); + + dstrclear(cmd); + for (param = opt->paramlist, i = 0; param; param = param->next, i++) + dstrcatf(cmd, "%s ", paramvalues[i]); + dstrcat(cmd, opt->custom_command); + free_paramvalues(opt, paramvalues); +} + +void build_cups_custom_jcl_command(dstr_t *cmd, option_t *opt, const char *values) +{ + param_t *param; + int i; + char orderstr[8]; + char **paramvalues = paramvalues_from_string(opt, values); + + dstrcpy(cmd, opt->custom_command); + for (param = opt->paramlist, i = 0; param; param = param->next, i++) { + snprintf(orderstr, 8, "\\%d", param->order); + dstrreplace(cmd, orderstr, paramvalues[i], 0); + } + free_paramvalues(opt, paramvalues); +} + +int composite_get_command(dstr_t *cmd, option_t *opt, int optionset, int section) +{ + char *copy, *cur, *p; + option_t *dep; + const char * valstr; + dstr_t *depcmd; + + dstrclear(cmd); + if (!option_is_composite(opt)) + return 0; + + if (!(valstr = option_get_value(opt, optionset))) + return 0; + + depcmd = create_dstr(); + copy = strdup(valstr); + /* Dependent options have been set to the right value in composite_set_values, + so just find out which options depend on this composite and get their commands + for "optionset" with option_get_command() */ + for (cur = strtok(copy, " \t"); cur; cur = strtok(NULL, " \t")) { + dstrclear(depcmd); + if ((p = strchr(cur, '='))) { + *p++ = '\0'; + if ((dep = find_option(cur))) + option_get_command(depcmd, dep, optionset, section); + } + else if (startswith(cur, "no") || startswith(cur, "No")) { + if ((dep = find_option(&cur[2]))) + option_get_command(depcmd, dep, optionset, section); + } + else { + if ((dep = find_option(cur))) + option_get_command(depcmd, dep, optionset, section); + } + if (depcmd->len) + dstrcatf(cmd, "%s\n", depcmd->data); + } + free(copy); + free_dstr(depcmd); + return cmd->len != 0; +} + +int option_is_in_section(option_t *opt, int section) +{ + if (opt->section == section) + return 1; + if (opt->section == SECTION_ANYSETUP && (section == SECTION_PAGESETUP || section == SECTION_DOCUMENTSETUP)) + return 1; + return 0; +} + +int option_is_custom_value(option_t *opt, const char *value) +{ + if (opt->type == TYPE_BOOL || opt->type == TYPE_ENUM) + return 0; + + return !option_has_choice(opt, value); +} + +int option_get_command(dstr_t *cmd, option_t *opt, int optionset, int section) +{ + const char *valstr; + choice_t *choice = NULL; + + dstrclear(cmd); + + if (option_is_composite(opt)) + return composite_get_command(cmd, opt, optionset, section); + + if (section >= 0 && !option_is_in_section(opt, section)) + return 1; /* empty command for this section */ + + valstr = option_get_value(opt, optionset); + if (!valstr) + return 0; + + /* If the value is set to a predefined choice */ + choice = option_find_choice(opt, valstr); + if (choice) { + dstrcpy(cmd, choice->command); + return 1; + } + + /* Consider "None" as the empty string for string and password options */ + if ((opt->type == TYPE_STRING || opt->type == TYPE_PASSWORD) && + !strcasecmp(valstr, "None")) + valstr = ""; + + /* Custom value */ + if (option_use_foomatic_prototype(opt)) + build_foomatic_custom_command(cmd, opt, valstr); + else { + dstrcpy(cmd, opt->custom_command); + if ((option_get_section(opt) == SECTION_JCLSETUP) || + (opt->style == 'J')) + build_cups_custom_jcl_command(cmd, opt, valstr); + else + build_cups_custom_ps_command(cmd, opt, valstr); + } + + return cmd->len != 0; +} + +void composite_set_values(option_t *opt, int optionset, const char *values) +{ + char *copy, *cur, *p; + option_t *dep; + value_t *val; + + copy = strdup(values); + for (cur = strtok(copy, " \t"); cur; cur = strtok(NULL, " \t")) { + if ((p = strchr(cur, '='))) { + *p++ = '\0'; + if ((dep = find_option(cur))) { + val = option_assure_value(dep, optionset); + val->fromoption = opt; + val->value = get_valid_value_string(dep, p); + } + else + _log("Could not find option \"%s\" (set from composite \"%s\")", cur, opt->name); + } + else if (startswith(cur, "no") || startswith(cur, "No")) { + if ((dep = find_option(&cur[2]))) { + val = option_assure_value(dep, optionset); + val->fromoption = opt; + val->value = get_valid_value_string(dep, "0"); + } + } + else { + if ((dep = find_option(cur))) { + val = option_assure_value(dep, optionset); + val->fromoption = opt; + val->value = get_valid_value_string(dep, "1"); + } + } + } + free(copy); +} + +int option_set_value(option_t *opt, int optionset, const char *value) +{ + value_t *val = option_assure_value(opt, optionset); + char *newvalue; + choice_t *choice; + option_t *fromopt; + + newvalue = get_valid_value_string(opt, value); + if (!newvalue) + return 0; + + free(val->value); + val->value = NULL; + + if (startswith(newvalue, "From") && (fromopt = find_option(&newvalue[4])) && + option_is_composite(fromopt)) { + /* TODO only set the changed option, not all of them */ + choice = option_find_choice(fromopt, + option_get_value(fromopt, optionset)); + + composite_set_values(fromopt, optionset, choice->command); + } + else { + val->value = newvalue; + } + + if (option_is_composite(opt)) { + /* set dependent values */ + choice = option_find_choice(opt, value); + if (choice && !isempty(choice->command)) + composite_set_values(opt, optionset, choice->command); + } + return 1; +} + +int option_accepts_value(option_t *opt, const char *value) +{ + char *val = get_valid_value_string(opt, value); + if (!val) + return 0; + free(val); + return 1; +} + +int option_has_choice(option_t *opt, const char *choice) +{ + return option_find_choice(opt, choice) != NULL; +} + +const char * option_text(option_t *opt) +{ + if (isempty(opt->text)) + return opt->text; + return opt->text; +} + +int option_type(option_t *opt) +{ + return opt->type; +} + +void option_set_order(option_t *opt, double order) +{ + option_t *prev; + + /* remove opt from old position */ + if (opt == optionlist_sorted_by_order) + optionlist_sorted_by_order = opt->next_by_order; + else { + for (prev = optionlist_sorted_by_order; + prev && prev->next_by_order != opt; + prev = prev->next_by_order); + prev->next_by_order = opt->next_by_order; + } + + opt->order = order; + + /* insert into new position */ + if (!optionlist_sorted_by_order) + optionlist_sorted_by_order = opt; + else if (optionlist_sorted_by_order->order > opt->order) { + opt->next_by_order = optionlist_sorted_by_order; + optionlist_sorted_by_order = opt; + } + else { + for (prev = optionlist_sorted_by_order; + prev->next_by_order && prev->next_by_order->order < opt->order; + prev = prev->next_by_order); + opt->next_by_order = prev->next_by_order; + prev->next_by_order = opt; + } +} + +/* Set option from *FoomaticRIPOption keyword */ +void option_set_from_string(option_t *opt, const char *str) +{ + char type[32], style[32]; + double order; + int matches; + + matches = sscanf(str, "%31s %31s %c %lf", type, style, &opt->spot, &order); + if (matches < 3) { + _log("Can't read the value of *FoomaticRIPOption for \"%s\"", opt->name); + return; + } + opt->type = type_from_string(type); + opt->style = style_from_string(style); + + if (matches == 4) + option_set_order(opt, order); +} + +static choice_t * option_assure_choice(option_t *opt, const char *name) +{ + choice_t *choice, *last = NULL; + + for (choice = opt->choicelist; choice; choice = choice->next) { + if (!strcasecmp(choice->value, name)) + return choice; + last = choice; + } + if (!choice) { + choice = calloc(1, sizeof(choice_t)); + if (last) + last->next = choice; + else + opt->choicelist = choice; + strlcpy(choice->value, name, 128); + } + return choice; +} + +static void unhtmlify(char *dest, size_t size, const char *src) +{ + jobparams_t *job = get_current_job(); + char *pdest = dest; + const char *psrc = src; + const char *repl; + struct tm *t = localtime(&job->time); + char tmpstr[10]; + + while (*psrc && pdest - dest < size) { + + if (*psrc == '&') { + psrc++; + repl = NULL; + + /* Replace HTML/XML entities by the original characters */ + if (!prefixcmp(psrc, "apos;")) + repl = "\'"; + else if (!prefixcmp(psrc, "quot;")) + repl = "\""; + else if (!prefixcmp(psrc, "gt;")) + repl = ">"; + else if (!prefixcmp(psrc, "lt;")) + repl = "<"; + else if (!prefixcmp(psrc, "amp;")) + repl = "&"; + + /* Replace special entities by job->data */ + else if (!prefixcmp(psrc, "job;")) + repl = job->id; + else if (!prefixcmp(psrc, "user;")) + repl = job->user; + else if (!prefixcmp(psrc, "host;")) + repl = job->host; + else if (!prefixcmp(psrc, "title;")) + repl = job->title; + else if (!prefixcmp(psrc, "copies;")) + repl = job->copies; + else if (!prefixcmp(psrc, "rbinumcopies;")) { + if (job->rbinumcopies > 0) { + snprintf(tmpstr, 10, "%d", job->rbinumcopies); + repl = tmpstr; + } + else + repl = job->copies; + } + else if (!prefixcmp(psrc, "options;")) + repl = job->optstr->data; + else if (!prefixcmp(psrc, "year;")) { + sprintf(tmpstr, "%04d", t->tm_year + 1900); + repl = tmpstr; + } + else if (!prefixcmp(psrc, "month;")) { + sprintf(tmpstr, "%02d", t->tm_mon + 1); + repl = tmpstr; + } + else if (!prefixcmp(psrc, "date;")) { + sprintf(tmpstr, "%02d", t->tm_mday); + repl = tmpstr; + } + else if (!prefixcmp(psrc, "hour;")) { + sprintf(tmpstr, "%02d", t->tm_hour); + repl = tmpstr; + } + else if (!prefixcmp(psrc, "min;")) { + sprintf(tmpstr, "%02d", t->tm_min); + repl = tmpstr; + } + else if (!prefixcmp(psrc, "sec;")) { + sprintf(tmpstr, "%02d", t->tm_sec); + repl = tmpstr; + } + + if (repl) { + strncpy(pdest, repl, size - (pdest - dest)); + pdest += strlen(repl); + psrc = strchr(psrc, ';') +1; + } + else { + *pdest = '&'; + pdest++; + } + } + else { + *pdest = *psrc; + pdest++; + psrc++; + } + } + *pdest = '\0'; +} + +/* + * Checks whether 'code' contains active PostScript, i.e. not only comments + */ +static int contains_active_postscript(const char *code) +{ + char **line, **lines; + int contains_ps = 0; + + if (!(lines = argv_split(code, "\n", NULL))) + return 0; + + for (line = lines; *line && !contains_ps; line++) + contains_ps = !isempty(*line) && + !startswith(skip_whitespace(*line), "%"); + + argv_free(lines); + return contains_ps; +} + +void option_set_choice(option_t *opt, const char *name, const char *text, + const char *code) +{ + choice_t *choice; + + if (opt->type == TYPE_BOOL) { + if (is_true_string(name)) + choice = option_assure_choice(opt, "1"); + else + choice = option_assure_choice(opt, "0"); + } + else + choice = option_assure_choice(opt, name); + + if (text) + strlcpy(choice->text, text, 128); + + if (!code) + { + _log("Warning: No code for choice \"%s\" of option \"%s\"\n", + choice->text, opt->name); + return; + } + + if (!startswith(code, "%% FoomaticRIPOptionSetting")) + unhtmlify(choice->command, 1024, code); +} + +/* + * Parameters + */ + +int param_set_allowed_chars(param_t *param, const char *value) +{ + char rxstr[128], tmp[128]; + + param->allowedchars = malloc(sizeof(regex_t)); + unhtmlify(tmp, 128, value); + snprintf(rxstr, 128, "^[%s]*$", tmp); + if (regcomp(param->allowedchars, rxstr, 0) != 0) { + regfree(param->allowedchars); + param->allowedchars = NULL; + return 0; + } + return 1; +} + +int param_set_allowed_regexp(param_t *param, const char *value) +{ + char tmp[128]; + + param->allowedregexp = malloc(sizeof(regex_t)); + unhtmlify(tmp, 128, value); + if (regcomp(param->allowedregexp, tmp, 0) != 0) { + regfree(param->allowedregexp); + param->allowedregexp = NULL; + return 0; + } + return 1; +} + +void option_set_custom_command(option_t *opt, const char *cmd) +{ + size_t len = strlen(cmd) + 50; + free(opt->custom_command); + opt->custom_command = malloc(len); + unhtmlify(opt->custom_command, len, cmd); +} + +param_t * option_add_custom_param_from_string(option_t *opt, + const char *name, const char *text, const char *str) +{ + param_t *param = calloc(1, sizeof(param_t)); + param_t *p; + char typestr[33]; + int n; + + strlcpy(param->name, name, 128); + strlcpy(param->text, text, 128); + + n = sscanf(str, "%d%15s%19s%19s", + ¶m->order, typestr, param->min, param->max); + + if (n != 4) { + _log("Could not parse custom parameter for '%s'!\n", opt->name); + free(param); + return NULL; + } + + if (!strcmp(typestr, "curve")) + param->type = TYPE_CURVE; + else if (!strcmp(typestr, "invcurve")) + param->type = TYPE_INVCURVE; + else if (!strcmp(typestr, "int")) + param->type = TYPE_INT; + else if (!strcmp(typestr, "real")) + param->type = TYPE_FLOAT; + else if (!strcmp(typestr, "passcode")) + param->type = TYPE_PASSCODE; + else if (!strcmp(typestr, "password")) + param->type = TYPE_PASSWORD; + else if (!strcmp(typestr, "points")) + param->type = TYPE_POINTS; + else if (!strcmp(typestr, "string")) + param->type = TYPE_STRING; + else { + _log("Unknown custom parameter type for param '%s' for option '%s'\n", param->name, opt->name); + free(param); + return NULL; + } + + param->next = NULL; + + /* Insert param into opt->paramlist, sorted by order */ + if (!opt->paramlist) + opt->paramlist = param; + else if (opt->paramlist->order > param->order) { + param->next = opt->paramlist; + opt->paramlist = param; + } + else { + for (p = opt->paramlist; + p->next && p->next->order < param->order; + p = p->next); + param->next = p->next; + p->next = param; + } + + opt->param_count++; + return param; +} + +param_t * option_assure_foomatic_param(option_t *opt) +{ + param_t *param; + + if (opt->foomatic_param) + return opt->foomatic_param; + + param = calloc(1, sizeof(param_t)); + strcpy(param->name, "foomatic-param"); + param->order = 0; + param->type = opt->type; + + opt->foomatic_param = param; + return param; +} + + +/* + * Optionsets + */ + +const char * optionset_name(int idx) +{ + if (idx < 0 || idx >= optionset_count) { + _log("Optionset with index %d does not exist\n", idx); + return NULL; + } + return optionsets[idx]; +} + +int optionset(const char * name) +{ + int i; + + for (i = 0; i < optionset_count; i++) { + if (!strcmp(optionsets[i], name)) + return i; + } + + if (optionset_count == optionset_alloc) { + optionset_alloc *= 2; + optionsets = realloc(optionsets, optionset_alloc * sizeof(char *)); + for (i = optionset_count; i < optionset_alloc; i++) + optionsets[i] = NULL; + } + + optionsets[optionset_count] = strdup(name); + optionset_count++; + return optionset_count -1; +} + +void optionset_copy_values(int src_optset, int dest_optset) +{ + option_t *opt; + value_t *val; + + for (opt = optionlist; opt; opt = opt->next) { + for (val = opt->valuelist; val; val = val->next) { + if (val->optionset == src_optset) { + option_set_value(opt, dest_optset, val->value); + break; + } + } + } +} + +void optionset_delete_values(int optionset) +{ + option_t *opt; + value_t *val, *prev_val; + + for (opt = optionlist; opt; opt = opt->next) { + val = opt->valuelist; + prev_val = NULL; + while (val) { + if (val->optionset == optionset) { + if (prev_val) + prev_val->next = val->next; + else + opt->valuelist = val->next; + free_value(val); + val = prev_val ? prev_val->next : opt->valuelist; + break; + } else { + prev_val = val; + val = val->next; + } + } + } +} + +int optionset_equal(int optset1, int optset2, int exceptPS) +{ + option_t *opt; + const char *val1, *val2; + + for (opt = optionlist; opt; opt = opt->next) { + if (exceptPS && opt->style == 'G') + continue; + + val1 = option_get_value(opt, optset1); + val2 = option_get_value(opt, optset2); + + if (val1 && val2) { /* both entries exist */ + if (strcmp(val1, val2) != 0) + return 0; /* but aren't equal */ + } + else if (val1 || val2) /* one entry exists --> can't be equal */ + return 0; + /* If no extry exists, the non-existing entries + * are considered as equal */ + } + return 1; +} + +/* + * read_ppd_file() + */ +void read_ppd_file(const char *filename) +{ + FILE *fh; + char line [256]; /* PPD line length is max 255 (excl. \0) */ + char *p; + char key[128], name[64], text[64]; + dstr_t *value = create_dstr(); /* value can span multiple lines */ + double order; + value_t *val; + option_t *opt, *current_opt = NULL; + param_t *param; + + fh = fopen(filename, "r"); + if (!fh) { + _log("error opening %s\n", filename); + exit(EXIT_PRNERR_NORETRY_BAD_SETTINGS); + } + _log("Parsing PPD file ...\n"); + + dstrassure(value, 256); + + while (!feof(fh)) { + fgets(line, 256, fh); + + if (line[0] != '*' || startswith(line, "*%")) + continue; + + /* get the key */ + if (!(p = strchr(line, ':'))) + continue; + *p = '\0'; + + key[0] = name[0] = text[0] = '\0'; + sscanf(line, "*%127s%*[ \t]%63[^ \t/=)]%*1[/=]%63[^\n]", key, name, text); + + /* get the value */ + dstrclear(value); + sscanf(p +1, " %255[^\r\n]", value->data); + value->len = strlen(value->data); + if (!value->len) + _log("PPD: Missing value for key \"%s\"\n", line); + + while (1) { + /* "&&" is the continue-on-next-line marker */ + if (dstrendswith(value, "&&")) { + value->len -= 2; + value->data[value->len] = '\0'; + } + /* quoted but quotes are not yet closed */ + else if (value->data[0] == '\"' && !strchr(value->data +1, '\"')) + dstrcat(value, "\n"); /* keep newlines in quoted string*/ + /* not quoted, or quotes already closed */ + else + break; + + fgets(line, 256, fh); + dstrcat(value, line); + dstrremovenewline(value); + } + + /* remove quotes */ + if (value->data[0] == '\"') { + memmove(value->data, value->data +1, value->len +1); + p = strrchr(value->data, '\"'); + if (!p) { + _log("Invalid line: \"%s: ...\"\n", key); + continue; + } + *p = '\0'; + } + /* remove last newline */ + dstrremovenewline(value); + + /* process key/value pairs */ + if (strcmp(key, "NickName") == 0) { + unhtmlify(printer_model, 256, value->data); + } + else if (strcmp(key, "FoomaticIDs") == 0) { + /* *FoomaticIDs: <printer ID> <driver ID> */ + sscanf(value->data, "%*[ \t]%127[^ \t]%*[ \t]%127[^ \t\n]", + printer_id, driver); + } + else if (strcmp(key, "FoomaticRIPPostPipe") == 0) { + if (!postpipe) + postpipe = create_dstr(); + dstrassure(postpipe, value->len +128); + unhtmlify(postpipe->data, postpipe->alloc, value->data); + } + else if (strcmp(key, "FoomaticRIPCommandLine") == 0) { + unhtmlify(cmd, 1024, value->data); + } + else if (strcmp(key, "FoomaticRIPCommandLinePDF") == 0) { + unhtmlify(cmd_pdf, 1024, value->data); + } + else if (strcmp(key, "FoomaticNoPageAccounting") == 0) { + /* Boolean value */ + if (strcasecmp(value->data, "true") != 0) { + /* Driver is not compatible with page accounting according to the + Foomatic database, so turn it off for this driver */ + ps_accounting = 0; + _log("CUPS page accounting disabled by driver.\n"); + } + } + else if (!strcmp(key, "cupsFilter")) { + /* cupsFilter: <code> */ + /* only save the filter for "application/vnd.cups-raster" */ + if (prefixcmp(value->data, "application/vnd.cups-raster") == 0) { + p = strrchr(value->data, ' '); + if (p) + unhtmlify(cupsfilter, 256, p +1); + } + } + else if (startswith(key, "Custom") && !strcasecmp(name, "true")) { + /* Cups custom option: *CustomFoo True: "command" */ + if (startswith(&key[6], "JCL")) { + opt = assure_option(&key[9]); + opt->style = 'J'; + } + else + opt = assure_option(&key[6]); + option_set_custom_command(opt, value->data); + if (!strcmp(key, "CustomPageSize")) + option_set_custom_command(assure_option("PageRegion"), value->data); + } + else if (startswith(key, "ParamCustom")) { + /* Cups custom parameter: + *ParamCustomFoo Name/Text: order type minimum maximum */ + if (startswith(&key[11], "JCL")) + opt = assure_option(&key[14]); + else + opt = assure_option(&key[11]); + option_add_custom_param_from_string(opt, name, text, value->data); + } + else if (!strcmp(key, "OpenUI") || !strcmp(key, "JCLOpenUI")) { + /* "*[JCL]OpenUI *<option>[/<translation>]: <type>" */ + current_opt = assure_option(&name[1]); + if (!isempty(text)) + strlcpy(current_opt->text, text, 128); + if (startswith(key, "JCL")) + current_opt->style = 'J'; + /* Set the argument type only if not defined yet, + a definition in "*FoomaticRIPOption" has priority */ + if (current_opt->type == TYPE_NONE) + current_opt->type = type_from_string(value->data); + } + else if (!strcmp(key, "CloseUI") || !strcmp(key, "JCLCloseUI")) { + /* *[JCL]CloseUI: *<option> */ + if (!current_opt || !option_has_name(current_opt, value->data +1)) + _log("CloseUI found without corresponding OpenUI (%s).\n", value->data +1); + current_opt = NULL; + } + else if (!strcmp(key, "FoomaticRIPOption")) { + /* "*FoomaticRIPOption <option>: <type> <style> <spot> [<order>]" + <order> only used for 1-choice enum options */ + option_set_from_string(assure_option(name), value->data); + } + else if (!strcmp(key, "FoomaticRIPOptionPrototype")) { + /* "*FoomaticRIPOptionPrototype <option>: <code>" + Used for numerical and string options only */ + opt = assure_option(name); + opt->proto = malloc(128); + unhtmlify(opt->proto, 128, value->data); + } + else if (!strcmp(key, "FoomaticRIPOptionRange")) { + /* *FoomaticRIPOptionRange <option>: <min> <max> + Used for numerical options only */ + param = option_assure_foomatic_param(assure_option(name)); + sscanf(value->data, "%19s %19s", param->min, param->max); + } + else if (!strcmp(key, "FoomaticRIPOptionMaxLength")) { + /* "*FoomaticRIPOptionMaxLength <option>: <length>" + Used for string options only */ + param = option_assure_foomatic_param(assure_option(name)); + sscanf(value->data, "%19s", param->max); + } + else if (!strcmp(key, "FoomaticRIPOptionAllowedChars")) { + /* *FoomaticRIPOptionAllowedChars <option>: <code> + Used for string options only */ + param = option_assure_foomatic_param(assure_option(name)); + param_set_allowed_chars(param, value->data); + } + else if (!strcmp(key, "FoomaticRIPOptionAllowedRegExp")) { + /* "*FoomaticRIPOptionAllowedRegExp <option>: <code>" + Used for string options only */ + param = option_assure_foomatic_param(assure_option(name)); + param_set_allowed_regexp(param, value->data); + } + else if (!strcmp(key, "OrderDependency")) { + /* OrderDependency: <order> <section> *<option> */ + /* use 'text' to read <section> */ + sscanf(value->data, "%lf %63s *%63s", &order, text, name); + opt = assure_option(name); + opt->section = section_from_string(text); + option_set_order(opt, order); + } + + /* Default options are not yet validated (not all options/choices + have been read yet) */ + else if (!prefixcmp(key, "Default")) { + /* Default<option>: <value> */ + + /* TODO *DefaultColorSpace is a keyword and doesn't need to be extraced, does it? */ + if (!strcmp(key, "DefaultColorSpace")) + continue; + + opt = assure_option(&key[7]); + val = option_assure_value(opt, optionset("default")); + free(val->value); + val->value = strdup(value->data); + } + else if (!prefixcmp(key, "FoomaticRIPDefault")) { + /* FoomaticRIPDefault<option>: <value> + Used for numerical options only */ + opt = assure_option(&key[18]); + val = option_assure_value(opt, optionset("default")); + free(val->value); + val->value = strdup(value->data); + } + + /* Current argument */ + else if (current_opt && !strcmp(key, current_opt->name)) { + /* *<option> <choice>[/translation]: <code> */ + option_set_choice(current_opt, name, text, value->data); + } + else if (!strcmp(key, "FoomaticRIPOptionSetting")) { + /* "*FoomaticRIPOptionSetting <option>[=<choice>]: <code> + For boolean options <choice> is not given */ + option_set_choice(assure_option(name), + isempty(text) ? "true" : text, NULL, value->data); + } + + /* "*(Foomatic|)JCL(Begin|ToPSInterpreter|End|Prefix): <code>" + The printer supports PJL/JCL when there is such a line */ + else if (!prefixcmp(key, "JCLBegin") || + !prefixcmp(key, "FoomaticJCLBegin")) { + unhexify(jclbegin, 256, value->data); + if (!jclprefixset && strstr(jclbegin, "PJL") == NULL) + jclprefix[0] = '\0'; + } + else if (!prefixcmp(key, "JCLToPSInterpreter") || + !prefixcmp(key, "FoomaticJCLToPSInterpreter")) { + unhexify(jcltointerpreter, 256, value->data); + } + else if (!prefixcmp(key, "JCLEnd") || + !prefixcmp(key, "FoomaticJCLEnd")) { + unhexify(jclend, 256, value->data); + } + else if (!prefixcmp(key, "JCLPrefix") || + !prefixcmp(key, "FoomaticJCLPrefix")) { + unhexify(jclprefix, 256, value->data); + jclprefixset = 1; + } + else if (!prefixcmp(key, "% COMDATA #")) { + /* old foomtic 2.0.x PPD file */ + _log("You are using an old Foomatic 2.0 PPD file, which is no " + "longer supported by Foomatic >4.0. Exiting.\n"); + exit(1); /* TODO exit more gracefully */ + } + } + + fclose(fh); + free_dstr(value); + + /* Validate default options by resetting them with option_set_value() */ + for (opt = optionlist; opt; opt = opt->next) { + val = option_find_value(opt, optionset("default")); + if (val) { + /* if fromopt is set, this value has already been validated */ + if (!val->fromoption) + option_set_value(opt, optionset("default"), val->value); + } + else + /* Make sure that this option has a default choice, even if none is + defined in the PPD file */ + option_set_value(opt, optionset("default"), opt->choicelist->value); + } +} + +int ppd_supports_pdf() +{ + option_t *opt; + + /* If at least one option inserts PostScript code, we cannot support PDF */ + for (opt = optionlist; opt; opt = opt->next) + { + choice_t *choice; + + if (!option_is_ps_command(opt)) + continue; + + for (choice = opt->choicelist; choice; choice = choice->next) + if (contains_active_postscript(choice->command)) + return 0; + } + + if (!isempty(cmd_pdf)) + return 1; + + /* Ghostscript also accepts PDF, use that if it is in the normal command + * line */ + if (startswith(cmd, "gs")) + { + strncpy(cmd_pdf, cmd, 1024); + return 1; + } + + return 0; +} + +/* build a renderer command line, based on the given option set */ +int build_commandline(int optset, dstr_t *cmdline, int pdfcmdline) +{ + option_t *opt; + const char *userval; + char *s, *p; + dstr_t *cmdvar = create_dstr(); + dstr_t *open = create_dstr(); + dstr_t *close = create_dstr(); + char letters[] = "%A %B %C %D %E %F %G %H %I %J %K %L %M %W %X %Y %Z"; + int jcl = 0; + + dstr_t *local_jclprepend = create_dstr(); + + dstrclear(prologprepend); + dstrclear(setupprepend); + dstrclear(pagesetupprepend); + + if (cmdline) + dstrcpy(cmdline, pdfcmdline ? cmd_pdf : cmd); + + for (opt = optionlist_sorted_by_order; opt; opt = opt->next_by_order) { + /* composite options have no direct influence, and all their dependents + have already been set */ + if (option_is_composite(opt)) + continue; + + userval = option_get_value(opt, optset); + option_get_command(cmdvar, opt, optset, -1); + + /* Insert the built snippet at the correct place */ + if (option_is_ps_command(opt)) { + /* Place this Postscript command onto the prepend queue + for the appropriate section. */ + if (cmdvar->len) { + dstrcpyf(open, "[{\n%%%%BeginFeature: *%s ", opt->name); + if (opt->type == TYPE_BOOL) + dstrcatf(open, is_true_string(userval) ? "True\n" : "False\n"); + else + dstrcatf(open, "%s\n", userval); + dstrcpyf(close, "\n%%%%EndFeature\n} stopped cleartomark\n"); + + switch (option_get_section(opt)) { + case SECTION_PROLOG: + dstrcatf(prologprepend, "%s%s%s", open->data, cmdvar->data, close->data); + break; + + case SECTION_ANYSETUP: + if (optset != optionset("currentpage")) + dstrcatf(setupprepend, "%s%s%s", open->data, cmdvar->data, close->data); + else if (strcmp(option_get_value(opt, optionset("header")), userval) != 0) + dstrcatf(pagesetupprepend, "%s%s%s", open->data, cmdvar->data, close->data); + break; + + case SECTION_DOCUMENTSETUP: + dstrcatf(setupprepend, "%s%s%s", open->data, cmdvar->data, close->data); + break; + + case SECTION_PAGESETUP: + dstrcatf(pagesetupprepend, "%s%s%s", open->data, cmdvar->data, close->data); + break; + + case SECTION_JCLSETUP: /* PCL/JCL argument */ + s = malloc(cmdvar->len +1); + unhexify(s, cmdvar->len +1, cmdvar->data); + dstrcatf(local_jclprepend, "%s", s); + free(s); + break; + + default: + dstrcatf(setupprepend, "%s%s%s", open->data, cmdvar->data, close->data); + } + } + } + else if (option_is_jcl_arg(opt)) { + jcl = 1; + /* Put JCL commands onto JCL stack */ + if (cmdvar->len) { + char *s = malloc(cmdvar->len +1); + unhexify(s, cmdvar->len +1, cmdvar->data); + if (!startswith(cmdvar->data, jclprefix)) + dstrcatf(local_jclprepend, "%s%s\n", jclprefix, s); + else + dstrcat(local_jclprepend, s); + free(s); + } + } + else if (option_is_commandline_arg(opt) && cmdline) { + /* Insert the processed argument in the command line + just before every occurrence of the spot marker. */ + p = malloc(3); + snprintf(p, 3, "%%%c", opt->spot); + s = malloc(cmdvar->len +3); + snprintf(s, cmdvar->len +3, "%s%%%c", cmdvar->data, opt->spot); + dstrreplace(cmdline, p, s, 0); + free(p); + free(s); + } + + /* Insert option into command line of CUPS raster driver */ + if (cmdline && strstr(cmdline->data, "%Y")) { + if (isempty(userval)) + continue; + s = malloc(strlen(opt->name) + strlen(userval) + 20); + sprintf(s, "%s=%s %%Y", opt->name, userval); + dstrreplace(cmdline, "%Y", s, 0); + free(s); + } + } + + /* Tidy up after computing option statements for all of P, J, and C types: */ + + /* C type finishing */ + /* Pluck out all of the %n's from the command line prototype */ + if (cmdline) { + s = strtok(letters, " "); + do { + dstrreplace(cmdline, s, "", 0); + } while ((s = strtok(NULL, " "))); + } + + /* J type finishing */ + /* Compute the proper stuff to say around the job */ + if (jcl && !jobhasjcl) { + /* command to switch to the interpreter */ + dstrcatf(local_jclprepend, "%s", jcltointerpreter); + + /* Arrange for JCL RESET command at the end of job */ + dstrcpy(jclappend, jclend); + + argv_free(jclprepend); + jclprepend = argv_split(local_jclprepend->data, "\r\n", NULL); + } + + free_dstr(cmdvar); + free_dstr(open); + free_dstr(close); + free_dstr(local_jclprepend); + + return !isempty(cmd); +} + +/* if "comments" is set, add "%%BeginProlog...%%EndProlog" */ +void append_prolog_section(dstr_t *str, int optset, int comments) +{ + /* Start comment */ + if (comments) { + _log("\"Prolog\" section is missing, inserting it.\n"); + dstrcat(str, "%%BeginProlog\n"); + } + + /* Generate the option code (not necessary when CUPS is spooler and + PostScript data is not converted from PDF) */ + if ((spooler != SPOOLER_CUPS) || pdfconvertedtops) { + _log("Inserting option code into \"Prolog\" section.\n"); + build_commandline(optset, NULL, 0); + dstrcat(str, prologprepend->data); + } + + /* End comment */ + if (comments) + dstrcat(str, "%%EndProlog\n"); +} + +void append_setup_section(dstr_t *str, int optset, int comments) +{ + /* Start comment */ + if (comments) { + _log("\"Setup\" section is missing, inserting it.\n"); + dstrcat(str, "%%BeginSetup\n"); + } + + /* PostScript code to generate accounting messages for CUPS */ + if (spooler == SPOOLER_CUPS) { + _log("Inserting PostScript code for CUPS' page accounting\n"); + dstrcat(str, accounting_prolog); + } + + /* Generate the option code (not necessary when CUPS is spooler and + PostScript data is not converted from PDF) */ + if ((spooler != SPOOLER_CUPS) || pdfconvertedtops) { + _log("Inserting option code into \"Setup\" section.\n"); + build_commandline(optset, NULL, 0); + dstrcat(str, setupprepend->data); + } + + /* End comment */ + if (comments) + dstrcat(str, "%%EndSetup\n"); +} + +void append_page_setup_section(dstr_t *str, int optset, int comments) +{ + /* Start comment */ + if (comments) { + _log("\"PageSetup\" section is missing, inserting it.\n"); + dstrcat(str, "%%BeginPageSetup\n"); + } + + /* Generate the option code (not necessary when CUPS is spooler) */ + _log("Inserting option code into \"PageSetup\" section.\n"); + build_commandline(optset, NULL, 0); + dstrcat(str, pagesetupprepend->data); + + /* End comment */ + if (comments) + dstrcat(str, "%%EndPageSetup\n"); +} + + +typedef struct page_range { + short even, odd; + unsigned first, last; + struct page_range *next; +} page_range_t; + +static page_range_t * parse_page_ranges(const char *ranges) +{ + page_range_t *head, *tail = NULL; + char *tokens, *tok; + int cnt; + + tokens = strdup(ranges); + for (tok = strtok(tokens, ","); tok; tok = strtok(NULL, ",")) { + page_range_t *pr = calloc(1, sizeof(page_range_t)); + + if (startswith(tok, "even")) + pr->even = 1; + else if (startswith(tok, "odd")) + pr->odd = 1; + else if ((cnt = sscanf(tok, "%d-%d", &pr->first, &pr->last))) { + /* If 'last' has not been read, this could mean only one page (no + * hyphen) or all pages to the end */ + if (cnt == 1 && !endswith(tok, "-")) + pr->last = pr->first; + else if (cnt == 2 && pr->first > pr->last) { + unsigned tmp = pr->first; + pr->first = pr->last; + pr->last = tmp; + } + } + else { + printf("Invalid page range: %s\n", tok); + free(pr); + continue; + } + + if (tail) { + tail->next = pr; + tail = pr; + } + else + tail = head = pr; + } + + free(tokens); + return head; +} + +static void free_page_ranges(page_range_t *ranges) +{ + page_range_t *pr; + while (ranges) { + pr = ranges; + ranges = ranges->next; + free(pr); + } +} + +/* Parse a string containing page ranges and either check whether a + given page is in the ranges or, if the given page number is zero, + determine the score how specific this page range string is.*/ +int get_page_score(const char *pages, int page) +{ + page_range_t *ranges = parse_page_ranges(pages); + page_range_t *pr; + int totalscore = 0; + int pageinside = 0; + + for (pr = ranges; pr; pr = pr->next) { + if (pr->even) { + totalscore += 50000; + if (page % 2 == 0) + pageinside = 1; + } + else if (pr->odd) { + totalscore += 50000; + if (page % 2 == 1) + pageinside = 1; + } + else if (pr->first == pr->last) { /* Single page */ + totalscore += 1; + if (page == pr->first) + pageinside = 1; + } + else if (pr->last == 0) { /* To the end of the document */ + totalscore += 100000; + if (page >= pr->first) + pageinside = 1; + } + else { /* Sequence of pages */ + totalscore += pr->last - pr->first +1; + if (page >= pr->first && page <= pr->last) + pageinside = 1; + } + } + + free_page_ranges(ranges); + + if (page == 0 || pageinside) + return totalscore; + + return 0; +} + +/* Set the options for a given page */ +void set_options_for_page(int optset, int page) +{ + int score, bestscore; + option_t *opt; + value_t *val, *bestvalue; + const char *ranges; + const char *optsetname; + + for (opt = optionlist; opt; opt = opt->next) { + + bestscore = 10000000; + bestvalue = NULL; + for (val = opt->valuelist; val; val = val->next) { + + optsetname = optionset_name(val->optionset); + if (!startswith(optsetname, "pages:")) + continue; + + ranges = &optsetname[6]; /* after "pages:" */ + score = get_page_score(ranges, page); + if (score && score < bestscore) { + bestscore = score; + bestvalue = val; + } + } + + if (bestvalue) + option_set_value(opt, optset, bestvalue->value); + } +} + diff --git a/options.h b/options.h new file mode 100644 index 0000000..6e66d04 --- /dev/null +++ b/options.h @@ -0,0 +1,160 @@ + +#ifndef options_h +#define options_h + + +#include <stddef.h> +#include <regex.h> +#include "util.h" + +/* Option types */ +#define TYPE_NONE 0 +#define TYPE_ENUM 1 +#define TYPE_PICKMANY 2 +#define TYPE_BOOL 3 +#define TYPE_INT 4 +#define TYPE_FLOAT 5 +#define TYPE_STRING 6 +#define TYPE_PASSWORD 7 +#define TYPE_CURVE 8 +#define TYPE_INVCURVE 9 +#define TYPE_PASSCODE 10 +#define TYPE_POINTS 11 + +/* Sections */ +#define SECTION_ANYSETUP 1 +#define SECTION_PAGESETUP 2 +#define SECTION_PROLOG 3 +#define SECTION_DOCUMENTSETUP 4 +#define SECTION_JCLSETUP 5 + + + +typedef struct choice_s { + char value [128]; + char text [128]; + char command[1024]; + struct choice_s *next; +} choice_t; + +/* Custom option parameter */ +typedef struct param_s { + char name [128]; + char text [128]; /* formerly comment, changed to 'text' to + be consistent with cups */ + int order; + + int type; + char min[20], max[20]; /* contents depend on 'type' */ + + regex_t *allowedchars; + regex_t *allowedregexp; + + struct param_s *next; +} param_t; + +/* Option */ +typedef struct option_s { + char name [128]; + char text [128]; + char varname [128]; /* clean version of 'name' (no spaces etc.) */ + int type; + int style; + char spot; + double order; + int section; + + int notfirst; /* TODO remove */ + + choice_t *choicelist; + + /* Foomatic PPD extensions */ + char *proto; /* *FoomaticRIPOptionPrototype: if this is set + it will be used with only the first option + in paramlist (there should be only one) */ + param_t *foomatic_param; + + /* CUPS custom options */ + char *custom_command; /* *CustomFoo */ + param_t *paramlist; /* for custom values, sorted by stack order */ + size_t param_count; + + struct value_s *valuelist; + + struct option_s *next; + struct option_s *next_by_order; +} option_t; + + +/* A value for an option */ +typedef struct value_s { + int optionset; + char *value; + option_t *fromoption; /* This is set when this value is set by a composite */ + struct value_s *next; +} value_t; + + +extern option_t *optionlist; +extern option_t *optionlist_sorted_by_order; + +extern char jclbegin[256]; +extern char jcltointerpreter[256]; +extern char jclend[256]; +extern char jclprefix[256]; + +extern char cmd[1024]; +extern char cmd_pdf[1024]; + +extern int ps_accounting; + + +int option_is_composite(option_t *opt); +int option_is_ps_command(option_t *opt); +int option_is_jcl_arg(option_t *opt); +int option_is_commandline_arg(option_t *opt); + + +int option_get_section(option_t *opt); /* TODO deprecated */ + +/* handles ANYSETUP (for (PAGE|DOCUMENT)SETUP) */ +int option_is_in_section(option_t *opt, int section); + +void options_init(); +void options_free(); + +size_t option_count(); +option_t *find_option(const char *name); + +void read_ppd_file(const char *filename); + +int ppd_supports_pdf(); + + +int option_set_value(option_t *opt, int optset, const char *value); +const char * option_get_value(option_t *opt, int optset); + +/* section == -1 for all sections */ +int option_get_command(dstr_t *cmd, option_t *opt, int optset, int section); + +int option_accepts_value(option_t *opt, const char *value); +int option_has_choice(option_t *opt, const char *choice); +int option_is_custom_value(option_t *opt, const char *value); + + +const char * optionset_name(int idx); +int optionset(const char * name); + +void optionset_copy_values(int src_optset, int dest_optset); +int optionset_equal(int optset1, int optset2, int exceptPS); +void optionset_delete_values(int optionset); + +void append_prolog_section(dstr_t *str, int optset, int comments); +void append_setup_section(dstr_t *str, int optset, int comments); +void append_page_setup_section(dstr_t *str, int optset, int comments); +int build_commandline(int optset, dstr_t *cmdline, int pdfcmdline); + +void set_options_for_page(int optset, int page); + +#endif + @@ -0,0 +1,359 @@ + +#include "foomaticrip.h" +#include "util.h" +#include "options.h" +#include "process.h" +#include "renderer.h" + +#include <stdlib.h> +#include <ctype.h> +#include <sys/wait.h> +#include <unistd.h> +#include <errno.h> + +#include <ghostscript/iapi.h> +#include <ghostscript/ierrors.h> + +#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0])) + + +const char *pagecountcode = + "/pdffile (%s) (r) file def\n" + "pdfdict begin\n" + "pdffile pdfopen begin\n" + "(PageCount: ) print\n" + "pdfpagecount == flush\n" /* 'flush' makes sure that gs_stdout is called + before gsapi_run_string returns */ + "currentdict pdfclose\n" + "end end\n"; + +char gsout [256]; + +static int wait_for_renderer(); + + +static const char * temp_dir() +{ + static const char *tmpdir = NULL; + + if (!tmpdir) + { + const char *dirs[] = { getenv("TMPDIR"), P_tmpdir, "/tmp", NULL }; + const char **dir; + + for (dir = dirs; *dir; dir++) + if (access(*dir, W_OK) == 0) { + tmpdir = *dir; + break; + } + if (tmpdir) + { + _log("Storing temporary files in %s\n", tmpdir); + setenv("TMPDIR", tmpdir, 1); /* for child processes */ + } + else + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, + "Cannot find a writable temp dir."); + } + + return tmpdir; +} + +int gs_stdout(void *instance, const char *str, int len) +{ + int last; + if (isempty(gsout)) { + last = len < 256 ? len : 255; + strncpy(gsout, str, last +1); + gsout[last] = '\0'; + } + return len; /* ignore everything after the first few chars */ +} + +int gs_stderr(void *instance, const char *str, int len) +{ + char *buf = malloc(len +1); + strncpy(buf, str, len); + buf[len] = '\0'; + _log("Ghostscript: %s", buf); + free(buf); + return len; +} + +static int pdf_count_pages(const char *filename) +{ + void *minst; + int gsargc = 3; + char *gsargv[] = { "", "-dNODISPLAY", "-q" }; + int pagecount; + int exit_code; + char code[2048]; + + if (gsapi_new_instance(&minst, NULL) < 0) { + _log("Could not create ghostscript instance\n"); + return -1; + } + gsapi_set_stdio(minst, NULL, gs_stdout, gs_stderr); + if (gsapi_init_with_args(minst, gsargc, gsargv) < 0) { + _log("Could not init ghostscript\n"); + gsapi_exit(minst); + gsapi_delete_instance(minst); + return -1; + } + + snprintf(code, 2048, pagecountcode, filename); + if (gsapi_run_string(minst, code, 0, &exit_code) == 0) { + if (sscanf(gsout, "PageCount: %d", &pagecount) < 1) + pagecount = -1; + } + + gsapi_exit(minst); + gsapi_delete_instance(minst); + return pagecount; +} + +pid_t kid3 = 0; + + +static int start_renderer(const char *cmd) +{ + if (kid3 != 0) + wait_for_renderer(); + + _log("Starting renderer with command: %s\n", cmd); + kid3 = start_process("kid3", exec_kid3, (void *)cmd, NULL, NULL); + if (kid3 < 0) + return 0; + + return 1; +} + +static int wait_for_renderer() +{ + int status; + + waitpid(kid3, &status, 0); + + if (!WIFEXITED(status)) { + _log("Kid3 did not finish normally.\n"); + exit(EXIT_PRNERR_NORETRY_BAD_SETTINGS); + } + + _log("Kid3 exit status: %d\n", WEXITSTATUS(status)); + if (WEXITSTATUS(status) != 0) + exit(EXIT_PRNERR_NORETRY_BAD_SETTINGS); + + kid3 = 0; + return 1; +} + +/* + * Extract pages 'first' through 'last' from the pdf and write them into a + * temporary file. + */ +static int pdf_extract_pages(char filename[PATH_MAX], + const char *pdffilename, + int first, + int last) +{ + void *minst; + char filename_arg[PATH_MAX], first_arg[50], last_arg[50]; + const char *gs_args[] = { "", "-q", "-dNOPAUSE", "-dBATCH", + "-dPARANOIDSAFER", "-sDEVICE=pdfwrite", filename_arg, first_arg, + last_arg, pdffilename }; + + _log("Extracting pages %d through %d\n", first, last); + + snprintf(filename, PATH_MAX, "%s/foomatic-XXXXXX", temp_dir()); + mktemp(filename); + if (!filename[0]) + return 0; + + if (gsapi_new_instance(&minst, NULL) < 0) + { + _log("Could not create ghostscript instance\n"); + return 0; + } + + snprintf(filename_arg, PATH_MAX, "-sOutputFile=%s", filename); + snprintf(first_arg, 50, "-dFirstPage=%d", first); + if (last > 0) + snprintf(last_arg, 50, "-dLastPage=%d", last); + else + first_arg[0] = '\0'; + + gsapi_set_stdio(minst, NULL, NULL, gs_stderr); + + if (gsapi_init_with_args(minst, ARRAY_LEN(gs_args), (char **)gs_args) < 0) + { + _log("Could not run ghostscript to extract the pages\n"); + gsapi_exit(minst); + gsapi_delete_instance(minst); + return 0; + } + + gsapi_exit(minst); + gsapi_delete_instance(minst); + return 1; +} + +static int render_pages_with_generic_command(dstr_t *cmd, + const char *filename, + int firstpage, + int lastpage) +{ + char tmpfile[PATH_MAX]; + int result; + + /* TODO it might be a good idea to give pdf command lines the possibility + * to get the file on the command line rather than piped through stdin + * (maybe introduce a &filename; ??) */ + + if (lastpage < 0) /* i.e. print the whole document */ + dstrcatf(cmd, " < %s", filename); + else + { + if (!pdf_extract_pages(tmpfile, filename, firstpage, lastpage)) + return 0; + dstrcatf(cmd, " < %s", tmpfile); + } + + result = start_renderer(cmd->data); + + if (lastpage > 0) + unlink(tmpfile); + + return result; +} + +static int render_pages_with_ghostscript(dstr_t *cmd, + size_t start_gs_cmd, + size_t end_gs_cmd, + const char *filename, + int firstpage, + int lastpage) +{ + char *p; + + /* No need to create a temporary file, just give ghostscript the file and + * first/last page on the command line */ + + /* Some command lines want to read from stdin */ + for (p = &cmd->data[end_gs_cmd -1]; isspace(*p); p--) + ; + if (*p == '-') + *p = ' '; + + dstrinsertf(cmd, end_gs_cmd, " %s ", filename); + + if (lastpage > 0) + dstrinsertf(cmd, start_gs_cmd +2, + " -dFirstPage=%d -dLastPage=%d ", + firstpage, lastpage); + else + dstrinsertf(cmd, start_gs_cmd +2, + " -dFirstPage=%d ", firstpage); + + return start_renderer(cmd->data); +} + +static int render_pages(const char *filename, int firstpage, int lastpage) +{ + dstr_t *cmd = create_dstr(); + size_t start, end; + int result; + + build_commandline(optionset("currentpage"), cmd, 1); + + extract_command(&start, &end, cmd->data, "gs"); + if (start == end) + /* command is not Ghostscript */ + result = render_pages_with_generic_command(cmd, + filename, + firstpage, + lastpage); + else + /* Ghostscript command, tell it which pages we want to render */ + result = render_pages_with_ghostscript(cmd, + start, + end, + filename, + firstpage, + lastpage); + + free_dstr(cmd); + return result; +} + +static int print_pdf_file(const char *filename) +{ + int page_count, i; + int firstpage; + + page_count = pdf_count_pages(filename); + + if (page_count <= 0) + return 0; + _log("File contains %d pages\n", page_count); + + optionset_copy_values(optionset("header"), optionset("currentpage")); + optionset_copy_values(optionset("currentpage"), optionset("previouspage")); + firstpage = 1; + for (i = 1; i <= page_count; i++) + { + set_options_for_page(optionset("currentpage"), i); + if (!optionset_equal(optionset("currentpage"), optionset("previouspage"), 1)) + { + render_pages(filename, firstpage, i); + firstpage = i; + } + optionset_copy_values(optionset("currentpage"), optionset("previouspage")); + } + if (firstpage == 1) + render_pages(filename, 1, -1); /* Render the whole document */ + else + render_pages(filename, firstpage, page_count); + + wait_for_renderer(); + + return 1; +} + +int print_pdf(FILE *s, + const char *alreadyread, + size_t len, + const char *filename, + size_t startpos) +{ + char tmpfilename[PATH_MAX] = ""; + int result; + + /* If reading from stdin, write everything into a temporary file */ + /* TODO don't do this if there aren't any pagerange-limited options */ + if (s == stdin) + { + int fd; + FILE *tmpfile; + + snprintf(tmpfilename, PATH_MAX, "%s/foomatic-XXXXXX", temp_dir()); + fd = mkstemp(tmpfilename); + if (fd < 0) { + _log("Could not create temporary file: %s\n", strerror(errno)); + return EXIT_PRNERR_NORETRY_BAD_SETTINGS; + } + + tmpfile = fdopen(fd, "r+"); + copy_file(tmpfile, stdin, alreadyread, len); + fclose(tmpfile); + + filename = tmpfilename; + } + + result = print_pdf_file(filename); + + if (!isempty(tmpfilename)) + unlink(tmpfilename); + + return result; +} + @@ -0,0 +1,8 @@ + +#ifndef pdf_h +#define pdf_h + +int print_pdf(FILE *s, const char *alreadyread, size_t len, const char *filename, int startpos); + +#endif + diff --git a/postscript.c b/postscript.c new file mode 100644 index 0000000..b82ba9a --- /dev/null +++ b/postscript.c @@ -0,0 +1,1288 @@ + +#include "foomaticrip.h" +#include "util.h" +#include "options.h" +#include "fileconverter.h" +#include "renderer.h" +#include "process.h" + +#include <errno.h> +#include <unistd.h> +#include <ctype.h> +#include <stdlib.h> + +void get_renderer_handle(const dstr_t *prepend, FILE **fd, pid_t *pid); +int close_renderer_handle(FILE *rendererhandle, pid_t rendererpid); + +#define LT_BEGIN_FEATURE 1 +#define LT_FOOMATIC_RIP_OPTION_SETTING 2 +int line_type(const char *line) +{ + const char *p; + if (startswith(line, "%%BeginFeature:")) + return LT_BEGIN_FEATURE; + p = line; + while (*p && isspace(*p)) p++; + if (!startswith(p, "%%")) + return 0; + p += 2; + while (*p && isspace(*p)) p++; + if (startswith(p, "FoomaticRIPOptionSetting:")) + return LT_FOOMATIC_RIP_OPTION_SETTING; + return 0; +} + + +/* Next, examine the PostScript job for traces of command-line and + JCL options. PPD-aware applications and spoolers stuff option + settings directly into the file, they do not necessarily send + PPD options by the command line. Also stuff in PostScript code + to apply option settings given by the command line and to set + the defaults given in the PPD file. + + Examination strategy: read lines from STDIN until the first + %%Page: comment appears and save them as @psheader. This is the + page-independent header part of the PostScript file. The + PostScript interpreter (renderer) must execute this part once + before rendering any assortment of pages. Then pages can be + printed in any arbitrary selection or order. All option + settings we find here will be collected in the default option + set for the RIP command line. + + Now the pages will be read and sent to the renderer, one after + the other. Every page is read into memory until the + %%EndPageSetup comment appears (or a certain amount of lines was + read). So we can get option settings only valid for this + page. If we have such settings we set them in the modified + command set for this page. + + If the renderer is not running yet (first page) we start it with + the command line built from the current modified command set and + send the first page to it, in the end we leave the renderer + running and keep input and output pipes open, so that it can + accept further pages. If the renderer is still running from + the previous page and the current modified command set is the + same as the one for the previous page, we send the page. If + the command set is different, we close the renderer, re-start + it with the command line built from the new modified command + set, send the header again, and then the page. + + After the last page the trailer (%%Trailer) is sent. + + The output pipe of this program stays open all the time so that + the spooler does not assume that the job has finished when the + renderer is re-started. + + Non DSC-conforming documents will be read until a certain line + number is reached. Command line or JCL options inserted later + will be ignored. + + If options are implemented by PostScript code supposed to be + stuffed into the job's PostScript data we stuff the code for all + these options into our job data, So all default settings made in + the PPD file (the user can have edited the PPD file to change + them) are taken care of and command line options get also + applied. To give priority to settings made by applications we + insert the options's code in the beginnings of their respective + sections, so that sommething, which is already inserted, gets + executed after our code. Missing sections are automatically + created. In non-DSC-conforming files we insert the option code + in the beginning of the file. This is the same policy as used by + the "pstops" filter of CUPS. + + If CUPS is the spooler, the option settings were already + inserted by the "pstops" filter, so we don't insert them + again. The only thing we do is correcting settings of numerical + options when they were set to a value not available as choice in + the PPD file, As "pstops" does not support "real" numerical + options, it sees these settings as an invalid choice and stays + with the default setting. In this case we correct the setting in + the first occurence of the option's code, as this one is the one + added by CUPS, later occurences come from applications and + should not be touched. + + If the input is not PostScript (if there is no "%!" after + $maxlinestopsstart lines) a file conversion filter will + automatically be applied to the incoming data, so that we will + process the resulting PostScript here. This way we have always + PostScript data here and so we can apply the printer/driver + features described in the PPD file. + + Supported file conversion filters are "a2ps", "enscript", + "mpage", and spooler-specific filters. All filters convert + plain text to PostScript, "a2ps" also other formats. The + conversion filter is always used when one prints the + documentation pages, as they are created as plain text, + when CUPS is the spooler "pstops" is executed after the + filter so that the default option settings from the PPD file + and CUPS-specific options as N-up get applied. On regular + printouts one gets always PostScript when CUPS or PPR is + the spooler, so the filter is only used for regular + printouts under LPD, LPRng, GNUlpr or without spooler. +*/ + +/* PostScript sections */ +#define PS_SECTION_JCLSETUP 1 +#define PS_SECTION_PROLOG 2 +#define PS_SECTION_SETUP 3 +#define PS_SECTION_PAGESETUP 4 + +#define MAX_NON_DSC_LINES_IN_HEADER 1000 +#define MAX_LINES_FOR_PAGE_OPTIONS 200 + +typedef struct { + size_t pos; + + FILE *file; + const char *alreadyread; + size_t len; +} stream_t; + +void _print_ps(stream_t *stream); + +int stream_next_line(dstr_t *line, stream_t *s) +{ + int c; + size_t cnt = 0; + + dstrclear(line); + while (s->pos < s->len) { + c = s->alreadyread[s->pos++]; + dstrputc(line, c); + cnt++; + if (c == '\n') + return cnt; + } + + while ((c = fgetc(s->file)) != EOF) { + dstrputc(line, c); + cnt++; + if (c == '\n') + return cnt; + } + return cnt; +} + +int print_ps(FILE *file, const char *alreadyread, size_t len, const char *filename) +{ + stream_t stream; + + if (file != stdin && (dup2(fileno(file), fileno(stdin)) < 0)) { + _log("Could not dup %s to stdin.\n", filename); + return 0; + } + + stream.pos = 0; + stream.file = stdin; + stream.alreadyread = alreadyread; + stream.len = len; + _print_ps(&stream); + return 1; +} + +void _print_ps(stream_t *stream) +{ + char *p; + + int maxlines = 1000; /* Maximum number of lines to be read when the + documenent is not DSC-conforming. + "$maxlines = 0" means that all will be read and + examined. If it is discovered that the input + file is DSC-conforming, this will be set to 0. */ + + int maxlinestopsstart = 200; /* That many lines are allowed until the + "%!" indicating PS comes. These + additional lines in the + beginning are usually JCL + commands. The lines will be + ignored by our parsing but + passed through. */ + + int printprevpage = 0; /* We set this when encountering "%%Page:" and the + previous page is not printed yet. Then it will + be printed and the new page will be prepared in + the next run of the loop (we don't read a new + line and don't increase the $linect then). */ + + int linect = 0; /* how many lines have we examined */ + int nonpslines = 0; /* lines before "%!" found yet. */ + int more_stuff = 1; /* there is more stuff in stdin */ + int saved = 0; /* DSC line not precessed yet */ + int isdscjob = 0; /* is the job dsc conforming */ + int inheader = 1; /* Are we still in the header, before first + "%%Page:" comment= */ + + int optionsalsointoheader = 0; /* 1: We are in a "%%BeginSetup... + %%EndSetup" section after the first + "%%Page:..." line (OpenOffice.org + does this and intends the options here + apply to the whole document and not + only to the current page). We have to + add all lines also to the end of the + @psheader now and we have to set + non-PostScript options also in the + "header" optionset. 0: otherwise. */ + + int insertoptions = 1; /* If we find out that a file with a DSC magic + string ("%!PS-Adobe-") is not really DSC- + conforming, we insert the options directly + after the line with the magic string. We use + this variable to store the number of the line + with the magic string */ + + int prologfound = 0; /* Did we find the + "%%BeginProlog...%%EndProlog" section? */ + int setupfound = 0; /* Did we find the + %%BeginSetup...%%EndSetup" section? */ + int pagesetupfound = 0; /* special page setup handling needed */ + + int inprolog = 0; /* We are between "%%BeginProlog" and "%%EndProlog" */ + int insetup = 0; /* We are between "%%BeginSetup" and "%%EndSetup" */ + int infeature = 0; /* We are between "%%BeginFeature" and "%%EndFeature" */ + + int optionreplaced = 0; /* Will be set to 1 when we are in an + option ("%%BeginFeature... + %%EndFeature") which we have replaced. */ + + int postscriptsection = PS_SECTION_JCLSETUP; /* In which section of the PostScript file + are we currently ? */ + + int nondsclines = 0; /* Number of subsequent lines found which are at a + non-DSC-conforming place, between the sections + of the header.*/ + + int nestinglevel = 0; /* Are we in the main document (0) or in an + embedded document bracketed by "%%BeginDocument" + and "%%EndDocument" (>0) We do not parse the + PostScript in an embedded document. */ + + int inpageheader = 0; /* Are we in the header of a page, + between "%%BeginPageSetup" and + "%%EndPageSetup" (1) or not (0). */ + + int passthru = 0; /* 0: write data into psfifo, + 1: pass data directly to the renderer */ + + int lastpassthru = 0; /* State of 'passthru' in previous line + (to allow debug output when $passthru + switches. */ + + int ignorepageheader = 0; /* Will be set to 1 as soon as active + code (not between "%%BeginPageSetup" + and "%%EndPageSetup") appears after a + "%%Page:" comment. In this case + "%%BeginPageSetup" and + "%%EndPageSetup" is not allowed any + more on this page and will be ignored. + Will be set to 0 when a new "%%Page:" + comment appears. */ + + int optset = optionset("header"); /* Where do the option settings which + we have found go? */ + + /* current line */ + dstr_t *line = create_dstr(); + + dstr_t *onelinebefore = create_dstr(); + dstr_t *twolinesbefore = create_dstr(); + + /* The header of the PostScript file, to be send after each start of the renderer */ + dstr_t *psheader = create_dstr(); + + /* The input FIFO, data which we have pulled from stdin for examination, + but not send to the renderer yet */ + dstr_t *psfifo = create_dstr(); + + FILE *fileconverter_handle = NULL; /* File handle to converter process */ + pid_t fileconverter_pid = 0; /* PID of the fileconverter process */ + + int ignoreline; + + int ooo110 = 0; /* Flag to work around an application bug */ + + int currentpage = 0; /* The page which we are currently printing */ + + option_t *o; + const char *val; + + int linetype; + + dstr_t *linesafterlastbeginfeature = create_dstr(); /* All codelines after the last "%%BeginFeature" */ + + char optionname [128]; + char value [128]; + int fromcomposite = 0; + + dstr_t *pdest; + + double width, height; + + pid_t rendererpid = 0; + FILE *rendererhandle = NULL; + + int retval; + + dstr_t *tmp = create_dstr(); + jobhasjcl = 0; + + /* We do not parse the PostScript to find Foomatic options, we check + only whether we have PostScript. */ + if (dontparse) + maxlines = 1; + + _log("Reading PostScript input ...\n"); + + do { + ignoreline = 0; + + if (printprevpage || saved || stream_next_line(line, stream)) { + saved = 0; + if (linect == nonpslines) { + /* In the beginning should be the postscript leader, + sometimes after some JCL commands */ + if ( !(line->data[0] == '%' && line->data[1] == '!') && + !(line->data[1] == '%' && line->data[2] == '!')) /* There can be a Windows control character before "%!" */ + { + nonpslines++; + if (maxlines == nonpslines) + maxlines ++; + jobhasjcl = 1; + + if (nonpslines > maxlinestopsstart) { + /* This is not a PostScript job, we must convert it */ + _log("Job does not start with \"%%!\", is it Postscript?\n" + "Starting file converter\n"); + + /* Reset all variables but conserve the data which we have already read */ + jobhasjcl = 0; + linect = 0; + nonpslines = 1; /* Take into account that the line of this run of the loop + will be put into @psheader, so the first line read by + the file converter is already the second line */ + maxlines = 1001; + + dstrclear(onelinebefore); + dstrclear(twolinesbefore); + + dstrcpyf(tmp, "%s%s%s", psheader, psfifo, line); + dstrclear(psheader); + dstrclear(psfifo); + dstrclear(line); + + /* Start the file conversion filter */ + if (!fileconverter_pid) + get_fileconverter_handle(tmp->data, &fileconverter_handle, &fileconverter_pid); + else + rip_die(EXIT_JOBERR, "File conversion filter probably crashed\n"); + + /* Read the further data from the file converter and not from STDIN */ + if (close(fileno(stdin)) == -1 && errno != ESPIPE) + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "Couldn't close STDIN\n"); + if (dup2(fileno(stdin), fileno(fileconverter_handle)) == -1) + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "Couldn't dup fileconverter_handle\n"); + } + } + else { + /* Do we have a DSC-conforming document? */ + if ((line->data[0] == '%' && startswith(line->data, "%!PS-Adobe-")) || + (line->data[1] == '%' && startswith(line->data, "%!PS-Adobe-"))) + { + /* Do not stop parsing the document */ + if (!dontparse) { + maxlines = 0; + isdscjob = 1; + insertoptions = linect + 1; + /* We have written into psfifo before, now we continue in + psheader and move over the data which is already in psfifo */ + dstrcat(psheader, psfifo->data); + dstrclear(psfifo); + } + _log("--> This document is DSC-conforming!\n"); + } + else { + /* Job is not DSC-conforming, stick in all PostScript + option settings in the beginning */ + append_prolog_section(line, optset, 1); + append_setup_section(line, optset, 1); + append_page_setup_section(line, optset, 1); + prologfound = 1; + setupfound = 1; + pagesetupfound = 1; + } + } + } + else { + if (startswith(line->data, "%")) { + if (startswith(line->data, "%%BeginDocument")) { + /* Beginning of an embedded document + Note that Adobe Acrobat has a bug and so uses + "%%BeginDocument " instead of "%%BeginDocument:" */ + nestinglevel++; + _log("Embedded document, nesting level now: %d\n", nestinglevel); + } + else if (nestinglevel > 0 && startswith(line->data, "%%EndDocument")) { + /* End of an embedded document */ + nestinglevel--; + _log("End of embedded document, nesting level now: %d\n", nestinglevel); + } + else if (nestinglevel == 0 && startswith(line->data, "%%Creator")) { + /* Here we set flags to treat particular bugs of the + PostScript produced by certain applications */ + p = strstr(line->data, "%%Creator") + 9; + while (*p && (isspace(*p) || *p == ':')) p++; + if (!strcmp(p, "OpenOffice.org")) { + p += 14; + while (*p && isspace(*p)) p++; + if (sscanf(p, "1.1.%d", &ooo110) == 1) { + _log("Document created with OpenOffice.org 1.1.x\n"); + ooo110 = 1; + } + } else if (!strcmp(p, "StarOffice 8")) { + p += 12; + _log("Document created with StarOffice 8\n"); + ooo110 = 1; + } + } + else if (nestinglevel == 0 && startswith(line->data, "%%BeginProlog")) { + /* Note: Below is another place where a "Prolog" section + start will be considered. There we assume start of the + "Prolog" if the job is DSC-Conformimg, but an arbitrary + comment starting with "%%Begin", but not a comment + explicitly treated here, is found. This is done because + many "dvips" (TeX/LaTeX) files miss the "%%BeginProlog" + comment. + Beginning of Prolog */ + _log("\n-----------\nFound: %%%%BeginProlog\n"); + inprolog = 1; + if (inheader) + postscriptsection = PS_SECTION_PROLOG; + nondsclines = 0; + /* Insert options for "Prolog" */ + if (!prologfound) { + append_prolog_section(line, optset, 0); + prologfound = 1; + } + } + else if (nestinglevel == 0 && startswith(line->data, "%%EndProlog")) { + /* End of Prolog */ + _log("Found: %%%%EndProlog\n"); + inprolog = 0; + insertoptions = linect +1; + } + else if (nestinglevel == 0 && startswith(line->data, "%%BeginSetup")) { + /* Beginning of Setup */ + _log("\n-----------\nFound: %%%%BeginSetup\n"); + insetup = 1; + nondsclines = 0; + /* We need to distinguish with the $inheader variable + here whether we are in the header or on a page, as + OpenOffice.org inserts a "%%BeginSetup...%%EndSetup" + section after the first "%%Page:..." line and assumes + this section to be valid for all pages. */ + if (inheader) { + postscriptsection = PS_SECTION_SETUP; + /* If there was no "Prolog" but there are + options for the "Prolog", push a "Prolog" + with these options onto the psfifo here */ + if (!prologfound) { + dstrclear(tmp); + append_prolog_section(tmp, optset, 1); + dstrprepend(line, tmp->data); + prologfound = 1; + } + /* Insert options for "DocumentSetup" or "AnySetup" */ + if (spooler != SPOOLER_CUPS && !setupfound) { + /* For non-CUPS spoolers or no spooler at all, + we leave everythnig as it is */ + append_setup_section(line, optset, 0); + setupfound = 1; + } + } + else { + /* Found option settings must be stuffed into both + the header and the currrent page now. They will + be written into both the "header" and the + "currentpage" optionsets and the PostScript code + lines of this section will not only go into the + output stream, but also added to the end of the + @psheader, so that they get repeated (to preserve + the embedded PostScript option settings) on a + restart of the renderer due to command line + option changes */ + optionsalsointoheader = 1; + _log("\"%%%%BeginSetup\" in page header\n"); + } + } + else if (nestinglevel == 0 && startswith(line->data, "%%EndSetup")) { + /* End of Setup */ + _log("Found: %%%%EndSetup\n"); + insetup = 0; + if (inheader) { + if (spooler == SPOOLER_CUPS) { + /* In case of CUPS, we must insert the + accounting stuff just before the + %%EndSetup comment in order to leave any + EndPage procedures that have been + defined by either the pstops filter or + the PostScript job itself fully + functional. */ + if (!setupfound) { + dstrclear(tmp); + append_setup_section(tmp, optset, 0); + dstrprepend(line, tmp->data); + setupfound = 1; + } + } + insertoptions = linect +1; + } + else { + /* The "%%BeginSetup...%%EndSetup" which + OpenOffice.org has inserted after the first + "%%Page:..." line ends here, so the following + options go only onto the current page again */ + optionsalsointoheader = 0; + } + } + else if (nestinglevel == 0 && startswith(line->data, "%%Page:")) { + if (!lastpassthru && !inheader) { + /* In the last line we were not in passthru mode, + so the last page is not printed. Prepare to do + it now. */ + printprevpage = 1; + passthru = 1; + _log("New page found but previous not printed, print it now.\n"); + } + else { + /* the previous page is printed, so we can prepare + the current one */ + _log("\n-----------\nNew page: %s", line->data); + printprevpage = 0; + currentpage++; + /* We consider the beginning of the page already as + page setup section, as some apps do not use + "%%PageSetup" tags. */ + postscriptsection = PS_SECTION_PAGESETUP; + + /* TODO can this be removed? + Save PostScript state before beginning the page + $line .= "/foomatic-saved-state save def\n"; */ + + /* Here begins a new page */ + if (inheader) { + build_commandline(optset, NULL, 0); + /* Here we add some stuff which still + belongs into the header */ + dstrclear(tmp); + + /* If there was no "Setup" but there are + options for the "Setup", push a "Setup" + with these options onto the @psfifo here */ + if (!setupfound) { + append_setup_section(tmp, optset, 1); + setupfound = 1; + } + /* If there was no "Prolog" but there are + options for the "Prolog", push a "Prolog" + with these options onto the @psfifo here */ + if (!prologfound) { + append_prolog_section(tmp, optset, 1); + prologfound = 1; + } + /* Now we push this into the header */ + dstrcat(psheader, tmp->data); + + /* The first page starts, so header ends */ + inheader = 0; + nondsclines = 0; + /* Option setting should go into the page + specific option set now */ + optset = optionset("currentpage"); + } + else { + /* Restore PostScript state after completing the + previous page: + + foomatic-saved-state restore + %%Page: ... + /foomatic-saved-state save def + + Print this directly, so that if we need to + restart the renderer for this page due to + a command line change this is done under the + old instance of the renderer + rint $rendererhandle + "foomatic-saved-state restore\n"; */ + + /* Save the option settings of the previous page */ + optionset_copy_values(optionset("currentpage"), optionset("previouspage")); + optionset_delete_values(optionset("currentpage")); + } + /* Initialize the option set */ + optionset_copy_values(optionset("header"), optionset("currentpage")); + + /* Set the command line options which apply only + to given pages */ + set_options_for_page(optionset("currentpage"), currentpage); + pagesetupfound = 0; + if (spooler == SPOOLER_CUPS) { + /* Remove the "notfirst" flag from all options + forseen for the "PageSetup" section, because + when these are numerical options for CUPS. + they have to be set to the correct value + for every page */ + for (o = optionlist; o; o = o->next) { + if (option_get_section(o ) == SECTION_PAGESETUP) + o->notfirst = 0; + } + } + /* Now the page header comes, so buffer the data, + because we must perhaps shut down and restart + the renderer */ + passthru = 0; + ignorepageheader = 0; + optionsalsointoheader = 0; + } + } + else if (nestinglevel == 0 && !ignorepageheader && + startswith(line->data, "%%BeginPageSetup")) { + /* Start of the page header, up to %%EndPageSetup + nothing of the page will be drawn, page-specific + option settngs (as letter-head paper for page 1) + go here*/ + _log("\nFound: %%%%BeginPageSetup\n"); + passthru = 0; + inpageheader = 1; + postscriptsection = PS_SECTION_PAGESETUP; + optionsalsointoheader = (ooo110 && currentpage == 1) ? 1 : 0; + /* Insert PostScript option settings + (options for section "PageSetup") */ + if (isdscjob) { + append_page_setup_section(line, optset, 0); + pagesetupfound = 1; + } + } + else if (nestinglevel == 0 && !ignorepageheader && + startswith(line->data, "%%BeginPageSetup")) { + /* End of the page header, the page is ready to be printed */ + _log("Found: %%%%EndPageSetup\n"); + _log("End of page header\n"); + /* We cannot for sure say that the page header ends here + OpenOffice.org puts (due to a bug) a "%%BeginSetup... + %%EndSetup" section after the first "%%Page:...". It + is possible that CUPS inserts a "%%BeginPageSetup... + %%EndPageSetup" before this section, which means that + the options in the "%%BeginSetup...%%EndSetup" + section are after the "%%EndPageSetup", so we + continue for searching options up to the buffer size + limit $maxlinesforpageoptions. */ + passthru = 0; + inpageheader = 0; + optionsalsointoheader = 0; + } + else if (nestinglevel == 0 && !optionreplaced && (!passthru || !isdscjob) && + ((linetype = line_type(line->data)) && + (linetype == LT_BEGIN_FEATURE || linetype == LT_FOOMATIC_RIP_OPTION_SETTING))) { + + /* parse */ + if (linetype == LT_BEGIN_FEATURE) { + dstrcpy(tmp, line->data); + p = strtok(tmp->data, " \t"); /* %%BeginFeature: */ + p = strtok(NULL, " \t="); /* Option */ + if (*p == '*') p++; + strlcpy(optionname, p, 128); + p = strtok(NULL, " \t\r\n"); /* value */ + fromcomposite = 0; + strlcpy(value, p, 128); + } + else { /* LT_FOOMATIC_RIP_OPTION_SETTING */ + dstrcpy(tmp, line->data); + p = strstr(tmp->data, "FoomaticRIPOptionSetting:"); + p = strtok(p, " \t"); /* FoomaticRIPOptionSetting */ + p = strtok(NULL, " \t="); /* Option */ + strlcpy(optionname, p, 128); + p = strtok(NULL, " \t\r\n"); /* value */ + if (*p == '@') { /* fromcomposite */ + p++; + fromcomposite = 1; + } + else + fromcomposite = 0; + strlcpy(value, p, 128); + } + + /* Mark that we are in a "Feature" section */ + if (linetype == LT_BEGIN_FEATURE) { + infeature = 1; + dstrclear(linesafterlastbeginfeature); + } + + /* OK, we have an option. If it's not a + Postscript-style option (ie, it's command-line or + JCL) then we should note that fact, since the + attribute-to-filter option passing in CUPS is kind of + funky, especially wrt boolean options. */ + _log("Found: %s", line->data); + if ((o = find_option(optionname))) { + _log(" Option: %s=%s%s\n", optionname, fromcomposite ? "From" : "", value); + if (spooler == SPOOLER_CUPS && + linetype == LT_BEGIN_FEATURE && + !option_get_value(o, optionset("notfirst")) && + strcmp(option_get_value(o, optset), value) != 0 && + (inheader || option_get_section(o) == SECTION_PAGESETUP)) { + + /* We have the first occurence of an option + setting and the spooler is CUPS, so this + setting is inserted by "pstops" or + "imagetops". The value from the command + line was not inserted by "pstops" or + "imagetops" so it seems to be not under + the choices in the PPD. Possible + reasons: + + - "pstops" and "imagetops" ignore settings + of numerical or string options which are + not one of the choices in the PPD file, + and inserts the default value instead. + + - On the command line an option was applied + only to selected pages: + "-o <page ranges>:<option>=<values> + This is not supported by CUPS, so not + taken care of by "pstops". + + We must fix this here by replacing the + setting inserted by "pstops" or "imagetops" + with the exact setting given on the command + line. */ + + /* $arg->{$optionset} is already + range-checked, so do not check again here + Insert DSC comment */ + pdest = (inheader && isdscjob) ? psheader : psfifo; + if (option_is_ps_command(o)) { + /* PostScript option, insert the code */ + + option_get_command(tmp, o, optset, -1); + if (!(val = option_get_value(o, optset))) + val = ""; + + /* Boolean and enumerated choice options can only be set in the + * PageSetup section */ + if ((inheader && option_is_custom_value(o, val)) || !inheader) + { + if (o->type == TYPE_BOOL) + dstrcatf(pdest, "%%%%BeginFeature: *%s %s\n", o->name, + val && !strcmp(val, "1") ? "True" : "False"); + else + dstrcatf(pdest, "%%%%BeginFeature: *%s %s\n", o->name, val); + + dstrcatf(pdest, "%s\n", tmp->data); + + /* We have replaced this option on the FIFO */ + optionreplaced = 1; + } + } + else { /* Command line or JCL option */ + val = option_get_value(o, optset); + + if (!inheader || option_is_custom_value(o, val)) { + dstrcatf(pdest, "%%%% FoomaticRIPOptionSetting: %s=%s\n", + o->name, val ? val : ""); + optionreplaced = 1; + } + } + + if (optionreplaced) { + val = option_get_value(o, optset); + _log(" --> Correcting numerical/string option to %s=%s (Command line argument)\n", + o->name, val ? val : ""); + } + } + + /* Mark that we have already found this option */ + o->notfirst = 1; + if (!optionreplaced) { + if (o->style != 'G') { + /* Controlled by '<Composite>' setting of + a member option of a composite option */ + if (fromcomposite) { + dstrcpyf(tmp, "From%s", value); + strlcpy(value, tmp->data, 128); + } + + /* Non PostScript option + Check whether it is valid */ + if (option_set_value(o, optset, value)) { + _log("Setting option\n"); + strlcpy(value, option_get_value(o, optset), 128); + if (optionsalsointoheader) + option_set_value(o, optionset("header"), value); + if (o->type == TYPE_ENUM && + (!strcmp(o->name, "PageSize") || !strcmp(o->name, "PageRegion")) && + startswith(value, "Custom") && + linetype == LT_FOOMATIC_RIP_OPTION_SETTING) { + /* Custom Page size */ + width = height = 0.0; + p = linesafterlastbeginfeature->data; + while (*p && isspace(*p)) p++; + width = strtod(p, &p); + while (*p && isspace(*p)) p++; + height = strtod(p, &p); + if (width && height) { + dstrcpyf(tmp, "%s.%fx%f", value, width, height); + strlcpy(value, tmp->data, 128); + option_set_value(o, optset, value); + if (optionsalsointoheader) + option_set_value(o, optionset("header"), value); + } + } + /* For a composite option insert the + code from the member options with + current setting "From<composite>" + The code from the member options + is chosen according to the setting + of the composite option. */ + if (option_is_composite(o) && linetype == LT_FOOMATIC_RIP_OPTION_SETTING) { + build_commandline(optset, NULL, 0); /* TODO can this be removed? */ + + /* TODO merge section and ps_section */ + if (postscriptsection == PS_SECTION_JCLSETUP) + option_get_command(tmp, o, optset, SECTION_JCLSETUP); + else if (postscriptsection == PS_SECTION_PROLOG) + option_get_command(tmp, o, optset, SECTION_PROLOG); + else if (postscriptsection == PS_SECTION_SETUP) + option_get_command(tmp, o, optset, SECTION_DOCUMENTSETUP); + else if (postscriptsection == PS_SECTION_PAGESETUP) + option_get_command(tmp, o, optset, SECTION_PAGESETUP); + dstrcat(line, tmp->data); + } + } + else + _log(" --> Invalid option setting found in job\n"); + } + else if (fromcomposite) { + /* PostScript option, but we have to look up + the PostScript code to be inserted from + the setting of a composite option, as + this option is set to "Controlled by + '<Composite>'". */ + /* Set the option */ + dstrcpyf(tmp, "From%s", value); + strlcpy(value, tmp->data, 128); + if (option_set_value(o, optset, value)) { + _log(" --> Looking up setting in composite option %s\n", value); + if (optionsalsointoheader) + option_set_value(o, optionset("header"), value); + /* update composite options */ + build_commandline(optset, NULL, 0); + /* Substitute PostScript comment by the real code */ + /* TODO what exactly is the next line doing? */ + /* dstrcpy(line, o->compositesubst->data); */ + } + else + _log(" --> Invalid option setting found in job\n"); + } + else + /* it is a PostScript style option with + the code readily inserted, no option + for the renderer command line/JCL to set, + no lookup of a composite option needed, + so nothing to do here... */ + _log(" --> Option will be set by PostScript interpreter\n"); + } + } + else + /* This option is unknown to us, WTF? */ + _log("Unknown option %s=%s found in the job\n", optionname, value); + } + else if (nestinglevel == 0 && startswith(line->data, "%%EndFeature")) { + /* End of feature */ + infeature = 0; + /* If the option setting was replaced, it ends here, + too, and the next option is not necessarily also replaced */ + optionreplaced = 0; + dstrclear(linesafterlastbeginfeature); + } + else if (nestinglevel == 0 && isdscjob && !prologfound && + startswith(line->data, "%%Begin")) { + /* In some PostScript files (especially when generated + by "dvips" of TeX/LaTeX) the "%%BeginProlog" is + missing, so assume that it was before the current + line (the first line starting with "%%Begin". */ + _log("Job claims to be DSC-conforming, but \"%%%%BeginProlog\" " + "was missing before first line with another" + "\"%%%%BeginProlog\" comment (is this a TeX/LaTeX/dvips-generated" + " PostScript file?). Assuming start of \"Prolog\" here.\n"); + /* Beginning of Prolog */ + inprolog = 1; + nondsclines = 0; + /* Insert options for "Prolog" before the current line */ + dstrcpyf(tmp, "%%%%BeginProlog\n"); + append_prolog_section(tmp, optset, 0); + dstrprepend(line, tmp->data); + prologfound = 1; + } + else if (nestinglevel == 0 && ( + startswith(line->data, "%RBINumCopies:") || + startswith(line->data, "%%RBINumCopies:"))) { + p = strchr(line->data, ':') +1; + get_current_job()->rbinumcopies = atoi(p); + _log("Found %RBINumCopies: %d\n", get_current_job()->rbinumcopies); + } + else if (startswith(skip_whitespace(line->data), "%") || + startswith(skip_whitespace(line->data), "$")) + /* This is an unknown PostScript comment or a blank + line, no active code */ + ignoreline = 1; + } + else { + /* This line is active PostScript code */ + if (infeature) + /* Collect coe in a "%%BeginFeature: ... %%EndFeature" + section, to get the values for a custom option + setting */ + dstrcat(linesafterlastbeginfeature, line->data); + + if (inheader) { + if (!inprolog && !insetup) { + /* Outside the "Prolog" and "Setup" section + a correct DSC-conforming document has no + active PostScript code, so consider the + file as non-DSC-conforming when there are + too many of such lines. */ + nondsclines++; + if (nondsclines > MAX_NON_DSC_LINES_IN_HEADER) { + /* Consider document as not DSC-conforming */ + _log("This job seems not to be DSC-conforming, " + "DSC-comment for next section not found, " + "stopping to parse the rest, passing it " + "directly to the renderer.\n"); + /* Stop scanning for further option settings */ + maxlines = 1; + isdscjob = 0; + /* Insert defaults and command line settings in + the beginning of the job or after the last valid + section */ + dstrclear(tmp); + if (prologfound) + append_prolog_section(tmp, optset, 1); + if (setupfound) + append_setup_section(tmp, optset, 1); + if (pagesetupfound) + append_page_setup_section(tmp, optset, 1); + dstrinsert(psheader, line_start(psheader->data, insertoptions), tmp->data); + + prologfound = 1; + setupfound = 1; + pagesetupfound = 1; + } + } + } + else if (!inpageheader) { + /* PostScript code inside a page, but not between + "%%BeginPageSetup" and "%%EndPageSetup", so + we are perhaps already drawing onto a page now */ + if (startswith(onelinebefore->data, "%%Page")) + _log("No page header or page header not DSC-conforming\n"); + /* Stop buffering lines to search for options + placed not DSC-conforming */ + if (line_count(psfifo->data) >= MAX_LINES_FOR_PAGE_OPTIONS) { + _log("Stopping search for page header options\n"); + passthru = 1; + /* If there comes a page header now, ignore it */ + ignorepageheader = 1; + optionsalsointoheader = 0; + } + /* Insert PostScript option settings (options for the + * section "PageSetup" */ + if (isdscjob && !pagesetupfound) { + append_page_setup_section(psfifo, optset, 1); + pagesetupfound = 1; + } + } + } + } + + /* Debug Info */ + if (lastpassthru != passthru) { + if (passthru) + _log("Found: %s --> Output goes directly to the renderer now.\n\n", line->data); + else + _log("Found: %s --> Output goes to the FIFO buffer now.\n\n", line->data); + } + + /* We are in an option which was replaced, do not output the current line */ + if (optionreplaced) + dstrclear(line); + + /* If we are in a "%%BeginSetup...%%EndSetup" section after + the first "%%Page:..." and the current line belongs to + an option setting, we have to copy the line also to the + @psheader. */ + if (optionsalsointoheader && (infeature || startswith(line->data, "%%EndFeature"))) + dstrcat(psheader, line->data); + + /* Store or send the current line */ + if (inheader && isdscjob) { + /* We are still in the PostScript header, collect all lines + in @psheader */ + dstrcat(psheader, line->data); + } + else { + if (passthru && isdscjob) { + if (!lastpassthru) { + /* + * We enter passthru mode with this line, so the + * command line can have changed, check it and close + * the renderer if needed + */ + if (rendererpid && !optionset_equal(optionset("currentpage"), optionset("previouspage"), 0)) { + _log("Command line/JCL options changed, restarting renderer\n"); + retval = close_renderer_handle(rendererhandle, rendererpid); + if (retval != EXIT_PRINTED) + rip_die(retval, "Error closing renderer\n"); + rendererpid = 0; + } + } + + /* Flush psfifo and send line directly to the renderer */ + if (!rendererpid) { + /* No renderer running, start it */ + dstrcpy(tmp, psheader->data); + dstrcat(tmp, psfifo->data); + get_renderer_handle(tmp, &rendererhandle, &rendererpid); + /* psfifo is sent out, flush it */ + dstrclear(psfifo); + } + + if (!isempty(psfifo->data)) { + /* Send psfifo to renderer */ + fwrite(psfifo->data, psfifo->len, 1, rendererhandle); + /* flush psfifo */ + dstrclear(psfifo); + } + + /* Send line to renderer */ + if (!printprevpage) { + fwrite(line->data, line->len, 1, rendererhandle); + + while (stream_next_line(line, stream) > 0) { + if (startswith(line->data, "%%")) { + _log("Found: %s", line->data); + _log(" --> Continue DSC parsing now.\n\n"); + saved = 1; + break; + } + else { + fwrite(line->data, line->len, 1, rendererhandle); + linect++; + } + } + } + } + else { + /* Push the line onto the stack to split up later */ + dstrcat(psfifo, line->data); + } + } + + if (!printprevpage) + linect++; + } + else { + /* EOF! */ + more_stuff = 0; + + /* No PostScript header in the whole file? Then it's not + PostScript, convert it. + We open the file converter here when the file has less + lines than the amount which we search for the PostScript + header ($maxlinestopsstart). */ + if (linect <= nonpslines) { + /* This is not a PostScript job, we must convert it */ + _log("\nJob does not start with \"%%!\", is it PostScript?\n" + "Starting file converter\n"); + + /* Reset all variables but conserve the data which + we already have read */ + jobhasjcl = 0; + linect = 0; + maxlines = 1000; + dstrclear(onelinebefore); + dstrclear(twolinesbefore); + dstrclear(line); + + dstrcpy(tmp, psheader->data); + dstrcat(tmp, psfifo->data); + dstrclear(psfifo); + dstrclear(psheader); + + /* Start the file conversion filter */ + if (!fileconverter_pid) + get_fileconverter_handle(tmp->data, &fileconverter_handle, &fileconverter_pid); + else + rip_die(EXIT_JOBERR, "File conversion filter probably crashed\n"); + + /* Read the further data from the file converter and + not from STDIN */ + if (close(fileno(stdin)) != 0) + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "Couldn't close STDIN\n"); + + if (dup2(fileno(fileconverter_handle), fileno(stdin)) == -1) + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "Couldn't dup fileconverterhandle\n"); + + /* Now we have new (converted) stuff in STDIN, so + continue in the loop */ + more_stuff = 1; + } + } + + lastpassthru = passthru; + + if (!ignoreline && !printprevpage) { + dstrcpy(twolinesbefore, onelinebefore->data); + dstrcpy(onelinebefore, line->data); + } + + } while ((maxlines == 0 || linect < maxlines) && more_stuff != 0); + + /* Some buffer still containing data? Send it out to the renderer */ + if (more_stuff || inheader || !isempty(psfifo->data)) { + /* Flush psfifo and send the remaining data to the renderer, this + only happens with non-DSC-conforming jobs or non-Foomatic PPDs */ + if (more_stuff) + _log("Stopped parsing the PostScript data, " + "sending rest directly to the renderer.\n"); + else + _log("Flushing FIFO.\n"); + + if (inheader) { + build_commandline(optset, NULL, 0); + /* No page initialized yet? Copy the "header" option set into the + "currentpage" option set, so that the renderer will find the + options settings. */ + optionset_copy_values(optionset("header"), optionset("currentpage")); + optset = optionset("currentpage"); + + /* If not done yet, insert defaults and command line settings + in the beginning of the job or after the last valid section */ + dstrclear(tmp); + if (prologfound) + append_prolog_section(tmp, optset, 1); + if (setupfound) + append_setup_section(tmp, optset, 1); + if (pagesetupfound) + append_page_setup_section(tmp, optset, 1); + dstrinsert(psheader, line_start(psheader->data, insertoptions), tmp->data); + + prologfound = 1; + setupfound = 1; + pagesetupfound = 1; + } + + if (rendererpid > 0 && !optionset_equal(optionset("currentpage"), optionset("previouspage"), 0)) { + _log("Command line/JCL options changed, restarting renderer\n"); + retval = close_renderer_handle(rendererhandle, rendererpid); + if (retval != EXIT_PRINTED) + rip_die(retval, "Error closing renderer\n"); + rendererpid = 0; + } + + if (!rendererpid) { + dstrcpy(tmp, psheader->data); + dstrcat(tmp, psfifo->data); + get_renderer_handle(tmp, &rendererhandle, &rendererpid); + /* We have sent psfifo now */ + dstrclear(psfifo); + } + + if (psfifo->len) { + /* Send psfifo to the renderer */ + fwrite(psfifo->data, psfifo->len, 1, rendererhandle); + dstrclear(psfifo); + } + + /* Print the rest of the input data */ + if (more_stuff) { + while (stream_next_line(tmp, stream)) + fwrite(tmp->data, tmp->len, 1, rendererhandle); + } + } + + /* At every "%%Page:..." comment we have saved the PostScript state + and we have increased the page number. So if the page number is + non-zero we had at least one "%%Page:..." comment and so we have + to give a restore the PostScript state. + if ($currentpage > 0) { + print $rendererhandle "foomatic-saved-state restore\n"; + } */ + + /* Close the renderer */ + if (rendererpid) { + retval = close_renderer_handle(rendererhandle, rendererpid); + if (retval != EXIT_PRINTED) + rip_die(retval, "Error closing renderer\n"); + rendererpid = 0; + } + + /* Close the file converter (if it was used) */ + if (fileconverter_pid) { + retval = close_fileconverter_handle(fileconverter_handle, fileconverter_pid); + if (retval != EXIT_PRINTED) + rip_die(retval, "Error closing file converter\n"); + fileconverter_pid = 0; + } + + free_dstr(line); + free_dstr(onelinebefore); + free_dstr(twolinesbefore); + free_dstr(psheader); + free_dstr(psfifo); + free_dstr(tmp); +} + +/* + * Run the renderer command line (and if defined also the postpipe) and returns + * a file handle for stuffing in the PostScript data. + */ +void get_renderer_handle(const dstr_t *prepend, FILE **fd, pid_t *pid) +{ + pid_t kid3; + FILE *kid3in; + dstr_t *cmdline = create_dstr(); + + /* Build the command line and get the JCL commands */ + build_commandline(optionset("currentpage"), cmdline, 0); + massage_gs_commandline(cmdline); + + _log("\nStarting renderer with command: \"%s\"\n", cmdline->data); + kid3 = start_process("kid3", exec_kid3, (void *)cmdline->data, &kid3in, NULL); + if (kid3 < 0) + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "Cannot fork for kid3\n"); + + /* Feed the PostScript header and the FIFO contents */ + if (prepend) + fwrite(prepend->data, prepend->len, 1, kid3in); + + /* We are the parent, return glob to the file handle */ + *fd = kid3in; + *pid = kid3; + + free_dstr(cmdline); +} + +/* Close the renderer process and wait until all kid processes finish */ +int close_renderer_handle(FILE *rendererhandle, pid_t rendererpid) +{ + int status; + + _log("\nClosing renderer\n"); + fclose(rendererhandle); + + status = wait_for_process(rendererpid); + if (WIFEXITED(status)) + return WEXITSTATUS(status); + else + return EXIT_PRNERR_NORETRY_BAD_SETTINGS; +} + diff --git a/postscript.h b/postscript.h new file mode 100644 index 0000000..b851dd3 --- /dev/null +++ b/postscript.h @@ -0,0 +1,8 @@ + +#ifndef postscript_h +#define postscript_h + +int print_ps(FILE *s, const char *alreadyread, size_t len, const char *filename); + +#endif + diff --git a/process.c b/process.c new file mode 100644 index 0000000..9808cda --- /dev/null +++ b/process.c @@ -0,0 +1,200 @@ + +#include "foomaticrip.h" +#include "process.h" +#include <unistd.h> +#include "util.h" +#include <sys/wait.h> +#include <errno.h> +#include <stdlib.h> + +int kidgeneration = 0; + +struct process { + char name[64]; + pid_t pid; + int isgroup; +}; + +#define MAX_CHILDS 4 +struct process procs[MAX_CHILDS] = { + { "", -1, 0 }, + { "", -1, 0 }, + { "", -1, 0 }, + { "", -1, 0 } +}; + +void add_process(const char *name, int pid, int isgroup) +{ + int i; + for (i = 0; i < MAX_CHILDS; i++) { + if (procs[i].pid == -1) { + strlcpy(procs[i].name, name, 64); + procs[i].pid = pid; + procs[i].isgroup = isgroup; + return; + } + } + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "Didn't think there would be that many child processes... Exiting.\n"); +} + +int find_process(int pid) +{ + int i; + for (i = 0; i < MAX_CHILDS; i++) + if (procs[i].pid == pid) + return i; + return -1; +} + +void clear_proc_list() +{ + int i; + for (i = 0; i < MAX_CHILDS; i++) + procs[i].pid = -1; +} + +void kill_all_processes() +{ + int i; + + for (i = 0; i < MAX_CHILDS; i++) { + if (procs[i].pid == -1) + continue; + _log("Killing %s\n", procs[i].name); + kill(procs[i].isgroup ? -procs[i].pid : procs[i].pid, 15); + sleep(1 << (3 - kidgeneration)); + kill(procs[i].isgroup ? -procs[i].pid : procs[i].pid, 9); + } + clear_proc_list(); +} + +static int _start_process(const char *name, + int (*proc_func)(FILE *, FILE *, void *), + void *user_arg, FILE **pipe_in, FILE **pipe_out, + int createprocessgroup) +{ + pid_t pid; + int pfdin[2], pfdout[2]; + int ret; + FILE *in, *out; + + if (pipe_in) + pipe(pfdin); + if (pipe_out) + pipe(pfdout); + + _log("Starting process \"%s\" (generation %d)\n", name, kidgeneration +1); + + pid = fork(); + if (pid < 0) { + _log("Could not fork for %s\n", name); + if (pipe_in) { + close(pfdin[0]); + close(pfdin[1]); + } + if (pipe_out) { + close(pfdout[0]); + close(pfdout[1]); + } + return -1; + } + + if (pid == 0) { /* Child */ + if (pipe_in) { + close(pfdin[1]); + in = fdopen(pfdin[0], "r"); + } + else + in = NULL; + + if (pipe_out) { + close(pfdout[0]); + out = fdopen(pfdout[1], "w"); + } + else + out = NULL; + + if (createprocessgroup) + setpgid(0, 0); + + kidgeneration++; + + /* The subprocess list is only valid for the parent. Clear it. */ + clear_proc_list(); + + ret = proc_func(in, out, user_arg); + exit(ret); + } + + /* Parent */ + if (pipe_in) { + close(pfdin[0]); + *pipe_in = fdopen(pfdin[1], "w"); + if (!*pipe_in) + _log("fdopen: %s\n", strerror(errno)); + } + if (pipe_out) { + close(pfdout[1]); + *pipe_out = fdopen(pfdout[0], "r"); + if (!*pipe_out) + _log("fdopen: %s\n", strerror(errno)); + } + + /* Add the child process to the list of open processes (to be able to kill + * them in case of a signal. */ + add_process(name, pid, createprocessgroup); + + return pid; +} + +int exec_command(FILE *in, FILE *out, void *cmd) +{ + if (in && dup2(fileno(in), fileno(stdin)) < 0) + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "%s: Could not dup stdin\n", (const char *)cmd); + if (out && dup2(fileno(out), fileno(stdout)) < 0) + rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "%s: Could not dup stdout\n", (const char *)cmd); + + execl(get_modern_shell(), get_modern_shell(), "-c", (const char *)cmd, (char *)NULL); + + _log("Error: Executing \"%s -c %s\" failed (%s).\n", get_modern_shell(), (const char *)cmd, strerror(errno)); + return EXIT_PRNERR_NORETRY_BAD_SETTINGS; +} + +int start_system_process(const char *name, const char *command, FILE **fdin, FILE **fdout) +{ + return _start_process(name, exec_command, (void*)command, fdin, fdout, 1); +} + +int start_process(const char *name, int (*proc_func)(FILE *, FILE *, void *), void *user_arg, FILE **fdin, FILE **fdout) +{ + return _start_process(name, proc_func, user_arg, fdin, fdout, 0); +} + +int wait_for_process(int pid) +{ + int i; + int status; + + i = find_process(pid); + if (i < 0) { + _log("No such process \"%d\"", pid); + return -1; + } + + waitpid(procs[i].pid, &status, 0); + if (WIFEXITED(status)) + _log("%s exited with status %d\n", procs[i].name, WEXITSTATUS(status)); + else if (WIFSIGNALED(status)) + _log("%s received signal %d\n", procs[i].name, WTERMSIG(status)); + + /* remove from process list */ + procs[i].pid = -1; + return status; +} + +int run_system_process(const char *name, const char *command) +{ + int pid = start_system_process(name, command, NULL, NULL); + return wait_for_process(pid); +} + diff --git a/process.h b/process.h new file mode 100644 index 0000000..bc201b5 --- /dev/null +++ b/process.h @@ -0,0 +1,26 @@ + +#ifndef process_h +#define process_h + +#include <stdio.h> +#include <sys/types.h> +#include <sys/wait.h> + +pid_t start_process(const char *name, int (*proc_func)(), void *user_arg, FILE **fdin, FILE **fdout); +pid_t start_system_process(const char *name, const char *command, FILE **fdin, FILE **fdout); + +/* returns command's return status (see waitpid(2)) */ +int run_system_process(const char *name, const char *command); + +pid_t create_pipe_process(const char *name, + FILE *src, + FILE *dest, + const char *alreadyread, + size_t alreadyread_len); + +int wait_for_process(int pid); + +void kill_all_processes(); + +#endif + diff --git a/renderer.c b/renderer.c new file mode 100644 index 0000000..57f7281 --- /dev/null +++ b/renderer.c @@ -0,0 +1,450 @@ + +#define _GNU_SOURCE + +#include <signal.h> +#include <ctype.h> +#include <stdlib.h> +#include <unistd.h> + +#include "foomaticrip.h" +#include "util.h" +#include "process.h" +#include "options.h" + +/* + * Check whether we have a Ghostscript version with redirection of the standard + * output of the PostScript programs via '-sstdout=%stderr' + */ +int test_gs_output_redirection() +{ + char gstestcommand[PATH_MAX]; + char output[10] = ""; + + snprintf(gstestcommand, PATH_MAX, "%s -dQUIET -dPARANOIDSAFER -dNOPAUSE " + "-dBATCH -dNOMEDIAATTRS -sDEVICE=pswrite -sstdout=%%stderr " + "-sOutputFile=/dev/null -c '(hello\n) print flush' 2>&1", gspath); + + FILE *pd = popen(gstestcommand, "r"); + if (!pd) { + _log("Failed to execute ghostscript!\n"); + return 0; + } + + fread(output, 1, 10, pd); + pclose(pd); + + if (startswith(output, "hello")) + return 1; + + return 0; +} + +/* + * Massage arguments to make ghostscript execute properly as a filter, with + * output on stdout and errors on stderr etc. (This function does what + * foomatic-gswrapper used to do) + */ +void massage_gs_commandline(dstr_t *cmd) +{ + int gswithoutputredirection = test_gs_output_redirection(); + size_t start, end; + dstr_t *gscmd, *cmdcopy; + + extract_command(&start, &end, cmd->data, "gs"); + if (start == end) /* cmd doesn't call ghostscript */ + return; + + gscmd = create_dstr(); + dstrncpy(gscmd, &cmd->data[start], end - start); + + /* If Ghostscript does not support redirecting the standard output + of the PostScript program to standard error with '-sstdout=%stderr', sen + the job output data to fd 3; errors will be on 2(stderr) and job ps + program interpreter output on 1(stdout). */ + if (gswithoutputredirection) + dstrreplace(gscmd, "-sOutputFile=- ", "-sOutputFile=%stdout ", 0); + else + dstrreplace(gscmd, "-sOutputFile=- ", "-sOutputFile=/dev/fd/3 ", 0); + + /* Use always buffered input. This works around a Ghostscript + bug which prevents printing encrypted PDF files with Adobe Reader 8.1.1 + and Ghostscript built as shared library (Ghostscript bug #689577, Ubuntu + bug #172264) */ + if (dstrendswith(gscmd, " -")) + dstrcat(gscmd, "_"); + else + dstrreplace(gscmd, " - ", " -_ ", 0); + dstrreplace(gscmd, " /dev/fd/0", " -_ ", 0); + + /* Turn *off* -q (quiet!); now that stderr is useful! :) */ + dstrreplace(gscmd, " -q ", " ", 0); + + /* Escape any quotes, and then quote everything just to be sure... + Escaping a single quote inside single quotes is a bit complex as the + shell takes everything literal there. So we have to assemble it by + concatinating different quoted strings. Finally we get e.g.: 'x'"'"'y' + or ''"'"'xy' or 'xy'"'"'' or ... */ + /* dstrreplace(cmd, "'", "'\"'\"'"); TODO tbd */ + + dstrremove(gscmd, start, 2); /* Remove 'gs' */ + if (gswithoutputredirection) + { + dstrprepend(gscmd, " -sstdout=%stderr "); + dstrprepend(gscmd, gspath); + } + else + { + dstrprepend(gscmd, gspath); + dstrcat(gscmd, " 3>&1 1>&2"); + } + + /* put gscmd back into cmd, between 'start' and 'end' */ + cmdcopy = create_dstr(); + dstrcpy(cmdcopy, cmd->data); + + dstrncpy(cmd, cmdcopy->data, start); + dstrcat(cmd, gscmd->data); + dstrcat(cmd, &cmdcopy->data[end]); + + free_dstr(gscmd); + free_dstr(cmdcopy); + + /* If the renderer command line contains the "echo" command, replace the + * "echo" by the user-chosen $myecho (important for non-GNU systems where + * GNU echo is in a special path */ + dstrreplace(cmd, "echo", echopath, 0); /* TODO search for \wecho\w */ +} + +char * read_line(FILE *stream, size_t *readbytes) +{ + char *line; + size_t alloc = 64, len = 0; + int c; + + line = malloc(alloc); + + while ((c = fgetc(stream)) != EOF) { + if (len >= alloc -1) { + alloc *= 2; + line = realloc(line, alloc); + } + line[len] = (char)c; + len++; + if (c == '\n') + break; + } + + line[len] = '\0'; + *readbytes = len; + return line; +} + +write_binary_data(FILE *stream, const char *data, size_t bytes) +{ + int i; + for (i=0; i < bytes; i++) + { + fputc(data[i], stream); + } +} + +/* + * Read all lines containing 'jclstr' from 'stream' (actually, one more) and + * return them in a zero terminated array. + */ +static char ** read_jcl_lines(FILE *stream, const char *jclstr, + size_t *readbinarybytes) +{ + char *line; + char **result; + size_t alloc = 8, cnt = 0; + + result = malloc(alloc * sizeof(char *)); + + /* read from the renderer output until the first non-JCL line appears */ + while ((line = read_line(stream, readbinarybytes))) + { + if (cnt >= alloc -1) + { + alloc *= 2; + result = realloc(result, alloc * sizeof(char *)); + } + result[cnt] = line; + if (!strstr(line, jclstr)) + break; + /* Remove newline from the end of a line containing JCL */ + result[cnt][*readbinarybytes - 1] = '\0'; + cnt++; + } + + cnt++; + result[cnt] = NULL; + return result; +} + +static int jcl_keywords_equal(const char *jclline1, const char *jclline2, + const char *jclstr) +{ + char *j1, *j2, *p1, *p2; + + j1 = strstr(jclline1, jclstr); + if (!j1) return 0; + if (!(p1 = strchr(skip_whitespace(j1), '='))) + p1 = j1[strlen(j1)]; + p1--; + while (p1 > j1 && isspace(*p1)) + p1--; + + j2 = strstr(jclline2, jclstr); + if (!j2) return 0; + if (!(p2 = strchr(skip_whitespace(j2), '='))) + p2 = j2[strlen(j2)]; + p2--; + while (p2 > j2 && isspace(*p2)) + p2--; + + if (p1 - j1 != p2 - j2) return 0; + return strncmp(j1, j2, p1 - j1 + 1) == 0; +} + +/* + * Finds the keyword of line in opts + */ +static const char * jcl_options_find_keyword(char **opts, const char *line, + const char *jclstr) +{ + if (!opts) + return NULL; + + while (*opts) + { + if (jcl_keywords_equal(*opts, line, jclstr)) + return *opts; + opts++; + } + return NULL; +} + +static void argv_write(FILE *stream, char **argv, const char *sep) +{ + if (!argv) + return; + + while (*argv) + fprintf(stream, "%s%s", *argv++, sep); +} + +/* + * Merges 'original_opts' and 'pref_opts' and writes them to 'stream'. Header / + * footer is taken from 'original_opts'. If both have the same options, the one + * from 'pref_opts' is preferred + * Returns true, if original_opts was not empty + */ +static int write_merged_jcl_options(FILE *stream, + char **original_opts, + char **opts, + size_t readbinarybytes, + const char *jclstr) +{ + char *p = strstr(original_opts[0], jclstr); + char header[128]; + char **optsp; + + /* No JCL options in original_opts, just prepend opts */ + if (argv_count(original_opts) == 1) + { + fprintf(stream, "%s", jclbegin); + argv_write(stream, opts, "\n"); + write_binary_data(stream, original_opts[0], readbinarybytes); + return 0; + } + + if (argv_count(original_opts) == 2) + { + /* If we have only one line of JCL it is probably something like the + * "@PJL ENTER LANGUAGE=..." line which has to be in the end, but it + * also contains the "<esc>%-12345X" which has to be in the beginning + * of the job */ + if (p) + fwrite(original_opts[0], 1, p - original_opts[0], stream); + else + fprintf(stream, "%s\n", original_opts[0]); + + argv_write(stream, opts, "\n"); + + if (p) + fprintf(stream, "%s\n", p); + + write_binary_data(stream, original_opts[1], readbinarybytes); + return 1; + } + + /* Write jcl header */ + strncpy(header, original_opts[0], p - original_opts[0]); + header[p - original_opts[0]] = '\0'; + fprintf(stream, "%s", header); + + for (optsp = opts; *optsp; optsp++) + if (!jcl_options_find_keyword(original_opts, *optsp, jclstr)) + fprintf(stream, "%s\n", *optsp); + + for (optsp = original_opts; *(optsp + 1); optsp++) { + if (optsp != original_opts) p = *optsp; + if (jcl_options_find_keyword(opts, p, jclstr)) + fprintf(stream, "%s\n", jcl_options_find_keyword(opts, p, jclstr)); + else + fprintf(stream, "%s\n", p); + } + write_binary_data(stream, *optsp, readbinarybytes); + + return 1; +} + +void log_jcl() +{ + char **opt; + + _log("JCL: %s", jclbegin); + if (jclprepend) + for (opt = jclprepend; *opt; opt++) + _log("%s\n", *opt); + + _log("<job data> %s\n\n", jclappend->data); +} + +int exec_kid4(FILE *in, FILE *out, void *user_arg) +{ + FILE *fileh = open_postpipe(); + int driverjcl; + size_t readbinarybytes; + + log_jcl(); + + /* wrap the JCL around the job data, if there are any options specified... + * Should the driver already have inserted JCL commands we merge our JCL + * header with the one from the driver */ + if (argv_count(jclprepend) > 0) + { + if (!isspace(jclprepend[0][0])) + { + char *jclstr, **jclheader; + size_t pos; + + pos = strcspn(jclprepend[0], " \t\n\r"); + jclstr = malloc(pos +1); + strncpy(jclstr, jclprepend[0], pos); + jclstr[pos] = '\0'; + + jclheader = read_jcl_lines(in, jclstr, &readbinarybytes); + + driverjcl = write_merged_jcl_options(fileh, + jclheader, + jclprepend, + readbinarybytes, + jclstr); + + free(jclstr); + argv_free(jclheader); + } + else + /* No merging of JCL header possible, simply prepend it */ + argv_write(fileh, jclprepend, "\n"); + } + + /* The job data */ + copy_file(fileh, in, NULL, 0); + + /* A JCL trailer */ + if (argv_count(jclprepend) > 0 && !driverjcl) + fwrite(jclappend->data, jclappend->len, 1, fileh); + + fclose(in); + if (fclose(fileh) != 0) + { + _log("error closing postpipe\n"); + return EXIT_PRNERR_NORETRY_BAD_SETTINGS; + } + + return EXIT_PRINTED; +} + +int exec_kid3(FILE *in, FILE *out, void *user_arg) +{ + dstr_t *commandline; + int kid4; + FILE *kid4in; + int status; + + commandline = create_dstr(); + dstrcpy(commandline, (const char *)user_arg); + + kid4 = start_process("kid4", exec_kid4, NULL, &kid4in, NULL); + if (kid4 < 0) + return EXIT_PRNERR_NORETRY_BAD_SETTINGS; + + if (in && dup2(fileno(in), fileno(stdin)) < 0) { + _log("kid3: Could not dup stdin\n"); + fclose(kid4in); + return EXIT_PRNERR_NORETRY_BAD_SETTINGS; + } + if (dup2(fileno(kid4in), fileno(stdout)) < 0) { + _log("kid3: Could not dup stdout to kid4\n"); + fclose(kid4in); + return EXIT_PRNERR_NORETRY_BAD_SETTINGS; + } + if (debug) + { + if (!redirect_log_to_stderr()) { + fclose(kid4in); + return EXIT_PRNERR_NORETRY_BAD_SETTINGS; + } + + /* Save the data supposed to be fed into the renderer also into a file*/ + dstrprepend(commandline, "tee -a " LOG_FILE ".ps | ( "); + dstrcat(commandline, ")"); + } + + /* Actually run the thing */ + status = run_system_process("renderer", commandline->data); + + if (in) + fclose(in); + fclose(kid4in); + fclose(stdin); + fclose(stdout); + free_dstr(commandline); + + if (WIFEXITED(status)) { + switch (WEXITSTATUS(status)) { + case 0: /* Success! */ + /* wait for postpipe/output child */ + wait_for_process(kid4); + _log("kid3 finished\n"); + return EXIT_PRINTED; + case 1: + _log("Possible error on renderer command line or PostScript error. Check options."); + return EXIT_JOBERR; + case 139: + _log("The renderer may have dumped core."); + return EXIT_JOBERR; + case 141: + _log("A filter used in addition to the renderer itself may have failed."); + return EXIT_PRNERR; + case 243: + case 255: /* PostScript error? */ + return EXIT_JOBERR; + } + } + else if (WIFSIGNALED(status)) { + switch (WTERMSIG(status)) { + case SIGUSR1: + return EXIT_PRNERR; + case SIGUSR2: + return EXIT_PRNERR_NORETRY; + case SIGTTIN: + return EXIT_ENGAGED; + } + } + return EXIT_PRNERR; +} + diff --git a/renderer.h b/renderer.h new file mode 100644 index 0000000..963208d --- /dev/null +++ b/renderer.h @@ -0,0 +1,9 @@ + +#ifndef renderer_h +#define renderer_h + +void massage_gs_commandline(dstr_t *cmd); +int exec_kid3(FILE *in, FILE *out, void *user_arg); + +#endif + diff --git a/spooler.c b/spooler.c new file mode 100644 index 0000000..8255d51 --- /dev/null +++ b/spooler.c @@ -0,0 +1,465 @@ + +#include "spooler.h" +#include "foomaticrip.h" +#include "util.h" +#include "options.h" +#include <stdlib.h> +#include <unistd.h> + +const char *spooler_name(int spooler) +{ + switch (spooler) { + case SPOOLER_CUPS: return "cups"; + case SPOOLER_SOLARIS: return "solaris"; + case SPOOLER_LPD: return "lpd"; + case SPOOLER_LPRNG: return "lprng"; + case SPOOLER_GNULPR: return "gnu lpr"; + case SPOOLER_PPR: return "ppr"; + case SPOOLER_PPR_INT: return "ppr interface"; + case SPOOLER_CPS: return "cps"; + case SPOOLER_PDQ: return "pdq"; + case SPOOLER_DIRECT: return "direct"; + }; + return "<unknown>"; +} + +/* 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). +*/ +const char *accounting_prolog_code = + "[{\n" + "%% Code for writing CUPS accounting tags on standard error\n" + "\n" + "/cupsPSLevel2 % Determine whether we can do PostScript level 2 or newer\n" + " systemdict/languagelevel 2 copy\n" + " known{get exec}{pop pop 1}ifelse 2 ge\n" + "def\n" + "\n" + "cupsPSLevel2\n" + "{ % in case of level 2 or higher\n" + " currentglobal true setglobal % define a dictioary foomaticDict\n" + " globaldict begin % in global VM and establish a\n" + " /foomaticDict % pages count key there\n" + " <<\n" + " /PhysPages 0\n" + " >>def\n" + " end\n" + " setglobal\n" + "}if\n" + "\n" + "/cupsGetNumCopies { % Read the number of Copies requested for the current\n" + " % page\n" + " cupsPSLevel2\n" + " {\n" + " % PS Level 2+: Get number of copies from Page Device dictionary\n" + " currentpagedevice /NumCopies get\n" + " }\n" + " {\n" + " % PS Level 1: Number of copies not in Page Device dictionary\n" + " null\n" + " }\n" + " ifelse\n" + " % Check whether the number is defined, if it is \"null\" use #copies \n" + " % instead\n" + " dup null eq {\n" + " pop #copies\n" + " }\n" + " if\n" + " % Check whether the number is defined now, if it is still \"null\" use 1\n" + " % instead\n" + " dup null eq {\n" + " pop 1\n" + " } if\n" + "} bind def\n" + "\n" + "/cupsWrite { % write a string onto standard error\n" + " (%stderr) (w) file\n" + " exch writestring\n" + "} bind def\n" + "\n" + "/cupsFlush % flush standard error to make it sort of unbuffered\n" + "{\n" + " (%stderr)(w)file flushfile\n" + "}bind def\n" + "\n" + "cupsPSLevel2\n" + "{ % In language level 2, we try to do something reasonable\n" + " <<\n" + " /EndPage\n" + " [ % start the array that becomes the procedure\n" + " currentpagedevice/EndPage 2 copy known\n" + " {get} % get the existing EndPage procedure\n" + " {pop pop {exch pop 2 ne}bind}ifelse % there is none, define the default\n" + " /exec load % make sure it will be executed, whatever it is\n" + " /dup load % duplicate the result value\n" + " { % true: a sheet gets printed, do accounting\n" + " currentglobal true setglobal % switch to global VM ...\n" + " foomaticDict begin % ... and access our special dictionary\n" + " PhysPages 1 add % count the sheets printed (including this one)\n" + " dup /PhysPages exch def % and save the value\n" + " end % leave our dict\n" + " exch setglobal % return to previous VM\n" + " (PAGE: )cupsWrite % assemble and print the accounting string ...\n" + " 16 string cvs cupsWrite % ... the sheet count ...\n" + " ( )cupsWrite % ... a space ...\n" + " cupsGetNumCopies % ... the number of copies ...\n" + " 16 string cvs cupsWrite % ...\n" + " (\\n)cupsWrite % ... a newline\n" + " cupsFlush\n" + " }/if load\n" + " % false: current page gets discarded; do nothing \n" + " ]cvx bind % make the array executable and apply bind\n" + " >>setpagedevice\n" + "}\n" + "{\n" + " % In language level 1, we do no accounting currently, as there is no global VM\n" + " % the contents of which are undesturbed by save and restore. \n" + " % If we may be sure that showpage never gets called inside a page related save / restore pair\n" + " % we might implement an hack with showpage similar to the one above.\n" + "}ifelse\n" + "\n" + "} stopped cleartomark\n"; + + +void init_ppr(list_t *arglist, jobparams_t *job) +{ + size_t arg_count = list_item_count(arglist); + char ppr_printer [256]; + char ppr_address [128]; + char ppr_options [1024]; + char ppr_jobbreak [128]; + char ppr_feedback [128]; + char ppr_codes [128]; + char ppr_jobname [128]; + char ppr_routing [128]; + char ppr_for [128] = ""; + char ppr_filetype [128] = ""; + char ppr_filetoprint [128] = ""; + FILE *ph; + char tmp[256]; + char *p; + + + /* TODO read interface.sh and signal.sh for exit and signal codes respectively */ + + /* Check whether we run as a PPR interface (if not, we run as a PPR RIP) + 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. */ + if ((arg_count == 11 || arg_count == 10 || arg_count == 8) && + atoi(arglist_get(arglist, 3)) < 100 && atoi(arglist_get(arglist, 5)) < 100) + { + /* get all command line parameters */ + strncpy_omit(ppr_printer, arglist_get(arglist, 0), 256, omit_shellescapes); + strlcpy(ppr_address, arglist_get(arglist, 1), 128); + strncpy_omit(ppr_options, arglist_get(arglist, 2), 1024, omit_shellescapes); + strlcpy(ppr_jobbreak, arglist_get(arglist, 3), 128); + strlcpy(ppr_feedback, arglist_get(arglist, 4), 128); + strlcpy(ppr_codes, arglist_get(arglist, 5), 128); + strncpy_omit(ppr_jobname, arglist_get(arglist, 6), 128, omit_shellescapes); + strncpy_omit(ppr_routing, arglist_get(arglist, 7), 128, omit_shellescapes); + if (arg_count >= 8) { + strlcpy(ppr_for, arglist_get(arglist, 8), 128); + strlcpy(ppr_filetype, arglist_get(arglist, 9), 128); + if (arg_count >= 10) + strncpy_omit(ppr_filetoprint, arglist_get(arglist, 10), 128, omit_shellescapes); + } + + /* Common job parameters */ + strcpy(job->printer, ppr_printer); + strcpy(job->title, ppr_jobname); + if (isempty(job->title) && !isempty(ppr_filetoprint)) + strcpy(job->title, ppr_filetoprint); + dstrcatf(job->optstr, " %s %s", ppr_options, ppr_routing); + + /* Get the path of the PPD file from the queue configuration */ + snprintf(tmp, 255, "LANG=en_US; ppad show %s | grep PPDFile", ppr_printer); + tmp[255] = '\0'; + ph = popen(tmp, "r"); + if (ph) { + fgets(tmp, 255, ph); + tmp[255] = '\0'; + pclose(ph); + + strncpy_omit(job->ppdfile, tmp, 255, omit_shellescapes); + if (job->ppdfile[0] == '/') { + strcpy(tmp, job->ppdfile); + strcpy(job->ppdfile, "../../share/ppr/PPDFiles/"); + strncat(job->ppdfile, tmp, 200); + } + if ((p = strrchr(job->ppdfile, '\n'))) + *p = '\0'; + } + else { + job->ppdfile[0] = '\0'; + } + + /* We have PPR and run as an interface */ + spooler = SPOOLER_PPR_INT; + } +} + +void init_cups(list_t *arglist, dstr_t *filelist, jobparams_t *job) +{ + char path [1024] = ""; + char cups_jobid [128]; + char cups_user [128]; + char cups_jobtitle [128]; + char cups_copies [128]; + char cups_options [512]; + char cups_filename [256]; + char texttopspath[PATH_MAX]; + + if (getenv("CUPS_FONTPATH")) + strcpy(path, getenv("CUPS_FONTPATH")); + else if (getenv("CUPS_DATADIR")) { + strcpy(path, getenv("CUPS_DATADIR")); + strcat(path, "/fonts"); + } + if (getenv("GS_LIB")) { + strcat(path, ":"); + strcat(path, getenv("GS_LIB")); + } + setenv("GS_LIB", path, 1); + + /* Get all command line parameters */ + strncpy_omit(cups_jobid, arglist_get(arglist, 0), 128, omit_shellescapes); + strncpy_omit(cups_user, arglist_get(arglist, 1), 128, omit_shellescapes); + strncpy_omit(cups_jobtitle, arglist_get(arglist, 2), 128, omit_shellescapes); + strncpy_omit(cups_copies, arglist_get(arglist, 3), 128, omit_shellescapes); + strncpy_omit(cups_options, arglist_get(arglist, 4), 512, omit_shellescapes); + + /* Common job parameters */ + strcpy(job->id, cups_jobid); + strcpy(job->title, cups_jobtitle); + strcpy(job->user, cups_user); + strcpy(job->copies, cups_copies); + dstrcatf(job->optstr, " %s", cups_options); + + /* Check for and handle inputfile vs stdin */ + if (list_item_count(arglist) > 4) { + strncpy_omit(cups_filename, arglist_get(arglist, 5), 256, omit_shellescapes); + if (cups_filename[0] != '-') { + /* We get input from a file */ + dstrcatf(filelist, "%s ", cups_filename); + _log("Getting input from file %s\n", cups_filename); + } + } + + accounting_prolog = ps_accounting ? accounting_prolog_code : NULL; + + /* 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. */ + file_basename(job->printer, job->ppdfile, 256); + + /* Use cups' texttops if no fileconverter is set + * Apply "pstops" when having used a file converter under CUPS, so CUPS + * can stuff the default settings into the PostScript output of the file + * converter (so all CUPS settings get also applied when one prints the + * documentation pages (all other files we get already converted to + * PostScript by CUPS). */ + if (isempty(fileconverter)) { + if (find_in_path("texttops", cupsfilterpath, texttopspath)) { + snprintf(fileconverter, PATH_MAX, "%s/texttops '%s' '%s' '%s' '%s' " + "page-top=36 page-bottom=36 page-left=36 page-right=36 " + "nolandscape cpi=12 lpi=7 columns=1 wrap %s'" + "| %s/pstops '%s' '%s' '%s' '%s' '%s'", + texttopspath, cups_jobid, cups_user, cups_jobtitle, cups_copies, cups_options, + texttopspath, cups_jobid, cups_user, cups_jobtitle, cups_copies, cups_options); + } + } +} + +void init_solaris(list_t *arglist, dstr_t *filelist, jobparams_t *job) +{ + char *str; + int len; + listitem_t *i; + + /* Get all command line parameters */ + strncpy_omit(job->title, arglist_get(arglist, 2), 128, omit_shellescapes); + + len = strlen(arglist_get(arglist, 4)); + str = malloc(len +1); + strncpy_omit(str, arglist_get(arglist, 4), len, omit_shellescapes); + dstrcatf(job->optstr, " %s", str); + free(str); + + for (i = arglist->first; i; i = i->next) + dstrcatf(filelist, "%s ", (char*)i->data); +} + +/* used by init_direct_cps_pdq to find a ppd file */ +int find_ppdfile(const char *user_default_path, jobparams_t *job) +{ + /* Search also common spooler-specific locations, this way a printer + configured under a certain spooler can also be used without spooler */ + + strcpy(job->ppdfile, job->printer); + if (access(job->ppdfile, R_OK) == 0) + return 1; + + /* CPS can have the PPD in the spool directory */ + if (spooler == SPOOLER_CPS) { + snprintf(job->ppdfile, 256, "/var/spool/lpd/%s/%s.ppd", job->printer, job->printer); + if (access(job->ppdfile, R_OK) == 0) + return 1; + snprintf(job->ppdfile, 256, "/var/local/spool/lpd/%s/%s.ppd", job->printer, job->printer); + if (access(job->ppdfile, R_OK) == 0) + return 1; + snprintf(job->ppdfile, 256, "/var/local/lpd/%s/%s.ppd", job->printer, job->printer); + if (access(job->ppdfile, R_OK) == 0) + return 1; + snprintf(job->ppdfile, 256, "/var/spool/lpd/%s.ppd", job->printer); + if (access(job->ppdfile, R_OK) == 0) + return 1; + snprintf(job->ppdfile, 256, "/var/local/spool/lpd/%s.ppd", job->printer); + if (access(job->ppdfile, R_OK) == 0) + return 1; + snprintf(job->ppdfile, 256, "/var/local/lpd/%s.ppd", job->printer); + if (access(job->ppdfile, R_OK) == 0) + return 1; + } + snprintf(job->ppdfile, 256, "%s.ppd", job->printer); /* current dir */ + if (access(job->ppdfile, R_OK) == 0) + return 1; + snprintf(job->ppdfile, 256, "%s/%s.ppd", user_default_path, job->printer); /* user dir */ + if (access(job->ppdfile, R_OK) == 0) + return 1; + snprintf(job->ppdfile, 256, "%s/direct/%s.ppd", CONFIG_PATH, job->printer); /* system dir */ + if (access(job->ppdfile, R_OK) == 0) + return 1; + snprintf(job->ppdfile, 256, "%s/%s.ppd", CONFIG_PATH, job->printer); /* system dir */ + if (access(job->ppdfile, R_OK) == 0) + return 1; + snprintf(job->ppdfile, 256, "/etc/cups/ppd/%s.ppd", job->printer); /* CUPS config dir */ + if (access(job->ppdfile, R_OK) == 0) + return 1; + snprintf(job->ppdfile, 256, "/usr/local/etc/cups/ppd/%s.ppd", job->printer); /* CUPS config dir */ + if (access(job->ppdfile, R_OK) == 0) + return 1; + snprintf(job->ppdfile, 256, "/usr/share/ppr/PPDFiles/%s.ppd", job->printer); /* PPR PPDs */ + if (access(job->ppdfile, R_OK) == 0) + return 1; + snprintf(job->ppdfile, 256, "/usr/local/share/ppr/PPDFiles/%s.ppd", job->printer); /* PPR PPDs */ + if (access(job->ppdfile, R_OK) == 0) + return 1; + + /* nothing found */ + job->ppdfile[0] = '\0'; + return 0; +} + +/* search 'configfile' for 'key', copy value into dest, return success */ +int configfile_find_option(const char *configfile, const char *key, char *dest, size_t destsize) +{ + FILE *fh; + char line [1024]; + char *p; + + dest[0] = '\0'; + + if (!(fh = fopen(configfile, "r"))) + return 0; + + while (fgets(line, 1024, fh)) { + if (!prefixcmp(line, "default")) { + p = strchr(line, ':'); + if (p) { + strncpy_omit(dest, p, destsize, omit_whitespace); + if (dest[0]) + break; + } + } + } + fclose(fh); + return dest[0] != '\0'; +} + +/* tries to find a default printer name in various config files and copies the + * result into the global var 'printer'. Returns success */ +int find_default_printer(const char *user_default_path, jobparams_t *job) +{ + char configfile [1024]; + char *key = "default"; + + if (configfile_find_option("./.directconfig", key, job->printer, 256)) + return 1; + if (configfile_find_option("./directconfig", key, job->printer, 256)) + return 1; + if (configfile_find_option("./.config", key, job->printer, 256)) + return 1; + strlcpy(configfile, user_default_path, 1024); + strlcat(configfile, "/direct/.config", 1024); + if (configfile_find_option(configfile, key, job->printer, 256)) + return 1; + strlcpy(configfile, user_default_path, 1024); + strlcat(configfile, "/direct.conf", 1024); + if (configfile_find_option(configfile, key, job->printer, 256)) + return 1; + if (configfile_find_option(CONFIG_PATH "/direct/.config", key, job->printer, 256)) + return 1; + if (configfile_find_option(CONFIG_PATH "/direct.conf", key, job->printer, 256)) + return 1; + + return 0; +} + +void init_direct_cps_pdq(list_t *arglist, dstr_t *filelist, jobparams_t *job) +{ + char tmp [1024]; + listitem_t *i; + char user_default_path [PATH_MAX]; + + strlcpy(user_default_path, getenv("HOME"), 256); + strlcat(user_default_path, "/.foomatic/", 256); + + /* Which files do we want to print? */ + for (i = arglist->first; i; i = i->next) { + strncpy_omit(tmp, (char*)i->data, 1024, omit_shellescapes); + dstrcatf(filelist, "%s ", tmp); + } + + if (job->ppdfile[0] == '\0') { + if (job->printer[0] == '\0') { + /* No printer definition file selected, check whether we have a + default printer defined */ + find_default_printer(user_default_path, job); + } + + /* Neither in a config file nor on the command line a printer was selected */ + if (!job->printer[0]) { + _log("No printer definition (option \"-P <name>\") specified!\n"); + exit(EXIT_PRNERR_NORETRY_BAD_SETTINGS); + } + + /* Search for the PPD file */ + if (!find_ppdfile(user_default_path, job)) { + _log("There is no readable PPD file for the printer %s, is it configured?\n"); + exit(EXIT_PRNERR_NORETRY_BAD_SETTINGS); + } + } +} + diff --git a/spooler.h b/spooler.h new file mode 100644 index 0000000..8b915c8 --- /dev/null +++ b/spooler.h @@ -0,0 +1,15 @@ + +#ifndef SPOOLER_H +#define SPOOLER_H + +#include "foomaticrip.h" +#include "util.h" + +const char *spooler_name(int spooler); +void init_ppr(list_t *arglist, jobparams_t *job); +void init_cups(list_t *arglist, dstr_t *filelist, jobparams_t *job); +void init_solaris(list_t *arglist, dstr_t *filelist, jobparams_t *job); +void init_direct_cps_pdq(list_t *arglist, dstr_t *filelist, jobparams_t *job); + +#endif + diff --git a/test/foomatic-test-input-ps.ps b/test/foomatic-test-input-ps.ps new file mode 100644 index 0000000..a03c8fa --- /dev/null +++ b/test/foomatic-test-input-ps.ps @@ -0,0 +1,54 @@ +%!PS-Adobe-3.0 +%%BoundingBox: 0 0 612 792 +%%Pages: 4 +%%LanguageLevel: 1 +%%DocumentData: Clean7Bit +%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman +%%Creator: Till Kamppeter, The Linux Foundation +%%CreationDate: D:20071017174200+0100 +%%Title: PostScript test file for testing/debugging foomatic-rip +%%EndComments +%%BeginProlog +/PAGE { +/pagenumber exch def +% Black frame magic from CUPS test page +initclip newpath clippath pathbbox +/pageTop exch def +/pageRight exch def +/pageBottom exch def +/pageLeft exch def +4 setlinewidth +0 setgray closepath stroke +% "Test Page N" in upper left corner +pageLeft 4 add pageTop 30 sub moveto +/Helvetica-Bold findfont +24 scalefont setfont +( Test Page ) show +pagenumber 1 string cvs show +} bind def +%%EndProlog +% The content of the page is kept simple, so that one sees insertions done +% by foomatic-rip or any pre filter easily. Simply make a black frame around +% the imageable area and write "Test page N" in Helvetica Bold 24pt in the upper +% left corner of each page +%%Page: 1 1 +gsave +1 PAGE +grestore +showpage +%%Page: 2 2 +gsave +2 PAGE +grestore +showpage +%%Page: 3 3 +gsave +3 PAGE +grestore +showpage +%%Page: 4 4 +gsave +4 PAGE +grestore +showpage +%%EOF diff --git a/test/foomatic-test-renderer b/test/foomatic-test-renderer new file mode 100755 index 0000000..de3401e --- /dev/null +++ b/test/foomatic-test-renderer @@ -0,0 +1,53 @@ +#!/bin/sh + +# This is foomatic-test-renderer, a dummy renderer executable for testing +# and debugging foomatic-rip. + +# To use it, create a test PPD file with lines like +# +# *cupsFilter: "application/vnd.cups-postscript 0 foomatic-rip" +# *FoomaticRIPCommandLine: "foomatic-test-renderer%A%B%C%Z" +# +# and use foomatic-rip with this PPD file. If you do this via a print queue +# point the output of the queue into a file +# +# This program does nothing more than outputting the unchanged input data +# and after that the command line with which it was called in a PostScript +# comment (so one can still display the output as PostScript if the input +# was PostScript). +# +# With the option "-p OPTION=VALUE" supplied one or more times, a PJL +# header with appropriate options and also PJL to close the job will be added +# Supply "-p" in the end of the command line to generate a PJL header +# without option settings + +commandline=$* + +output="`cat` +% $0 $commandline" + +pjl=0 +while [ -n "$*" ]; do + arg=$1 + shift + if [ "$arg" = "-p" ]; then + if [ "$pjl" = "0" ]; then + pjl=1 + printf "\033%%-12345X" + #printf "@PJL\r\n" + fi + if [ -n "$1" ]; then + printf "@PJL SET $1\r\n" + shift + fi + fi +done +if [ "$pjl" = "1" ]; then + printf "@PJL ENTER LANGUAGE=POSTSCRIPT\r\n" +fi + +echo "$output" + +if [ "$pjl" = "1" ]; then + printf "\033%%-12345X@PJL EOJ\r\n" +fi diff --git a/test/foomatic-test.ppd b/test/foomatic-test.ppd new file mode 100644 index 0000000..31aef02 --- /dev/null +++ b/test/foomatic-test.ppd @@ -0,0 +1,419 @@ +*PPD-Adobe: "4.3" +*% +*% For information on using this, and to obtain the required backend +*% script, consult http://www.openprinting.org/ +*% +*% This file is published under the GNU General Public License +*% +*% PPD-O-MATIC (3.0.0 or newer) generated this PPD file. It is for use with +*% all programs and environments which use PPD files for dealing with +*% printer capability information. The printer must be configured with the +*% "foomatic-rip" backend filter script of Foomatic 3.0.0 or newer. This +*% file and "foomatic-rip" work together to support PPD-controlled printer +*% driver option access with arbitrary free software printer drivers and +*% printing spoolers. +*% +*% To save this file on your disk, wait until the download has completed +*% (the animation of the browser logo must stop) and then use the +*% "Save as..." command in the "File" menu of your browser or in the +*% pop-up manu when you click on this document with the right mouse button. +*% DO NOT cut and paste this file into an editor with your mouse. This can +*% introduce additional line breaks which lead to unexpected results. +*% +*% You may save this file as 'foomatic-test.ppd' +*% +*% +*FormatVersion: "4.3" +*FileVersion: "1.1" +*LanguageVersion: English +*LanguageEncoding: ISOLatin1 +*PCFileName: "TEST.PPD" +*Manufacturer: "Test" +*Product: "(Testprinter)" +*cupsVersion: 1.0 +*cupsManualCopies: True +*cupsModelNumber: 2 +*cupsFilter: "application/vnd.cups-postscript 0 foomatic-rip" +*%pprRIP: foomatic-rip other +*ModelName: "Test Testprinter" +*ShortNickName: "Test Testprinter testdriver" +*NickName: "Test Testprinter Foomatic/testdriver" +*PSVersion: "(3010.000) 550" +*PSVersion: "(3010.000) 651" +*PSVersion: "(3010.000) 652" +*PSVersion: "(3010.000) 653" +*PSVersion: "(3010.000) 704" +*PSVersion: "(3010.000) 705" +*PSVersion: "(3010.000) 800" +*LanguageLevel: "3" +*ColorDevice: False +*DefaultColorSpace: Gray +*FileSystem: False +*Throughput: "1" +*LandscapeOrientation: Plus90 +*TTRasterizer: Type42 +*1284DeviceID: "MFG:Test;MDL:Testprinter;DES:Test Testprinter;CMD:POSTSCRIPT;CLS:PRINTER;DRV:Dtestdriver,R0,M0;" + +*driverName testdriver/testdriver: "" +*driverUrl: "http://www.openprinting.org/" +*driverObsolete: False + + + + +*HWMargins: 18 36 18 36 +*VariablePaperSize: True +*MaxMediaWidth: 100000 +*MaxMediaHeight: 100000 +*NonUIOrderDependency: 100 AnySetup *CustomPageSize +*CustomPageSize True: "pop pop pop +<</PageSize [ 5 -2 roll ] /ImagingBBox null>>setpagedevice" +*End +*ParamCustomPageSize Width: 1 points 36 100000 +*ParamCustomPageSize Height: 2 points 36 100000 +*ParamCustomPageSize Orientation: 3 int 0 0 +*ParamCustomPageSize WidthOffset: 4 points 0 0 +*ParamCustomPageSize HeightOffset: 5 points 0 0 + +*FoomaticIDs: Test-Testprinter testdriver +*FoomaticRIPCommandLine: "%Afoomatic-test-renderer %B %C %D %E %F %Z" + +*OpenGroup: General/General + +*OpenUI *PageSize/Page Size: PickOne +*OrderDependency: 100 AnySetup *PageSize +*DefaultPageSize: Letter +*PageSize Letter/Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice" +*PageSize A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice" +*PageSize Legal/Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice" +*CloseUI: *PageSize + +*OpenUI *PageRegion: PickOne +*OrderDependency: 100 AnySetup *PageRegion +*DefaultPageRegion: Letter +*PageRegion Letter/Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice" +*PageRegion A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice" +*PageRegion Legal/Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice" +*CloseUI: *PageRegion + +*DefaultImageableArea: Letter +*ImageableArea Letter/Letter: "18 36 594 756" +*ImageableArea A4/A4: "18 36 577 806" +*ImageableArea Legal/Legal: "18 36 594 972" + +*DefaultPaperDimension: Letter +*PaperDimension Letter/Letter: "612 792" +*PaperDimension A4/A4: "595 842" +*PaperDimension Legal/Legal: "612 1008" + +*CloseGroup: General + +*OpenGroup: FilterHandling/Filter Handling + +*OpenUI *FilterPath/Filter Path: PickOne +*FoomaticRIPOption FilterPath: string CmdLine A +*FoomaticRIPOptionMaxLength FilterPath:255 +*FoomaticRIPOptionAllowedChars FilterPath: "./A-Za-z0-9_-" +*OrderDependency: 150 AnySetup *FilterPath +*FoomaticRIPOptionPrototype FilterPath: "%s" +*DefaultFilterPath: Current +*FilterPath None/None: "" +*FilterPath Current/Current directory: "%% FoomaticRIPOptionSetting: FilterPath=Current" +*FoomaticRIPOptionSetting FilterPath=Current: "./" +*CloseUI: *FilterPath + +*CloseGroup: FilterHandling + +*OpenGroup: PSTest/Standard PostScript test options + +*OpenUI *Option1/Option 1: PickOne +*OrderDependency: 200 DocumentSetup *Option1 +*DefaultOption1: Choice2 +*Option1 Choice1/Choice 1: "<</HWResolution [1200 1200]>> setpagedevice % Option1: Choice1" +*Option1 Choice2/Choice 2: "<</HWResolution [1200 600]>> setpagedevice % Option1: Choice2" +*Option1 Choice3/Choice 3: " + % Option1: Choice3 + <</HWResolution [ 600 600]>> setpagedevice" +*End +*CloseUI: *Option1 + +*OpenUI *Option2/Option 2: PickOne +*OrderDependency: 210 DocumentSetup *Option2 +*DefaultOption2: Choice3 +*Option2 Choice1/Choice 1: "<</Test [Example1]>> setpagedevice % Option2: Choice1" +*Option2 Choice2/Choice 2: "<</Test [Example2]>> setpagedevice % Option2: Choice2" +*Option2 Choice3/Choice 3: " + % Option2: Choice3 + <</Test [Example3]>> setpagedevice" +*End +*CloseUI: *Option2 + +*OpenUI *Option3/Option 3: PickOne +*OrderDependency: 250 AnySetup *Option3 +*DefaultOption3: Choice1 +*Option3 Choice1/Choice 1: "% Option3: Choice1" +*Option3 Choice2/Choice 2: "% Option3: Choice2" +*Option3 Choice3/Choice 3: "% Option3: Choice3" +*CloseUI: *Option3 + +*OpenUI *Option4/Option 4: PickOne +*OrderDependency: 260 PageSetup *Option4 +*DefaultOption4: Choice1 +*Option4 Choice1/Choice 1: "% Option4: Choice1" +*Option4 Choice2/Choice 2: "% Option4: Choice2" +*Option4 Choice3/Choice 3: "% Option4: Choice3" +*CloseUI: *Option4 + +*OpenUI *Option5/Option 5: PickOne +*OrderDependency: 270 Prolog *Option5 +*DefaultOption5: Choice1 +*Option5 Choice1/Choice 1: "% Option5: Choice1" +*Option5 Choice2/Choice 2: "% Option5: Choice2" +*Option5 Choice3/Choice 3: "% Option5: Choice3" +*CloseUI: *Option5 + +*OpenUI *Option6/Option 6: PickOne +*OrderDependency: 280 JCLSetup *Option6 +*DefaultOption6: Choice1 +*Option6 Choice1/Choice 1: "@PJL SET TEST6=CHOICE1<0A>" +*Option6 Choice2/Choice 2: "@PJL SET TEST6=CHOICE2<0A>" +*Option6 Choice3/Choice 3: "@PJL SET TEST6=CHOICE3<0A>" +*CloseUI: *Option6 + +*OpenUI *Option7/Option 7: Boolean +*OrderDependency: 205 AnySetup *Option7 +*DefaultOption7: True +*Option7 True: "% Option7: True" +*Option7 False: "% Option7: False" +*CloseUI: *Option7 + +*OpenUI *Option8/Option 8: Boolean +*OrderDependency: 206 AnySetup *Option8 +*DefaultOption8: False +*Option8 True: "% Option8: True" +*Option8 False: "% Option8: False" +*CloseUI: *Option8 + +*CloseGroup: PSTest + +*OpenGroup: FoomaticTest/Test options with Foomatic keywords + +*OpenUI *FoomaticOption1/Foomatic Option 1: PickOne +*FoomaticRIPOption FoomaticOption1: enum CmdLine B +*OrderDependency: 300 AnySetup *FoomaticOption1 +*DefaultFoomaticOption1: Choice1 +*FoomaticOption1 Choice1/Choice 1: "%% FoomaticRIPOptionSetting: FoomaticOption1=Choice1" +*FoomaticRIPOptionSetting FoomaticOption1=Choice1: " --option1=choice1" +*FoomaticOption1 Choice2/Choice 2: "%% FoomaticRIPOptionSetting: FoomaticOption1=Choice2" +*FoomaticRIPOptionSetting FoomaticOption1=Choice2: " --option1=choice2" +*FoomaticOption1 Choice3/Choice 3: "%% FoomaticRIPOptionSetting: FoomaticOption1=Choice3" +*FoomaticRIPOptionSetting FoomaticOption1=Choice3: " --option1=choice3" +*CloseUI: *FoomaticOption1 + +*OpenUI *FoomaticOption2/Foomatic Option 2: PickOne +*FoomaticRIPOption FoomaticOption2: enum JCL B +*OrderDependency: 300 AnySetup *FoomaticOption2 +*DefaultFoomaticOption2: Choice1 +*FoomaticOption2 Choice1/Choice 1: "%% FoomaticRIPOptionSetting: FoomaticOption2=Choice1" +*FoomaticRIPOptionSetting FoomaticOption2=Choice1: "SET TEST2=CHOICE1" +*FoomaticOption2 Choice2/Choice 2: "%% FoomaticRIPOptionSetting: FoomaticOption2=Choice2" +*FoomaticRIPOptionSetting FoomaticOption2=Choice2: "SET TEST2=CHOICE2" +*FoomaticOption2 Choice3/Choice 3: "%% FoomaticRIPOptionSetting: FoomaticOption2=Choice3" +*FoomaticRIPOptionSetting FoomaticOption2=Choice3: "SET TEST2=CHOICE3" +*CloseUI: *FoomaticOption2 + +*OpenUI *FoomaticPJLMergeTest/Test for PJL Merging: PickOne +*FoomaticRIPOption FoomaticPJLMergeTest: string CmdLine E +*FoomaticRIPOptionAllowedChars FoomaticPJLMergeTest: " ./A-Za-z0-9_='-" +*OrderDependency: 399 AnySetup *FoomaticPJLMergeTest +*FoomaticRIPOptionPrototype FoomaticPJLMergeTest: "%s" +*DefaultFoomaticPJLMergeTest: NoDriverPJL +*FoomaticPJLMergeTest NoDriverPJL/No driver-generated PJL: "%% FoomaticRIPOptionSetting: FoomaticPJLMergeTest=NoDriverPJL" +*FoomaticRIPOptionSetting FoomaticPJLMergeTest=NoDriverPJL: "" +*FoomaticPJLMergeTest DriverPJL/Simulate driver-generated PJL: "%% FoomaticRIPOptionSetting: FoomaticPJLMergeTest=DriverPJL" +*FoomaticRIPOptionSetting FoomaticPJLMergeTest=DriverPJL: " -p 'TEST2=CHOICE3' -p 'TEST6=CHOICE3' -p 'RESOLUTION=600'" +*CloseUI: *FoomaticPJLMergeTest + + +*OpenUI *FoomaticOption3/Foomatic Option 3: PickOne +*FoomaticRIPOption FoomaticOption3: string PS Z +*FoomaticRIPOptionMaxLength FoomaticOption3: 8 +*FoomaticRIPOptionAllowedChars FoomaticOption3: "./A-Za-z0-9_-" +*OrderDependency: 350 AnySetup *FoomaticOption3 +*FoomaticRIPOptionPrototype FoomaticOption3: "% FoomaticOption3: %s" +*DefaultFoomaticOption3: Choice1 +*FoomaticOption3 Choice1/Choice 1: "% FoomaticOption3: Choice1" +*FoomaticOption3 Choice2/Choice 2: "% FoomaticOption3: Choice2" +*FoomaticOption3 Choice3/Choice 3: "% FoomaticOption3: Choice3" +*CloseUI: *FoomaticOption3 + +*OpenUI *FoomaticOption4/Foomatic Option 4: PickOne +*FoomaticRIPOption FoomaticOption4: password PS Z +*FoomaticRIPOptionMaxLength FoomaticOption4: 8 +*FoomaticRIPOptionAllowedRegExp FoomaticOption4: "^[A-Za-z0-9]*$" +*OrderDependency: 360 AnySetup *FoomaticOption4 +*FoomaticRIPOptionPrototype FoomaticOption4: "% FoomaticOption4: %s" +*DefaultFoomaticOption4: Choice1 +*FoomaticOption4 Choice1/Choice 1: "% FoomaticOption4: Choice1" +*FoomaticOption4 Choice2/Choice 2: "% FoomaticOption4: Choice2" +*FoomaticOption4 Choice3/Choice 3: "% FoomaticOption4: Choice3" +*CloseUI: *FoomaticOption4 + +*OpenUI *FoomaticOption5/Foomatic Option 5: PickOne +*FoomaticRIPOption FoomaticOption5: int PS Z +*FoomaticRIPOptionRange FoomaticOption5: -10 10 +*OrderDependency: 370 AnySetup *FoomaticOption5 +*FoomaticRIPOptionPrototype FoomaticOption5: "% FoomaticOption5: %s" +*DefaultFoomaticOption5: 2 +*FoomaticRIPDefaultFoomaticOption5: 2 +*FoomaticOption5 -10/-10: "% FoomaticOption5: -10" +*FoomaticOption5 -8/-8: "% FoomaticOption5: -8" +*FoomaticOption5 -6/-6: "% FoomaticOption5: -6" +*FoomaticOption5 -4/-4: "% FoomaticOption5: -4" +*FoomaticOption5 -2/-2: "% FoomaticOption5: -2" +*FoomaticOption5 0/0: "% FoomaticOption5: 0" +*FoomaticOption5 2/2: "% FoomaticOption5: 2" +*FoomaticOption5 4/4: "% FoomaticOption5: 4" +*FoomaticOption5 6/6: "% FoomaticOption5: 6" +*FoomaticOption5 8/8: "% FoomaticOption5: 8" +*FoomaticOption5 10/10: "% FoomaticOption5: 10" +*CloseUI: *FoomaticOption5 + +*OpenUI *FoomaticOption6/Foomatic Option 6: PickOne +*FoomaticRIPOption FoomaticOption6: float PS Z +*FoomaticRIPOptionRange FoomaticOption6: -2.5 2.5 +*OrderDependency: 380 AnySetup *FoomaticOption6 +*FoomaticRIPOptionPrototype FoomaticOption6: "% FoomaticOption6: %s" +*DefaultFoomaticOption6: 1.0 +*FoomaticRIPDefaultFoomaticOption6: 1.2 +*FoomaticOption6 -2.5/-2.5: "% FoomaticOption6: -2.5" +*FoomaticOption6 -2.0/-2.0: "% FoomaticOption6: -2.0" +*FoomaticOption6 -1.5/-1.5: "% FoomaticOption6: -1.5" +*FoomaticOption6 -1.0/-1.0: "% FoomaticOption6: -1.0" +*FoomaticOption6 -0.5/-0.5: "% FoomaticOption6: -0.5" +*FoomaticOption6 0/0: "% FoomaticOption6: 0" +*FoomaticOption6 0.5/0.5: "% FoomaticOption6: 0.5" +*FoomaticOption6 1.0/1.0: "% FoomaticOption6: 1.0" +*FoomaticOption6 1.5/1.5: "% FoomaticOption6: 1.5" +*FoomaticOption6 2.0/2.0: "% FoomaticOption6: 2.0" +*FoomaticOption6 2.5/2.5: "% FoomaticOption6: 2.5" +*CloseUI: *FoomaticOption6 + +*FoomaticRIPOption FoomaticOption7: enum CmdLine B 390 +*FoomaticRIPOptionSetting FoomaticOption7=TheOnlyChoice: " --FoomaticOption7" + +*OpenUI *FoomaticOption8/Foomatic Option 8: PickOne +*FoomaticRIPOption FoomaticOption8: enum Composite C +*OrderDependency: 392 AnySetup *FoomaticOption8 +*DefaultFoomaticOption8: Choice3 +*FoomaticOption8 Choice1/Choice 1: "%% FoomaticRIPOptionSetting: FoomaticOption8=Choice1" +*FoomaticRIPOptionSetting FoomaticOption8=Choice1: "FoomaticOption9=ChoiceA FoomaticOptionA=ChoiceD" +*FoomaticOption8 Choice2/Choice 2: "%% FoomaticRIPOptionSetting: FoomaticOption8=Choice2" +*FoomaticRIPOptionSetting FoomaticOption8=Choice2: "FoomaticOption9=ChoiceB FoomaticOptionA=ChoiceE" +*FoomaticOption8 Choice3/Choice 3: "%% FoomaticRIPOptionSetting: FoomaticOption8=Choice3" +*FoomaticRIPOptionSetting FoomaticOption8=Choice3: "FoomaticOption9=ChoiceC FoomaticOptionA=ChoiceF" +*CloseUI: *FoomaticOption8 + +*OpenUI *FoomaticOptionB/Foomatic Option B: PickOne +*FoomaticRIPOption FoomaticOptionB: enum Composite C +*OrderDependency: 395 AnySetup *FoomaticOptionB +*DefaultFoomaticOptionB: Choice2 +*FoomaticOptionB Choice1/Choice 1: "%% FoomaticRIPOptionSetting: FoomaticOptionB=Choice1" +*FoomaticRIPOptionSetting FoomaticOptionB=Choice1: "FoomaticOptionC=ChoiceA FoomaticOptionD=ChoiceD" +*FoomaticOptionB Choice2/Choice 2: "%% FoomaticRIPOptionSetting: FoomaticOptionB=Choice2" +*FoomaticRIPOptionSetting FoomaticOptionB=Choice2: "FoomaticOptionC=ChoiceB FoomaticOptionD=ChoiceE" +*FoomaticOptionB Choice3/Choice 3: "%% FoomaticRIPOptionSetting: FoomaticOptionB=Choice3" +*FoomaticRIPOptionSetting FoomaticOptionB=Choice3: "FoomaticOptionC=ChoiceC FoomaticOptionD=ChoiceF" +*CloseUI: *FoomaticOptionB + +*FoomaticRIPOption FoomaticOptionE: enum CmdLine D 398 +*FoomaticRIPOptionSetting FoomaticOptionE=TheOnlyChoice: " --Foomatic&& +OptionE --user='&user;' --host='&host;' --title='&title;' --copies='&&& +copies;' --options='(&options;)' --date='&month;/&date;/&year;' --time='&&& +hour;:&min;:&sec;' --special='&<>"'" +*End + +*CloseGroup: FoomaticTest + +*OpenGroup: FoomaticOption8/Foomatic Option 8 + +*OpenUI *FoomaticOption9/Foomatic Option 9: PickOne +*FoomaticRIPOption FoomaticOption9: enum CmdLine D +*OrderDependency: 393 AnySetup *FoomaticOption9 +*DefaultFoomaticOption9: FromFoomaticOption8 +*FoomaticOption9 FromFoomaticOption8/Controlled by 'Foomatic Option 8': "%% FoomaticRIPOptionSetting: FoomaticOption9=@FoomaticOption8" +*FoomaticOption9 ChoiceA/Choice A: "%% FoomaticRIPOptionSetting: FoomaticOption9=ChoiceA" +*FoomaticRIPOptionSetting FoomaticOption9=ChoiceA: " --option9=choiceA" +*FoomaticOption9 ChoiceB/Choice B: "%% FoomaticRIPOptionSetting: FoomaticOption9=ChoiceB" +*FoomaticRIPOptionSetting FoomaticOption9=ChoiceB: " --option9=choiceB" +*FoomaticOption9 ChoiceC/Choice C: "%% FoomaticRIPOptionSetting: FoomaticOption9=ChoiceC" +*FoomaticRIPOptionSetting FoomaticOption9=ChoiceC: " --option9=choiceC" +*CloseUI: *FoomaticOption9 + +*OpenUI *FoomaticOptionA/Foomatic Option A: PickOne +*FoomaticRIPOption FoomaticOptionA: enum CmdLine D +*OrderDependency: 394 AnySetup *FoomaticOptionA +*DefaultFoomaticOptionA: FromFoomaticOption8 +*FoomaticOptionA FromFoomaticOption8/Controlled by 'Foomatic Option 8': "%% FoomaticRIPOptionSetting: FoomaticOption9=@FoomaticOption8" +*FoomaticOptionA ChoiceD/Choice D: "%% FoomaticRIPOptionSetting: FoomaticOptionA=ChoiceD" +*FoomaticRIPOptionSetting FoomaticOptionA=ChoiceD: " --optionA=choiceD" +*FoomaticOptionA ChoiceE/Choice E: "%% FoomaticRIPOptionSetting: FoomaticOptionA=ChoiceE" +*FoomaticRIPOptionSetting FoomaticOptionA=ChoiceE: " --optionA=choiceE" +*FoomaticOptionA ChoiceF/Choice F: "%% FoomaticRIPOptionSetting: FoomaticOptionA=ChoiceF" +*FoomaticRIPOptionSetting FoomaticOptionA=ChoiceF: " --optionA=choiceF" +*CloseUI: *FoomaticOptionA + +*CloseGroup: FoomaticOption8 + +*FoomaticRIPOption FoomaticOptionC: enum CmdLine D 396 +*FoomaticRIPOptionSetting FoomaticOptionC=FromFoomaticOptionB: "" +*FoomaticRIPOptionSetting FoomaticOptionC=ChoiceA: " --optionC=choiceA" +*FoomaticRIPOptionSetting FoomaticOptionC=ChoiceB: " --optionC=choiceB" +*FoomaticRIPOptionSetting FoomaticOptionC=ChoiceC: " --optionC=choiceC" + +*FoomaticRIPOption FoomaticOptionD: enum CmdLine D 397 +*FoomaticRIPOptionSetting FoomaticOptionD=FromFoomaticOptionB: "" +*FoomaticRIPOptionSetting FoomaticOptionD=ChoiceD: " --optionD=choiceD" +*FoomaticRIPOptionSetting FoomaticOptionD=ChoiceE: " --optionD=choiceE" +*FoomaticRIPOptionSetting FoomaticOptionD=ChoiceF: " --optionD=choiceF" + + +*% Generic boilerplate PPD stuff as standard PostScript fonts and so on + +*DefaultFont: Courier +*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM +*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM +*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM +*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM +*Font Bookman-Demi: Standard "(001.004S)" Standard ROM +*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM +*Font Bookman-Light: Standard "(001.004S)" Standard ROM +*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM +*Font Courier: Standard "(002.004S)" Standard ROM +*Font Courier-Bold: Standard "(002.004S)" Standard ROM +*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM +*Font Courier-Oblique: Standard "(002.004S)" Standard ROM +*Font Helvetica: Standard "(001.006S)" Standard ROM +*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM +*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM +*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM +*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM +*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM +*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM +*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM +*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM +*Font Palatino-Bold: Standard "(001.005S)" Standard ROM +*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM +*Font Palatino-Italic: Standard "(001.005S)" Standard ROM +*Font Palatino-Roman: Standard "(001.005S)" Standard ROM +*Font Symbol: Special "(001.007S)" Special ROM +*Font Times-Bold: Standard "(001.007S)" Standard ROM +*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM +*Font Times-Italic: Standard "(001.007S)" Standard ROM +*Font Times-Roman: Standard "(001.007S)" Standard ROM +*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM +*Font ZapfDingbats: Special "(001.004S)" Standard ROM + diff --git a/test/lsbfuncs.sh b/test/lsbfuncs.sh new file mode 100755 index 0000000..7ff8fb7 --- /dev/null +++ b/test/lsbfuncs.sh @@ -0,0 +1,387 @@ +# lsbfuncs.sh : LSB test suite specific common shell functions +# +########################################################################## +# (C) Copyright 1998-2001 The Open Group +# +# All rights reserved. No part of this source code may be reproduced, +# stored in a retrieval system, or transmitted, in any form or by any +# means, electronic, mechanical, photocopying, recording or otherwise, +# except as stated in the end-user licence agreement, without the prior +# permission of the copyright owners. +# +# X/Open and the 'X' symbol are trademarks of X/Open Company Limited in +# the UK and other countries. +# +# PROJECT: LSB-FHS +# PRODUCT: LSB.fhs/SRC/lsblib/lsbfuncs.sh +# AUTHOR: Andrew Josey, The Open Group +# DATE CREATED: 21 Dec 1998 +########################################################################## + +# This is $Revision: 1.6 $ +# +# $Log: lsbfuncs.sh,v $ +# Revision 1.6 2002/01/17 02:21:24 cyeoh +# modifies lsb_test_symlink soboth symlink "from" and "to" are followed +# for symlinks. This changes the behaviour such that if the "to" is +# a symlink but "from" does point to what "to" points to then it returns +# true. +# +# Revision 1.5 2001/07/20 11:49:47 ajosey +# add further diagnostics +# +# Revision 1.4 2001/07/20 11:27:33 ajosey +# add in more diagnostics to lsb_test_file +# +# Revision 1.3 2001/07/20 11:20:08 ajosey +# add in diagnostic to lsb_test_file +# +# Revision 1.2 2001/07/18 06:58:55 ajosey +# add header, and cvs revision stuff +# +# +#Current contents +# lsb_setarch() +# lsb_test_symlink() +# lsb_test_dir() +# lsb_test_dir_searchable() +# lsb_test_file() +# lsb_test_exec +# lsb_test_device_by_name() +# These functions return the following codes +# +# PASS=0 +# FAIL=1 +# WARNING=2 +# UNRESOLVED=3 +# + +# lsb_setarch: sets the $lsb_arch environment variable to the +# current architecture +lsb_setarch() +{ + lsb_arch=`uname -m` + case $lsb_arch in + i?86) lsb_arch=i386;; + sparc) lsb_arch=sparc;; + *) lsb_arch=unknown;; + esac +} + +# lsb_test_symlink symlink destination +# Argument 1: symlink from name +# Argument 2: to name +# Returns +# 0 = PASS, yes symlink points to destination +# 1 = FAIL, +# 3 = UNRESOLVED,Setup problem +# +# On a failure or setup problem a diagnostic message is omitted +# +# Calls lsblib routines: +# lsb_realpath, lsb_issymlink +# +lsb_test_symlink() { + func_name=lsb_is_symlink + # validate that we have two arguments + if test $# -lt 2 + then + echo "$func_name: Missing argument"; return 3 # unresolved + fi + from="$1" + to="$2" + + # cannot use test -L as not in POSIX.2 so call wrapper + # that does an lstat() + lsb_issymlink $from + rval=$? + if test $rval -eq 3 # unresolved + then + return 3 # unresolved + fi + if ! test $rval -eq 0 + then + if ! test -e $from + then + echo "$from does not exist (expected symlink to $to)" + return 1 # fail + else + echo "$from expected to be symlink to $to, returned non-symlink" + return 1 # fail + fi + else + # its a symlink so lets validate where it points to + # need to call realpath , which is a c program wrapping on realpath3c + pathptr=`lsb_realpath $from` + if test $? -ne 0 + then + return 3 # unresolved + fi + pathptr_to=`lsb_realpath $to` + if test $? -ne 0 + then + # Destination does not point anywhere + return 3 # unresolved + fi + if test "$pathptr" = "$pathptr_to" + then + return 0 # pass + else + echo "$from expected to be symlink to $to, pointed to $pathptr" + return 1 # fail + fi + fi +} + +# lsb_test_dir filename +# test for presence of a directory called filename +# Argument: filename to test if its a directory +# Returns: 0 PASS , it's a directory +# 1 FAIL, its not a directory or a symlink +# 2 WARNING its a symlink +# 3 UNRESOLVED error +lsb_test_dir() { + func_name=lsb_test_dir + # validate that we have one arguments + if test $# -lt 1 + then + echo "$func_name: Missing argument" + return 3 # unresolved + fi + + _fname=$1 + # if it does not exist then fail + if ! test -e $_fname + then + tet_infoline "$_fname: directory not found" + return 1 # fail + fi + + # since test -d will follow the symlink, we should check + # for a symlink using the lstat wrapper first + lsb_issymlink $_fname + rval=$? + if test $rval -eq 3 # unresolved + then + return 3 # unresolved + fi + if ! test $rval -eq 0 + then + # not a symlink + if test -d $_fname + then + # success + return 0 # pass + else + # not a symlink and not a directory + tet_infoline "$_fname: not a directory or a symlink" + return 1 # fail + fi + else + # warning , its a symlink when we expected a directory + return 2 # warning + fi +} +# lsb_test_dir_searchable filename +# test for presence of a directory and that it can be searched +# Argument: filename +# Returns: 0 PASS , it's a file and it exists +# 1 FAIL, its not a file or a symlink +# 3 UNRESOLVED error +lsb_test_dir_searchable() { + func_name=lsb_test_dir_searchable + # validate that we have one arguments + if test $# -lt 1 + then + echo "$func_name: Missing argument" + return 3 + fi + lsb_test_dir $1 + funcret=$? + if test $funcret -eq 0 -o $funcret -eq 2 + then + ( ls $1 ) > /dev/null 2> _lsb.stderr + if test $? -ne 0 + then + echo "$func_name: expected be able to search directory $1, got an error" + if test -s _lsb.stderr + then + cat _lsb.stderr + rm _lsb.stderr + fi + else + rm _lsb.stderr + return 0 + fi + + else + return $funcret + fi + + + +} +# lsb_test_file filename +# test for presence of a filename +# Argument: filename +# Returns: 0 PASS , it's a file and it exists +# 1 FAIL, its not a file or a symlink +# 2 WARNING its a symlink +# 3 UNRESOLVED error +lsb_test_file() { + func_name=lsb_test_file + # validate that we have one arguments + if test $# -lt 1 + then + echo "$func_name: Missing argument" + return 3 + fi + _fname=$1 + # if it does not exist then fail + if ! test -e $_fname + then + tet_infoline "$_fname: file not found" + return 1 + fi + # since test -f will follow the symlink, we should check + # for a symlink using the lstat wrapper first + lsb_issymlink $_fname + rval=$? + if test $rval -eq 3 + then + return 3 + fi + if ! test $rval -eq 0 + then + # not a symlink + if test -f $_fname + then + # success + return 0 + else + # not a symlink and not a file + tet_infoline "$_fname: not a file or a symlink" + return 1 + fi + else + # warning , its a symlink when we expected a file + tet_infoline "$_fname: found a symlink" + return 2 + fi +} + + +# lsb_test_exec: +# check that a utility can be executed +# if privilege is needed then an lsb_execwithpriv tool is used. +# +# if a utility needs an argument such as a file to parse that should be +# supplied. +# Returns: +# 0 - PASS +# 1 - Fail +# 3 - Unresolved +# + +lsb_test_exec() +{ + +test $# -eq 0 && return 3 # unresolved + +_ExecWithPriv="" +if test "$1" = "lsb_execwithpriv" +then + _ExecWithPriv="$1" ; shift + case "$1" + in + *) _ExecWithPriv="$_ExecWithPriv IGNORED_ARG" ; shift ;; + esac +fi + +rm -f _ltexec.stderr > /dev/null 2>&1 +#( $_ExecWithPriv exec "$@" ) > /dev/null 2> _ltexec.stderr +( $_ExecWithPriv exec "$@" ) +return $? + +#if test -s _ltexec.stderr +#then +# cat _ltexec.stderr +# rm -f _ltexec.stderr +# return 1 # fail +#else +# rm -f _ltexec.stderr +# return 0 # pass +#fi +} + +# lsb_test_device_by_name name b|c major# minor# +# +# test whether a device exists, the type and the expected major and +# minor number +# +# Calls : +# lsb_devstat a wrapper to stat that when called with a device +# name as the first argument outputs four space separated strings +# device-name type majorno minorno +# +# Returns: +# 0 PASS +# 1 FAIL +# 3 Unresolved + +lsb_test_device_by_name() { + func_name=lsb_test_device_by_name + # validate that we have one arguments + if test $# -lt 4 + then + echo "$func_name: Missing argument(s)" + return 3 # unresolved + fi + _devname=$1 + _devtype=$2 + _major=$3 + _minor=$4 + + case $_devtype in + b) + if ! test -b $_devname + then + return 1 # fail + fi ;; + c) + if ! test -c $_devname + then + return 1 # fail + fi ;; + *) + echo "$func_name: unknown device type argument ($_devtype)" + return 3 # unresolved + ;; + esac + + _retval=`lsb_devstat $_devname` + set $_retval + if test "$1" = "$_devname" -a "$2" = "$_devtype" -a "$3" = "$_major" -a "$4" = "$_minor" + then + return 0 # pass + else + if ! test "$1" = "$_devname" + then + echo "$func_name: expected device name:\"$_devname\" got \"$1\"" + fi + if ! test "$2" = "$_devtype" + then + echo "$func_name: expected device type: \"$_devtype\" got \"$2\"" + fi + if ! test "$3" = "$_major" + then + echo "$func_name: expected major number: \"$_major\" got \"$3\"" + fi + if ! test "$4" = "$_minor" + then + echo "$func_name: expected minor number: \"$_minor\" got \"$4\"" + fi + return 1 # fail + fi + +} diff --git a/test/shfuncs.sh b/test/shfuncs.sh new file mode 100755 index 0000000..572273d --- /dev/null +++ b/test/shfuncs.sh @@ -0,0 +1,187 @@ +# shfuncs : test suite common shell functions + +########################################################################## +# (C) Copyright 1998-2001 The Open Group +# +# All rights reserved. No part of this source code may be reproduced, +# stored in a retrieval system, or transmitted, in any form or by any +# means, electronic, mechanical, photocopying, recording or otherwise, +# except as stated in the end-user licence agreement, without the prior +# permission of the copyright owners. +# +# X/Open and the 'X' symbol are trademarks of X/Open Company Limited in +# the UK and other countries. +# +# PROJECT: LSB-FHS +# PRODUCT: LSB.fhs/SRC/common/lsblib/shfuncs.sh +# AUTHOR: Andrew Josey, The Open Group +# DATE CREATED: 21 Dec 1998 +# +# Derived from the TET demo test suites +########################################################################## + +# This is $Revision: 1.2 $ +# +# $Log: shfuncs.sh,v $ +# Revision 1.2 2001/07/18 06:58:55 ajosey +# add header, and cvs revision stuff +# + + +tpstart() # write test purpose banner and initialise variables +{ + tet_infoline "$*" + FAIL=N +} + +tpresult() # give test purpose result +{ + # $1 is result code to give if FAIL=N (default PASS) + if [ $FAIL = N ] + then + tet_result ${1-PASS} + else + tet_result FAIL + fi +} + +check_exit() # execute command (saving output) and check exit code +{ + # $1 is command, $2 is expected exit code (0 or "N" for non-zero) + eval "$1" > out.stdout 2> out.stderr + CODE=$? + if [ $2 = 0 -a $CODE -ne 0 ] + then + tet_infoline "Command ($1) gave exit code $CODE, expected 0" + FAIL=Y + elif [ $2 != 0 -a $CODE -eq 0 ] + then + tet_infoline "Command ($1) gave exit code $CODE, expected non-zero" + FAIL=Y + fi +} + +check_exit_value() # check that $1 equates $2 +{ + CODE=$1 + if [ $2 = 0 -a $CODE -ne 0 ] + then + tet_infoline "exit code $CODE returned, expected 0" + FAIL=Y + elif [ $2 != 0 -a $CODE -eq 0 ] + then + tet_infoline "exit code $CODE returned, expected non-zero" + FAIL=Y + fi +} + +check_prep_exit_value() # check that $2 equates $3 +{ + CODE=$2 + if [ $3 = 0 -a $CODE -ne 0 ] + then + tet_infoline "$1 command returned exit code $CODE, expected 0" + FAIL=Y + elif [ $3 != 0 -a $CODE -eq 0 ] + then + tet_infoline "$1 command returned exit code $CODE, expected non-zero" + FAIL=Y + fi +} + +check_nostdout() # check that nothing went to stdout +{ + if [ -s out.stdout ] + then + tet_infoline "Unexpected output written to stdout, as shown below:" + infofile out.stdout stdout: + FAIL=Y + fi +} + +check_nostderr() # check that nothing went to stderr +{ + if [ -s out.stderr ] + then + tet_infoline "Unexpected output written to stderr, as shown below:" + infofile out.stderr stderr: + FAIL=Y + fi +} + +check_stdout() # check that a string went to stdout +{ + case $1 in + "") + if [ ! -s out.stdout ] + then + tet_infoline "Expected output to stdout, but none written" + FAIL=Y + fi + ;; + *) + grep "$1" out.stdout 2>&1 >/dev/null + if [ $? -ne 0 ] + then + tet_infoline "Output written to stdout did not contain \"$1\", got below:" + infofile out.stdout stdout: + FAIL=Y + fi + ;; + esac +} + +check_stderr() # check that stderr matches expected error +{ + # $1 is file containing regexp for expected error + # if no argument supplied, just check out.stderr is not empty + + case $1 in + "") + if [ ! -s out.stderr ] + then + tet_infoline "Expected output to stderr, but none written" + FAIL=Y + fi + ;; + *) + expfile="$1" + OK=Y + exec 4<&0 0< "$expfile" 3< out.stderr + while read expline + do + if read line <&3 + then + if expr "$line" : "$expline" > /dev/null + then + : + else + OK=N + break + fi + else + OK=N + fi + done + exec 0<&4 3<&- 4<&- + if [ $OK = N ] + then + tet_infoline "Incorrect output written to stderr, as shown below" + infofile "$expfile" "expected stderr:" + infofile out.stderr "received stderr:" + FAIL=Y + fi + ;; + esac +} + +infofile() # write file to journal using tet_infoline +{ + # $1 is file name, $2 is prefix for tet_infoline + + prefix=$2 + while read line + do + tet_infoline "$prefix$line" + done < $1 +} diff --git a/test/tcm.sh b/test/tcm.sh new file mode 100755 index 0000000..d8d98cb --- /dev/null +++ b/test/tcm.sh @@ -0,0 +1,571 @@ +# +# SCCS: @(#)tcm.sh 1.17 (03/03/31) +# +# UniSoft Ltd., London, England +# +# (C) Copyright 1996 X/Open Company Limited +# +# All rights reserved. No part of this source code may be reproduced, +# stored in a retrieval system, or transmitted, in any form or by any +# means, electronic, mechanical, photocopying, recording or otherwise, +# except as stated in the end-user licence agreement, without the prior +# permission of the copyright owners. +# A copy of the end-user licence agreement is contained in the file +# Licence which accompanies this distribution. +# +# X/Open and the 'X' symbol are trademarks of X/Open Company Limited in +# the UK and other countries. +# +# ************************************************************************ + +# Copyright 1990 Open Software Foundation (OSF) +# Copyright 1990 Unix International (UI) +# Copyright 1990 X/Open Company Limited (X/Open) +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose and without fee is hereby granted, provided +# that the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of OSF, UI or X/Open not be used in +# advertising or publicity pertaining to distribution of the software +# without specific, written prior permission. OSF, UI and X/Open make +# no representations about the suitability of this software for any purpose. +# It is provided "as is" without express or implied warranty. +# +# OSF, UI and X/Open DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL OSF, UI or X/Open BE LIABLE FOR ANY SPECIAL, INDIRECT OR +# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. +# +# *********************************************************************** +# +# SCCS: @(#)tcm.sh 1.17 03/31/03 +# NAME: Shell Test Case Manager +# PRODUCT: TET (Test Environment Toolkit) +# as supplied with TETware release 3.7 +# AUTHOR: Andrew Dingwall, UniSoft Ltd. +# DATE CREATED: 1 November 1990 +# +# DESCRIPTION: +# This file contains the support routines for the sequencing and control +# of invocable components and test purposes. +# It should be sourced (by means of the shell . command) into a shell +# script containing definitions of the invocable components and test +# purposes that may be executed, after those definitions have been made. +# Test purposes may be written as shell functions or executable +# shell scripts. +# +# This file sources tetapi.sh which contains the shell API functions. +# Test purposes written as separate shell scripts must also source +# tetapi.sh in order to use those functions. +# +# The user-supplied shell variable iclist should contain a list of all +# the invocable components in the testset; +# these are named ic1, ic2 ... etc. +# For each invocable component thus specified, the user should define +# a variable whose name is the same as that of the component. +# Each such variable should contain the names of the test purposes +# associated with each invocable component; for example: +# iclist="ic1 ic2" +# ic1="test1-1 test1-2 test1-3" +# ic2="test2-1 test2-2" +# +# The NUMBERS of the invocable components to be executed are specified +# on the command line. +# In addition, the user may define the variables tet_startup and +# tet_cleanup; if defined, the related functions (or shell scripts) +# are executed at the start and end of processing, respectively. +# +# The TCM makes the NAME of the currently executing test purpose +# available in the environment variable tet_thistest. +# +# The TCM reads configuration variables from the file specified by the +# TET_CONFIG environment variable; these are placed in the environment +# and marked as readonly. +# +# MODIFICATIONS: +# +# Geoff Clare, 11 Oct 1991 +# Replace signal lists with markers to be edited by make INSTALL. +# Remove local TET_VERSION to avoid conflict with env. variable. +# +# Geoff Clare, 29 Jan 1992 +# Implement TET_TRAP_FUNCTION in place of tet_setsigs(), and +# TET_DEFAULT_SIGS in place of tet_defaultsigs(). +# +# Andrew Dingwall, 18 Jan 1993 +# Reset block and sequence number to 1 before each +# test purpose is executed. +# +# Geoff Clare, UniSoft Ltd., August 1996 +# Make TP number unique over test case, not just IC. +# Get default TET_NSIG from makefile. +# +# Geoff Clare, UniSoft Ltd., 3 Sept 1996 +# Only give non-existent IC message for requested IC +# numbers (not for ICs executed via an "all" in the IC list). +# +# Andrew Dingwall, UniSoft Ltd., October 1996 +# Port to NT +# +# *********************************************************************** + +# +# TCM signal definitions +# The XXX_SIGNAL_LIST markers are replaced with proper lists by make INSTALL +# + +# standard signals - may not be specified in TET_SIG_IGN and TET_SIG_LEAVE +TET_STD_SIGNALS="1 2 3 4 6 8 13 14 15 10 12 20 18 21 22" + +# signals that are always unhandled +TET_SPEC_SIGNALS="9 17 19 11" + +# +# TCM global variables +# + +tet_thistest=""; export tet_thistest + +# +# "private" TCM variables +# + +TET_CWD=`pwd` +TET_OSNAME=`uname -s`; readonly TET_OSNAME; export TET_OSNAME +TET_DELETES=$TET_CWD/tet_deletes; readonly TET_DELETES; export TET_DELETES +TET_RESFILE=$TET_CWD/tet_xres; readonly TET_RESFILE; export TET_RESFILE +TET_STDERR=$TET_CWD/tet_stderr; readonly TET_STDERR; export TET_STDERR +TET_TESTS=$TET_CWD/tet_tests; readonly TET_TESTS +TET_TMPFILES=$TET_CWD/tet_tmpfiles; readonly TET_TMPFILES +TET_TMPRES=$TET_CWD/tet_tmpres; readonly TET_TMPRES; export TET_TMPRES + +TET_BLOCK=0; export TET_BLOCK +TET_CONTEXT=0; export TET_CONTEXT +TET_EXITVAL=0 +TET_SEQUENCE=0; export TET_SEQUENCE +TET_TPCOUNT=0; export TET_TPCOUNT +TET_TPNUMBER=0; export TET_TPNUMBER + +TET_TMP1=$TET_CWD/tet1.$$ +TET_TMP2=$TET_CWD/tet2.$$ + +# *********************************************************************** + +# +# "private" TCM function definitions +# these interfaces may go away one day +# + +# tet_ismember - return 0 if $1 is in the set $2 ... +# otherwise return 1 +tet_ismember(){ + TET_X=${1:?} + shift + for TET_Y in $* + do + if test 0$TET_X -eq $TET_Y + then + return 0 + fi + done + return 1 +} + + +# tet_abandon - signal handler used during startup and cleanup +tet_abandon(){ + TET_CAUGHTSIG=$1 + if test 15 -eq ${TET_CAUGHTSIG:?} + then + tet_sigterm $TET_CAUGHTSIG + else + tet_error "Abandoning testset: caught unexpected signal $TET_CAUGHTSIG" + fi + TET_EXITVAL=$TET_CAUGHTSIG exit +} + +# tet_sigterm - signal handler for SIGTERM +tet_sigterm(){ + TET_CAUGHTSIG=$1 + tet_error "Abandoning test case: received signal ${TET_CAUGHTSIG:?}" + tet_docleanup + TET_EXITVAL=$TET_CAUGHTSIG exit +} + +# tet_sigskip - signal handler used during test execution +tet_sigskip(){ + TET_CAUGHTSIG=$1 + tet_infoline "unexpected signal ${TET_CAUGHTSIG:?} received" + tet_result UNRESOLVED + if test 15 -eq ${TET_CAUGHTSIG:?} + then + tet_sigterm $TET_CAUGHTSIG + else + continue + fi +} + +# tet_tpend - report on a test purpose +tet_tpend(){ + TET_TPARG1=${1:?} + TET_RESULT= + eval `( + while read TET_NEXTRES + do + if test -z "$TET_RESULT" + then + TET_RESULT="$TET_NEXTRES" + continue + fi + case "$TET_NEXTRES" in + PASS) + ;; + FAIL) + TET_RESULT="$TET_NEXTRES" + ;; + UNRESOLVED|UNINITIATED) + if test FAIL != "$TET_RESULT" + then + TET_RESULT="$TET_NEXTRES" + fi + ;; + NORESULT) + if test FAIL != "$TET_RESULT" -a \ + UNRESOLVED != "$TET_RESULT" -a \ + UNINITIATED != "$TET_RESULT" + then + TET_RESULT="$TET_NEXTRES" + fi + ;; + UNSUPPORTED|NOTINUSE|UNTESTED) + if test PASS = "$TET_RESULT" + then + TET_RESULT="$TET_NEXTRES" + fi + ;; + *) + if test PASS = "$TET_RESULT" -o \ + UNSUPPORTED = "$TET_RESULT" -o \ + NOTINUSE = "$TET_RESULT" -o \ + UNTESTED = "$TET_RESULT" + then + TET_RESULT="$TET_NEXTRES" + fi + ;; + esac + done + echo TET_RESULT=\"$TET_RESULT\" + ) < $TET_TMPRES` + + > $TET_TMPRES + + TET_ABORT=NO + if test -z "$TET_RESULT" + then + TET_RESULT=NORESULT + TET_RESNUM=7 + elif tet_getcode "$TET_RESULT" # sets TET_RESNUM, TET_ABORT + then + : ok + else + TET_RESULT="NO RESULT NAME" + TET_RESNUM=-1 + fi + + tet_output 220 "$TET_TPARG1 $TET_RESNUM `date +%H:%M:%S`" "$TET_RESULT" + + if test YES = "$TET_ABORT" + then + TET_TRAP_FUNCTION=tet_abandon + tet_output 510 "" \ + "ABORT on result code $TET_RESNUM \"$TET_RESULT\"" + if test -n "$tet_cleanup" + then + tet_docleanup + fi + TET_EXITVAL=1 exit + fi +} + +# tet_docleanup - execute the tet_cleanup function +tet_docleanup(){ + tet_thistest= + TET_TPCOUNT=0 + TET_BLOCK=0 + tet_setblock + eval $tet_cleanup +} + +# *********************************************************************** + +# read in API functions +. ./tetapi.sh + + +# *********************************************************************** + + +# +# TCM main flow +# + +# capture command line args before they disappear +TET_TCM_ARGC=$# +TET_TCM_ARGS="$*" +TET_PNAME="$0"; readonly TET_PNAME; export TET_PNAME + +# arrange to clean up on exit +rm -f $TET_TMPFILES +> $TET_TMPFILES +trap 'rm -f `cat $TET_TMPFILES` $TET_TMPFILES; exit $TET_EXITVAL' 0 +trap exit 1 2 3 15 + +# open execution results file +(umask 0; rm -f $TET_RESFILE; > $TET_RESFILE) || TET_EXITVAL=1 exit + +# open other local files +for TET_A in $TET_DELETES $TET_STDERR $TET_TESTS \ + $TET_TMP1 $TET_TMPRES +do + rm -f $TET_A + echo $TET_A >> $TET_TMPFILES + > $TET_A +done + +# read in configuration variables and make them readonly +# strip comments and other non-variable assignments +# protect embedded spaces and single quotes in the value part +if test -n "$TET_CONFIG" +then + if test ! -r "$TET_CONFIG" + then + tet_error "can't read config file" $TET_CONFIG + else + sed "/^#/d; /^[ ]*\$/d; /^[^ ][^ ]*=/!d; + s/'/'\\\\''/g; s/\([^=]*\)=\(.*\)/\1='\2'/; p; + s/\([^=]*\)=.*/readonly \1/" $TET_CONFIG > $TET_TMP1 + . $TET_TMP1 + fi +fi + +# set current context to process ID +tet_setcontext + +# set up default results code file if so required +if test ! -r ${TET_CODE:=tet_code} +then + if test tet_code != "$TET_CODE" + then + tet_error "could not open results code file" \"$TET_CODE\" + fi + echo $TET_TMP2 >> $TET_TMPFILES + echo " +0 PASS Continue +1 FAIL Continue +2 UNRESOLVED Continue +3 NOTINUSE Continue +4 UNSUPPORTED Continue +5 UNTESTED Continue +6 UNINITIATED Continue +7 NORESULT Continue" > $TET_TMP2 + TET_CODE=$TET_TMP2 +fi + +# determine the full path name of the results code file +case $TET_OSNAME in +Windows_*) + case $TET_CODE in + [A-Za-z]:/*) + ;; + *) + TET_CODE=`pwd`/$TET_CODE + ;; + esac + ;; +*) + case $TET_CODE in + /*) + ;; + *) + TET_CODE=`pwd`/$TET_CODE + ;; + esac + ;; +esac + +readonly TET_CODE; export TET_CODE + +# process command-line args +if test 1 -gt $TET_TCM_ARGC +then + TET_TCM_ARGS=all +fi +TET_ICLAST=-1 +TET_ICLIST="`echo $iclist | tr -cd ' 0123456789'`" +: ${TET_ICLIST:=0} +TET_ICFIRST_DEF=`echo $TET_ICLIST | sed 's/ .*//'` +for TET_A in `echo $TET_TCM_ARGS | tr , ' '` +do + case $TET_A in + all*) + if test 0 -ge $TET_ICLAST + then + TET_ICFIRST=$TET_ICFIRST_DEF + for TET_B in $TET_ICLIST + do + if test $TET_B -le $TET_ICFIRST + then + TET_ICFIRST=$TET_B + fi + done + else + TET_ICFIRST=`expr $TET_ICLAST + 1` + fi + TET_ICLAST=$TET_ICFIRST + for TET_B in $TET_ICLIST + do + if test $TET_B -gt $TET_ICLAST + then + TET_ICLAST=$TET_B + fi + done + if test $TET_ICLAST -gt ${TET_B:=0} + then + TET_ICLAST=$TET_B + fi + ;; + *) + eval `echo $TET_A | sed 'h; s/^\([0-9]*\).*/TET_ICFIRST=\1/; + p; g; s/^[^\-]*-*//; s/^\([0-9]*\).*/TET_ICLAST=\1/'` + ;; + esac + TET_ICNO=${TET_ICFIRST:-$TET_ICFIRST_DEF} + while test $TET_ICNO -le ${TET_ICLAST:=$TET_ICNO} + do + if tet_ismember $TET_ICNO $TET_ICLIST + then + test -n "`eval echo \\${ic$TET_ICNO}`" && \ + echo ic$TET_ICNO + else + # only report if the IC was requested + case $TET_A in + all*) ;; + *) tet_error "IC $TET_ICNO is not defined" \ + "for this test case" + esac + fi + TET_ICNO=`expr $TET_ICNO + 1` + done >> $TET_TESTS +done +TET_ICCOUNT=`wc -l < $TET_TESTS | tr -cd 0123456789` + +# print startup message to execution results file +tet_output 15 "3.7 $TET_ICCOUNT" "TCM Start" + +# do initial signal list processing +for TET_A in TET_SIG_LEAVE TET_SIG_IGN +do + echo ${TET_A}2=\" + eval echo \$$TET_A | tr , '\012' | while read TET_B TET_JUNK + do + if test -z "$TET_B" + then + continue + elif tet_ismember $TET_B $TET_STD_SIGNALS $TET_SPEC_SIGNALS + then + tet_error "warning: illegal entry $TET_B" \ + "in $TET_A ignored" + else + echo $TET_B + fi + done + echo \" +done > $TET_TMP1 +. $TET_TMP1 +TET_SIG_LEAVE2="$TET_SIG_LEAVE2 $TET_SPEC_SIGNALS" +TET_A=1 +# The NSIG marker is edited by the makefile, but allow TET_NSIG to +# be overridden from the config file (or environment). +if test -z "$TET_NSIG" +then + TET_NSIG="32" +fi +TET_TRAP_FUNCTION=tet_abandon +TET_DEFAULT_SIGS= +while test $TET_A -lt $TET_NSIG +do + if tet_ismember $TET_A $TET_SIG_LEAVE2 + then + : + elif tet_ismember $TET_A $TET_SIG_IGN2 + then + trap "" $TET_A + else + trap "trap \"\" $TET_A; \$TET_TRAP_FUNCTION $TET_A" $TET_A + TET_DEFAULT_SIGS="$TET_DEFAULT_SIGS $TET_A" + fi + TET_A=`expr $TET_A + 1` +done + +# calculate starting TP number for each IC +TET_A= +for TET_B in $TET_ICLIST +do + # TET_A holds concatenation of TP lists for all previous ICs + set -- $TET_A + eval TET_TP_ADDNUM_$TET_B=$# + eval TET_A=\"\$TET_A \$ic$TET_B\" +done + +# do startup processing +eval $tet_startup + +# do main loop processing +for TET_ICNAME in `cat $TET_TESTS` +do + eval TET_TPLIST=\"\$$TET_ICNAME\" + TET_ICNUMBER=`echo $TET_ICNAME | tr -cd '0123456789'` + TET_TPCOUNT=`(set -- $TET_TPLIST; echo $#)` + tet_output 400 "$TET_ICNUMBER $TET_TPCOUNT `date +%H:%M:%S`" "IC Start" + TET_TPCOUNT=0 + for tet_thistest in $TET_TPLIST + do + TET_BLOCK=1 + TET_SEQUENCE=1 + TET_TPCOUNT=`expr $TET_TPCOUNT + 1` + eval TET_TPNUMBER=\`expr \$TET_TP_ADDNUM_$TET_ICNUMBER + $TET_TPCOUNT\` + tet_output 200 "$TET_TPNUMBER `date +%H:%M:%S`" "TP Start" + > $TET_TMPRES + TET_REASON="`tet_reason $tet_thistest`" + if test $? -eq 0 + then + tet_infoline "$TET_REASON" + tet_result UNINITIATED + else + TET_TRAP_FUNCTION=tet_sigskip + ( + trap $TET_DEFAULT_SIGS + unset TET_DEFAULT_SIGS + "$tet_thistest" + ) + fi + tet_tpend $TET_TPNUMBER + done + TET_TPNUMBER=0 + tet_output 410 "$TET_ICNUMBER $TET_TPCOUNT `date +%H:%M:%S`" "IC End" +done + +# do cleanup processing +TET_TRAP_FUNCTION=tet_abandon +if test -n "$tet_cleanup" +then + tet_docleanup +fi + +# successful exit +TET_EXITVAL=0 exit + diff --git a/test/testfoomaticrip b/test/testfoomaticrip new file mode 100755 index 0000000..5de100c --- /dev/null +++ b/test/testfoomaticrip @@ -0,0 +1,564 @@ +#!/bin/sh +# ------------------------------------------------- +# LSB test for presence and functionality of foomatic-rip +# ------------------------------------------------- +# Modification History: +# 11/15/2007 - Till Kamppeter - till.kamppeter@gmail.com +# ------------------------------------------------- +tet_startup="startup" # startup function +tet_cleanup="cleanup" # cleanup function +iclist="ic1 ic2 ic3 ic4 ic5 ic6 ic7 ic8 ic9 ic10 ic11 ic12 ic13" +ic1="tp1" +ic2="tp2" +ic3="tp3" +ic4="tp4" +ic5="tp5" +ic6="tp6" +ic7="tp7" +ic8="tp8" +ic9="tp9" +ic10="tp10" +ic11="tp11" +ic12="tp12" +ic13="tp13" + +FOOMATICRIP=`which foomatic-rip` +export PPD=`pwd`"/foomatic-test.ppd" +INPUTFILE=`pwd`"/foomatic-test-input-ps.ps" +IFILE=$INPUTFILE +BASECMDLINE="$FOOMATICRIP --ppd $PPD -o FilterPath="`pwd`"/" +PREVCMDLINE='' +HOSTNAME=`hostname` +JOBTITLE="$USER@$HOSTNAME" +PRIVATECUPSDIR="../../../cups" +if [ -x $PRIVATECUPSDIR/sbin/cupsd ]; then + PSTOPS="$PRIVATECUPSDIR/lib/cups/filter/pstops" + CUPSDCONF="$PRIVATECUPSDIR/etc/cups/cupsd.conf" + CUPSINIT1="xxx" + CUPSINIT2="xxx" + CUPSD="cupsd" + LPADMIN="$PRIVATECUPSDIR/sbin/lpadmin" + LPSTAT="$PRIVATECUPSDIR/bin/lpstat" + LPR="$PRIVATECUPSDIR/bin/lpr" +elif cups-config --version > /dev/null 2>&1; then + PSTOPS=`cups-config --serverbin`"/filter/pstops" + CUPSDCONF=`cups-config --serverroot`"/cupsd.conf" + CUPSINIT1="/etc/init.d/cups" + CUPSINIT2="/etc/init.d/cupsys" + CUPSD="cupsd" + LPADMIN="lpadmin" + LPSTAT="lpstat" + LPR="lpr" +else + PSTOPS="/usr/lib/cups/filter/pstops" + CUPSDCONF="/etc/cups/cupsd.conf" + CUPSINIT1="/etc/init.d/cups" + CUPSINIT2="/etc/init.d/cupsys" + CUPSD="cupsd" + LPADMIN="lpadmin" + LPSTAT="lpstat" + LPR="lpr" +fi +if cups-config --version > /dev/null 2>&1; then + CUPSFILTER=`cups-config --serverbin`"/filter" +else + CUPSFILTER="/usr/lib/cups/filter" +fi + +tp1() { + tpstart "Reference III.8.1" + tet_infoline "The implementation provides an exec-able version" + tet_infoline "of the foomatic-rip command in the PATH and in" + tet_infoline "the system's CUPS filter directory (symlink)" + test -x $FOOMATICRIP 2>out.stderr + check_exit_value $? 0 + check_nostderr + test -x "$CUPSFILTER/foomatic-rip" 2>out.stderr + check_exit_value $? 0 + check_nostderr + tpresult # set result code +} + +tp2() { + tpstart "Reference III.8.2" + tet_infoline "foomatic-rip inserts standard PPD options correctly into" + tet_infoline "the PostScript data stream." + test_foomatic_rip 'Option1 (PostScript) inserted' '' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*Option1\s+Choice2\s*[\n\r]+\s*\<\<\/HWResolution \[1200 600\]\>\> setpagedevice \% Option1: Choice2\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'Option2 (PostScript) inserted' '' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*Option2\s+Choice3\s*[\n\r]+\s*\% Option2: Choice3[\n\r]+ \<\<\/Test \[Example3\]\>\> setpagedevice[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'Option3 (PostScript) inserted' '' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*Option3\s+Choice1\s*[\n\r]+\s*\% Option3: Choice1\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'Option4 (PostScript) inserted' '' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*Option4\s+Choice1\s*[\n\r]+\s*\% Option4: Choice1\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'Option5 (PostScript) inserted' '' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*Option5\s+Choice1\s*[\n\r]+\s*\% Option5: Choice1\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'Option6 (PJL) inserted' '' \ + '\@PJL\s+SET\s+TEST6=CHOICE1\s*[\n\r]+' + test_foomatic_rip 'Option7 (PostScript) inserted' '' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*Option7\s+\S+\s*[\n\r]+\s*\% Option7: True\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'Option8 (PostScript) inserted' '' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*Option8\s+\S+\s*[\n\r]+\s*\% Option8: False\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + tpresult # set result code +} + +tp3() { + tpstart "Reference III.8.2" + tet_infoline "foomatic-rip inserts standard PPD options into the correct" + tet_infoline "sections of a DSC-compliant PostScript file and withing the" + tet_infoline "sections also in the correct order." + test_foomatic_rip 'JCLSetup: Option6' '' \ + '\%\-12345X\@PJL' \ + '\@PJL\s+SET\s+TEST6=CHOICE\d' \ + '\%\!PS' + test_foomatic_rip 'Prolog: Option5' '' \ + '\%\%BeginProlog' \ + '\%\%BeginFeature:\s*\*Option5\s+Choice\d' \ + '\%\%EndProlog' + test_foomatic_rip 'Setup: PageSize Option1 Option7 Option8 Option2 Option3' '' \ + '\%\%BeginSetup' \ + '\%\%BeginFeature:\s*\*PageSize\s+\S+' \ + '\%\%BeginFeature:\s*\*Option1\s+\S+' \ + '\%\%BeginFeature:\s*\*Option7\s+\S+' \ + '\%\%BeginFeature:\s*\*Option8\s+\S+' \ + '\%\%BeginFeature:\s*\*Option2\s+\S+' \ + '\%\%BeginFeature:\s*\*Option3\s+\S+' \ + '\%\%EndSetup' + test_foomatic_rip 'PageSetup: Page 1: Option4, Page 2: Option4, Page 3: Option4, Page 4: Option4' '' \ + '\%\%Page:\s*1\s+1' \ + '\%\%BeginFeature:\s*\*Option4\s+Choice\d' \ + 'gsave' \ + '\%\%Page:\s*2\s+2' \ + '\%\%BeginFeature:\s*\*Option4\s+Choice\d' \ + 'gsave' \ + '\%\%Page:\s*3\s+3' \ + '\%\%BeginFeature:\s*\*Option4\s+Choice\d' \ + 'gsave' \ + '\%\%Page:\s*4\s+4' \ + '\%\%BeginFeature:\s*\*Option4\s+Choice\d' \ + 'gsave' + tpresult # set result code +} + +tp4() { + tpstart "Reference III.8.2" + tet_infoline "foomatic-rip applies user-supplied option settings when" + tet_infoline "inserting PPD option code" + test_foomatic_rip 'Option1 (PostScript) with setting Choice1 inserted' \ + '-o Option1=Choice1' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*Option1\s+Choice1\s*[\n\r]+\s*\<\<\/HWResolution \[1200 1200\]\>\> setpagedevice \% Option1: Choice1\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'Option4 (PostScript) with setting Choice3 inserted for all 4 pages' \ + '-o Option4=Choice3' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*Option4\s+Choice3\s*[\n\r]+\s*\% Option4: Choice3\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*Option4\s+Choice3\s*[\n\r]+\s*\% Option4: Choice3\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*Option4\s+Choice3\s*[\n\r]+\s*\% Option4: Choice3\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*Option4\s+Choice3\s*[\n\r]+\s*\% Option4: Choice3\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'Option6 (PJL) with Choice2 inserted' \ + '-o Option6=Choice2' \ + '\@PJL\s+SET\s+TEST6=CHOICE2\s*[\n\r]+' + test_foomatic_rip 'Option7 (PostScript) with setting False inserted' \ + '-o Option7=False' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*Option7\s+\S+\s*[\n\r]+\s*\% Option7: False\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'Option8 (PostScript) with setting True inserted' \ + '-o Option8=True' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*Option8\s+\S+\s*[\n\r]+\s*\% Option8: True\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'Option1 (PostScript) inserted, invalid setting Choice4 ignored' \ + '-o Option1=Choice4' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*Option1\s+Choice2\s*[\n\r]+\s*\<\<\/HWResolution \[1200 600\]\>\> setpagedevice \% Option1: Choice2\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + tpresult # set result code +} + +tp5() { + tpstart "Reference III.8.2" + tet_infoline "foomatic-rip applies option settings to the renderer" + tet_infoline "command line" + test_foomatic_rip 'Renderer command line with arguments controlled by PPD options: FoomaticOption1 FoomaticOption7 FoomaticOption8 FoomaticOptionB FoomaticOptionE, check for presence, correct value, and order' \ + '' \ + 'foomatic-test-renderer[^\n\r]* --option1=choice1[^\n\r]* --FoomaticOption7[^\n\r]* --option9=choiceC[^\n\r]* --optionA=choiceF[^\n\r]* --optionC=choiceB[^\n\r]* --optionD=choiceE[^\n\r]* --FoomaticOptionE' + test_foomatic_rip 'Changed settings: FoomaticOption1=Choice3' \ + '-o FoomaticOption1=Choice3' \ + 'foomatic-test-renderer[^\n\r]* --option1=choice3[^\n\r]* --FoomaticOption7[^\n\r]* --option9=choiceC[^\n\r]* --optionA=choiceF[^\n\r]* --optionC=choiceB[^\n\r]* --optionD=choiceE[^\n\r]* --FoomaticOptionE' + tpresult +} + +tp6() { + tpstart "Reference III.8.2" + tet_infoline "foomatic-rip supports composite options, where one option" + tet_infoline "sets all member options" + test_foomatic_rip 'Composite options: FoomaticOption8 (Members FoomaticOption9 FoomaticOptionA), FoomaticOptionB (Members: FoomaticOptionC FoomaticOptionD)' \ + '' \ + 'foomatic-test-renderer[^\n\r]* --option9=choiceC[^\n\r]* --optionA=choiceF[^\n\r]* --optionC=choiceB[^\n\r]* --optionD=choiceE' + test_foomatic_rip 'Changing FoomaticOption8' \ + '-o FoomaticOption8=Choice1' \ + 'foomatic-test-renderer[^\n\r]* --option9=choiceA[^\n\r]* --optionA=choiceD[^\n\r]* --optionC=choiceB[^\n\r]* --optionD=choiceE' + test_foomatic_rip 'Changing FoomaticOptionB' \ + '-o FoomaticOptionB=Choice1' \ + 'foomatic-test-renderer[^\n\r]* --option9=choiceC[^\n\r]* --optionA=choiceF[^\n\r]* --optionC=choiceA[^\n\r]* --optionD=choiceD' + test_foomatic_rip 'FoomaticOption8 is a normal composite option, member options can be set individually' \ + '-o FoomaticOption9=ChoiceB' \ + 'foomatic-test-renderer[^\n\r]* --option9=choiceB[^\n\r]* --optionA=choiceF[^\n\r]* --optionC=choiceB[^\n\r]* --optionD=choiceE' + test_foomatic_rip 'FoomaticOptionB is a forced composite option, member options exist but are not advertized in GUIs' \ + '-o FoomaticOptionD=ChoiceF' \ + 'foomatic-test-renderer[^\n\r]* --option9=choiceC[^\n\r]* --optionA=choiceF[^\n\r]* --optionC=choiceB[^\n\r]* --optionD=choiceF' + tpresult +} + +tp7() { + tpstart "Reference III.8.2" + tet_infoline "String and password options allow (nearly) arbitrary strings" + test_foomatic_rip 'FoomaticOption3 is a string option' \ + '' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*FoomaticOption3\s+Choice1\s*[\n\r]+\s*\% FoomaticOption3: Choice1\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'FoomaticOption3: Another predefined choice (Choice2)' \ + '-o FoomaticOption3=Choice2' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*FoomaticOption3\s+Choice2\s*[\n\r]+\s*\% FoomaticOption3: Choice2\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'FoomaticOption3: A freely chosen string (DFhj_3-4)' \ + '-o FoomaticOption3=DFhj_3-4' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*FoomaticOption3\s+DFhj_3-4\s*[\n\r]+\s*\% FoomaticOption3: DFhj_3-4\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'FoomaticOption3: Too many characters (DFhj_3-45)' \ + '-o FoomaticOption3=DFhj_3-45' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*FoomaticOption3\s+Choice1\s*[\n\r]+\s*\% FoomaticOption3: Choice1\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'FoomaticOption3: Invalid characters (DFhj;3:4)' \ + '-o FoomaticOption3=DFhj;3:4' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*FoomaticOption3\s+Choice1\s*[\n\r]+\s*\% FoomaticOption3: Choice1\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'FoomaticOption4 is a password option (same as string, but GUIs hide input)' \ + '' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*FoomaticOption4\s+Choice1\s*[\n\r]+\s*\% FoomaticOption4: Choice1\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'FoomaticOption4: Valid string (DFhj3545)' \ + '-o FoomaticOption4=DFhj3545' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*FoomaticOption4\s+DFhj3545\s*[\n\r]+\s*\% FoomaticOption4: DFhj3545\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'FoomaticOption4: String does not match regexp (DFhj;3:4)' \ + '-o FoomaticOption4=DFhj;3:4' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*FoomaticOption4\s+Choice1\s*[\n\r]+\s*\% FoomaticOption4: Choice1\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + tpresult +} + +tp8() { + tpstart "Reference III.8.2" + tet_infoline "Numerical options allow any value in the range" + test_foomatic_rip 'FoomaticOption6 is a floating point numerical option, default 1.2 is not under the given choices' \ + '' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*FoomaticOption6\s+1.20*\s*[\n\r]+\s*\% FoomaticOption6: \s*1.20*\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'FoomaticOption6 set to -2.2, also not under the given choices' \ + '-o FoomaticOption6=-2.2' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*FoomaticOption6\s+\-2.20*\s*[\n\r]+\s*\% FoomaticOption6: \s*\-2.20*\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'FoomaticOption6 set to -4.6, value out of range, therefore ignored.' \ + '-o FoomaticOption6=-4.6' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*FoomaticOption6\s+1.20*\s*[\n\r]+\s*\% FoomaticOption6: \s*1.20*\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'FoomaticOption6 set to 10, also out of range.' \ + '-o FoomaticOption6=10' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*FoomaticOption6\s+1.20*\s*[\n\r]+\s*\% FoomaticOption6: \s*1.20*\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'FoomaticOption5 is an integer numerical option, default is 2' \ + '' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*FoomaticOption5\s+2\s*[\n\r]+\s*\% FoomaticOption5: \s*2\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'FoomaticOption5 set to -7' \ + '-o FoomaticOption5=-7' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*FoomaticOption5\s+\-7\s*[\n\r]+\s*\% FoomaticOption5: \s*\-7\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_foomatic_rip 'FoomaticOption5 set to 6.7, the digits after the decimal point get cut off.' \ + '-o FoomaticOption5=6.7' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*FoomaticOption5\s+6\S*\s*[\n\r]+\s*\% FoomaticOption5: \s*6\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + tpresult +} + +tp9() { + tpstart "Reference III.8.2" + tet_infoline "Disabled per Bug 1841 (http://bugs.linuxbase.org/show_bug.cgi?id=1841)" + tpresult UNTESTED + return + tet_infoline "Special entities get substituted by job parameters" + test_foomatic_rip 'Job parameters' \ + '' \ + 'foomatic-test-renderer[^\n\r]* --FoomaticOptionE --user='$USER' --host='$HOSTNAME' --title='$USER'\@'$HOSTNAME' --copies=1 --options=\(FilterPath=[^\n\r]* \) --date=\d\d\/\d\d\/\d+ --time=\d\d\:\d\d\:\d\d --special=\&\<\>\"' + tpresult +} + +tp10() { + tpstart "Reference III.8.2" + tet_infoline "PJL options from the PPD file get merged into PJL header" + tet_infoline "generated by the printer driver" + test_foomatic_rip 'FoomaticOption2 (PJL) inserted' '' \ + '\@PJL\s+SET\s+TEST2=CHOICE1\s*[\n\r]+' + test_foomatic_rip 'Option6 and FoomaticOption2 (both PJL) merged into driver-generated PJL header' \ + '-o FoomaticPJLMergeTest=DriverPJL' \ + '\%-12345X\@PJL\s+SET\s+TEST2=CHOICE1\s*[\n\r]+\s*\@PJL\s+SET\s+TEST6=CHOICE1\s*[\n\r]+\s*\@PJL\s+SET\s+RESOLUTION=600\s*[\n\r]+\s*\@PJL\s+ENTER\s+LANGUAGE=POSTSCRIPT\s*[\n\r]+' + tpresult +} + +tp11() { + tpstart "Reference III.8.2" + tet_infoline "Option settings can be applied to selected pages" + tet_infoline "(page overrides)" + test_foomatic_rip 'PageSetup: Page 1: Option4=Choice1, Page 2: Option4=Choice1, Page 3: Option4=Choice3, Page 4: Option4=Choice1' \ + '-o 3:Option4=Choice3' \ + '\%\%Page:\s*1\s+1' \ + '\%\%BeginFeature:\s*\*Option4\s+Choice1' \ + 'gsave' \ + '\%\%Page:\s*2\s+2' \ + '\%\%BeginFeature:\s*\*Option4\s+Choice1' \ + 'gsave' \ + '\%\%Page:\s*3\s+3' \ + '\%\%BeginFeature:\s*\*Option4\s+Choice3' \ + 'gsave' \ + '\%\%Page:\s*4\s+4' \ + '\%\%BeginFeature:\s*\*Option4\s+Choice1' \ + 'gsave' + test_foomatic_rip 'FoomaticOption1=Choice3 for pages 2-4' \ + '-o 2-4:FoomaticOption1=Choice3' \ + '\%\%Page:\s*1\s+1' \ + 'foomatic-test-renderer[^\n\r]* --option1=choice1' \ + '\%\%Page:\s*2\s+2' \ + '\%\%Page:\s*3\s+3' \ + '\%\%Page:\s*4\s+4' \ + 'foomatic-test-renderer[^\n\r]* --option1=choice3' + test_foomatic_rip 'FoomaticOption1=Choice3 for odd pages' \ + '-o odd:FoomaticOption1=Choice3' \ + '\%\%Page:\s*1\s+1' \ + 'foomatic-test-renderer[^\n\r]* --option1=choice3' \ + '\%\%Page:\s*2\s+2' \ + 'foomatic-test-renderer[^\n\r]* --option1=choice1' \ + '\%\%Page:\s*3\s+3' \ + 'foomatic-test-renderer[^\n\r]* --option1=choice3' \ + '\%\%Page:\s*4\s+4' \ + 'foomatic-test-renderer[^\n\r]* --option1=choice1' + test_foomatic_rip 'FoomaticOption1=Choice3 for pages 1-2 and 4' \ + '-o 1-2,4:FoomaticOption1=Choice3' \ + '\%\%Page:\s*1\s+1' \ + '\%\%Page:\s*2\s+2' \ + 'foomatic-test-renderer[^\n\r]* --option1=choice3' \ + '\%\%Page:\s*3\s+3' \ + 'foomatic-test-renderer[^\n\r]* --option1=choice1' \ + '\%\%Page:\s*4\s+4' \ + 'foomatic-test-renderer[^\n\r]* --option1=choice3' + tpresult +} + +tp12() { + tpstart "Reference III.8.2" + tet_infoline "PostScript code of options in the PostScript data stream" + tet_infoline "gets taken into account, foomatic-rip executes Foomatic" + tet_infoline "options" + IFILE="" + # The CUPS filter pstops inserts the PostScript code of the options + # of the PPD file given by the $PPD environment variable. Usually + # the default option settings are used. Non-default option settings + # can be supplied by the fifth command line argument. + # Note: The environment variable $PPD to tell pstops which PPD to use + # was already set in the beginning of this script + $PSTOPS 0 x y 1 "FoomaticOption2=Choice2" \ + $INPUTFILE 2> /dev/null | \ + test_foomatic_rip 'FoomaticOption2 with setting Choice2 inserted' \ + '' \ + '\@PJL\s+SET\s+TEST2=CHOICE2\s*[\n\r]+' + $PSTOPS 0 x y 1 "Option7=False" \ + $INPUTFILE 2> /dev/null | \ + test_foomatic_rip 'Option7 (PostScript) with setting False inserted' \ + '' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*Option7\s+\S+\s*[\n\r]+\s*\% Option7: False\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + $PSTOPS 0 x y 1 "FoomaticOption8=Choice1" \ + $INPUTFILE 2> /dev/null | \ + test_foomatic_rip 'Changing FoomaticOption8 (composite option)' \ + '' \ + 'foomatic-test-renderer[^\n\r]* --option9=choiceA[^\n\r]* --optionA=choiceD[^\n\r]* --optionC=choiceB[^\n\r]* --optionD=choiceE' + tpresult +} + +tp13() { + tpstart "Reference III.8.2" + tet_infoline "foomatic-rip acts as a CUPS filter and recognizes if it is" + tet_infoline "called as such. Also a test for the full printing workflow." + if ! grep -qi "FileDevice *yes" $CUPSDCONF; then + tet_infoline "Adding \"FileDevice Yes\" to cupsd.conf" + tet_infoline "This is needed so that we can print into a file." + echo "FileDevice yes" >> $CUPSDCONF + check_exit_value $? 0 + check_nostderr + $CUPSINIT1 restart 2>/dev/null || \ + $CUPSINIT2 restart 2>/dev/null || \ + killall -HUP $CUPSD 2>/dev/null + check_exit_value $? 0 + check_nostderr + sleep 3 + FILEDEVICEYESADDED=1 + fi + if [ -x $PRIVATECUPSDIR/sbin/cupsd ]; then + ln -s $FOOMATICRIP $PRIVATECUPSDIR/lib/cups/filter/ + fi + if [ -e $HOME/.cupsrc ]; then + IPP_PORT=632 + HOME=/tmp + export HOME IPP_PORT + fi + tet_infoline "Creating test print queue \"testprinter\"" + $LPADMIN -p testprinter -E -v file:/tmp/out.prn -P $PPD + check_exit_value $? 0 + check_nostderr + test_cups_job "Default option settings" \ + '' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*Option1\s+Choice2\s*[\n\r]+\s*\<\<\/HWResolution \[1200 600\]\>\> setpagedevice \% Option1: Choice2\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_cups_job "Option setting Option1=Choice1" \ + '-o Option1=Choice1' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*Option1\s+Choice1\s*[\n\r]+\s*\<\<\/HWResolution \[1200 1200\]\>\> setpagedevice \% Option1: Choice1\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_cups_job 'Changing FoomaticOption8' \ + '-o FoomaticOption8=Choice1' \ + 'foomatic-test-renderer[^\n\r]* --option9=choiceA[^\n\r]* --optionA=choiceD[^\n\r]* --optionC=choiceB[^\n\r]* --optionD=choiceE' + test_cups_job 'FoomaticOption4: Valid string (DFhj3545)' \ + '-o FoomaticOption4=DFhj3545' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*FoomaticOption4\s+DFhj3545\s*[\n\r]+\s*\% FoomaticOption4: DFhj3545\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + test_cups_job 'FoomaticOption5 set to -7' \ + '-o FoomaticOption5=-7' \ + '\[\{\s*[\n\r]+\s*\%\%BeginFeature:\s*\*FoomaticOption5\s+\-7\s*[\n\r]+\s*\% FoomaticOption5: \s*\-7\s*[\n\r]+\s*\%\%EndFeature\s*[\n\r]+\s*\}\s*stopped\s+cleartomark' + tet_infoline "Next test is with --user option, does not run on all LSB-compliant systems, see http://bugs.linuxbase.org/show_bug.cgi?id=1841" + test_cups_job 'Job parameters' \ + '' \ + 'foomatic-test-renderer[^\n\r]* --FoomaticOptionE --user='$USER' --host='$HOSTNAME' --title=TEST --copies=1 --options=\([^\n\r]*\) --date=\d\d\/\d\d\/\d+ --time=\d\d\:\d\d\:\d\d --special=\&\<\>\"' + test_cups_job 'FoomaticOption2 (PJL) inserted' '' \ + '\@PJL\s+SET\s+TEST2=CHOICE1\s*[\n\r]+' + test_cups_job 'Option6 and FoomaticOption2 (both PJL) merged into driver-generated PJL header' \ + '-o FoomaticPJLMergeTest=DriverPJL' \ + '\%-12345X\@PJL\s+SET\s+TEST2=CHOICE1\s*[\n\r]+\s*\@PJL\s+SET\s+TEST6=CHOICE1\s*[\n\r]+\s*\@PJL\s+SET\s+RESOLUTION=600\s*[\n\r]+\s*\@PJL\s+ENTER\s+LANGUAGE=POSTSCRIPT\s*[\n\r]+' + test_cups_job 'FoomaticOption1=Choice3 for pages 1-2 and 4' \ + '-o 1-2,4:FoomaticOption1=Choice3' \ + '\%\%Page:\s*1\s+1' \ + '\%\%Page:\s*2\s+2' \ + 'foomatic-test-renderer[^\n\r]* --option1=choice3' \ + '\%\%Page:\s*3\s+3' \ + 'foomatic-test-renderer[^\n\r]* --option1=choice1' \ + '\%\%Page:\s*4\s+4' \ + 'foomatic-test-renderer[^\n\r]* --option1=choice3' + tet_infoline "Removing test print queue \"testprinter\"" + $LPADMIN -x testprinter + check_exit_value $? 0 + check_nostderr + if [ -x $PRIVATECUPSDIR/sbin/cupsd ]; then + rm -f $PRIVATECUPSDIR/lib/cups/filter/foomatic-rip + fi + if [ "$FILEDEVICEYESADDED" = "1" ]; then + tet_infoline "Removing \"FileDevice yes\" from cupsd.conf" + perl -p -i -e 's/FileDevice yes\n//sm' $CUPSDCONF + check_exit_value $? 0 + check_nostderr + $CUPSINIT1 restart 2>/dev/null || \ + $CUPSINIT2 restart 2>/dev/null || \ + killall -HUP $CUPSD 2>/dev/null + check_exit_value $? 0 + check_nostderr + fi + tpresult +} + +test_foomatic_rip() { + COMMENT=$1 + shift + EXTRAOPTS=$1 + shift + CMDLINE="$BASECMDLINE $EXTRAOPTS $IFILE" + if [ "$CMDLINE" != "$PREVCMDLINE" ] + then + tet_infoline "Executing $CMDLINE" + $CMDLINE > out.stdout 2>out.stderr + PREVCMDLINE="$CMDLINE" + fi + check_exit_value $? 0 + check_nostderr + SEARCHTERM='' + while [ -n "$1" ] + do + if [ -n "$SEARCHTERM" ] + then + SEARCHTERM=$SEARCHTERM'.*' + fi + SEARCHTERM=$SEARCHTERM`/bin/echo "$1" | sed 's/ /\\\\x20/g'` + shift + done + tet_infoline "Checking: $COMMENT" + check_stdout_binary_P $SEARCHTERM +} + +test_cups_job () { + COMMENT=$1 + shift + EXTRAOPTS=$1 + shift + SEARCHTERM='' + while [ -n "$1" ] + do + if [ -n "$SEARCHTERM" ] + then + SEARCHTERM=$SEARCHTERM'.*' + fi + SEARCHTERM=$SEARCHTERM`/bin/echo "$1" | sed 's/ /\\\\x20/g'` + shift + done + tet_infoline "$COMMENT" + tet_infoline "Sending print job with option settings \"$EXTRAOPTS\"" + $LPR -P testprinter -J "TEST" -o FilterPath=`pwd`'/' $EXTRAOPTS $INPUTFILE + check_exit_value $? 0 + check_nostderr + counter=30 + while [ "`$LPSTAT -o testprinter | wc -l`" != "0" ]; do + counter=$(($counter - 1)) + if [ "$counter" = "0" ]; then + tet_infoline "Print job timeout" + FAIL=Y + break + fi + sleep 1 + done + chown $USER out.stdout + check_exit_value $? 0 + check_nostderr + cat /tmp/out.prn | perl -e 'my $a = join("",<>); exit !($a =~ /'$SEARCHTERM'/sm)' + if [ $? -ne 0 ] + then + tet_infoline "Output written to stdout did not contain \""`echo $SEARCHTERM | perl -p -e 's/\\\\/\\\\\\\\/g'`"\"" + FAIL=Y + fi +} + +# This is a derived function from LIB/shfuncs.sh/check_stdout() +# It checks whether string $1 is present in file out.stdout +# Differences: +# 1. It does not output file when check_stdout failed +# 2. It's using Perl rather than grep (grep -P is not available in all distros) +check_stdout_binary_P() # check that a string went to stdout +{ + case $1 in + "") + if [ ! -s out.stdout ] + then + tet_infoline "Expected output to stdout, but none written" + FAIL=Y + fi + ;; + *) + cat out.stdout | perl -e 'my $a = join("",<>); exit !($a =~ /'$1'/sm)' + if [ $? -ne 0 ] + then + tet_infoline "Output written to stdout did not contain \""`echo $1 | perl -p -e 's/\\\\/\\\\\\\\/g'`"\"" + FAIL=Y + fi + ;; + esac +} + +startup() { + rm -f tet_xres +} + +cleanup() { + if [ -f tet_xres ];then + #mv tet_xres journal.gs-test + rm -f out.stdout + rm -f out.stderr + rm -f /tmp/out.prn + fi +} + +# source common shell functions + +. ./shfuncs.sh +. ./lsbfuncs.sh + +# execute shell test case manager - must be last line +. ./tcm.sh + diff --git a/test/tetapi.sh b/test/tetapi.sh new file mode 100755 index 0000000..a835769 --- /dev/null +++ b/test/tetapi.sh @@ -0,0 +1,313 @@ +# +# SCCS: @(#)tetapi.sh 1.17 (03/03/31) +# +# UniSoft Ltd., London, England +# +# (C) Copyright 1996 X/Open Company Limited +# +# All rights reserved. No part of this source code may be reproduced, +# stored in a retrieval system, or transmitted, in any form or by any +# means, electronic, mechanical, photocopying, recording or otherwise, +# except as stated in the end-user licence agreement, without the prior +# permission of the copyright owners. +# A copy of the end-user licence agreement is contained in the file +# Licence which accompanies this distribution. +# +# X/Open and the 'X' symbol are trademarks of X/Open Company Limited in +# the UK and other countries. +# +# ************************************************************************ + +# Copyright 1990 Open Software Foundation (OSF) +# Copyright 1990 Unix International (UI) +# Copyright 1990 X/Open Company Limited (X/Open) +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose and without fee is hereby granted, provided +# that the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of OSF, UI or X/Open not be used in +# advertising or publicity pertaining to distribution of the software +# without specific, written prior permission. OSF, UI and X/Open make +# no representations about the suitability of this software for any purpose. +# It is provided "as is" without express or implied warranty. +# +# OSF, UI and X/Open DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL OSF, UI or X/Open BE LIABLE FOR ANY SPECIAL, INDIRECT OR +# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. +# +# *********************************************************************** +# +# SCCS: @(#)tetapi.sh 1.17 03/31/03 +# NAME: Shell API Support Routines +# PRODUCT: TET (Test Environment Toolkit) +# as supplied with TETware release 3.7 +# AUTHOR: Andrew Dingwall, UniSoft Ltd. +# DATE CREATED: 1 November 1990 +# +# DESCRIPTION: +# This file contains shell functions for use with the shell API. +# It is sourced automatically by the shell TCM. +# In addition it should be sourced by test purposes that are written as +# separate shell scripts, by means of the shell . command. +# +# The following functions are provided: +# +# tet_setcontext +# tet_setblock +# tet_infoline +# tet_result +# tet_delete +# tet_reason +# +# MODIFICATIONS: +# +# Geoff Clare, 29 Jan 1992 +# Rewrite tet_setcontext() so context number will change. +# +# Geoff Clare, UniSoft Ltd., August 1996 +# Make TP number unique over test case, not just IC. +# Use $$ as context number whenever possible. +# +# Andrew Dingwall, UniSoft Ltd., October 1996 +# Port to NT +# +# Andrew Dingwall, The Open Group, January 2002 +# changed "ed -" to "ed -s" so as to conform to UNIX2003 +# +# *********************************************************************** + +# +# publicly available shell API functions +# + +# set current context and reset block and sequence +# usage: tet_setcontext +# Note that when tet_setcontext is called in a subshell started using +# "( ... )" we cannot use $$ because it has the same value as in the parent. +tet_setcontext(){ + if test $$ != "$TET_CONTEXT" + then + TET_CONTEXT=$$ + else + # obtain a new, unused PID without generating a zombie process. + TET_CONTEXT=`(:)& echo $!` + fi + TET_BLOCK=1 + TET_SEQUENCE=1 +} + +# increment the current block ID, reset the sequence number to 1 +# usage: tet_setblock +tet_setblock(){ + TET_BLOCK=`expr ${TET_BLOCK:?} + 1` + TET_SEQUENCE=1 +} + +# print an information line to the execution results file +# and increment the sequence number +# usage: tet_infoline args [...] +tet_infoline(){ + tet_output 520 "${TET_TPNUMBER:?} ${TET_CONTEXT:?} ${TET_BLOCK:?} ${TET_SEQUENCE:?}" "$*" + TET_SEQUENCE=`expr $TET_SEQUENCE + 1` +} + +# record a test result for later emmision to the execution results file +# by tet_tpend +# usage: tet_result result_name +# (note that a result name is expected, not a result code number) +tet_result(){ + TET_ARG1="${1:?}" + if tet_getcode "$TET_ARG1" + then + : ok + else + tet_error "invalid result name \"$TET_ARG1\"" \ + "passed to tet_result" + TET_ARG1=NORESULT + fi + + echo $TET_ARG1 >> ${TET_TMPRES:?} + unset TET_ARG1 +} + +# mark a test purpose as deleted +# usage: tet_delete test_name reason [...] +tet_delete(){ + TET_ARG1=${1:?} + shift + TET_ARG2N="$*" + if test -z "$TET_ARG2N" + then + tet_undelete $TET_ARG1 + return + fi + + case $TET_OSNAME in + Windows_*) + TET_DEVNULL=nul + ;; + *) + TET_DEVNULL=/dev/null + ;; + esac + + if tet_reason $TET_ARG1 > $TET_DEVNULL + then + tet_undelete $TET_ARG1 + fi + + echo "$TET_ARG1 $TET_ARG2N" >> ${TET_DELETES:?} + unset TET_ARG1 TET_ARG2N +} + +# print the reason why a test purpose has been deleted +# return 0 if the test purpose has been deleted, 1 otherwise +# usage: tet_reason test_name +tet_reason(){ + : ${1:?} + ( + while read TET_A TET_B + do + if test X"$TET_A" = X"$1" + then + echo "$TET_B" + exit 0 + fi + done + exit 1 + ) < ${TET_DELETES:?} + + return $? +} + + +# ****************************************************************** + +# +# "private" functions for internal use by the shell API +# these are not published interfaces and may go away one day +# + + +# tet_getcode +# look up a result code name in the result code definition file +# return 0 if successful with the result number in TET_RESNUM and TET_ABORT +# set to YES or NO +# otherwise return 1 if the code could not be found +tet_getcode(){ + TET_ABORT=NO + TET_RESNUM=-1 + : ${TET_CODE:?} + + TET_A="${1:?}" + eval "`sed '/^#/d; /^[ ]*$/d' $TET_CODE | while read TET_B + do + eval set -- $TET_B + if test X\"$2\" = X\"$TET_A\" + then + echo TET_RESNUM=\\"$1\\" + echo TET_ABACTION=\\"$3\\" + exit + fi + done`" + unset TET_A + + case "$TET_RESNUM" in + -1) + unset TET_ABACTION + return 1 + ;; + esac + + case "$TET_ABACTION" in + ""|Continue) + TET_ABORT=NO + ;; + Abort) + TET_ABORT=YES + ;; + *) + tet_error "invalid action field \"$TET_ABACTION\" in file" \ + $TET_CODE + TET_ABORT=NO + ;; + esac + + unset TET_ABACTION + return 0 +} + +# tet_undelete - undelete a test purpose +# Note: if your system has a very old version of ed(1) which doesn't +# understand -s, change the invocation to "ed -" +tet_undelete(){ + echo "g/^${1:?} /d +w +q" | ed -s ${TET_DELETES:?} +} + +# tet_error - print an error message to stderr and on TCM Message line +tet_error(){ + echo "$TET_PNAME: $*" 1>&2 + echo "510|${TET_ACTIVITY:-0}|$*" >> ${TET_RESFILE:?} +} + +# tet_output - print a line to the execution results file +tet_output(){ + > ${TET_STDERR:?} + + case $TET_OSNAME in + Windows_*) + TET_DEVNULL=nul + ;; + *) + TET_DEVNULL=/dev/null + ;; + esac + + awk 'END { + if (length(tet_arg2) > 0) + tet_sp = " "; + else + tet_sp = ""; + line = sprintf("%d|%s%s%s|%s", tet_arg1, tet_activity, \ + tet_sp, tet_arg2, tet_arg3); + + # ensure no newline characters in data + nl = sprintf("\n"); + n = split(line, a, nl); + if (n > 1) + { + line = a[1]; + for (i = 2; i <= n; i++) + { + if (a[i] != "") + line = line " " a[i]; + } + } + + # journal lines must not exceed 512 bytes + if (length(line) > 511) + { + printf("warning: results file line truncated: prefix: %d|%s%s%s|\n", tet_arg1, tet_activity, tet_sp, tet_arg2) >tet_stderr; + line = substr(line, 1, 511); + } + + # line is now OK to print + print line; + }' "tet_arg1=${1:?}" "tet_arg2=$2" "tet_arg3=$3" \ + "tet_activity=${TET_ACTIVITY:-0}" \ + "tet_stderr=$TET_STDERR" $TET_DEVNULL >> ${TET_RESFILE:?} + + if test -s $TET_STDERR + then + tet_error "`cat $TET_STDERR`" + fi + > $TET_STDERR +} + @@ -0,0 +1,1042 @@ + +#include "util.h" +#include "foomaticrip.h" +#include <ctype.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <stdarg.h> +#include <assert.h> + + +const char* shellescapes = "|<>&!$\'\"#*?()[]{}"; + +int prefixcmp(const char *str, const char *prefix) +{ + return strncmp(str, prefix, strlen(prefix)); +} + +int prefixcasecmp(const char *str, const char *prefix) +{ + return strncasecmp(str, prefix, strlen(prefix)); +} + +int startswith(const char *str, const char *prefix) +{ + return str ? (strncmp(str, prefix, strlen(prefix)) == 0) : 0; +} + +int endswith(const char *str, const char *postfix) +{ + int slen = strlen(str); + int plen = strlen(postfix); + const char *pstr; + + if (slen < plen) + return 0; + + pstr = &str[slen - plen]; + return strcmp(str, postfix) == 0; +} + +const char * skip_whitespace(const char *str) +{ + while (*str && isspace(*str)) + str++; + return str; +} + +void strlower(char *dest, size_t destlen, const char *src) +{ + char *pdest = dest; + const char *psrc = src; + while (*psrc && --destlen > 0) + { + *pdest = tolower(*psrc); + pdest++; + psrc++; + } + *pdest = '\0'; +} + +int isempty(const char *string) +{ + return string && string[0] == '\0'; +} + +const char * strncpy_omit(char* dest, const char* src, size_t n, int (*omit_func)(int)) +{ + const char* psrc = src; + char* pdest = dest; + int cnt = n -1; + if (!pdest) + return NULL; + if (psrc) { + while (*psrc != 0 && cnt > 0) { + if (!omit_func(*psrc)) { + *pdest = *psrc; + pdest++; + cnt--; + } + psrc++; + } + } + *pdest = '\0'; + return psrc; +} +int omit_unprintables(int c) { return c>= '\x00' && c <= '\x1f'; } +int omit_shellescapes(int c) { return strchr(shellescapes, c) != NULL; } +int omit_specialchars(int c) { return omit_unprintables(c) || omit_shellescapes(c); } +int omit_whitespace(int c) { return c == ' ' || c == '\t'; } + +size_t strlcpy(char *dest, const char *src, size_t size) +{ + char *pdest = dest; + const char *psrc = src; + + if (!src) { + dest[0] = '\0'; + return 0; + } + + if (size) { + while (--size && (*pdest++ = *psrc++) != '\0'); + *pdest = '\0'; + } + if (!size) + while (*psrc++); + return (psrc - src -1); +} + +size_t strlcat(char *dest, const char *src, size_t size) +{ + char *pdest = dest; + const char *psrc = src; + size_t i = size; + size_t len; + + while (--i && *pdest) + pdest++; + len = pdest - dest; + + if (!i) + return strlen(src) + len; + + while (i-- && *psrc) + *pdest++ = *psrc++; + *pdest = '\0'; + + return len + (psrc - src); +} + +void strrepl(char *str, const char *chars, char repl) +{ + char *p = str; + + while (*p) { + if (strchr(chars, *p)) + *p = repl; + p++; + } +} + +void strrepl_nodups(char *str, const char *chars, char repl) +{ + char *pstr = str; + char *p = str; + int prev = 0; + + while (*pstr) { + if (strchr(chars, *pstr) || *pstr == repl) { + if (!prev) { + *p = repl; + p++; + prev = 1; + } + } + else { + *p = *pstr; + p++; + prev = 0; + } + pstr++; + } + *p = '\0'; +} + +void strclr(char *str) +{ + while (*str) { + *str = '\0'; + str++; + } +} + +char * strnchr(const char *str, int c, size_t n) +{ + char *p = (char*)str; + + while (*p && --n > 0) { + if (*p == (char)c) + return p; + p++; + } + return p; +} + +void escapechars(char *dest, size_t size, const char *src, const char *esc_chars) +{ + const char *psrc = src; + + while (*psrc && --size > 0) { + if (strchr(esc_chars, *psrc)) + *dest++ = '\\'; + *dest++ = *psrc++; + } +} + +const char * strncpy_tochar(char *dest, const char *src, size_t max, const char *stopchars) +{ + const char *psrc = src; + char *pdest = dest; + while (*psrc && --max > 0 && !strchr(stopchars, *psrc)) { + *pdest = *psrc; + pdest++; + psrc++; + } + *pdest = '\0'; + return psrc +1; +} + +int find_in_path(const char *progname, const char *paths, char *found_in) +{ + char *pathscopy; + char *path; + char filepath[PATH_MAX]; + + if (access(progname, X_OK) == 0) + return 1; + + pathscopy = strdup(paths); + for (path = strtok(pathscopy, ":"); path; path = strtok(NULL, ":")) { + strlcpy(filepath, path, PATH_MAX); + strlcat(filepath, "/", PATH_MAX); + strlcat(filepath, progname, PATH_MAX); + + if (access(filepath, X_OK) == 0) { + if (found_in) + strlcpy(found_in, path, PATH_MAX); + free(pathscopy); + return 1; + } + } + + if (found_in) + found_in[0] = '\0'; + free(pathscopy); + return 0; +} + +void file_basename(char *dest, const char *path, size_t dest_size) +{ + const char *p = strrchr(path, '/'); + char *pdest = dest; + if (!pdest) + return; + if (p) + p += 1; + else + p = path; + while (*p != 0 && *p != '.' && --dest_size > 0) { + *pdest++ = *p++; + } + *pdest = '\0'; +} + +void make_absolute_path(char *path, int len) +{ + char *tmp, *cwd; + + if (path[0] != '/') { + tmp = malloc(len +1); + strlcpy(tmp, path, len); + + cwd = malloc(len); + getcwd(cwd, len); + strlcpy(path, cwd, len); + strlcat(path, "/", len); + strlcat(path, tmp, len); + + free(tmp); + free(cwd); + } +} + +int is_true_string(const char *str) +{ + return str && (!strcmp(str, "1") || !strcasecmp(str, "Yes") || + !strcasecmp(str, "On") || !strcasecmp(str, "True")); +} + +int is_false_string(const char *str) +{ + return str && (!strcmp(str, "0") || !strcasecmp(str, "No") || + !strcasecmp(str, "Off") || !strcasecmp(str, "False") || + !strcasecmp(str, "None")); +} + +int digit(char c) +{ + if (c >= '0' && c <= '9') + return (int)c - (int)'0'; + return -1; +} + +static const char * next_token(const char *string, const char *separators) +{ + if (!string) + return NULL; + + while (*string && !strchr(separators, *string)) + string++; + + while (*string && strchr(separators, *string)) + string++; + + return string; +} + +static unsigned count_separators(const char *string, const char *separators) +{ + const char *p; + unsigned cnt = 0; + + if (!string) + return 0; + + for (p = string; *p; p = next_token(p, separators)) + cnt++; + + return cnt; +} + +/* + * Returns a zero terminated array of strings + */ +char ** argv_split(const char *string, const char *separators, int *cntp) +{ + unsigned cnt; + int i; + char **argv; + + if (!string) + return NULL; + + if ((cnt = count_separators(string, separators)) == 0) + return NULL; + + argv = malloc((cnt +1) * sizeof(char *)); + argv[cnt] = NULL; + + for (i = 0; i < cnt; i++) + { + size_t len = strcspn(string, separators); + char *s; + s = malloc(len + 1); + strncpy(s, string, len); + s[len] = '\0'; + argv[i] = s; + string = next_token(string, separators); + } + + if (cntp) + *cntp = cnt; + return argv; +} + +size_t argv_count(char **argv) +{ + size_t cnt = 0; + + if (!argv) + return 0; + + while (*argv++) + cnt++; + + return cnt; +} + +void argv_free(char **argv) +{ + char **p; + + if (!argv) + return; + + for (p = argv; *p; p++) + free(*p); + + free(argv); +} + +int line_count(const char *str) +{ + int cnt = 0; + while (*str) { + if (*str == '\n') + cnt++; + str++; + } + return cnt; +} + +int line_start(const char *str, int line_number) +{ + const char *p = str; + while (*p && line_number > 0) { + if (*p == '\n') + line_number--; + p++; + } + return p - str; +} + +void unhexify(char *dest, size_t size, const char *src) +{ + char *pdest = dest; + const char *psrc = src; + char cstr[3]; + + cstr[2] = '\0'; + + while (*psrc && pdest - dest < size -1) { + if (*psrc == '<') { + psrc++; + do { + cstr[0] = *psrc++; + cstr[1] = *psrc++; + if (!isxdigit(cstr[0]) || !isxdigit(cstr[1])) { + printf("Error replacing hex notation in %s!\n", src); + break; + } + *pdest++ = (char)strtol(cstr, NULL, 16); + } while (*psrc != '>'); + psrc++; + } + else + *pdest++ = *psrc++; + } + *pdest = '\0'; +} + +void extract_command(size_t *start, size_t *end, const char *cmdline, const char *cmd) +{ + char *copy = strdup(cmdline); + char *tok = NULL; + const char *delim = "|;"; + + *start = *end = 0; + for (tok = strtok(copy, delim); tok; tok = strtok(NULL, delim)) { + while (*tok && isspace(*tok)) + tok++; + if (startswith(tok, cmd)) { + *start = tok - copy; + *end = tok + strlen(tok) - copy; + break; + } + } + + free(copy); +} + +int contains_command(const char *cmdline, const char *cmd) +{ + size_t start = 0, end = 0; + + extract_command(&start, &end, cmdline, cmd); + if (start == 0 && end == 0) + return 0; + + return 1; +} + +/* + * Dynamic strings + */ +dstr_t * create_dstr() +{ + dstr_t *ds = malloc(sizeof(dstr_t)); + ds->len = 0; + ds->alloc = 32; + ds->data = malloc(ds->alloc); + ds->data[0] = '\0'; + return ds; +} + +void free_dstr(dstr_t *ds) +{ + free(ds->data); + free(ds); +} + +void dstrclear(dstr_t *ds) +{ + ds->len = 0; + ds->data[0] = '\0'; +} + +void dstrassure(dstr_t *ds, size_t alloc) +{ + if (ds->alloc < alloc) { + ds->alloc = alloc; + ds->data = realloc(ds->data, ds->alloc); + } +} + +void dstrcpy(dstr_t *ds, const char *src) +{ + size_t srclen; + + if (!src) { + ds->len = 0; + ds->data[0] = '\0'; + return; + } + + srclen = strlen(src); + + if (srclen >= ds->alloc) { + do { + ds->alloc *= 2; + } while (srclen >= ds->alloc); + ds->data = realloc(ds->data, ds->alloc); + } + + strcpy(ds->data, src); + ds->len = srclen; +} + +void dstrncpy(dstr_t *ds, const char *src, size_t n) +{ + if (n >= ds->alloc) { + do { + ds->alloc *= 2; + } while (n >= ds->alloc); + ds->data = realloc(ds->data, ds->alloc); + } + + strncpy(ds->data, src, n); + ds->len = n; + ds->data[ds->len] = '\0'; +} + +void dstrncat(dstr_t *ds, const char *src, size_t n) +{ + size_t needed = ds->len + n; + + if (needed >= ds->alloc) { + do { + ds->alloc *= 2; + } while (needed >= ds->alloc); + ds->data = realloc(ds->data, ds->alloc); + } + + strncpy(&ds->data[ds->len], src, n); + ds->len = needed; + ds->data[ds->len] = '\0'; +} + +void dstrcpyf(dstr_t *ds, const char *src, ...) +{ + va_list ap; + size_t srclen; + + va_start(ap, src); + srclen = vsnprintf(ds->data, ds->alloc, src, ap); + va_end(ap); + + if (srclen >= ds->alloc) { + do { + ds->alloc *= 2; + } while (srclen >= ds->alloc); + ds->data = realloc(ds->data, ds->alloc); + + va_start(ap, src); + vsnprintf(ds->data, ds->alloc, src, ap); + va_end(ap); + } + + ds->len = srclen; +} + +void dstrputc(dstr_t *ds, int c) +{ + if (ds->len +1 >= ds->alloc) { + ds->alloc *= 2; + ds->data = realloc(ds->data, ds->alloc); + } + ds->data[ds->len++] = c; + ds->data[ds->len] = '\0'; +} + +void dstrcat(dstr_t *ds, const char *src) +{ + size_t srclen = strlen(src); + size_t newlen = ds->len + srclen; + + if (newlen >= ds->alloc) { + do { + ds->alloc *= 2; + } while (newlen >= ds->alloc); + ds->data = realloc(ds->data, ds->alloc); + } + + memcpy(&ds->data[ds->len], src, srclen +1); + ds->len = newlen; +} + +void dstrcatf(dstr_t *ds, const char *src, ...) +{ + va_list ap; + size_t restlen = ds->alloc - ds->len; + size_t srclen; + + va_start(ap, src); + srclen = vsnprintf(&ds->data[ds->len], restlen, src, ap); + va_end(ap); + + if (srclen >= restlen) { + do { + ds->alloc *= 2; + restlen = ds->alloc - ds->len; + } while (srclen >= restlen); + ds->data = realloc(ds->data, ds->alloc); + + va_start(ap, src); + srclen = vsnprintf(&ds->data[ds->len], restlen, src, ap); + va_end(ap); + } + + ds->len += srclen; +} + +size_t fgetdstr(dstr_t *ds, FILE *stream) +{ + int c; + size_t cnt = 0; + + ds->len = 0; + if (ds->alloc == 0) { + ds->alloc = 256; + ds->data = malloc(ds->alloc); + } + + while ((c = fgetc(stream)) != EOF) { + if (ds->len +1 == ds->alloc) { + ds->alloc *= 2; + ds->data = realloc(ds->data, ds->alloc); + } + ds->data[ds->len++] = (char)c; + cnt ++; + if (c == '\n') + break; + } + ds->data[ds->len] = '\0'; + return cnt; +} + +/* + * Replace the first occurrence of 'find' after the index 'start' with 'repl' + * Returns the position right after the replaced string + */ +int dstrreplace(dstr_t *ds, const char *find, const char *repl, int start) +{ + char *p; + dstr_t *copy = create_dstr(); + int end = -1; + + dstrcpy(copy, ds->data); + + if ((p = strstr(©->data[start], find))) + { + dstrncpy(ds, copy->data, p - copy->data); + dstrcatf(ds, "%s", repl); + end = ds->len; + dstrcatf(ds, "%s", p + strlen(find)); + } + + free_dstr(copy); + return end; +} + +void dstrprepend(dstr_t *ds, const char *str) +{ + dstr_t *copy = create_dstr(); + dstrcpy(copy, ds->data); + dstrcpy(ds, str); + dstrcatf(ds, "%s", copy->data); + free_dstr(copy); +} + +void dstrinsert(dstr_t *ds, int idx, const char *str) +{ + char * copy = strdup(ds->data); + size_t len = strlen(str); + + if (idx >= ds->len) + idx = ds->len; + else if (idx < 0) + idx = 0; + + if (ds->len + len >= ds->alloc) { + do { + ds->alloc *= 2; + } while (ds->len + len >= ds->alloc); + free(ds->data); + ds->data = malloc(ds->alloc); + } + + strncpy(ds->data, copy, idx); + ds->data[idx] = '\0'; + strcat(ds->data, str); + strcat(ds->data, ©[idx]); + ds->len += len; + free(copy); +} + +void dstrinsertf(dstr_t *ds, int idx, const char *str, ...) +{ + va_list ap; + char *strf; + size_t len; + + va_start(ap, str); + len = vsnprintf(NULL, 0, str, ap); + va_end(ap); + + strf = malloc(len +1); + va_start(ap, str); + vsnprintf(strf, len +1, str, ap); + va_end(ap); + + dstrinsert(ds, idx, strf); + + free(strf); +} + +void dstrremove(dstr_t *ds, int idx, size_t count) +{ + char *p1, *p2; + + if (idx + count >= ds->len) + return; + + p1 = &ds->data[idx]; + p2 = &ds->data[idx + count]; + + while (*p2) { + *p1 = *p2; + p1++; + p2++; + } + *p1 = '\0'; +} + +static inline int isnewline(int c) +{ + return c == '\n' || c == '\r'; +} + +void dstrcatline(dstr_t *ds, const char *str) +{ + size_t eol = strcspn(str, "\n\r"); + if (isnewline(str[eol])) + eol++; + dstrncat(ds, str, eol); +} + +int dstrendswith(dstr_t *ds, const char *str) +{ + int len = strlen(str); + char *pstr; + + if (ds->len < len) + return 0; + pstr = &ds->data[ds->len - len]; + return strcmp(pstr, str) == 0; + +} + +void dstrfixnewlines(dstr_t *ds) +{ + if (ds->data[ds->len -1] == '\r') { + ds->data[ds->len -1] = '\n'; + } + else if (ds->data[ds->len -2] == '\r') { + ds->data[ds->len -1] = '\n'; + ds->data[ds->len -2] = '\0'; + ds->len -= 1; + } +} + +void dstrremovenewline(dstr_t *ds) +{ + if (!ds->len) + return; + + if (ds->data[ds->len -1] == '\r' || ds->data[ds->len -1] == '\n') { + ds->data[ds->len -1] = '\0'; + ds->len -= 1; + } + + if (ds->len < 2) + return; + + if (ds->data[ds->len -2] == '\r') { + ds->data[ds->len -2] = '\0'; + ds->len -= 2; + } +} + +void dstrtrim(dstr_t *ds) +{ + int pos = 0; + + while (pos < ds->len && isspace(ds->data[pos])) + pos++; + + if (pos > 0) { + ds->len -= pos; + memmove(ds->data, &ds->data[pos], ds->len +1); + } +} + +void dstrtrim_right(dstr_t *ds) +{ + if (!ds->len) + return; + + while (isspace(ds->data[ds->len -1])) + ds->len -= 1; + ds->data[ds->len] = '\0'; +} + + + +/* + * LIST + */ + +list_t * list_create() +{ + list_t *l = malloc(sizeof(list_t)); + l->first = NULL; + l->last = NULL; + return l; +} + +list_t * list_create_from_array(int count, void ** data) +{ + int i; + list_t *l = list_create(); + + for (i = 0; i < count; i++) + list_append(l, data[i]); + + return l; +} + +void list_free(list_t *list) +{ + listitem_t *i = list->first, *tmp; + while (i) { + tmp = i->next; + free(i); + i = tmp; + } +} + +size_t list_item_count(list_t *list) +{ + size_t cnt = 0; + listitem_t *i; + for (i = list->first; i; i = i->next) + cnt++; + return cnt; +} + +list_t * list_copy(list_t *list) +{ + list_t *l = list_create(); + listitem_t *i; + + for (i = list->first; i; i = i->next) + list_append(l, i->data); + return l; +} + +void list_prepend(list_t *list, void *data) +{ + listitem_t *item; + + assert(list); + + item = malloc(sizeof(listitem_t)); + item->data = data; + item->prev = NULL; + + if (list->first) { + item->next = list->first; + list->first->next = item; + list->first = item; + } + else { + item->next = NULL; + list->first = item; + list->last = item; + } +} + +void list_append(list_t *list, void *data) +{ + listitem_t *item; + + assert(list); + + item = malloc(sizeof(listitem_t)); + item->data = data; + item->next = NULL; + + if (list->last) { + item->prev = list->last; + list->last->next = item; + list->last = item; + } + else { + item->prev = NULL; + list->first = item; + list->last = item; + } +} + +void list_remove(list_t *list, listitem_t *item) +{ + assert(item); + + if (item->prev) + item->prev->next = item->next; + if (item->next) + item->next->prev = item->prev; + if (item == list->first) + list->first = item->next; + if (item == list->last) + list->last = item->prev; + + free(item); +} + +listitem_t * list_get(list_t *list, int idx) +{ + listitem_t *i; + for (i = list->first; i && idx; i = i->next) + idx--; + return i; +} + +listitem_t * arglist_find(list_t *list, const char *name) +{ + listitem_t *i; + for (i = list->first; i; i = i->next) { + if (!strcmp((const char*)i->data, name)) + return i; + } + return NULL; +} + +listitem_t * arglist_find_prefix(list_t *list, const char *name) +{ + listitem_t *i; + for (i = list->first; i; i= i->next) { + if (!prefixcmp((const char*)i->data, name)) + return i; + } + return NULL; +} + + +char * arglist_get_value(list_t *list, const char *name) +{ + listitem_t *i; + char *p; + + for (i = list->first; i; i = i->next) { + if (i->next && !strcmp(name, (char*)i->data)) + return (char*)i->next->data; + else if (!prefixcmp((char*)i->data, name)) { + p = &((char*)i->data)[strlen(name)]; + return *p == '=' ? p +1 : p; + } + } + return NULL; +} + +char * arglist_get(list_t *list, int idx) +{ + listitem_t *i = list_get(list, idx); + return i ? (char*)i->data : NULL; +} + +int arglist_remove(list_t *list, const char *name) +{ + listitem_t *i; + char *i_name; + + for (i = list->first; i; i = i->next) { + i_name = (char*)i->data; + if (i->next && !strcmp(name, i_name)) { + list_remove(list, i->next); + list_remove(list, i); + return 1; + } + else if (!prefixcmp(i_name, name)) { + list_remove(list, i); + return 1; + } + } + return 0; +} + +int arglist_remove_flag(list_t *list, const char *name) +{ + listitem_t *i = arglist_find(list, name); + if (i) { + list_remove(list, i); + return 1; + } + return 0; +} + +int copy_file(FILE *dest, + FILE *src, + const char *alreadyread, + size_t alreadyread_len) +{ + char buf[8192]; + size_t bytes; + + if (alreadyread && alreadyread_len) + { + if (fwrite(alreadyread, 1, alreadyread_len, dest) < alreadyread_len) + { + _log("Could not write to temp file\n"); + return 0; + } + } + + while ((bytes = fread(buf, 1, 8192, src))) + fwrite(buf, 1, bytes, dest); + + return !ferror(src) && !ferror(dest); +} + @@ -0,0 +1,177 @@ + +#ifndef util_h +#define util_h + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include <string.h> +#include <stdio.h> + + +extern const char* shellescapes; + +int isempty(const char *string); +int prefixcmp(const char *str, const char *prefix); +int prefixcasecmp(const char *str, const char *prefix); + +int startswith(const char *str, const char *prefix); +int endswith(const char *str, const char *postfix); + +const char * skip_whitespace(const char *str); + +void strlower(char *dest, size_t destlen, const char *src); + +/* + * Like strncpy, but omits characters for which omit_func returns true + * It also assures that dest is zero terminated. + * Returns a pointer to the position in 'src' right after the last byte that has been copied. + */ +const char * strncpy_omit(char* dest, const char* src, size_t n, int (*omit_func)(int)); + +int omit_unprintables(int c); +int omit_shellescapes(int c); +int omit_specialchars(int c); +int omit_whitespace(int c); + +/* TODO check for platforms which already have strlcpy and strlcat */ + +/* Copy at most size-1 characters from src to dest + dest will always be \0 terminated (unless size == 0) + returns strlen(src) */ +size_t strlcpy(char *dest, const char *src, size_t size); +size_t strlcat(char *dest, const char *src, size_t size); + +/* Replace all occurences of each of the characters in 'chars' by 'repl' */ +void strrepl(char *str, const char *chars, char repl); + +/* Replace all occurences of each of the characters in 'chars' by 'repl', + but do not allow consecutive 'repl' chars */ +void strrepl_nodups(char *str, const char *chars, char repl); + +/* clears 'str' with \0s */ +void strclr(char *str); + +char * strnchr(const char *str, int c, size_t n); + +void escapechars(char *dest, size_t size, const char *src, const char *esc_chars); + +/* copies characters from 'src' to 'dest', until 'src' contains a character from 'stopchars' + will not copy more than 'max' chars + dest will be zero terminated in either case + returns a pointer to the position right after the last byte that has been copied +*/ +const char * strncpy_tochar(char *dest, const char *src, size_t max, const char *stopchars); + +/* 'paths' is a colon seperated list of paths (like $PATH) + * 'found_in' may be NULL if it is not needed */ +int find_in_path(const char *progname, const char *paths, char *found_in); + +/* extracts the base name of 'path', i.e. only the filename, without path or extension */ +void file_basename(char *dest, const char *path, size_t dest_size); + +/* if 'path' is relative, prepend cwd */ +void make_absolute_path(char *path, int len); + +int is_true_string(const char *str); /* "1", "Yes", "On", "True" */ +int is_false_string(const char *str); /* "0", "No", "Off", "False", "None" */ + +int digit(char c); /* returns 0-9 if c is a digit, otherwise -1 */ + +int line_count(const char *str); + +/* returns the index of the beginning of the line_number'th line in str */ +int line_start(const char *str, int line_number); + +/* Replace hex notation for unprintable characters in PPD files + by the actual characters ex: "<0A>" --> chr(hex("0A")) */ +void unhexify(char *dest, size_t size, const char *src); + +void extract_command(size_t *start, size_t *end, const char *cmdline, const char *cmd); + +char ** argv_split(const char *string, const char *separators, int *cntp); +size_t argv_count(char **argv); +void argv_free(char **argv); + +/* + * Returns non-zero if 'cmdline' calls 'cmd' in some way + */ +int contains_command(const char *cmdline, const char *cmd); + +int copy_file(FILE *dest, FILE *src, const char *alreadyread, size_t alreadyread_len); + +/* Dynamic string */ +typedef struct dstr { + char *data; + size_t len; + size_t alloc; +} dstr_t; + +dstr_t * create_dstr(); +void free_dstr(dstr_t *ds); +void dstrclear(dstr_t *ds); +void dstrassure(dstr_t *ds, size_t alloc); +void dstrcpy(dstr_t *ds, const char *src); +void dstrncpy(dstr_t *ds, const char *src, size_t n); +void dstrncat(dstr_t *ds, const char *src, size_t n); +void dstrcpyf(dstr_t *ds, const char *src, ...); +void dstrcat(dstr_t *ds, const char *src); +void dstrcatf(dstr_t *ds, const char *src, ...); +void dstrputc(dstr_t *ds, int c); +size_t fgetdstr(dstr_t *ds, FILE *stream); /* returns number of characters read */ +int dstrreplace(dstr_t *ds, const char *find, const char *repl, int start); +void dstrprepend(dstr_t *ds, const char *str); +void dstrinsert(dstr_t *ds, int idx, const char *str); +void dstrinsertf(dstr_t *ds, int idx, const char *str, ...); +void dstrremove(dstr_t *ds, int idx, size_t count); +void dstrcatline(dstr_t *ds, const char *str); /* appends the first line from str to ds (incl. \n) */ + +int dstrendswith(dstr_t *ds, const char *str); +void dstrfixnewlines(dstr_t *ds); +void dstrremovenewline(dstr_t *ds); +void dstrtrim(dstr_t *ds); +void dstrtrim_right(dstr_t *ds); + + +/* Doubly linked list of void pointers */ +typedef struct listitem_s { + void *data; + struct listitem_s *prev, *next; +} listitem_t; + +typedef struct { + listitem_t *first, *last; +} list_t; + +list_t * list_create(); +list_t * list_create_from_array(int count, void ** data); /* array values are NOT copied */ +void list_free(list_t *list); + +size_t list_item_count(list_t *list); + +list_t * list_copy(list_t *list); + +void list_prepend(list_t *list, void *data); +void list_append(list_t *list, void *data); +void list_remove(list_t *list, listitem_t *item); + +listitem_t * list_get(list_t *list, int idx); + + +/* Argument values may be seperated from their keys in the following ways: + - with whitespace (i.e. it is in the next list entry) + - with a '=' + - not at all +*/ +listitem_t * arglist_find(list_t *list, const char *name); +listitem_t * arglist_find_prefix(list_t *list, const char *name); + +char * arglist_get_value(list_t *list, const char *name); +char * arglist_get(list_t *list, int idx); + +int arglist_remove(list_t *list, const char *name); +int arglist_remove_flag(list_t *list, const char *name); + +#endif + |