diff options
author | Gicu GORODENCO | 2015-06-21 23:45:16 +0200 |
---|---|---|
committer | Gicu GORODENCO | 2015-06-21 23:45:16 +0200 |
commit | 459e936b400ca0345765f3859df37da12e26d138 (patch) | |
tree | 9d64b6c4634b65c3bec502337956f4c43860f75f | |
download | aur-459e936b400ca0345765f3859df37da12e26d138.tar.gz |
v2.0.0-1
-rw-r--r-- | .SRCINFO | 78 | ||||
-rw-r--r-- | PKGBUILD | 165 | ||||
-rw-r--r-- | add-ipp-backend-of-cups-1.4.patch | 1992 | ||||
-rw-r--r-- | cups-1.6.0-fix-install-perms.patch | 25 | ||||
-rw-r--r-- | cups-1.6.2-statedir.patch | 12 | ||||
-rw-r--r-- | cups-no-export-ssllibs.patch | 12 | ||||
-rw-r--r-- | cups-no-gcrypt.patch | 11 | ||||
-rw-r--r-- | cups-no-gzip-man.patch | 18 | ||||
-rw-r--r-- | cups.install | 28 | ||||
-rw-r--r-- | cups.logrotate | 5 | ||||
-rw-r--r-- | cups.pam | 3 |
11 files changed, 2349 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO new file mode 100644 index 000000000000..672c7379e5fe --- /dev/null +++ b/.SRCINFO @@ -0,0 +1,78 @@ +# Generated by makepkg 4.2.1 +# Wed Apr 8 23:38:47 UTC 2015 +pkgbase = cups-ipp14 + pkgver = 2.0.2 + pkgrel = 1 + url = http://www.cups.org/ + arch = i686 + arch = x86_64 + license = GPL + makedepends = libtiff>=4.0.0 + makedepends = libpng>=1.5.7 + makedepends = acl + makedepends = pam + makedepends = xdg-utils + makedepends = krb5 + makedepends = gnutls + makedepends = cups-filters + makedepends = bc + makedepends = colord + makedepends = xinetd + makedepends = gzip + makedepends = autoconf + makedepends = libusb + makedepends = dbus + makedepends = avahi + makedepends = hicolor-icon-theme + makedepends = systemd + makedepends = inetutils + makedepends = libpaper + makedepends = valgrind + provides = cups + conflicts = cups + replaces = cups + source = http://www.cups.org/software/2.0.2/cups-2.0.2-source.tar.bz2 + source = http://www.cups.org/software/2.0.2/cups-2.0.2-source.tar.bz2.sig + source = cups.logrotate + source = cups.pam + source = cups-no-export-ssllibs.patch + source = cups-no-gcrypt.patch + source = cups-no-gzip-man.patch + source = cups-1.6.2-statedir.patch + source = cups-1.6.0-fix-install-perms.patch + source = add-ipp-backend-of-cups-1.4.patch + md5sums = 6e0ea72dbafcf5baaa1cf4178e71096d + md5sums = SKIP + md5sums = fc8286f185e2cc5f7e1f6843bf193e2b + md5sums = 96f82c38f3f540b53f3e5144900acf17 + md5sums = 3ba9e3410df1dc3015463d615ef91b3b + md5sums = 1beb4896f217bc241bc08a422274ec0c + md5sums = 90c30380d4c8cd48a908cfdadae1ea24 + md5sums = 451609db34f95209d64c38474de27ce1 + md5sums = 5117f65342fcc69c6a506529e4daca9e + md5sums = 49e1c75beb87e9b7c9511f59509839e7 + +pkgname = cups-ipp14 + pkgdesc = The CUPS Printing System - daemon package + install = cups.install + depends = acl + depends = pam + depends = libcups-ipp14>=2.0.2 + depends = cups-filters + depends = bc + depends = colord + depends = dbus + depends = systemd + depends = libpaper + depends = hicolor-icon-theme + optdepends = xdg-utils: xdg .desktop file support + backup = etc/cups/cupsd.conf + backup = etc/cups/snmp.conf + backup = etc/cups/printers.conf + backup = etc/cups/classes.conf + backup = etc/cups/cups-files.conf + backup = etc/cups/subscriptions.conf + backup = etc/dbus-1/system.d/cups.conf + backup = etc/logrotate.d/cups + backup = etc/pam.d/cups + diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 000000000000..3c6e538373d3 --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,165 @@ +# $Id$ +# Maintainer: Gicu GORODENCO <cyclopsihus@gmail.com> +# Contributor (cups): Andreas Radke <andyrtr@archlinux.org> + +_pkgbase="cups" +pkgbase="${_pkgbase}-ipp14" +### Commenting the "split packages sections - unsupported by AUR apparently ### +#pkgname=('libcups-ipp14' 'cups-ipp14') +pkgname=(${pkgbase}) +pkgver=2.0.2 +pkgrel=1 +arch=('i686' 'x86_64') +provides=('cups') +replaces=('cups') +conflicts=('cups') +license=('GPL') +url="http://www.cups.org/" +makedepends=('libtiff>=4.0.0' 'libpng>=1.5.7' 'acl' 'pam' 'xdg-utils' 'krb5' 'gnutls' + 'cups-filters' 'bc' 'colord' 'xinetd' 'gzip' 'autoconf' 'libusb' 'dbus' + 'avahi' 'hicolor-icon-theme' 'systemd' 'inetutils' 'libpaper' 'valgrind') +source=(http://www.cups.org/software/${pkgver}/cups-${pkgver}-source.tar.bz2{,.sig} + cups.logrotate cups.pam + # improve build and linking + cups-no-export-ssllibs.patch + cups-no-gcrypt.patch + cups-no-gzip-man.patch + cups-1.6.2-statedir.patch + cups-1.6.0-fix-install-perms.patch + # bugfixes + # IPP 1.4 + add-ipp-backend-of-cups-1.4.patch) + +md5sums=('6e0ea72dbafcf5baaa1cf4178e71096d' + 'SKIP' + 'fc8286f185e2cc5f7e1f6843bf193e2b' + '96f82c38f3f540b53f3e5144900acf17' + '3ba9e3410df1dc3015463d615ef91b3b' + '1beb4896f217bc241bc08a422274ec0c' + '90c30380d4c8cd48a908cfdadae1ea24' + '451609db34f95209d64c38474de27ce1' + '5117f65342fcc69c6a506529e4daca9e' + '49e1c75beb87e9b7c9511f59509839e7') + + +prepare() { + + cd ${_pkgbase}-${pkgver} + + # Applying patch to add ipp14 backend: + patch -Np1 -i ${srcdir}/add-ipp-backend-of-cups-1.4.patch + + # improve build and linking + # Do not export SSL libs in cups-config + patch -Np1 -i ${srcdir}/cups-no-export-ssllibs.patch + # https://www.cups.org/str.php?L4399 + patch -Np1 -i ${srcdir}/cups-no-gcrypt.patch + # don't zip man pages in make install, let makepkg do that / Fedora + patch -Np1 -i ${srcdir}/cups-no-gzip-man.patch + # move /var/run -> /run for pid file + patch -Np1 -i ${srcdir}/cups-1.6.2-statedir.patch + # fix permissions on some files (by Gentoo) - alternative: cups-0755.patch by FC + patch -Np0 -i ${srcdir}/cups-1.6.0-fix-install-perms.patch + + # bug fixes + + # set MaxLogSize to 0 to prevent using cups internal log rotation + sed -i -e '5i\ ' conf/cupsd.conf.in + sed -i -e '6i# Disable cups internal logging - use logrotate instead' conf/cupsd.conf.in + sed -i -e '7iMaxLogSize 0' conf/cupsd.conf.in + + # Rebuild configure script for not zipping man-pages. + aclocal -I config-scripts + autoconf -I config-scripts +} + +build() { + cd ${_pkgbase}-${pkgver} + ./configure --prefix=/usr \ + --sysconfdir=/etc \ + --localstatedir=/var \ + --sbindir=/usr/bin \ + --libdir=/usr/lib \ + --with-logdir=/var/log/cups \ + --with-docdir=/usr/share/cups/doc \ + --with-cups-user=daemon \ + --with-cups-group=lp \ + --enable-pam=yes \ + --enable-raw-printing \ + --enable-dbus --with-dbusdir=/etc/dbus-1 \ + --enable-ssl=yes \ + --enable-threads \ + --enable-avahi\ + --enable-libpaper \ + --with-php=/usr/bin/php-cgi \ + --with-optim="$CFLAGS" #--help + make +} + +check() { + cd ${_pkgbase}-${pkgver} + #make -k check || /bin/true +} + +package() { +pkgdesc="The CUPS Printing System - daemon package" +install=cups.install +backup=(etc/cups/cupsd.conf + etc/cups/snmp.conf + etc/cups/printers.conf + etc/cups/classes.conf + etc/cups/cups-files.conf + etc/cups/subscriptions.conf + etc/dbus-1/system.d/cups.conf + etc/logrotate.d/cups + etc/pam.d/cups) +depends=('acl' 'pam' "libcups-ipp14>=${pkgver}" 'cups-filters' 'bc' 'colord' + 'dbus' 'systemd' 'libpaper' 'hicolor-icon-theme') +optdepends=('xdg-utils: xdg .desktop file support') + + cd ${_pkgbase}-${pkgver} + make BUILDROOT=${pkgdir} install-data install-exec + + # this one we ship in the libcups pkg + rm -f ${pkgdir}/usr/bin/cups-config + + # kill the sysv stuff + rm -rf ${pkgdir}/etc/rc*.d + rm -rf ${pkgdir}/etc/init.d + install -D -m644 ../cups.logrotate ${pkgdir}/etc/logrotate.d/cups + install -D -m644 ../cups.pam ${pkgdir}/etc/pam.d/cups + + # fix perms on /var/spool and /etc + chmod 755 ${pkgdir}/var/spool + chmod 755 ${pkgdir}/etc + + # install ssl directory where to store the certs, solves some samba issues + install -dm700 -g lp ${pkgdir}/etc/cups/ssl + # remove directory from package, it will be recreated at each server start + rm -rf ${pkgdir}/run + + # install some more configuration files that will get filled by cupsd + touch ${pkgdir}/etc/cups/printers.conf + touch ${pkgdir}/etc/cups/classes.conf + touch ${pkgdir}/etc/cups/subscriptions.conf + chgrp -R lp ${pkgdir}/etc/cups + + # fix .desktop file + sed -i 's|^Exec=htmlview http://localhost:631/|Exec=xdg-open http://localhost:631/|g' ${pkgdir}/usr/share/applications/cups.desktop + + # compress some driver files, adopted from Fedora + find ${pkgdir}/usr/share/cups/model -name "*.ppd" | xargs gzip -n9f + + # remove client.conf man page + rm -f ${pkgdir}/usr/share/man/man5/client.conf.5 + + # remove files now part of cups-filters + rm -v ${pkgdir}/usr/share/cups/banners/* + rm -v ${pkgdir}/usr/share/cups/data/testprint + # comment out all conversion rules which use any of the removed filters + perl -p -i -e 's:^(.*\s+bannertops\s*)$:#\1:' $pkgdir/usr/share/cups/mime/mime.convs + + + # comment out unnecessary PageLogFormat entry + sed -i -e 's:PageLogFormat:#PageLogFormat:' $pkgdir/etc/cups/cupsd.conf* +} diff --git a/add-ipp-backend-of-cups-1.4.patch b/add-ipp-backend-of-cups-1.4.patch new file mode 100644 index 000000000000..24928a55de90 --- /dev/null +++ b/add-ipp-backend-of-cups-1.4.patch @@ -0,0 +1,1992 @@ +--- a/backend/Makefile ++++ b/backend/Makefile +@@ -29,6 +29,7 @@ + # See http://www.cups.org/documentation.php/api-filter.html for more info... + RBACKENDS = \ + ipp \ ++ ipp14 \ + lpd \ + $(DNSSD_BACKEND) + UBACKENDS = \ +@@ -50,6 +51,7 @@ + snmp-supplies.o + OBJS = \ + ipp.o \ ++ ipp14.o \ + lpd.o \ + dnssd.o \ + snmp.o \ +@@ -250,6 +252,17 @@ + + + # ++# ipp14 ++# ++ ++ipp14: ipp14.o ../cups/$(LIBCUPS) libbackend.a ++ echo Linking $@... ++ $(CC) $(LDFLAGS) -o ipp14 ipp14.o libbackend.a $(LIBS) ++ #$(RM) http ++ #$(LN) ipp14 http ++ ++ ++# + # lpd + # + +--- /dev/null ++++ b/backend/ipp14.c +@@ -0,0 +1,1953 @@ ++/* ++ * "$Id: ipp.c 8950 2010-01-14 22:40:19Z mike $" ++ * ++ * IPP backend for the Common UNIX Printing System (CUPS). ++ * ++ * Copyright 2007-2010 by Apple Inc. ++ * Copyright 1997-2007 by Easy Software Products, all rights reserved. ++ * ++ * These coded instructions, statements, and computer programs are the ++ * property of Apple Inc. and are protected by Federal copyright ++ * law. Distribution and use rights are outlined in the file "LICENSE.txt" ++ * "LICENSE" which should have been included with this file. If this ++ * file is missing or damaged, see the license at "http://www.cups.org/". ++ * ++ * This file is subject to the Apple OS-Developed Software exception. ++ * ++ * Contents: ++ * ++ * main() - Send a file to the printer or server. ++ * cancel_job() - Cancel a print job. ++ * check_printer_state() - Check the printer state... ++ * compress_files() - Compress print files... ++ * password_cb() - Disable the password prompt for ++ * cupsDoFileRequest(). ++ * report_attr() - Report an IPP attribute value. ++ * report_printer_state() - Report the printer state. ++ * run_pictwps_filter() - Convert PICT files to PostScript when printing ++ * remotely. ++ * sigterm_handler() - Handle 'terminate' signals that stop the backend. ++ */ ++ ++/* ++ * Include necessary headers. ++ */ ++ ++#include <cups/http-private.h> ++#include "backend-private.h" ++#include <sys/types.h> ++#include <sys/stat.h> ++#include <sys/wait.h> ++ ++/* ++ * Globals... ++ */ ++ ++static char *password = NULL; /* Password for device URI */ ++static int password_tries = 0; /* Password tries */ ++static const char *auth_info_required = "none"; ++ /* New auth-info-required value */ ++#ifdef __APPLE__ ++static char pstmpname[1024] = ""; /* Temporary PostScript file name */ ++#endif /* __APPLE__ */ ++static char tmpfilename[1024] = ""; /* Temporary spool file name */ ++static int job_cancelled = 0; /* Job cancelled? */ ++ ++ ++/* ++ * Local functions... ++ */ ++ ++static void cancel_job(http_t *http, const char *uri, int id, ++ const char *resource, const char *user, int version); ++static void check_printer_state(http_t *http, const char *uri, ++ const char *resource, const char *user, ++ int version, int job_id); ++#ifdef HAVE_LIBZ ++static void compress_files(int num_files, char **files); ++#endif /* HAVE_LIBZ */ ++static const char *password_cb(const char *); ++static void report_attr(ipp_attribute_t *attr); ++static int report_printer_state(ipp_t *ipp, int job_id); ++ ++#ifdef __APPLE__ ++static int run_pictwps_filter(char **argv, const char *filename); ++#endif /* __APPLE__ */ ++static void sigterm_handler(int sig); ++ ++ ++/* ++ * 'main()' - Send a file to the printer or server. ++ * ++ * Usage: ++ * ++ * printer-uri job-id user title copies options [file] ++ */ ++ ++int /* O - Exit status */ ++main(int argc, /* I - Number of command-line args */ ++ char *argv[]) /* I - Command-line arguments */ ++{ ++ int i; /* Looping var */ ++ int send_options; /* Send job options? */ ++ int num_options; /* Number of printer options */ ++ cups_option_t *options; /* Printer options */ ++ const char *device_uri; /* Device URI */ ++ char scheme[255], /* Scheme in URI */ ++ hostname[1024], /* Hostname */ ++ username[255], /* Username info */ ++ resource[1024], /* Resource info (printer name) */ ++ addrname[256], /* Address name */ ++ *optptr, /* Pointer to URI options */ ++ *name, /* Name of option */ ++ *value, /* Value of option */ ++ sep; /* Separator character */ ++ int snmp_fd, /* SNMP socket */ ++ start_count, /* Page count via SNMP at start */ ++ page_count, /* Page count via SNMP */ ++ have_supplies; /* Printer supports supply levels? */ ++ int num_files; /* Number of files to print */ ++ char **files, /* Files to print */ ++ *filename; /* Pointer to single filename */ ++ int port; /* Port number (not used) */ ++ char uri[HTTP_MAX_URI]; /* Updated URI without user/pass */ ++ ipp_status_t ipp_status; /* Status of IPP request */ ++ http_t *http; /* HTTP connection */ ++ ipp_t *request, /* IPP request */ ++ *response, /* IPP response */ ++ *supported; /* get-printer-attributes response */ ++ time_t start_time; /* Time of first connect */ ++ int recoverable; /* Recoverable error shown? */ ++ int contimeout; /* Connection timeout */ ++ int delay; /* Delay for retries... */ ++ int compression, /* Do compression of the job data? */ ++ waitjob, /* Wait for job complete? */ ++ waitprinter; /* Wait for printer ready? */ ++ ipp_attribute_t *job_id_attr; /* job-id attribute */ ++ int job_id; /* job-id value */ ++ ipp_attribute_t *job_sheets; /* job-media-sheets-completed */ ++ ipp_attribute_t *job_state; /* job-state */ ++ ipp_attribute_t *copies_sup; /* copies-supported */ ++ ipp_attribute_t *format_sup; /* document-format-supported */ ++ ipp_attribute_t *printer_state; /* printer-state attribute */ ++ ipp_attribute_t *printer_accepting; /* printer-is-accepting-jobs */ ++ int copies, /* Number of copies for job */ ++ copies_remaining; /* Number of copies remaining */ ++ const char *content_type, /* CONTENT_TYPE environment variable */ ++ *final_content_type; /* FINAL_CONTENT_TYPE environment var */ ++#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) ++ struct sigaction action; /* Actions for POSIX signals */ ++#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ ++ int version; /* IPP version */ ++ static const char * const pattrs[] = ++ { /* Printer attributes we want */ ++ "com.apple.print.recoverable-message", ++ "copies-supported", ++ "document-format-supported", ++ "marker-colors", ++ "marker-high-levels", ++ "marker-levels", ++ "marker-low-levels", ++ "marker-message", ++ "marker-names", ++ "marker-types", ++ "printer-is-accepting-jobs", ++ "printer-state", ++ "printer-state-message", ++ "printer-state-reasons", ++ }; ++ static const char * const jattrs[] = ++ { /* Job attributes we want */ ++ "job-media-sheets-completed", ++ "job-state" ++ }; ++ ++ ++ /* ++ * Make sure status messages are not buffered... ++ */ ++ ++ setbuf(stderr, NULL); ++ ++ /* ++ * Ignore SIGPIPE and catch SIGTERM signals... ++ */ ++ ++#ifdef HAVE_SIGSET ++ sigset(SIGPIPE, SIG_IGN); ++ sigset(SIGTERM, sigterm_handler); ++#elif defined(HAVE_SIGACTION) ++ memset(&action, 0, sizeof(action)); ++ action.sa_handler = SIG_IGN; ++ sigaction(SIGPIPE, &action, NULL); ++ ++ sigemptyset(&action.sa_mask); ++ sigaddset(&action.sa_mask, SIGTERM); ++ action.sa_handler = sigterm_handler; ++ sigaction(SIGTERM, &action, NULL); ++#else ++ signal(SIGPIPE, SIG_IGN); ++ signal(SIGTERM, sigterm_handler); ++#endif /* HAVE_SIGSET */ ++ ++ /* ++ * Check command-line... ++ */ ++ ++ if (argc == 1) ++ { ++ char *s; ++ ++ if ((s = strrchr(argv[0], '/')) != NULL) ++ s ++; ++ else ++ s = argv[0]; ++ ++ printf("network %s \"Unknown\" \"%s (%s)\"\n", ++ s, _cupsLangString(cupsLangDefault(), ++ _("Internet Printing Protocol")), s); ++ return (CUPS_BACKEND_OK); ++ } ++ else if (argc < 6) ++ { ++ _cupsLangPrintf(stderr, ++ _("Usage: %s job-id user title copies options [file]\n"), ++ argv[0]); ++ return (CUPS_BACKEND_STOP); ++ } ++ ++ /* ++ * Get the (final) content type... ++ */ ++ ++ if ((content_type = getenv("CONTENT_TYPE")) == NULL) ++ content_type = "application/octet-stream"; ++ ++ if ((final_content_type = getenv("FINAL_CONTENT_TYPE")) == NULL) ++ { ++ final_content_type = content_type; ++ ++ if (!strncmp(final_content_type, "printer/", 8)) ++ final_content_type = "application/vnd.cups-raw"; ++ } ++ ++ /* ++ * Extract the hostname and printer name from the URI... ++ */ ++ ++ if ((device_uri = cupsBackendDeviceURI(argv)) == NULL) ++ return (CUPS_BACKEND_FAILED); ++ ++ httpSeparateURI(HTTP_URI_CODING_ALL, device_uri, scheme, sizeof(scheme), ++ username, sizeof(username), hostname, sizeof(hostname), &port, ++ resource, sizeof(resource)); ++ ++ if (!port) ++ port = IPP_PORT; /* Default to port 631 */ ++ ++ if (!strcmp(scheme, "https")) ++ cupsSetEncryption(HTTP_ENCRYPT_ALWAYS); ++ else ++ cupsSetEncryption(HTTP_ENCRYPT_IF_REQUESTED); ++ ++ /* ++ * See if there are any options... ++ */ ++ ++ compression = 0; ++ version = 11; ++ waitjob = 1; ++ waitprinter = 1; ++ contimeout = 7 * 24 * 60 * 60; ++ ++ if ((optptr = strchr(resource, '?')) != NULL) ++ { ++ /* ++ * Yup, terminate the device name string and move to the first ++ * character of the optptr... ++ */ ++ ++ *optptr++ = '\0'; ++ ++ /* ++ * Then parse the optptr... ++ */ ++ ++ while (*optptr) ++ { ++ /* ++ * Get the name... ++ */ ++ ++ name = optptr; ++ ++ while (*optptr && *optptr != '=' && *optptr != '+' && *optptr != '&') ++ optptr ++; ++ ++ if ((sep = *optptr) != '\0') ++ *optptr++ = '\0'; ++ ++ if (sep == '=') ++ { ++ /* ++ * Get the value... ++ */ ++ ++ value = optptr; ++ ++ while (*optptr && *optptr != '+' && *optptr != '&') ++ optptr ++; ++ ++ if (*optptr) ++ *optptr++ = '\0'; ++ } ++ else ++ value = (char *)""; ++ ++ /* ++ * Process the option... ++ */ ++ ++ if (!strcasecmp(name, "waitjob")) ++ { ++ /* ++ * Wait for job completion? ++ */ ++ ++ waitjob = !strcasecmp(value, "on") || ++ !strcasecmp(value, "yes") || ++ !strcasecmp(value, "true"); ++ } ++ else if (!strcasecmp(name, "waitprinter")) ++ { ++ /* ++ * Wait for printer idle? ++ */ ++ ++ waitprinter = !strcasecmp(value, "on") || ++ !strcasecmp(value, "yes") || ++ !strcasecmp(value, "true"); ++ } ++ else if (!strcasecmp(name, "encryption")) ++ { ++ /* ++ * Enable/disable encryption? ++ */ ++ ++ if (!strcasecmp(value, "always")) ++ cupsSetEncryption(HTTP_ENCRYPT_ALWAYS); ++ else if (!strcasecmp(value, "required")) ++ cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); ++ else if (!strcasecmp(value, "never")) ++ cupsSetEncryption(HTTP_ENCRYPT_NEVER); ++ else if (!strcasecmp(value, "ifrequested")) ++ cupsSetEncryption(HTTP_ENCRYPT_IF_REQUESTED); ++ else ++ { ++ _cupsLangPrintf(stderr, ++ _("ERROR: Unknown encryption option value \"%s\"!\n"), ++ value); ++ } ++ } ++ else if (!strcasecmp(name, "version")) ++ { ++ if (!strcmp(value, "1.0")) ++ version = 10; ++ else if (!strcmp(value, "1.1")) ++ version = 11; ++ else if (!strcmp(value, "2.0")) ++ version = 20; ++ else if (!strcmp(value, "2.1")) ++ version = 21; ++ else ++ { ++ _cupsLangPrintf(stderr, ++ _("ERROR: Unknown version option value \"%s\"!\n"), ++ value); ++ } ++ } ++#ifdef HAVE_LIBZ ++ else if (!strcasecmp(name, "compression")) ++ { ++ compression = !strcasecmp(value, "true") || ++ !strcasecmp(value, "yes") || ++ !strcasecmp(value, "on") || ++ !strcasecmp(value, "gzip"); ++ } ++#endif /* HAVE_LIBZ */ ++ else if (!strcasecmp(name, "contimeout")) ++ { ++ /* ++ * Set the connection timeout... ++ */ ++ ++ if (atoi(value) > 0) ++ contimeout = atoi(value); ++ } ++ else ++ { ++ /* ++ * Unknown option... ++ */ ++ ++ _cupsLangPrintf(stderr, ++ _("ERROR: Unknown option \"%s\" with value \"%s\"!\n"), ++ name, value); ++ } ++ } ++ } ++ ++ /* ++ * If we have 7 arguments, print the file named on the command-line. ++ * Otherwise, copy stdin to a temporary file and print the temporary ++ * file. ++ */ ++ ++ if (argc == 6) ++ { ++ /* ++ * Copy stdin to a temporary file... ++ */ ++ ++ int fd; /* File descriptor */ ++ http_addrlist_t *addrlist; /* Address list */ ++ off_t tbytes; /* Total bytes copied */ ++ ++ ++ fputs("STATE: +connecting-to-device\n", stderr); ++ fprintf(stderr, "DEBUG: Looking up \"%s\"...\n", hostname); ++ ++ if ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, "1")) == NULL) ++ { ++ _cupsLangPrintf(stderr, _("ERROR: Unable to locate printer \'%s\'!\n"), ++ hostname); ++ return (CUPS_BACKEND_STOP); ++ } ++ ++ snmp_fd = _cupsSNMPOpen(addrlist->addr.addr.sa_family); ++ ++ if ((fd = cupsTempFd(tmpfilename, sizeof(tmpfilename))) < 0) ++ { ++ _cupsLangPrintError("ERROR", _("Unable to create temporary file")); ++ return (CUPS_BACKEND_FAILED); ++ } ++ ++ _cupsLangPuts(stderr, _("INFO: Copying print data...\n")); ++ ++ tbytes = backendRunLoop(-1, fd, snmp_fd, &(addrlist->addr), 0, 0, ++ backendNetworkSideCB); ++ ++ if (snmp_fd >= 0) ++ _cupsSNMPClose(snmp_fd); ++ ++ httpAddrFreeList(addrlist); ++ ++ close(fd); ++ ++ /* ++ * Don't try printing files less than 2 bytes... ++ */ ++ ++ if (tbytes <= 1) ++ { ++ _cupsLangPuts(stderr, _("ERROR: Empty print file!\n")); ++ unlink(tmpfilename); ++ return (CUPS_BACKEND_FAILED); ++ } ++ ++ /* ++ * Point to the single file from stdin... ++ */ ++ ++ filename = tmpfilename; ++ num_files = 1; ++ files = &filename; ++ send_options = 0; ++ } ++ else ++ { ++ /* ++ * Point to the files on the command-line... ++ */ ++ ++ num_files = argc - 6; ++ files = argv + 6; ++ send_options = 1; ++ ++#ifdef HAVE_LIBZ ++ if (compression) ++ compress_files(num_files, files); ++#endif /* HAVE_LIBZ */ ++ } ++ ++ fprintf(stderr, "DEBUG: %d files to send in job...\n", num_files); ++ ++ /* ++ * Set the authentication info, if any... ++ */ ++ ++ cupsSetPasswordCB(password_cb); ++ ++ if (username[0]) ++ { ++ /* ++ * Use authenticaion information in the device URI... ++ */ ++ ++ if ((password = strchr(username, ':')) != NULL) ++ *password++ = '\0'; ++ ++ cupsSetUser(username); ++ } ++ else if (!getuid()) ++ { ++ /* ++ * Try loading authentication information from the environment. ++ */ ++ ++ const char *ptr = getenv("AUTH_USERNAME"); ++ ++ if (ptr) ++ cupsSetUser(ptr); ++ ++ password = getenv("AUTH_PASSWORD"); ++ } ++ ++ /* ++ * Try connecting to the remote server... ++ */ ++ ++ delay = 5; ++ recoverable = 0; ++ start_time = time(NULL); ++ ++ fputs("STATE: +connecting-to-device\n", stderr); ++ ++ do ++ { ++ fprintf(stderr, "DEBUG: Connecting to %s:%d\n", hostname, port); ++ _cupsLangPuts(stderr, _("INFO: Connecting to printer...\n")); ++ ++ if ((http = httpConnectEncrypt(hostname, port, cupsEncryption())) == NULL) ++ { ++ if (job_cancelled) ++ break; ++ ++ if (getenv("CLASS") != NULL) ++ { ++ /* ++ * If the CLASS environment variable is set, the job was submitted ++ * to a class and not to a specific queue. In this case, we want ++ * to abort immediately so that the job can be requeued on the next ++ * available printer in the class. ++ */ ++ ++ _cupsLangPuts(stderr, ++ _("INFO: Unable to contact printer, queuing on next " ++ "printer in class...\n")); ++ ++ if (tmpfilename[0]) ++ unlink(tmpfilename); ++ ++ /* ++ * Sleep 5 seconds to keep the job from requeuing too rapidly... ++ */ ++ ++ sleep(5); ++ ++ return (CUPS_BACKEND_FAILED); ++ } ++ ++ if (errno == ECONNREFUSED || errno == EHOSTDOWN || ++ errno == EHOSTUNREACH) ++ { ++ if (contimeout && (time(NULL) - start_time) > contimeout) ++ { ++ _cupsLangPuts(stderr, _("ERROR: Printer not responding!\n")); ++ return (CUPS_BACKEND_FAILED); ++ } ++ ++ recoverable = 1; ++ ++ _cupsLangPrintf(stderr, ++ _("WARNING: recoverable: Network host \'%s\' is busy; " ++ "will retry in %d seconds...\n"), ++ hostname, delay); ++ ++ sleep(delay); ++ ++ if (delay < 30) ++ delay += 5; ++ } ++ else if (h_errno) ++ { ++ _cupsLangPrintf(stderr, _("ERROR: Unable to locate printer \'%s\'!\n"), ++ hostname); ++ return (CUPS_BACKEND_STOP); ++ } ++ else ++ { ++ recoverable = 1; ++ ++ fprintf(stderr, "DEBUG: Connection error: %s\n", strerror(errno)); ++ _cupsLangPuts(stderr, ++ _("ERROR: recoverable: Unable to connect to printer; will " ++ "retry in 30 seconds...\n")); ++ sleep(30); ++ } ++ ++ if (job_cancelled) ++ break; ++ } ++ } ++ while (http == NULL); ++ ++ if (job_cancelled || !http) ++ { ++ if (tmpfilename[0]) ++ unlink(tmpfilename); ++ ++ return (CUPS_BACKEND_FAILED); ++ } ++ ++ fputs("STATE: -connecting-to-device\n", stderr); ++ _cupsLangPuts(stderr, _("INFO: Connected to printer...\n")); ++ ++#ifdef AF_INET6 ++ if (http->hostaddr->addr.sa_family == AF_INET6) ++ fprintf(stderr, "DEBUG: Connected to [%s]:%d (IPv6)...\n", ++ httpAddrString(http->hostaddr, addrname, sizeof(addrname)), ++ ntohs(http->hostaddr->ipv6.sin6_port)); ++ else ++#endif /* AF_INET6 */ ++ if (http->hostaddr->addr.sa_family == AF_INET) ++ fprintf(stderr, "DEBUG: Connected to %s:%d (IPv4)...\n", ++ httpAddrString(http->hostaddr, addrname, sizeof(addrname)), ++ ntohs(http->hostaddr->ipv4.sin_port)); ++ ++ /* ++ * See if the printer supports SNMP... ++ */ ++ ++ if ((snmp_fd = _cupsSNMPOpen(http->hostaddr->addr.sa_family)) >= 0) ++ have_supplies = !backendSNMPSupplies(snmp_fd, http->hostaddr, &start_count, ++ NULL); ++ else ++ have_supplies = start_count = 0; ++ ++ /* ++ * Build a URI for the printer and fill the standard IPP attributes for ++ * an IPP_PRINT_FILE request. We can't use the URI in argv[0] because it ++ * might contain username:password information... ++ */ ++ ++ httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), scheme, NULL, hostname, ++ port, resource); ++ ++ /* ++ * First validate the destination and see if the device supports multiple ++ * copies. We have to do this because some IPP servers (e.g. HP JetDirect) ++ * don't support the copies attribute... ++ */ ++ ++ copies_sup = NULL; ++ format_sup = NULL; ++ supported = NULL; ++ ++ do ++ { ++ /* ++ * Check for side-channel requests... ++ */ ++ ++ backendCheckSideChannel(snmp_fd, http->hostaddr); ++ ++ /* ++ * Build the IPP request... ++ */ ++ ++ request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); ++ request->request.op.version[0] = version / 10; ++ request->request.op.version[1] = version % 10; ++ ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", ++ NULL, uri); ++ ++ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, ++ "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]), ++ NULL, pattrs); ++ ++ /* ++ * Do the request... ++ */ ++ ++ fputs("DEBUG: Getting supported attributes...\n", stderr); ++ ++ if (http->version < HTTP_1_1) ++ httpReconnect(http); ++ ++ if ((supported = cupsDoRequest(http, request, resource)) == NULL) ++ ipp_status = cupsLastError(); ++ else ++ ipp_status = supported->request.status.status_code; ++ ++ if (ipp_status > IPP_OK_CONFLICT) ++ { ++ if (ipp_status == IPP_PRINTER_BUSY || ++ ipp_status == IPP_SERVICE_UNAVAILABLE) ++ { ++ if (contimeout && (time(NULL) - start_time) > contimeout) ++ { ++ _cupsLangPuts(stderr, _("ERROR: Printer not responding!\n")); ++ return (CUPS_BACKEND_FAILED); ++ } ++ ++ recoverable = 1; ++ ++ _cupsLangPrintf(stderr, ++ _("WARNING: recoverable: Network host \'%s\' is busy; " ++ "will retry in %d seconds...\n"), ++ hostname, delay); ++ ++ report_printer_state(supported, 0); ++ ++ sleep(delay); ++ ++ if (delay < 30) ++ delay += 5; ++ } ++ else if ((ipp_status == IPP_BAD_REQUEST || ++ ipp_status == IPP_VERSION_NOT_SUPPORTED) && version > 10) ++ { ++ /* ++ * Switch to IPP/1.0... ++ */ ++ ++ _cupsLangPrintf(stderr, ++ _("INFO: Printer does not support IPP/%d.%d, trying " ++ "IPP/1.0...\n"), version / 10, version % 10); ++ version = 10; ++ httpReconnect(http); ++ } ++ else if (ipp_status == IPP_NOT_FOUND) ++ { ++ _cupsLangPuts(stderr, _("ERROR: Destination printer does not exist!\n")); ++ ++ if (supported) ++ ippDelete(supported); ++ ++ return (CUPS_BACKEND_STOP); ++ } ++ else if (ipp_status == IPP_NOT_AUTHORIZED || ipp_status == IPP_FORBIDDEN) ++ { ++ if (!strncmp(httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE), ++ "Negotiate", 9)) ++ auth_info_required = "negotiate"; ++ ++ fprintf(stderr, "ATTR: auth-info-required=%s\n", auth_info_required); ++ return (CUPS_BACKEND_AUTH_REQUIRED); ++ } ++ else ++ { ++ _cupsLangPrintf(stderr, ++ _("ERROR: Unable to get printer status (%s)!\n"), ++ cupsLastErrorString()); ++ sleep(10); ++ } ++ ++ if (supported) ++ ippDelete(supported); ++ ++ continue; ++ } ++ else if ((copies_sup = ippFindAttribute(supported, "copies-supported", ++ IPP_TAG_RANGE)) != NULL) ++ { ++ /* ++ * Has the "copies-supported" attribute - does it have an upper ++ * bound > 1? ++ */ ++ ++ if (copies_sup->values[0].range.upper <= 1) ++ copies_sup = NULL; /* No */ ++ } ++ ++ format_sup = ippFindAttribute(supported, "document-format-supported", ++ IPP_TAG_MIMETYPE); ++ ++ if (format_sup) ++ { ++ fprintf(stderr, "DEBUG: document-format-supported (%d values)\n", ++ format_sup->num_values); ++ for (i = 0; i < format_sup->num_values; i ++) ++ fprintf(stderr, "DEBUG: [%d] = \"%s\"\n", i, ++ format_sup->values[i].string.text); ++ } ++ ++ report_printer_state(supported, 0); ++ } ++ while (ipp_status > IPP_OK_CONFLICT); ++ ++ /* ++ * See if the printer is accepting jobs and is not stopped; if either ++ * condition is true and we are printing to a class, requeue the job... ++ */ ++ ++ if (getenv("CLASS") != NULL) ++ { ++ printer_state = ippFindAttribute(supported, "printer-state", ++ IPP_TAG_ENUM); ++ printer_accepting = ippFindAttribute(supported, "printer-is-accepting-jobs", ++ IPP_TAG_BOOLEAN); ++ ++ if (printer_state == NULL || ++ (printer_state->values[0].integer > IPP_PRINTER_PROCESSING && ++ waitprinter) || ++ printer_accepting == NULL || ++ !printer_accepting->values[0].boolean) ++ { ++ /* ++ * If the CLASS environment variable is set, the job was submitted ++ * to a class and not to a specific queue. In this case, we want ++ * to abort immediately so that the job can be requeued on the next ++ * available printer in the class. ++ */ ++ ++ _cupsLangPuts(stderr, ++ _("INFO: Unable to contact printer, queuing on next " ++ "printer in class...\n")); ++ ++ ippDelete(supported); ++ httpClose(http); ++ ++ if (tmpfilename[0]) ++ unlink(tmpfilename); ++ ++ /* ++ * Sleep 5 seconds to keep the job from requeuing too rapidly... ++ */ ++ ++ sleep(5); ++ ++ return (CUPS_BACKEND_FAILED); ++ } ++ } ++ ++ if (recoverable) ++ { ++ /* ++ * If we've shown a recoverable error make sure the printer proxies ++ * have a chance to see the recovered message. Not pretty but ++ * necessary for now... ++ */ ++ ++ fputs("INFO: recovered: \n", stderr); ++ sleep(5); ++ } ++ ++ /* ++ * See if the printer supports multiple copies... ++ */ ++ ++ copies = atoi(argv[4]); ++ ++ if (copies_sup || argc < 7) ++ { ++ copies_remaining = 1; ++ ++ if (argc < 7) ++ copies = 1; ++ } ++ else ++ copies_remaining = copies; ++ ++ /* ++ * Then issue the print-job request... ++ */ ++ ++ job_id = 0; ++ ++ while (copies_remaining > 0) ++ { ++ /* ++ * Check for side-channel requests... ++ */ ++ ++ backendCheckSideChannel(snmp_fd, http->hostaddr); ++ ++ /* ++ * Build the IPP request... ++ */ ++ ++ if (job_cancelled) ++ break; ++ ++ if (num_files > 1) ++ request = ippNewRequest(IPP_CREATE_JOB); ++ else ++ request = ippNewRequest(IPP_PRINT_JOB); ++ ++ request->request.op.version[0] = version / 10; ++ request->request.op.version[1] = version % 10; ++ ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", ++ NULL, uri); ++ ++ fprintf(stderr, "DEBUG: printer-uri = \"%s\"\n", uri); ++ ++ if (argv[2][0]) ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, ++ "requesting-user-name", NULL, argv[2]); ++ ++ fprintf(stderr, "DEBUG: requesting-user-name = \"%s\"\n", argv[2]); ++ ++ /* ++ * Only add a "job-name" attribute if the remote server supports ++ * copy generation - some IPP implementations like HP's don't seem ++ * to like UTF-8 job names (STR #1837)... ++ */ ++ ++ if (argv[3][0] && copies_sup) ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, ++ argv[3]); ++ ++ fprintf(stderr, "DEBUG: job-name = \"%s\"\n", argv[3]); ++ ++#ifdef HAVE_LIBZ ++ if (compression) ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, ++ "compression", NULL, "gzip"); ++#endif /* HAVE_LIBZ */ ++ ++ /* ++ * Handle options on the command-line... ++ */ ++ ++ options = NULL; ++ num_options = cupsParseOptions(argv[5], 0, &options); ++ ++#ifdef __APPLE__ ++ if (!strcasecmp(final_content_type, "application/pictwps") && ++ num_files == 1) ++ { ++ if (format_sup != NULL) ++ { ++ for (i = 0; i < format_sup->num_values; i ++) ++ if (!strcasecmp(final_content_type, format_sup->values[i].string.text)) ++ break; ++ } ++ ++ if (format_sup == NULL || i >= format_sup->num_values) ++ { ++ /* ++ * Remote doesn't support "application/pictwps" (i.e. it's not MacOS X) ++ * so convert the document to PostScript... ++ */ ++ ++ if (run_pictwps_filter(argv, files[0])) ++ { ++ if (pstmpname[0]) ++ unlink(pstmpname); ++ ++ if (tmpfilename[0]) ++ unlink(tmpfilename); ++ ++ return (CUPS_BACKEND_FAILED); ++ } ++ ++ files[0] = pstmpname; ++ ++ /* ++ * Change the MIME type to application/postscript and change the ++ * number of copies to 1... ++ */ ++ ++ final_content_type = "application/postscript"; ++ copies = 1; ++ copies_remaining = 1; ++ send_options = 0; ++ } ++ } ++#endif /* __APPLE__ */ ++ ++ if (format_sup != NULL) ++ { ++ for (i = 0; i < format_sup->num_values; i ++) ++ if (!strcasecmp(final_content_type, format_sup->values[i].string.text)) ++ break; ++ ++ if (i < format_sup->num_values) ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, ++ "document-format", NULL, final_content_type); ++ } ++ ++ if (copies_sup && version > 10 && send_options) ++ { ++ /* ++ * Only send options if the destination printer supports the copies ++ * attribute and IPP/1.1. This is a hack for the HP and Lexmark ++ * implementations of IPP, which do not accept extension attributes ++ * and incorrectly report a client-error-bad-request error instead of ++ * the successful-ok-unsupported-attributes status. In short, at least ++ * some HP and Lexmark implementations of IPP are non-compliant. ++ */ ++ ++ cupsEncodeOptions(request, num_options, options); ++ ++ ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "copies", ++ copies); ++ } ++ ++ cupsFreeOptions(num_options, options); ++ ++ /* ++ * If copies aren't supported, then we are likely dealing with an HP ++ * JetDirect. The HP IPP implementation seems to close the connection ++ * after every request - that is, it does *not* implement HTTP Keep- ++ * Alive, which is REQUIRED by HTTP/1.1... ++ */ ++ ++ if (!copies_sup) ++ httpReconnect(http); ++ ++ /* ++ * Do the request... ++ */ ++ ++ if (http->version < HTTP_1_1) ++ httpReconnect(http); ++ ++ if (num_files > 1) ++ response = cupsDoRequest(http, request, resource); ++ else ++ response = cupsDoFileRequest(http, request, resource, files[0]); ++ ++ ipp_status = cupsLastError(); ++ ++ if (ipp_status > IPP_OK_CONFLICT) ++ { ++ job_id = 0; ++ ++ if (job_cancelled) ++ break; ++ ++ if (ipp_status == IPP_SERVICE_UNAVAILABLE || ++ ipp_status == IPP_PRINTER_BUSY) ++ { ++ _cupsLangPuts(stderr, ++ _("INFO: Printer busy; will retry in 10 seconds...\n")); ++ sleep(10); ++ } ++ else if ((ipp_status == IPP_BAD_REQUEST || ++ ipp_status == IPP_VERSION_NOT_SUPPORTED) && version > 10) ++ { ++ /* ++ * Switch to IPP/1.0... ++ */ ++ ++ _cupsLangPrintf(stderr, ++ _("INFO: Printer does not support IPP/%d.%d, trying " ++ "IPP/1.0...\n"), version / 10, version % 10); ++ version = 10; ++ httpReconnect(http); ++ } ++ else ++ { ++ /* ++ * Update auth-info-required as needed... ++ */ ++ ++ _cupsLangPrintf(stderr, _("ERROR: Print file was not accepted (%s)!\n"), ++ cupsLastErrorString()); ++ ++ if (ipp_status == IPP_NOT_AUTHORIZED || ipp_status == IPP_FORBIDDEN) ++ { ++ fprintf(stderr, "DEBUG: WWW-Authenticate=\"%s\"\n", ++ httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE)); ++ ++ /* ++ * Normal authentication goes through the password callback, which sets ++ * auth_info_required to "username,password". Kerberos goes directly ++ * through GSSAPI, so look for Negotiate in the WWW-Authenticate header ++ * here and set auth_info_required as needed... ++ */ ++ ++ if (!strncmp(httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE), ++ "Negotiate", 9)) ++ auth_info_required = "negotiate"; ++ } ++ } ++ } ++ else if ((job_id_attr = ippFindAttribute(response, "job-id", ++ IPP_TAG_INTEGER)) == NULL) ++ { ++ _cupsLangPuts(stderr, ++ _("NOTICE: Print file accepted - job ID unknown.\n")); ++ job_id = 0; ++ } ++ else ++ { ++ job_id = job_id_attr->values[0].integer; ++ _cupsLangPrintf(stderr, _("NOTICE: Print file accepted - job ID %d.\n"), ++ job_id); ++ } ++ ++ ippDelete(response); ++ ++ if (job_cancelled) ++ break; ++ ++ if (job_id && num_files > 1) ++ { ++ for (i = 0; i < num_files; i ++) ++ { ++ /* ++ * Check for side-channel requests... ++ */ ++ ++ backendCheckSideChannel(snmp_fd, http->hostaddr); ++ ++ /* ++ * Send the next file in the job... ++ */ ++ ++ request = ippNewRequest(IPP_SEND_DOCUMENT); ++ request->request.op.version[0] = version / 10; ++ request->request.op.version[1] = version % 10; ++ ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", ++ NULL, uri); ++ ++ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", ++ job_id); ++ ++ if (argv[2][0]) ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, ++ "requesting-user-name", NULL, argv[2]); ++ ++ if ((i + 1) == num_files) ++ ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1); ++ ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, ++ "document-format", NULL, content_type); ++ ++ if (http->version < HTTP_1_1) ++ httpReconnect(http); ++ ++ ippDelete(cupsDoFileRequest(http, request, resource, files[i])); ++ ++ if (cupsLastError() > IPP_OK_CONFLICT) ++ { ++ ipp_status = cupsLastError(); ++ ++ _cupsLangPrintf(stderr, ++ _("ERROR: Unable to add file %d to job: %s\n"), ++ job_id, cupsLastErrorString()); ++ break; ++ } ++ } ++ } ++ ++ if (ipp_status <= IPP_OK_CONFLICT && argc > 6) ++ { ++ fprintf(stderr, "PAGE: 1 %d\n", copies_sup ? atoi(argv[4]) : 1); ++ copies_remaining --; ++ } ++ else if (ipp_status == IPP_SERVICE_UNAVAILABLE || ++ ipp_status == IPP_PRINTER_BUSY) ++ continue; ++ else ++ copies_remaining --; ++ ++ /* ++ * Wait for the job to complete... ++ */ ++ ++ if (!job_id || !waitjob) ++ continue; ++ ++ _cupsLangPuts(stderr, _("INFO: Waiting for job to complete...\n")); ++ ++ for (delay = 1; !job_cancelled;) ++ { ++ /* ++ * Check for side-channel requests... ++ */ ++ ++ backendCheckSideChannel(snmp_fd, http->hostaddr); ++ ++ /* ++ * Build an IPP_GET_JOB_ATTRIBUTES request... ++ */ ++ ++ request = ippNewRequest(IPP_GET_JOB_ATTRIBUTES); ++ request->request.op.version[0] = version / 10; ++ request->request.op.version[1] = version % 10; ++ ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", ++ NULL, uri); ++ ++ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", ++ job_id); ++ ++ if (argv[2][0]) ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, ++ "requesting-user-name", NULL, argv[2]); ++ ++ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, ++ "requested-attributes", sizeof(jattrs) / sizeof(jattrs[0]), ++ NULL, jattrs); ++ ++ /* ++ * Do the request... ++ */ ++ ++ if (!copies_sup || http->version < HTTP_1_1) ++ httpReconnect(http); ++ ++ response = cupsDoRequest(http, request, resource); ++ ipp_status = cupsLastError(); ++ ++ if (ipp_status == IPP_NOT_FOUND) ++ { ++ /* ++ * Job has gone away and/or the server has no job history... ++ */ ++ ++ ippDelete(response); ++ ++ ipp_status = IPP_OK; ++ break; ++ } ++ ++ if (ipp_status > IPP_OK_CONFLICT) ++ { ++ if (ipp_status != IPP_SERVICE_UNAVAILABLE && ++ ipp_status != IPP_PRINTER_BUSY) ++ { ++ ippDelete(response); ++ ++ _cupsLangPrintf(stderr, ++ _("ERROR: Unable to get job %d attributes (%s)!\n"), ++ job_id, cupsLastErrorString()); ++ break; ++ } ++ } ++ ++ if (response) ++ { ++ if ((job_state = ippFindAttribute(response, "job-state", ++ IPP_TAG_ENUM)) != NULL) ++ { ++ /* ++ * Stop polling if the job is finished or pending-held... ++ */ ++ ++ if (job_state->values[0].integer > IPP_JOB_STOPPED) ++ { ++ if ((job_sheets = ippFindAttribute(response, ++ "job-media-sheets-completed", ++ IPP_TAG_INTEGER)) != NULL) ++ fprintf(stderr, "PAGE: total %d\n", ++ job_sheets->values[0].integer); ++ ++ ippDelete(response); ++ break; ++ } ++ } ++ else ++ { ++ /* ++ * If the printer does not return a job-state attribute, it does not ++ * conform to the IPP specification - break out immediately and fail ++ * the job... ++ */ ++ ++ fputs("DEBUG: No job-state available from printer - stopping queue.\n", ++ stderr); ++ ipp_status = IPP_INTERNAL_ERROR; ++ break; ++ } ++ } ++ ++ ippDelete(response); ++ ++ /* ++ * Check the printer state and report it if necessary... ++ */ ++ ++ check_printer_state(http, uri, resource, argv[2], version, job_id); ++ ++ /* ++ * Wait 1-10 seconds before polling again... ++ */ ++ ++ sleep(delay); ++ ++ delay ++; ++ if (delay > 10) ++ delay = 1; ++ } ++ } ++ ++ /* ++ * Cancel the job as needed... ++ */ ++ ++ if (job_cancelled && job_id) ++ cancel_job(http, uri, job_id, resource, argv[2], version); ++ ++ /* ++ * Check the printer state and report it if necessary... ++ */ ++ ++ check_printer_state(http, uri, resource, argv[2], version, job_id); ++ ++ /* ++ * Collect the final page count as needed... ++ */ ++ ++ if (have_supplies && ++ !backendSNMPSupplies(snmp_fd, http->hostaddr, &page_count, NULL) && ++ page_count > start_count) ++ fprintf(stderr, "PAGE: total %d\n", page_count - start_count); ++ ++#ifdef HAVE_GSSAPI ++ /* ++ * See if we used Kerberos at all... ++ */ ++ ++ if (http->gssctx) ++ auth_info_required = "negotiate"; ++#endif /* HAVE_GSSAPI */ ++ ++ /* ++ * Free memory... ++ */ ++ ++ httpClose(http); ++ ++ ippDelete(supported); ++ ++ /* ++ * Remove the temporary file(s) if necessary... ++ */ ++ ++ if (tmpfilename[0]) ++ unlink(tmpfilename); ++ ++#ifdef HAVE_LIBZ ++ if (compression) ++ { ++ for (i = 0; i < num_files; i ++) ++ unlink(files[i]); ++ } ++#endif /* HAVE_LIBZ */ ++ ++#ifdef __APPLE__ ++ if (pstmpname[0]) ++ unlink(pstmpname); ++#endif /* __APPLE__ */ ++ ++ /* ++ * Return the queue status... ++ */ ++ ++ fprintf(stderr, "ATTR: auth-info-required=%s\n", auth_info_required); ++ ++ if (ipp_status == IPP_NOT_AUTHORIZED || ipp_status == IPP_FORBIDDEN) ++ return (CUPS_BACKEND_AUTH_REQUIRED); ++ else if (ipp_status == IPP_INTERNAL_ERROR) ++ return (CUPS_BACKEND_STOP); ++ else if (ipp_status > IPP_OK_CONFLICT) ++ return (CUPS_BACKEND_FAILED); ++ else ++ { ++ _cupsLangPuts(stderr, _("INFO: Ready to print.\n")); ++ return (CUPS_BACKEND_OK); ++ } ++} ++ ++ ++/* ++ * 'cancel_job()' - Cancel a print job. ++ */ ++ ++static void ++cancel_job(http_t *http, /* I - HTTP connection */ ++ const char *uri, /* I - printer-uri */ ++ int id, /* I - job-id */ ++ const char *resource, /* I - Resource path */ ++ const char *user, /* I - requesting-user-name */ ++ int version) /* I - IPP version */ ++{ ++ ipp_t *request; /* Cancel-Job request */ ++ ++ ++ _cupsLangPuts(stderr, _("INFO: Canceling print job...\n")); ++ ++ request = ippNewRequest(IPP_CANCEL_JOB); ++ request->request.op.version[0] = version / 10; ++ request->request.op.version[1] = version % 10; ++ ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", ++ NULL, uri); ++ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", id); ++ ++ if (user && user[0]) ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, ++ "requesting-user-name", NULL, user); ++ ++ /* ++ * Do the request... ++ */ ++ ++ if (http->version < HTTP_1_1) ++ httpReconnect(http); ++ ++ ippDelete(cupsDoRequest(http, request, resource)); ++ ++ if (cupsLastError() > IPP_OK_CONFLICT) ++ _cupsLangPrintf(stderr, _("ERROR: Unable to cancel job %d: %s\n"), id, ++ cupsLastErrorString()); ++} ++ ++ ++/* ++ * 'check_printer_state()' - Check the printer state... ++ */ ++ ++static void ++check_printer_state( ++ http_t *http, /* I - HTTP connection */ ++ const char *uri, /* I - Printer URI */ ++ const char *resource, /* I - Resource path */ ++ const char *user, /* I - Username, if any */ ++ int version, /* I - IPP version */ ++ int job_id) /* I - Current job ID */ ++{ ++ ipp_t *request, /* IPP request */ ++ *response; /* IPP response */ ++ static const char * const attrs[] = /* Attributes we want */ ++ { ++ "com.apple.print.recoverable-message", ++ "marker-colors", ++ "marker-levels", ++ "marker-message", ++ "marker-names", ++ "marker-types", ++ "printer-state-message", ++ "printer-state-reasons" ++ }; ++ ++ ++ /* ++ * Check on the printer state... ++ */ ++ ++ request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); ++ request->request.op.version[0] = version / 10; ++ request->request.op.version[1] = version % 10; ++ ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", ++ NULL, uri); ++ ++ if (user && user[0]) ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, ++ "requesting-user-name", NULL, user); ++ ++ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, ++ "requested-attributes", ++ (int)(sizeof(attrs) / sizeof(attrs[0])), NULL, attrs); ++ ++ /* ++ * Do the request... ++ */ ++ ++ if (http->version < HTTP_1_1) ++ httpReconnect(http); ++ ++ if ((response = cupsDoRequest(http, request, resource)) != NULL) ++ { ++ report_printer_state(response, job_id); ++ ippDelete(response); ++ } ++} ++ ++ ++#ifdef HAVE_LIBZ ++/* ++ * 'compress_files()' - Compress print files... ++ */ ++ ++static void ++compress_files(int num_files, /* I - Number of files */ ++ char **files) /* I - Files */ ++{ ++ int i, /* Looping var */ ++ fd; /* Temporary file descriptor */ ++ ssize_t bytes; /* Bytes read/written */ ++ size_t total; /* Total bytes read */ ++ cups_file_t *in, /* Input file */ ++ *out; /* Output file */ ++ struct stat outinfo; /* Output file information */ ++ char filename[1024], /* Temporary filename */ ++ buffer[32768]; /* Copy buffer */ ++ ++ ++ fprintf(stderr, "DEBUG: Compressing %d job files...\n", num_files); ++ for (i = 0; i < num_files; i ++) ++ { ++ if ((fd = cupsTempFd(filename, sizeof(filename))) < 0) ++ { ++ _cupsLangPrintf(stderr, ++ _("ERROR: Unable to create temporary compressed print " ++ "file: %s\n"), strerror(errno)); ++ exit(CUPS_BACKEND_FAILED); ++ } ++ ++ if ((out = cupsFileOpenFd(fd, "w9")) == NULL) ++ { ++ _cupsLangPrintf(stderr, ++ _("ERROR: Unable to open temporary compressed print " ++ "file: %s\n"), strerror(errno)); ++ exit(CUPS_BACKEND_FAILED); ++ } ++ ++ if ((in = cupsFileOpen(files[i], "r")) == NULL) ++ { ++ _cupsLangPrintf(stderr, ++ _("ERROR: Unable to open print file \"%s\": %s\n"), ++ files[i], strerror(errno)); ++ cupsFileClose(out); ++ exit(CUPS_BACKEND_FAILED); ++ } ++ ++ total = 0; ++ while ((bytes = cupsFileRead(in, buffer, sizeof(buffer))) > 0) ++ if (cupsFileWrite(out, buffer, bytes) < bytes) ++ { ++ _cupsLangPrintf(stderr, ++ _("ERROR: Unable to write %d bytes to \"%s\": %s\n"), ++ (int)bytes, filename, strerror(errno)); ++ cupsFileClose(in); ++ cupsFileClose(out); ++ exit(CUPS_BACKEND_FAILED); ++ } ++ else ++ total += bytes; ++ ++ cupsFileClose(out); ++ cupsFileClose(in); ++ ++ files[i] = strdup(filename); ++ ++ if (!stat(filename, &outinfo)) ++ fprintf(stderr, ++ "DEBUG: File %d compressed to %.1f%% of original size, " ++ CUPS_LLFMT " bytes...\n", ++ i + 1, 100.0 * outinfo.st_size / total, ++ CUPS_LLCAST outinfo.st_size); ++ } ++} ++#endif /* HAVE_LIBZ */ ++ ++ ++/* ++ * 'password_cb()' - Disable the password prompt for cupsDoFileRequest(). ++ */ ++ ++static const char * /* O - Password */ ++password_cb(const char *prompt) /* I - Prompt (not used) */ ++{ ++ (void)prompt; ++ ++ /* ++ * Remember that we need to authenticate... ++ */ ++ ++ auth_info_required = "username,password"; ++ ++ if (password && *password && password_tries < 3) ++ { ++ password_tries ++; ++ ++ return (password); ++ } ++ else ++ { ++ /* ++ * Give up after 3 tries or if we don't have a password to begin with... ++ */ ++ ++ return (NULL); ++ } ++} ++ ++ ++/* ++ * 'report_attr()' - Report an IPP attribute value. ++ */ ++ ++static void ++report_attr(ipp_attribute_t *attr) /* I - Attribute */ ++{ ++ int i; /* Looping var */ ++ char value[1024], /* Value string */ ++ *valptr, /* Pointer into value string */ ++ *attrptr; /* Pointer into attribute value */ ++ ++ ++ /* ++ * Convert the attribute values into quoted strings... ++ */ ++ ++ for (i = 0, valptr = value; ++ i < attr->num_values && valptr < (value + sizeof(value) - 10); ++ i ++) ++ { ++ if (i > 0) ++ *valptr++ = ','; ++ ++ switch (attr->value_tag) ++ { ++ case IPP_TAG_INTEGER : ++ case IPP_TAG_ENUM : ++ snprintf(valptr, sizeof(value) - (valptr - value), "%d", ++ attr->values[i].integer); ++ valptr += strlen(valptr); ++ break; ++ ++ case IPP_TAG_TEXT : ++ case IPP_TAG_NAME : ++ case IPP_TAG_KEYWORD : ++ *valptr++ = '\"'; ++ for (attrptr = attr->values[i].string.text; ++ *attrptr && valptr < (value + sizeof(value) - 10); ++ attrptr ++) ++ { ++ if (*attrptr == '\\' || *attrptr == '\"') ++ *valptr++ = '\\'; ++ ++ *valptr++ = *attrptr; ++ } ++ *valptr++ = '\"'; ++ break; ++ ++ default : ++ /* ++ * Unsupported value type... ++ */ ++ ++ return; ++ } ++ } ++ ++ *valptr = '\0'; ++ ++ /* ++ * Tell the scheduler about the new values... ++ */ ++ ++ fprintf(stderr, "ATTR: %s=%s\n", attr->name, value); ++} ++ ++ ++/* ++ * 'report_printer_state()' - Report the printer state. ++ */ ++ ++static int /* O - Number of reasons shown */ ++report_printer_state(ipp_t *ipp, /* I - IPP response */ ++ int job_id) /* I - Current job ID */ ++{ ++ int i; /* Looping var */ ++ int count; /* Count of reasons shown... */ ++ ipp_attribute_t *caprm, /* com.apple.print.recoverable-message */ ++ *psm, /* printer-state-message */ ++ *reasons, /* printer-state-reasons */ ++ *marker; /* marker-* attributes */ ++ const char *reason; /* Current reason */ ++ const char *prefix; /* Prefix for STATE: line */ ++ char state[1024]; /* State string */ ++ int saw_caprw; /* Saw com.apple.print.recoverable-warning state */ ++ ++ ++ if ((psm = ippFindAttribute(ipp, "printer-state-message", ++ IPP_TAG_TEXT)) != NULL) ++ fprintf(stderr, "INFO: %s\n", psm->values[0].string.text); ++ ++ if ((reasons = ippFindAttribute(ipp, "printer-state-reasons", ++ IPP_TAG_KEYWORD)) == NULL) ++ return (0); ++ ++ saw_caprw = 0; ++ state[0] = '\0'; ++ prefix = "STATE: "; ++ ++ for (i = 0, count = 0; i < reasons->num_values; i ++) ++ { ++ reason = reasons->values[i].string.text; ++ ++ if (!strcmp(reason, "com.apple.print.recoverable-warning")) ++ saw_caprw = 1; ++ else if (strcmp(reason, "paused")) ++ { ++ strlcat(state, prefix, sizeof(state)); ++ strlcat(state, reason, sizeof(state)); ++ ++ prefix = ","; ++ } ++ } ++ ++ if (state[0]) ++ fprintf(stderr, "%s\n", state); ++ ++ /* ++ * Relay com.apple.print.recoverable-message... ++ */ ++ ++ if ((caprm = ippFindAttribute(ipp, "com.apple.print.recoverable-message", ++ IPP_TAG_TEXT)) != NULL) ++ fprintf(stderr, "WARNING: %s: %s\n", ++ saw_caprw ? "recoverable" : "recovered", ++ caprm->values[0].string.text); ++ ++ /* ++ * Relay the current marker-* attribute values... ++ */ ++ ++ if ((marker = ippFindAttribute(ipp, "marker-colors", IPP_TAG_NAME)) != NULL) ++ report_attr(marker); ++ if ((marker = ippFindAttribute(ipp, "marker-high-levels", ++ IPP_TAG_INTEGER)) != NULL) ++ report_attr(marker); ++ if ((marker = ippFindAttribute(ipp, "marker-levels", ++ IPP_TAG_INTEGER)) != NULL) ++ report_attr(marker); ++ if ((marker = ippFindAttribute(ipp, "marker-low-levels", ++ IPP_TAG_INTEGER)) != NULL) ++ report_attr(marker); ++ if ((marker = ippFindAttribute(ipp, "marker-message", IPP_TAG_TEXT)) != NULL) ++ report_attr(marker); ++ if ((marker = ippFindAttribute(ipp, "marker-names", IPP_TAG_NAME)) != NULL) ++ report_attr(marker); ++ if ((marker = ippFindAttribute(ipp, "marker-types", IPP_TAG_KEYWORD)) != NULL) ++ report_attr(marker); ++ ++ return (count); ++} ++ ++ ++#ifdef __APPLE__ ++/* ++ * 'run_pictwps_filter()' - Convert PICT files to PostScript when printing ++ * remotely. ++ * ++ * This step is required because the PICT format is not documented and ++ * subject to change, so developing a filter for other OS's is infeasible. ++ * Also, fonts required by the PICT file need to be embedded on the ++ * client side (which has the fonts), so we run the filter to get a ++ * PostScript file for printing... ++ */ ++ ++static int /* O - Exit status of filter */ ++run_pictwps_filter(char **argv, /* I - Command-line arguments */ ++ const char *filename)/* I - Filename */ ++{ ++ struct stat fileinfo; /* Print file information */ ++ const char *ppdfile; /* PPD file for destination printer */ ++ int pid; /* Child process ID */ ++ int fd; /* Temporary file descriptor */ ++ int status; /* Exit status of filter */ ++ const char *printer; /* PRINTER env var */ ++ static char ppdenv[1024]; /* PPD environment variable */ ++ ++ ++ /* ++ * First get the PPD file for the printer... ++ */ ++ ++ printer = getenv("PRINTER"); ++ if (!printer) ++ { ++ _cupsLangPuts(stderr, ++ _("ERROR: PRINTER environment variable not defined!\n")); ++ return (-1); ++ } ++ ++ if ((ppdfile = cupsGetPPD(printer)) == NULL) ++ { ++ _cupsLangPrintf(stderr, ++ _("ERROR: Unable to get PPD file for printer \"%s\" - " ++ "%s.\n"), printer, cupsLastErrorString()); ++ } ++ else ++ { ++ snprintf(ppdenv, sizeof(ppdenv), "PPD=%s", ppdfile); ++ putenv(ppdenv); ++ } ++ ++ /* ++ * Then create a temporary file for printing... ++ */ ++ ++ if ((fd = cupsTempFd(pstmpname, sizeof(pstmpname))) < 0) ++ { ++ _cupsLangPrintError("ERROR", _("Unable to create temporary file")); ++ if (ppdfile) ++ unlink(ppdfile); ++ return (-1); ++ } ++ ++ /* ++ * Get the owner of the spool file - it is owned by the user we want to run ++ * as... ++ */ ++ ++ if (argv[6]) ++ stat(argv[6], &fileinfo); ++ else ++ { ++ /* ++ * Use the OSX defaults, as an up-stream filter created the PICT ++ * file... ++ */ ++ ++ fileinfo.st_uid = 1; ++ fileinfo.st_gid = 80; ++ } ++ ++ if (ppdfile) ++ chown(ppdfile, fileinfo.st_uid, fileinfo.st_gid); ++ ++ fchown(fd, fileinfo.st_uid, fileinfo.st_gid); ++ ++ /* ++ * Finally, run the filter to convert the file... ++ */ ++ ++ if ((pid = fork()) == 0) ++ { ++ /* ++ * Child process for pictwpstops... Redirect output of pictwpstops to a ++ * file... ++ */ ++ ++ dup2(fd, 1); ++ close(fd); ++ ++ if (!getuid()) ++ { ++ /* ++ * Change to an unpriviledged user... ++ */ ++ ++ if (setgid(fileinfo.st_gid)) ++ return (errno); ++ ++ if (setuid(fileinfo.st_uid)) ++ return (errno); ++ } ++ ++ execlp("pictwpstops", printer, argv[1], argv[2], argv[3], argv[4], argv[5], ++ filename, NULL); ++ _cupsLangPrintf(stderr, _("ERROR: Unable to exec pictwpstops: %s\n"), ++ strerror(errno)); ++ return (errno); ++ } ++ ++ close(fd); ++ ++ if (pid < 0) ++ { ++ /* ++ * Error! ++ */ ++ ++ _cupsLangPrintf(stderr, _("ERROR: Unable to fork pictwpstops: %s\n"), ++ strerror(errno)); ++ if (ppdfile) ++ unlink(ppdfile); ++ return (-1); ++ } ++ ++ /* ++ * Now wait for the filter to complete... ++ */ ++ ++ if (wait(&status) < 0) ++ { ++ _cupsLangPrintf(stderr, _("ERROR: Unable to wait for pictwpstops: %s\n"), ++ strerror(errno)); ++ close(fd); ++ if (ppdfile) ++ unlink(ppdfile); ++ return (-1); ++ } ++ ++ if (ppdfile) ++ unlink(ppdfile); ++ ++ close(fd); ++ ++ if (status) ++ { ++ if (status >= 256) ++ _cupsLangPrintf(stderr, _("ERROR: pictwpstops exited with status %d!\n"), ++ status / 256); ++ else ++ _cupsLangPrintf(stderr, _("ERROR: pictwpstops exited on signal %d!\n"), ++ status); ++ ++ return (status); ++ } ++ ++ /* ++ * Return with no errors.. ++ */ ++ ++ return (0); ++} ++#endif /* __APPLE__ */ ++ ++ ++/* ++ * 'sigterm_handler()' - Handle 'terminate' signals that stop the backend. ++ */ ++ ++static void ++sigterm_handler(int sig) /* I - Signal */ ++{ ++ (void)sig; /* remove compiler warnings... */ ++ ++ if (!job_cancelled) ++ { ++ /* ++ * Flag that the job should be cancelled... ++ */ ++ ++ job_cancelled = 1; ++ return; ++ } ++ ++ /* ++ * The scheduler already tried to cancel us once, now just terminate ++ * after removing our temp files! ++ */ ++ ++ if (tmpfilename[0]) ++ unlink(tmpfilename); ++ ++#ifdef __APPLE__ ++ if (pstmpname[0]) ++ unlink(pstmpname); ++#endif /* __APPLE__ */ ++ ++ exit(1); ++} ++ ++ ++/* ++ * End of "$Id: ipp.c 8950 2010-01-14 22:40:19Z mike $". ++ */ diff --git a/cups-1.6.0-fix-install-perms.patch b/cups-1.6.0-fix-install-perms.patch new file mode 100644 index 000000000000..2d7a77c44f3d --- /dev/null +++ b/cups-1.6.0-fix-install-perms.patch @@ -0,0 +1,25 @@ +Index: Makedefs.in +=================================================================== +--- Makedefs.in (Revision 10520) ++++ Makedefs.in (Arbeitskopie) +@@ -40,14 +40,14 @@ + # Installation programs... + # + +-INSTALL_BIN = $(LIBTOOL) $(INSTALL) -c -m 555 @INSTALL_STRIP@ +-INSTALL_COMPDATA = $(INSTALL) -c -m 444 @INSTALL_GZIP@ ++INSTALL_BIN = $(LIBTOOL) $(INSTALL) -c -m 755 @INSTALL_STRIP@ ++INSTALL_COMPDATA = $(INSTALL) -c -m 644 @INSTALL_GZIP@ + INSTALL_CONFIG = $(INSTALL) -c -m @CUPS_CONFIG_FILE_PERM@ +-INSTALL_DATA = $(INSTALL) -c -m 444 ++INSTALL_DATA = $(INSTALL) -c -m 644 + INSTALL_DIR = $(INSTALL) -d +-INSTALL_LIB = $(LIBTOOL) $(INSTALL) -c -m 555 @INSTALL_STRIP@ +-INSTALL_MAN = $(INSTALL) -c -m 444 +-INSTALL_SCRIPT = $(INSTALL) -c -m 555 ++INSTALL_LIB = $(LIBTOOL) $(INSTALL) -c -m 755 @INSTALL_STRIP@ ++INSTALL_MAN = $(INSTALL) -c -m 644 ++INSTALL_SCRIPT = $(INSTALL) -c -m 755 + + # + # Default user, group, and system groups for the scheduler... diff --git a/cups-1.6.2-statedir.patch b/cups-1.6.2-statedir.patch new file mode 100644 index 000000000000..c44ebed07c50 --- /dev/null +++ b/cups-1.6.2-statedir.patch @@ -0,0 +1,12 @@ +diff -ruN cups-1.6.2.orig/config-scripts/cups-directories.m4 cups-1.6.2/config-scripts/cups-directories.m4 +--- cups-1.6.2.orig/config-scripts/cups-directories.m4 2012-10-01 03:55:23.000000000 +0200 ++++ cups-1.6.2/config-scripts/cups-directories.m4 2013-04-02 00:11:41.000000000 +0200 +@@ -420,7 +420,7 @@ + ;; + *) + # All others +- CUPS_STATEDIR="$localstatedir/run/cups" ++ CUPS_STATEDIR="/run/cups" + ;; + esac]) + AC_DEFINE_UNQUOTED(CUPS_STATEDIR, "$CUPS_STATEDIR") diff --git a/cups-no-export-ssllibs.patch b/cups-no-export-ssllibs.patch new file mode 100644 index 000000000000..e227bd182390 --- /dev/null +++ b/cups-no-export-ssllibs.patch @@ -0,0 +1,12 @@ +diff -up cups-1.5b1/config-scripts/cups-ssl.m4.no-export-ssllibs cups-1.5b1/config-scripts/cups-ssl.m4 +--- cups-1.6.2/config-scripts/cups-ssl.m4.no-export-ssllibs 2011-05-11 02:52:08.000000000 +0200 ++++ cups-1.6.2/config-scripts/cups-ssl.m4 2011-05-23 17:47:27.000000000 +0200 +@@ -180,7 +180,7 @@ + AC_SUBST(SSLFLAGS) + AC_SUBST(SSLLIBS) + +-EXPORT_SSLLIBS="$SSLLIBS" ++EXPORT_SSLLIBS="" + AC_SUBST(EXPORT_SSLLIBS) + + dnl diff --git a/cups-no-gcrypt.patch b/cups-no-gcrypt.patch new file mode 100644 index 000000000000..0cd64b191879 --- /dev/null +++ b/cups-no-gcrypt.patch @@ -0,0 +1,11 @@ +diff -up cups-2.0rc1/config-scripts/cups-ssl.m4.no-gcry cups-2.0rc1/config-scripts/cups-ssl.m4 +--- cups-2.0rc1/config-scripts/cups-ssl.m4.no-gcry 2014-09-12 15:41:23.324760213 +0200 ++++ cups-2.0rc1/config-scripts/cups-ssl.m4 2014-09-12 15:43:13.124203363 +0200 +@@ -60,7 +60,6 @@ if test x$enable_ssl != xno; then + dnl Then look for GNU TLS... + if test $have_ssl = 0 -a "x$enable_gnutls" != "xno" -a "x$PKGCONFIG" != x; then + AC_PATH_TOOL(LIBGNUTLSCONFIG,libgnutls-config) +- AC_PATH_TOOL(LIBGCRYPTCONFIG,libgcrypt-config) + if $PKGCONFIG --exists gnutls; then + have_ssl=1 + SSLLIBS=`$PKGCONFIG --libs gnutls` diff --git a/cups-no-gzip-man.patch b/cups-no-gzip-man.patch new file mode 100644 index 000000000000..69899b9cb7d9 --- /dev/null +++ b/cups-no-gzip-man.patch @@ -0,0 +1,18 @@ +diff -up cups-1.5b1/config-scripts/cups-manpages.m4.no-gzip-man cups-1.5b1/config-scripts/cups-manpages.m4 +--- cups-1.5b1/config-scripts/cups-manpages.m4.no-gzip-man 2011-05-12 07:21:56.000000000 +0200 ++++ cups-1.5b1/config-scripts/cups-manpages.m4 2011-05-23 17:25:50.000000000 +0200 +@@ -69,10 +69,10 @@ case "$uname" in + ;; + Linux* | GNU* | Darwin*) + # Linux, GNU Hurd, and OS X +- MAN1EXT=1.gz +- MAN5EXT=5.gz +- MAN7EXT=7.gz +- MAN8EXT=8.gz ++ MAN1EXT=1 ++ MAN5EXT=5 ++ MAN7EXT=7 ++ MAN8EXT=8 + MAN8DIR=8 + ;; + *) diff --git a/cups.install b/cups.install new file mode 100644 index 000000000000..77fac9326d27 --- /dev/null +++ b/cups.install @@ -0,0 +1,28 @@ +post_install() { + if [ -x usr/bin/xdg-icon-resource ]; then + xdg-icon-resource forceupdate --theme hicolor 2> /dev/null + fi + echo ">> If you use an HTTPS connection to CUPS, the first time you access" + echo ">> the interface it may take a very long time before the site comes up." + echo ">> This is because the first request triggers the generation of the CUPS" + echo ">> SSL certificates which can be a very time-consuming job." +} + +post_upgrade() { + if [ -x usr/bin/xdg-icon-resource ]; then + xdg-icon-resource forceupdate --theme hicolor 2> /dev/null + fi + + if [ "`vercmp $2 2.0.0-1`" -lt 0 ]; then + # important upgrade notice + echo "> systemd unit names have been renamed" + echo "> you should systemctl stop and disable cups.service and" + echo "> systemctl daemon-reload, start and enable org.cups.cupsd.service" + fi +} + +post_remove() { + if [ -x usr/bin/xdg-icon-resource ]; then + xdg-icon-resource forceupdate --theme hicolor 2> /dev/null + fi +} diff --git a/cups.logrotate b/cups.logrotate new file mode 100644 index 000000000000..19e12101be2b --- /dev/null +++ b/cups.logrotate @@ -0,0 +1,5 @@ +/var/log/cups/*_log { + missingok + notifempty + sharedscripts +} diff --git a/cups.pam b/cups.pam new file mode 100644 index 000000000000..53724d1f86a7 --- /dev/null +++ b/cups.pam @@ -0,0 +1,3 @@ +auth required pam_unix.so +account required pam_unix.so +session required pam_unix.so |