foomatic-filters-4.0.17/0000755000175100017510000000000011774332511013552 5ustar tilltillfoomatic-filters-4.0.17/spooler.h0000644000175100017510000000244411774332506015416 0ustar tilltill/* spooler.h * * Copyright (C) 2008 Till Kamppeter * Copyright (C) 2008 Lars Uebernickel * * This file is part of foomatic-rip. * * Foomatic-rip 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. * * Foomatic-rip 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 Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #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 foomatic-filters-4.0.17/colord.h0000644000175100017510000000173311774332506015215 0ustar tilltill/* colord.h * * Copyright (C) 2011 Richard Hughes * * This file is part of foomatic-rip. * * Foomatic-rip 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. * * Foomatic-rip 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 Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ char *colord_get_profile_for_device_id (const char *device_id, const char **qualifier_tuple); foomatic-filters-4.0.17/fileconverter.c0000644000175100017510000002031311774332506016570 0ustar tilltill/* fileconverter.c * * Copyright (C) 2008 Till Kamppeter * Copyright (C) 2008 Lars Uebernickel * * This file is part of foomatic-rip. * * Foomatic-rip 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. * * Foomatic-rip 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 Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include #include #include #include #include #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); break; } } 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; } foomatic-filters-4.0.17/Makefile.in0000644000175100017510000012445311774332511015630 0ustar tilltill# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ 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) @BUILD_DBUS_TRUE@am__append_1 = \ @BUILD_DBUS_TRUE@ colord.c \ @BUILD_DBUS_TRUE@ colord.h 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 compile 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 config.status.lineno mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = beh foomatic-rip.1 CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am__foomatic_rip_SOURCES_DIST = 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 colord.c colord.h @BUILD_DBUS_TRUE@am__objects_1 = foomatic_rip-colord.$(OBJEXT) am_foomatic_rip_OBJECTS = foomatic_rip-foomaticrip.$(OBJEXT) \ foomatic_rip-options.$(OBJEXT) foomatic_rip-pdf.$(OBJEXT) \ foomatic_rip-postscript.$(OBJEXT) foomatic_rip-util.$(OBJEXT) \ foomatic_rip-spooler.$(OBJEXT) foomatic_rip-process.$(OBJEXT) \ foomatic_rip-renderer.$(OBJEXT) \ foomatic_rip-fileconverter.$(OBJEXT) $(am__objects_1) foomatic_rip_OBJECTS = $(am_foomatic_rip_OBJECTS) am__DEPENDENCIES_1 = @BUILD_DBUS_TRUE@foomatic_rip_DEPENDENCIES = $(am__DEPENDENCIES_1) foomatic_rip_LINK = $(CCLD) $(foomatic_rip_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f 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 = $(am__foomatic_rip_SOURCES_DIST) 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 A2PS = @A2PS@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ # Paths for CUPS CUPS = @CUPS@ CUPS_BACKENDS = @CUPS_BACKENDS@ CUPS_CONFIG = @CUPS_CONFIG@ CUPS_FILTERS = @CUPS_FILTERS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ 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 = @INSTALL@ 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@ MKDIR_P = @MKDIR_P@ MPAGE = @MPAGE@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ POW_LIB = @POW_LIB@ # 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@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ 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@ builddir = @builddir@ 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@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ 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__append_1) @BUILD_DBUS_TRUE@foomatic_rip_CFLAGS = $(DBUS_CFLAGS) -DHAVE_DBUS @BUILD_DBUS_TRUE@foomatic_rip_LDADD = $(DBUS_LIBS) 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'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__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) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) $(AM_MAKEFLAGS) 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) ($(am__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)'; test -n "$(bindir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) foomatic-rip$(EXEEXT): $(foomatic_rip_OBJECTS) $(foomatic_rip_DEPENDENCIES) @rm -f foomatic-rip$(EXEEXT) $(foomatic_rip_LINK) $(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)/foomatic_rip-colord.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foomatic_rip-fileconverter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foomatic_rip-foomaticrip.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foomatic_rip-options.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foomatic_rip-pdf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foomatic_rip-postscript.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foomatic_rip-process.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foomatic_rip-renderer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foomatic_rip-spooler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foomatic_rip-util.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @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@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @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) '$<'` foomatic_rip-foomaticrip.o: foomaticrip.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-foomaticrip.o -MD -MP -MF $(DEPDIR)/foomatic_rip-foomaticrip.Tpo -c -o foomatic_rip-foomaticrip.o `test -f 'foomaticrip.c' || echo '$(srcdir)/'`foomaticrip.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-foomaticrip.Tpo $(DEPDIR)/foomatic_rip-foomaticrip.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='foomaticrip.c' object='foomatic_rip-foomaticrip.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-foomaticrip.o `test -f 'foomaticrip.c' || echo '$(srcdir)/'`foomaticrip.c foomatic_rip-foomaticrip.obj: foomaticrip.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-foomaticrip.obj -MD -MP -MF $(DEPDIR)/foomatic_rip-foomaticrip.Tpo -c -o foomatic_rip-foomaticrip.obj `if test -f 'foomaticrip.c'; then $(CYGPATH_W) 'foomaticrip.c'; else $(CYGPATH_W) '$(srcdir)/foomaticrip.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-foomaticrip.Tpo $(DEPDIR)/foomatic_rip-foomaticrip.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='foomaticrip.c' object='foomatic_rip-foomaticrip.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-foomaticrip.obj `if test -f 'foomaticrip.c'; then $(CYGPATH_W) 'foomaticrip.c'; else $(CYGPATH_W) '$(srcdir)/foomaticrip.c'; fi` foomatic_rip-options.o: options.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-options.o -MD -MP -MF $(DEPDIR)/foomatic_rip-options.Tpo -c -o foomatic_rip-options.o `test -f 'options.c' || echo '$(srcdir)/'`options.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-options.Tpo $(DEPDIR)/foomatic_rip-options.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='options.c' object='foomatic_rip-options.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-options.o `test -f 'options.c' || echo '$(srcdir)/'`options.c foomatic_rip-options.obj: options.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-options.obj -MD -MP -MF $(DEPDIR)/foomatic_rip-options.Tpo -c -o foomatic_rip-options.obj `if test -f 'options.c'; then $(CYGPATH_W) 'options.c'; else $(CYGPATH_W) '$(srcdir)/options.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-options.Tpo $(DEPDIR)/foomatic_rip-options.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='options.c' object='foomatic_rip-options.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-options.obj `if test -f 'options.c'; then $(CYGPATH_W) 'options.c'; else $(CYGPATH_W) '$(srcdir)/options.c'; fi` foomatic_rip-pdf.o: pdf.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-pdf.o -MD -MP -MF $(DEPDIR)/foomatic_rip-pdf.Tpo -c -o foomatic_rip-pdf.o `test -f 'pdf.c' || echo '$(srcdir)/'`pdf.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-pdf.Tpo $(DEPDIR)/foomatic_rip-pdf.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdf.c' object='foomatic_rip-pdf.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-pdf.o `test -f 'pdf.c' || echo '$(srcdir)/'`pdf.c foomatic_rip-pdf.obj: pdf.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-pdf.obj -MD -MP -MF $(DEPDIR)/foomatic_rip-pdf.Tpo -c -o foomatic_rip-pdf.obj `if test -f 'pdf.c'; then $(CYGPATH_W) 'pdf.c'; else $(CYGPATH_W) '$(srcdir)/pdf.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-pdf.Tpo $(DEPDIR)/foomatic_rip-pdf.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdf.c' object='foomatic_rip-pdf.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-pdf.obj `if test -f 'pdf.c'; then $(CYGPATH_W) 'pdf.c'; else $(CYGPATH_W) '$(srcdir)/pdf.c'; fi` foomatic_rip-postscript.o: postscript.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-postscript.o -MD -MP -MF $(DEPDIR)/foomatic_rip-postscript.Tpo -c -o foomatic_rip-postscript.o `test -f 'postscript.c' || echo '$(srcdir)/'`postscript.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-postscript.Tpo $(DEPDIR)/foomatic_rip-postscript.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='postscript.c' object='foomatic_rip-postscript.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-postscript.o `test -f 'postscript.c' || echo '$(srcdir)/'`postscript.c foomatic_rip-postscript.obj: postscript.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-postscript.obj -MD -MP -MF $(DEPDIR)/foomatic_rip-postscript.Tpo -c -o foomatic_rip-postscript.obj `if test -f 'postscript.c'; then $(CYGPATH_W) 'postscript.c'; else $(CYGPATH_W) '$(srcdir)/postscript.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-postscript.Tpo $(DEPDIR)/foomatic_rip-postscript.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='postscript.c' object='foomatic_rip-postscript.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-postscript.obj `if test -f 'postscript.c'; then $(CYGPATH_W) 'postscript.c'; else $(CYGPATH_W) '$(srcdir)/postscript.c'; fi` foomatic_rip-util.o: util.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-util.o -MD -MP -MF $(DEPDIR)/foomatic_rip-util.Tpo -c -o foomatic_rip-util.o `test -f 'util.c' || echo '$(srcdir)/'`util.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-util.Tpo $(DEPDIR)/foomatic_rip-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='util.c' object='foomatic_rip-util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-util.o `test -f 'util.c' || echo '$(srcdir)/'`util.c foomatic_rip-util.obj: util.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-util.obj -MD -MP -MF $(DEPDIR)/foomatic_rip-util.Tpo -c -o foomatic_rip-util.obj `if test -f 'util.c'; then $(CYGPATH_W) 'util.c'; else $(CYGPATH_W) '$(srcdir)/util.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-util.Tpo $(DEPDIR)/foomatic_rip-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='util.c' object='foomatic_rip-util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-util.obj `if test -f 'util.c'; then $(CYGPATH_W) 'util.c'; else $(CYGPATH_W) '$(srcdir)/util.c'; fi` foomatic_rip-spooler.o: spooler.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-spooler.o -MD -MP -MF $(DEPDIR)/foomatic_rip-spooler.Tpo -c -o foomatic_rip-spooler.o `test -f 'spooler.c' || echo '$(srcdir)/'`spooler.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-spooler.Tpo $(DEPDIR)/foomatic_rip-spooler.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='spooler.c' object='foomatic_rip-spooler.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-spooler.o `test -f 'spooler.c' || echo '$(srcdir)/'`spooler.c foomatic_rip-spooler.obj: spooler.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-spooler.obj -MD -MP -MF $(DEPDIR)/foomatic_rip-spooler.Tpo -c -o foomatic_rip-spooler.obj `if test -f 'spooler.c'; then $(CYGPATH_W) 'spooler.c'; else $(CYGPATH_W) '$(srcdir)/spooler.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-spooler.Tpo $(DEPDIR)/foomatic_rip-spooler.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='spooler.c' object='foomatic_rip-spooler.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-spooler.obj `if test -f 'spooler.c'; then $(CYGPATH_W) 'spooler.c'; else $(CYGPATH_W) '$(srcdir)/spooler.c'; fi` foomatic_rip-process.o: process.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-process.o -MD -MP -MF $(DEPDIR)/foomatic_rip-process.Tpo -c -o foomatic_rip-process.o `test -f 'process.c' || echo '$(srcdir)/'`process.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-process.Tpo $(DEPDIR)/foomatic_rip-process.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='process.c' object='foomatic_rip-process.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-process.o `test -f 'process.c' || echo '$(srcdir)/'`process.c foomatic_rip-process.obj: process.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-process.obj -MD -MP -MF $(DEPDIR)/foomatic_rip-process.Tpo -c -o foomatic_rip-process.obj `if test -f 'process.c'; then $(CYGPATH_W) 'process.c'; else $(CYGPATH_W) '$(srcdir)/process.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-process.Tpo $(DEPDIR)/foomatic_rip-process.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='process.c' object='foomatic_rip-process.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-process.obj `if test -f 'process.c'; then $(CYGPATH_W) 'process.c'; else $(CYGPATH_W) '$(srcdir)/process.c'; fi` foomatic_rip-renderer.o: renderer.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-renderer.o -MD -MP -MF $(DEPDIR)/foomatic_rip-renderer.Tpo -c -o foomatic_rip-renderer.o `test -f 'renderer.c' || echo '$(srcdir)/'`renderer.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-renderer.Tpo $(DEPDIR)/foomatic_rip-renderer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='renderer.c' object='foomatic_rip-renderer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-renderer.o `test -f 'renderer.c' || echo '$(srcdir)/'`renderer.c foomatic_rip-renderer.obj: renderer.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-renderer.obj -MD -MP -MF $(DEPDIR)/foomatic_rip-renderer.Tpo -c -o foomatic_rip-renderer.obj `if test -f 'renderer.c'; then $(CYGPATH_W) 'renderer.c'; else $(CYGPATH_W) '$(srcdir)/renderer.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-renderer.Tpo $(DEPDIR)/foomatic_rip-renderer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='renderer.c' object='foomatic_rip-renderer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-renderer.obj `if test -f 'renderer.c'; then $(CYGPATH_W) 'renderer.c'; else $(CYGPATH_W) '$(srcdir)/renderer.c'; fi` foomatic_rip-fileconverter.o: fileconverter.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-fileconverter.o -MD -MP -MF $(DEPDIR)/foomatic_rip-fileconverter.Tpo -c -o foomatic_rip-fileconverter.o `test -f 'fileconverter.c' || echo '$(srcdir)/'`fileconverter.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-fileconverter.Tpo $(DEPDIR)/foomatic_rip-fileconverter.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fileconverter.c' object='foomatic_rip-fileconverter.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-fileconverter.o `test -f 'fileconverter.c' || echo '$(srcdir)/'`fileconverter.c foomatic_rip-fileconverter.obj: fileconverter.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-fileconverter.obj -MD -MP -MF $(DEPDIR)/foomatic_rip-fileconverter.Tpo -c -o foomatic_rip-fileconverter.obj `if test -f 'fileconverter.c'; then $(CYGPATH_W) 'fileconverter.c'; else $(CYGPATH_W) '$(srcdir)/fileconverter.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-fileconverter.Tpo $(DEPDIR)/foomatic_rip-fileconverter.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fileconverter.c' object='foomatic_rip-fileconverter.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-fileconverter.obj `if test -f 'fileconverter.c'; then $(CYGPATH_W) 'fileconverter.c'; else $(CYGPATH_W) '$(srcdir)/fileconverter.c'; fi` foomatic_rip-colord.o: colord.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-colord.o -MD -MP -MF $(DEPDIR)/foomatic_rip-colord.Tpo -c -o foomatic_rip-colord.o `test -f 'colord.c' || echo '$(srcdir)/'`colord.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-colord.Tpo $(DEPDIR)/foomatic_rip-colord.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='colord.c' object='foomatic_rip-colord.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-colord.o `test -f 'colord.c' || echo '$(srcdir)/'`colord.c foomatic_rip-colord.obj: colord.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-colord.obj -MD -MP -MF $(DEPDIR)/foomatic_rip-colord.Tpo -c -o foomatic_rip-colord.obj `if test -f 'colord.c'; then $(CYGPATH_W) 'colord.c'; else $(CYGPATH_W) '$(srcdir)/colord.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/foomatic_rip-colord.Tpo $(DEPDIR)/foomatic_rip-colord.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='colord.c' object='foomatic_rip-colord.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-colord.obj `if test -f 'colord.c'; then $(CYGPATH_W) 'colord.c'; else $(CYGPATH_W) '$(srcdir)/colord.c'; fi` 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; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ 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; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) 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; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -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 $(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-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz $(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) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(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) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__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 \ && cd "$$am__cwd" \ || exit 1 $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @$(am__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 install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am 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: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) 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 distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-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 .MAKE: all install-am install-strip .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-lzma dist-shar dist-tarZ dist-xz 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-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am 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 # 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 # 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: foomatic-filters-4.0.17/process.h0000644000175100017510000000313111774332506015403 0ustar tilltill/* process.h * * Copyright (C) 2008 Till Kamppeter * Copyright (C) 2008 Lars Uebernickel * * This file is part of foomatic-rip. * * Foomatic-rip 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. * * Foomatic-rip 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 Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef process_h #define process_h #include #include #include 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 foomatic-filters-4.0.17/pdf.h0000644000175100017510000000203011774332506014473 0ustar tilltill/* pdf.h * * Copyright (C) 2008 Till Kamppeter * Copyright (C) 2008 Lars Uebernickel * * This file is part of foomatic-rip. * * Foomatic-rip 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. * * Foomatic-rip 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 Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef pdf_h #define pdf_h int print_pdf(FILE *s, const char *alreadyread, size_t len, const char *filename, int startpos); #endif foomatic-filters-4.0.17/mkinstalldirs0000755000175100017510000000123711774332506016367 0ustar tilltill#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain # $Id$ errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here foomatic-filters-4.0.17/missing0000755000175100017510000002623311774332511015157 0ustar tilltill#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2009-04-28.21; # UTC # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, # 2008, 2009 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 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, see . # 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=: sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' sed_minuso='s/.* -o \([^ ]*\).*/\1/p' # 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' autom4te touch the output file, or create a stub one 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] Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and \`g' are ignored when checking the name. Send bug reports to ." 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 # normalize program name to check for. program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` # 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). This is about non-GNU programs, so use $1 not # $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 $program 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 "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` 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 test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.h fi ;; esac fi if test ! -f y.tab.h; then echo >y.tab.h fi if test ! -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 test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if test ! -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 "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit $? 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 "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` 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-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: foomatic-filters-4.0.17/filter.conf0000644000175100017510000000274411774332506015721 0ustar tilltill# This file allows you to configure the "foomatic-rip" filter. # Uncomment the lines where you want to do a change and enter the # desired value. # Enter here your personal command for converting non-PostScript files # (especially text) to PostScript. Supported commands are "a2ps", # "enscript" or "mpage". Command line options will be automatically # set by "foomatic-rip". # textfilter: a2ps # Set debug to 1 to enable the debug logfile for "foomatic-rip"; it # will appear as /tmp/foomatic-rip.log It will contain status info of # the filtering process and the renderer's (usually GhostScript's) # stderr output. # WARNING: This logfile is a security hole; do not use in production. # debug: 0 ### CUPS only: # Set to 0 to suppress inserting postscript code for accounting. # ps_accounting: 1 ### General Configuration # Set echo to the path to an echo program that uses echo -n # echo: /bin/echo # set gspath to the GhostScript to be used by foomatic # gspath: gs # Set the PATH value to be used by foomatic-rip: # execpath: /usr/local/bin:/usr/bin:/bin # Set the directories in which foomatic-rip should search for CUPS filters: # cupsfilterpath: /usr/local/lib/cups/filter:/usr/local/lib/cups/filter:/usr/local/libexec/cups/filter:/opt/cups/filter:/usr/lib/cups/filter # Set the preferred shell to use when executing FoomaticRIPCommandLine and # friends. Several PPD files use shell constructs that require a more # modern shell like bash, zsh, or ksh. # preferred_shell: /bin/bash foomatic-filters-4.0.17/fileconverter.h0000644000175100017510000000226711774332506016605 0ustar tilltill/* fileconverter.h * * Copyright (C) 2008 Till Kamppeter * Copyright (C) 2008 Lars Uebernickel * * This file is part of foomatic-rip. * * Foomatic-rip 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. * * Foomatic-rip 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 Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef fileconverter_h #define fileconverter_h #include 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 foomatic-filters-4.0.17/USAGE0000644000175100017510000003074311774332506014354 0ustar tilltill Foomatic 4.0.17 =============== foomatic-filters ---------------- Filter scripts used by the printer spoolers to convert the incoming PostScript data into the printer's native format using a printer/driver specific, but spooler-independent PPD file. Till Kamppeter Lars Uebernickel http://www.openprinting.org/ This usage documentation file is written by Till Kamppeter Intro ----- Foomatic is a database providing information about the usage of 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 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 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/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 example requires editing of configuration files for adding a queue, whereas CUPS and PPR have specialized command line utilities. Foomatic puts a layer between the applications and the spoolers so that one has a common, spooler-independent command line interface for all spoolers, so that switching of spoolers or administration of a network with different spoolers gets much easier, because for the same operations there are the same commands, independent of the spooler. This command line interface can also be used as a base for spooler-independent graphical frontends. Installation ------------ Foomatic runs on all systems where one can run the Perl interpreter and Ghostscript. foomatic-filters needs the Perl interpreter for beh (Backend Error Handler) and the test suite. To build foomatic-rip you need a C compiler and its standard libraries. 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 http://www.openprinting.org/download/printing/ netcat: http://freshmeat.net/projects/netcat/ This package does not require any other Foomatic package. it can be 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, 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 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 directories listed under "Search path:" in the end of the "gs -h" output. Copy the ".upp" file to one of these directories when it was 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 " 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 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 make install "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 programs have to be installed and where the Perl interpreter is 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-rip), to get it into subdirectories of /usr (/usr/bin/foomatic-rip), enter: ./configure --prefix=/usr --sysconfdir=/etc make make install There are other things which can be adjusted by options on the "configure" command line, enter "./configure --help" for more info. You can also modify variables in the beginning of the "Makefile" after running "configure", but note that every run of "configure" re-creates the "Makefile". You can also run Foomatic out of its source directory (for example when you want to try it out, or when you don't have root access). Therefore enter (can be done as a normal user): ./configure make inplace 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, 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, 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://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 photo memory card access on all devices. It also adds maintenance functionality for inkjets, reporting of ink or toner levels and printer status, and also remote readout of the printers front-panel LCD. CUPS is required as the printing system when HPLIP is used. Note: The "hp" CUPS backend and "beh" (see below) cannot be used together. Setting up printers ------------------- If you have "foomatic-db-engine" installed, see the USAGE file there. If not, see, depending on your spooler: CUPS: http://www.openprinting.org/cups-doc.html LPD, LPRng, GNUlpr: http://www.openprinting.org/lpd-doc.html PPR: http://www.openprinting.org/ppr-doc.html PDQ: http://www.openprinting.org/pdq-doc.html CPS: http://www.tww.cx/cps.php Direct, spooler-less printing: http://www.openprinting.org/direct-doc.html Usage of PPD files (for all spoolers): http://www.openprinting.org/ppd-doc.html beh - Backend Error Handler --------------------------- A wrapper for CUPS backends to make error handling configurable 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. For system administrators this can get annoying, for newbie users who are not aware of this problem it looks like that CUPS is severely broken. They remove and re-install print queues, getting on the nerves of distro install support, people, or even switch back to a proprietary operating system. This script makes the handling of such backend errors configurable, so that the problem can easily be worked around. The new possibilities are: - Let queues simply not being disabled. Simple approach, but job gets lost. - Repeat a given number of times. - Repeat infinitely often, until the job gets finally through. This is the standard of LPRng, and it eliminates loss of the job. - The interval between two attemts to run the backend can also be configured. - Configuration is done independently for each print queue. So local printers and network printers can be treated differently. Usage: Make sure "beh" is in the CUPS backend directory (usually /usr/lib/cups/backend/) and world-readable and -executable. Restart CUPS (usually "killall -HUP cupsd" or "/etc/init.d/cups restart"). If all is correct "lpinfo -v" should have "beh" in its output. Then activate "beh" for your print queue(s) with command(s) like this: lpadmin -p -E -v beh:/
/// with : The name of your print queue
: Don't Disable, if "1", beh always exits with zero status, so the queue gets never disabled when the original backend exits with an error. "0" carries the error status of the last call of the backend (after retries) on to CUPS, so the queue usually gets disabled. : Attempts, number of attempts to recall the backend in case of an error. "0" means infinite retries. In this case
gets meaningless. : Delay between two attempts to call the beckend, to be given in seconds and as an integer number. Meaningless if is one. : The original URI, which your queue had before. Can be determined with "lpstat -v". All parameters, especially,
, , and have always to be specified, even if one of them is meaningless due to the setting of the others. beh works with every backend except the "hp" backend of HPLIP. Example URIs: beh:/1/3/5/socket://printer:9100 On the network printer with host name "printer" it is tried to access 3 times with 5 second delays between the attempts. If the job still fails, the queue is not disabled (and the job discarded). beh:/0/10/60/socket://printer:9100 Retry 10 times in one minute intervals, disable the queue when still not succeeding. beh:/1/0/60/usb://Brother/HL-5040%20series On a Brother HL-5040 on the USB try infinitely often until the printer comes back, in intervals of one minute. This way the job does not get lost when the printer is turned off and one can intendedly delay printing by simply switching off the printer. The ideal configuration for desktop printers and/or home users. foomatic-filters-4.0.17/util.h0000644000175100017510000001556011774332506014713 0ustar tilltill/* util.h * * Copyright (C) 2008 Till Kamppeter * Copyright (C) 2008 Lars Uebernickel * * This file is part of foomatic-rip. * * Foomatic-rip 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. * * Foomatic-rip 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 Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef util_h #define util_h #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include "config.h" #include #include extern const char* shellescapes; int isempty(const char *string); const char * temp_dir(); 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); int omit_whitespace_newline(int c); #ifndef HAVE_STRCASESTR /* strcasestr() is not available under Solaris */ char * strcasestr (const char *haystack, const char *needle); #endif /* 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 foomatic-filters-4.0.17/STANDARD_installation0000644000175100017510000000045211774332506017463 0ustar tilltill#!/bin/sh set -x set -e if [ ! -f configure ] ; then sh make_configure; fi ./configure --prefix=/usr --sysconfdir=/etc make make -n install set +x if [ "`id -u`" != 0 ] ; then echo "run make install as root:" echo "su root -c 'make install'" echo " OR " echo "sudo make install" exit 1 fi foomatic-filters-4.0.17/AUTHORS0000644000175100017510000000000011774332506014614 0ustar tilltillfoomatic-filters-4.0.17/acinclude.m40000644000175100017510000000273311774332506015754 0ustar tilltilldnl FM_PATH_DIR(VARIABLE, DIR-TO-CHECK-FOR [, VALUE-IF-NOT-FOUND [, PATH]]) AC_DEFUN([FM_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/]) AC_CACHE_VAL(ac_cv_path_$1, [case "[$]$1" in /*) ac_cv_path_$1="[$]$1" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_$1="[$]$1" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="ifelse([$4], , $PATH, [$4])" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -d $ac_dir/$ac_word; then ac_cv_path_$1="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" dnl If no 3rd arg is given, leave the cache variable unset, dnl so AC_PATH_PROGS will keep looking. ifelse([$3], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$3" ])dnl ;; esac])dnl $1="$ac_cv_path_$1" if test -n "[$]$1"; then AC_MSG_RESULT([$]$1) else AC_MSG_RESULT(no) fi AC_SUBST($1)dnl ]) dnl FM_PATH_DIRS(VARIABLE, DIRSS-TO-CHECK-FOR [, VALUE-IF-NOT-FOUND dnl [, PATH]]) AC_DEFUN([FM_PATH_DIRS], [for ac_dir in $2 do FM_PATH_DIR($1, [$]ac_dir, , $4) test -n "[$]$1" && break done ifelse([$3], , , [test -n "[$]$1" || $1="$3" ])]) foomatic-filters-4.0.17/NEWS0000644000175100017510000000000011774332506014243 0ustar tilltillfoomatic-filters-4.0.17/spooler.c0000644000175100017510000004557411774332506015424 0ustar tilltill/* spooler.c * * Copyright (C) 2008 Till Kamppeter * Copyright (C) 2008 Lars Uebernickel * * This file is part of foomatic-rip. * * Foomatic-rip 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. * * Foomatic-rip 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 Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "spooler.h" #include "foomaticrip.h" #include "util.h" #include "options.h" #include #include 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 ""; } /* 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]; int cups_options_len; char *cups_options; 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); cups_options_len = strlen(arglist_get(arglist, 4)); cups_options = malloc(cups_options_len + 1); strncpy_omit(cups_options, arglist_get(arglist, 4), cups_options_len + 1, 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 = accounting_prolog_code; /* 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); } } free(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 + 1, destsize, omit_whitespace_newline); 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 \") 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", job->printer); exit(EXIT_PRNERR_NORETRY_BAD_SETTINGS); } } } foomatic-filters-4.0.17/COPYING0000644000175100017510000004313111774332506014613 0ustar tilltill GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. foomatic-filters-4.0.17/config.h.in0000644000175100017510000001061611774332506015605 0ustar tilltill/* 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 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 header file. */ #undef HAVE_INTTYPES_H /* 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 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 header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the 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 `strcasestr' function. */ #undef HAVE_STRCASESTR /* 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 header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the 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 header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H /* Define to 1 if you have the 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 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 home page for this package. */ #undef PACKAGE_URL /* 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 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 does not define. */ #undef pid_t /* Define to rpl_realloc if the replacement function should be used. */ #undef realloc /* Define to `unsigned int' if does not define. */ #undef size_t /* Define to `int' if does not define. */ #undef ssize_t /* Define as `fork' if `vfork' does not work. */ #undef vfork foomatic-filters-4.0.17/util.c0000644000175100017510000005436611774332506014715 0ustar tilltill/* util.c * * Copyright (C) 2008 Till Kamppeter * Copyright (C) 2008 Lars Uebernickel * * This file is part of foomatic-rip. * * Foomatic-rip 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. * * Foomatic-rip 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 Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "util.h" #include "foomaticrip.h" #include #include #include #include #include #include const char* shellescapes = "|<>&!$\'\"#*?()[]{}"; const char * temp_dir() { static const char *tmpdir = NULL; if (!tmpdir) { const char *dirs[] = { getenv("TMPDIR"), P_tmpdir, "/tmp" }; int i; for (i = 0; i < (sizeof(dirs) / sizeof(dirs[0])); i++) { if (access(dirs[i], W_OK) == 0) { tmpdir = dirs[i]; 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 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'; } int omit_whitespace_newline(int c) { return omit_whitespace(c) || c == '\n'; } #ifndef HAVE_STRCASESTR char * strcasestr (const char *haystack, const char *needle) { char *p, *startn = 0, *np = 0; for (p = haystack; *p; p++) { if (np) { if (toupper(*p) == toupper(*np)) { if (!*++np) return startn; } else np = 0; } else if (toupper(*p) == toupper(*needle)) { np = needle + 1; startn = p; } } return 0; } #endif #ifndef __OpenBSD__ 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); } #endif /* ! __OpenBSD__ */ 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; if (isempty(psrc)) { return NULL; } 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); } foomatic-filters-4.0.17/options.h0000644000175100017510000001170011774332506015421 0ustar tilltill/* options.h * * Copyright (C) 2008 Till Kamppeter * Copyright (C) 2008 Lars Uebernickel * * This file is part of foomatic-rip. * * Foomatic-rip 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. * * Foomatic-rip 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 Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef options_h #define options_h #include #include #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[65536]; 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[4096]; extern char cmd_pdf[4096]; 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); const char *get_icc_profile_for_qualifier(const char **qualifier); const char **get_ppd_qualifier(void); #endif foomatic-filters-4.0.17/test/0000755000175100017510000000000011774332506014535 5ustar tilltillfoomatic-filters-4.0.17/test/tcm.sh0000755000175100017510000003427111774332506015666 0ustar tilltill# # 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 foomatic-filters-4.0.17/test/foomatic-test-input-ps.ps0000644000175100017510000000225711774332506021442 0ustar tilltill%!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 foomatic-filters-4.0.17/test/shfuncs.sh0000755000175100017510000001001311774332506016540 0ustar tilltill# 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 } foomatic-filters-4.0.17/test/tetapi.sh0000755000175100017510000001720311774332506016365 0ustar tilltill# # 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 } foomatic-filters-4.0.17/test/testfoomaticrip0000755000175100017510000006304211774332506017704 0ustar tilltill#!/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 foomatic-filters-4.0.17/test/foomatic-test.ppd0000644000175100017510000004441211774332506020025 0ustar tilltill*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 <>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: "<>setpagedevice" *PageSize A4/A4: "<>setpagedevice" *PageSize Legal/Legal: "<>setpagedevice" *CloseUI: *PageSize *OpenUI *PageRegion: PickOne *OrderDependency: 100 AnySetup *PageRegion *DefaultPageRegion: Letter *PageRegion Letter/Letter: "<>setpagedevice" *PageRegion A4/A4: "<>setpagedevice" *PageRegion Legal/Legal: "<>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: "<> setpagedevice % Option1: Choice1" *Option1 Choice2/Choice 2: "<> setpagedevice % Option1: Choice2" *Option1 Choice3/Choice 3: " % Option1: Choice3 <> setpagedevice" *End *CloseUI: *Option1 *OpenUI *Option2/Option 2: PickOne *OrderDependency: 210 DocumentSetup *Option2 *DefaultOption2: Choice3 *Option2 Choice1/Choice 1: "<> setpagedevice % Option2: Choice1" *Option2 Choice2/Choice 2: "<> setpagedevice % Option2: Choice2" *Option2 Choice3/Choice 3: " % Option2: Choice3 <> 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 foomatic-filters-4.0.17/test/foomatic-test-renderer0000755000175100017510000000254611774332506021054 0ustar tilltill#!/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 foomatic-filters-4.0.17/test/lsbfuncs.sh0000755000175100017510000002106511774332506016717 0ustar tilltill# 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 } foomatic-filters-4.0.17/pdf.c0000644000175100017510000002117611774332506014502 0ustar tilltill/* pdf.c * * Copyright (C) 2008 Till Kamppeter * Copyright (C) 2008 Lars Uebernickel * * This file is part of foomatic-rip. * * Foomatic-rip 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. * * Foomatic-rip 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 Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "foomaticrip.h" #include "util.h" #include "options.h" #include "process.h" #include "renderer.h" #include #include #include #include #include #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0])) static int wait_for_renderer(); static int pdf_count_pages(const char *filename) { char gscommand[4095]; char output[31] = ""; int pagecount; snprintf(gscommand, 4095, "%s -dNODISPLAY -q -c " "'/pdffile (%s) (r) file def pdfdict begin pdffile pdfopen begin " "(PageCount: ) print pdfpagecount == flush currentdict pdfclose " "end end quit'", gspath, filename); FILE *pd = popen(gscommand, "r"); if (!pd) rip_die(EXIT_STARVED, "Failed to execute ghostscript to determine number of input pages!\n"); fread(output, 1, 31, pd); pclose(pd); if (sscanf(output, "PageCount: %d", &pagecount) < 1) pagecount = -1; 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) rip_die(EXIT_STARVED, "Could not start renderer\n"); 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) { char gscommand[4095]; char filename_arg[PATH_MAX], first_arg[50], last_arg[50]; int fd; _log("Extracting pages %d through %d\n", first, last); snprintf(filename, PATH_MAX, "%s/foomatic-XXXXXX", temp_dir()); if ((fd = mkstemp(filename)) == -1) rip_die(EXIT_STARVED, "Unable to create temporary file!\n"); close (fd); 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'; snprintf(gscommand, 4095, "%s -q -dNOPAUSE -dBATCH -dPARANOIDSAFER -dNOINTERPOLATE" "-sDEVICE=pdfwrite %s %s %s %s", gspath, filename_arg, first_arg, last_arg, pdffilename); FILE *pd = popen(gscommand, "r"); if (!pd) rip_die(EXIT_STARVED, "Could not run ghostscript to extract the pages!\n"); pclose(pd); 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)) rip_die(EXIT_STARVED, "Could not run ghostscript to extract the pages!\n"); 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) rip_die(EXIT_JOBERR, "Unable to determine number of pages, page count: %d\n", page_count); _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; } foomatic-filters-4.0.17/foomaticrip.c0000644000175100017510000016402411774332506016245 0ustar tilltill/* foomaticrip.c * * Copyright (C) 2008 Till Kamppeter * Copyright (C) 2008 Lars Uebernickel * * This file is part of foomatic-rip. * * Foomatic-rip 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. * * Foomatic-rip 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 Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #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 #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_DBUS #include "colord.h" #endif /* 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, *cmdlineopts, *nextopt, *pagerange, *key, *value; option_t *opt, *opt2; int optset; char tmp [256]; _log("Printing system options:\n"); cmdlineopts = strdup(job->optstr->data); for (nextopt = extract_next_option(cmdlineopts, &pagerange, &key, &value); key; nextopt = extract_next_option(nextopt, &pagerange, &key, &value)) { /* Consider only options which are not in the PPD file here */ if ((opt = find_option(key)) != NULL) continue; 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); } 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 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 */ } else _log("Unknown boolean option \"%s\".\n", key); } free(cmdlineopts); _log("Options from the PPD file:\n"); cmdlineopts = strdup(job->optstr->data); for (nextopt = extract_next_option(cmdlineopts, &pagerange, &key, &value); key; nextopt = extract_next_option(nextopt, &pagerange, &key, &value)) { /* Consider only PPD file options here */ if ((opt = find_option(key)) == NULL) continue; if (value) _log("Pondering option '%s=%s'\n", key, value); else _log("Pondering option '%s'\n", key); if (pagerange) { snprintf(tmp, 256, "pages:%s", pagerange); optset = optionset(tmp); 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) { /* Various non-standard printer-specific options */ if (!option_set_value(opt, optset, value)) { _log(" invalid choice \"%s\", using \"%s\" instead\n", value, option_get_value(opt, optset)); } } /* Standard bool args: landscape; what to do here? duplex; we should just handle this one OK now? */ else if (!prefixcasecmp(key, "no")) option_set_value(opt, optset, "0"); else option_set_value(opt, optset, "1"); } free(cmdlineopts); } /* 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=" appends the data to the , "--genpdq=" creates/overwrites 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, * end; p = begin; end = begin + len; while (p < end) { p = memchr(p, '%', end - p); if (!p) return UNKNOWN_FILE; *startpos = p - begin; if ((end - p) > 2 && !memcmp(p, "%!", 2)) return PS_FILE; else if ((end - p) > 7 && !memcmp(p, "%PDF-1.", 7)) return PDF_FILE; ++ p; } *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, "")) 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) - 1, file); buf[n] = '\0'; type = guess_file_type(buf, n, &startpos); /* We do not use any JCL preceeded to the inputr data, as it is simply the PJL commands from the PPD file, and these commands we can also generate, end we even merge them with PJl from the driver */ /*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; char tmpfilename[PATH_MAX] = ""; _log("Driver does not understand PDF input, " "converting to PostScript\n"); pdfconvertedtops = 1; /* If reading from stdin, write everything into a temporary file */ if (file == 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, buf, n); fclose(tmpfile); filename = tmpfilename; } /* If the spooler is CUPS we use the pdftops filter of CUPS, to have always the same PDF->PostScript conversion method in the whole printing environment, including incompatibility workarounds in the CUPS filter (so this way we also have to maintain all these quirks only once). The "-dNOINTERPOLATE" makes Ghostscript rendering significantly faster. Note that Ghostscript's "pswrite" output device turns text into bitmaps and therefore produces huge PostScript files. In addition, this output device is deprecated. Therefore we use "ps2write". We give priority to Ghostscript here and use Poppler if Ghostscript is not available. */ if (spooler == SPOOLER_CUPS) snprintf(pdf2ps_cmd, PATH_MAX, "pdftops '%s' '%s' '%s' '%s' '%s' '%s'", job->id, job->user, job->title, "1", job->optstr->data, filename); else snprintf(pdf2ps_cmd, PATH_MAX, "gs -q -sstdout=%%stderr -sDEVICE=ps2write -sOutputFile=- " "-dBATCH -dNOPAUSE -dPARANOIDSAFER -dNOINTERPOLATE %s 2>/dev/null || " "pdftops -level2 -origpagesizes %s - 2>/dev/null", filename, filename); renderer_pid = start_system_process("pdf-to-ps", pdf2ps_cmd, &in, &out); 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("", 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("", 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) { int fd = mkstemp (LOG_FILE "-XXXXXX.log"); if (fd != -1) logh = fdopen(fd, "w"); else logh = stderr; } 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 (spooler != SPOOLER_CUPS && spooler != SPOOLER_PPR && spooler != SPOOLER_PPR_INT) { 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' && *str != ':') { if (isprint(*str) && strchr(shellescapes, *str) == NULL) *p++ = *str; str++; } } } /* CUPS calls foomatic-rip only with 5 or 6 positional parameters, not with named options, like for example "-p ". Also PPR does not used named options. */ if (spooler != SPOOLER_CUPS && spooler != SPOOLER_PPR && spooler != SPOOLER_PPR_INT) { /* 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; /* PPD file name given via the command line allow duplicates, and use the last specified one */ if (spooler != SPOOLER_GNULPR && spooler != SPOOLER_LPRNG && spooler != SPOOLER_LPD) { 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"); } } /* 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_LPRNG: if (job->ppdfile[0] != '\0') break; case SPOOLER_LPD: 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, ""); /* Check filelist */ p = strtok(strdup(filelist->data), " "); while (p) { if (strcmp(p, "") != 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; } /* gstoraster is the new name for pstoraster */ strlcat(tmp, "/gstoraster", 1024); if (access(tmp, X_OK) == 0) { havepstoraster = 1; strlcpy(pstoraster, tmp, 256); strlcat(pstoraster, " 0 '' '' 0 '%X'", 256); break; } } if (!havepstoraster) { const char **qualifier = NULL; const char *icc_profile = NULL; qualifier = get_ppd_qualifier(); _log("INFO: Using qualifer: '%s.%s.%s'\n", qualifier[0], qualifier[1], qualifier[2]); #ifdef HAVE_DBUS /* ask colord for the profile */ icc_profile = colord_get_profile_for_device_id ((const char *) getenv("PRINTER"), qualifier); #endif /* fall back to PPD */ if (icc_profile == NULL) { _log("INFO: need to look in PPD for matching qualifer\n"); icc_profile = get_icc_profile_for_qualifier(qualifier); } if (icc_profile != NULL) snprintf(cmd, sizeof(cmd), "-sOutputICCProfile='%s'", icc_profile); else cmd[0] = '\0'; snprintf(pstoraster, sizeof(pstoraster), "gs -dQUIET -dDEBUG -dPARANOIDSAFER -dNOPAUSE -dBATCH -dNOINTERPOLATE -dNOMEDIAATTRS -sDEVICE=cups %s -sOutputFile=- -", cmd); } /* build Ghostscript/CUPS driver command line */ snprintf(cmd, 1024, "%s | %s", pstoraster, cupsfilter); _log("INFO: Using command line: %s\n", cmd); /* 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, ""); /* Start the documentation page generator */ /* TODO tbd */ } 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")); if (!print_file(filename, 1)) rip_die(EXIT_PRNERR_NORETRY, "Could not print file %s\n", filename); 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 EXIT_PRINTED; } foomatic-filters-4.0.17/renderer.c0000644000175100017510000003442411774332506015537 0ustar tilltill/* renderer.c * * Copyright (C) 2008 Till Kamppeter * Copyright (C) 2008 Lars Uebernickel * * This file is part of foomatic-rip. * * Foomatic-rip 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. * * Foomatic-rip 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 Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #define _GNU_SOURCE #include #include #include #include #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=ps2write -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, 0, 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; } void 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 **optsp1 = NULL, **optsp2 = NULL; /* 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 "%-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); /* Insert the JCL commands from the PPD file right before the first "@PJL SET ..." line from the, if there are no "@PJL SET ..." lines, directly before "@PJL ENTER LANGUAGE ...", otherwise after the JCL commands from the driver */ for (optsp1 = original_opts; *(optsp1 + 1); optsp1++) { if (optsp2 == NULL && ((strstr(*optsp1, "ENTER LANGUAGE") != NULL) || (strncasecmp(*optsp1, "@PJL SET ", 9) == 0))) { for (optsp2 = opts; *optsp2; optsp2++) if (!jcl_options_find_keyword(original_opts, *optsp2, jclstr)) fprintf(stream, "%s\n", *optsp2); } if (optsp1 != original_opts) p = *optsp1; if (!p) _log("write_merged_jcl_options() dereferences NULL pointer p\n"); 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); } if (optsp2 == NULL) for (optsp2 = opts; *optsp2; optsp2++) if (!jcl_options_find_keyword(original_opts, *optsp2, jclstr)) fprintf(stream, "%s\n", *optsp2); write_binary_data(stream, *optsp1, readbinarybytes); return 1; } void log_jcl() { char **opt; _log("JCL: %s", jclbegin); if (jclprepend) for (opt = jclprepend; *opt; opt++) _log("%s\n", *opt); _log(" %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) { free_dstr(commandline); return EXIT_PRNERR_NORETRY_BAD_SETTINGS; } if (in && dup2(fileno(in), fileno(stdin)) < 0) { _log("kid3: Could not dup stdin\n"); fclose(kid4in); free_dstr(commandline); return EXIT_PRNERR_NORETRY_BAD_SETTINGS; } if (dup2(fileno(kid4in), fileno(stdout)) < 0) { _log("kid3: Could not dup stdout to kid4\n"); fclose(kid4in); free_dstr(commandline); return EXIT_PRNERR_NORETRY_BAD_SETTINGS; } if (debug) { if (!redirect_log_to_stderr()) { fclose(kid4in); free_dstr(commandline); return EXIT_PRNERR_NORETRY_BAD_SETTINGS; } /* Save the data supposed to be fed into the renderer also into a file*/ dstrprepend(commandline, "tee $(mktemp " LOG_FILE "-XXXXXX.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; } foomatic-filters-4.0.17/foomatic-rip.1.in0000644000175100017510000002323611774332506016644 0ustar tilltill.\" This -*- nroff -*- source file is part of foomatic. .hy 0 .TH FOOMATIC-RIP 1 "2002-11-26" "Foomatic Project" .SH NAME foomatic-rip \- Universal print filter/RIP wrapper .SH SYNOPSIS .SS \fRGeneral Options: .BI \fBfoomatic-rip\fR\ \fB[-v]\ [-q]\fP \fI\ .SS \fRSpooler-less printing/CPS (older versions) filter: .BI \fBfoomatic-rip\fR\ \fB[\fB-P\fR \ \fI\fR \ | \ \fB--ppd\fR \ \fI\fR \fB]\fR \ [\fB-J\fR\ \fI\fR ] [\fB-o\fR \ \fI