From b423cd4cb9fa8cf030cc046a59c28196f3edf6b4 Mon Sep 17 00:00:00 2001 From: jlovell Date: Tue, 28 Feb 2006 17:54:14 +0000 Subject: [PATCH] Load cups into easysw/current. git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@69 a1ca3aef-8c08-0410-bb20-df032aa958be --- CHANGES.txt | 22 +- CREDITS.txt | 3 +- Makedefs.in | 15 +- Makefile | 8 +- backend/ieee1284.c | 8 +- backend/ipp.c | 229 +- backend/parallel.c | 13 +- backend/serial.c | 31 +- backend/usb-unix.c | 6 +- backend/usb.c | 6 +- cgi-bin/classes.c | 10 +- cgi-bin/help.c | 15 +- cgi-bin/ipp-var.c | 12 +- cgi-bin/printers.c | 174 +- conf/Makefile | 14 +- config-scripts/cups-ldap.m4 | 50 + config-scripts/cups-scripting.m4 | 21 +- config-scripts/cups-threads.m4 | 32 +- config.h.in | 14 +- configure.in | 9 +- cups/cups.h | 13 +- cups/dest.c | 41 +- cups/encode.c | 88 +- cups/file.c | 46 +- cups/getputfile.c | 37 +- cups/http-addr.c | 157 +- cups/http-support.c | 42 +- cups/http.c | 138 +- cups/http.h | 7 +- cups/mark.c | 84 +- cups/options.c | 473 +- cups/ppd.c | 31 +- cups/ppd.h | 22 +- cups/request.c | 37 +- cups/testfile.c | 8 +- cups/testi18n.c | 10 +- cups/usersys.c | 102 +- cups/util.c | 13 +- doc/Makefile | 9 +- doc/help/api-array.html | 2 +- doc/help/api-cups.html | 2 +- doc/help/api-filedir.html | 2 +- doc/help/api-filter.html | 2 +- doc/help/api-httpipp.html | 2 +- doc/help/api-ppd.html | 10 +- doc/help/api-raster.html | 573 ++ doc/help/cupsd-conf-reference.html | 4 + doc/help/spec-command.html | 108 + doc/help/spec-ppd.html | 42 +- doc/images/clean-print-heads.gif | Bin 0 -> 615 bytes doc/images/print-self-test-page.gif | Bin 0 -> 674 bytes filter/Makefile | 15 +- filter/api-raster.shtml | 60 + filter/hpgl-input.c | 29 +- filter/image-private.h | 19 +- filter/image-zoom.c | 34 +- filter/image.h | 18 +- filter/imagetoraster.c | 14 +- filter/raster.c | 28 +- filter/raster.h | 6 +- locale/Makefile | 6 +- locale/cups.pot | 313 +- locale/cups_fr.po | 3245 -------- locale/cups_ja.po | 332 +- man/Makefile | 5 +- man/client.conf.man.in | 58 + man/{lpoptions.man => lpoptions.man.in} | 10 +- packaging/cups.list.in | 6 +- packaging/cups.spec.in | 30 +- scheduler/Makefile | 11 +- scheduler/auth.c | 8 +- scheduler/classes.c | 29 +- scheduler/client.c | 316 +- scheduler/conf.c | 60 +- scheduler/conf.h | 7 +- scheduler/cups-deviced.c | 8 +- scheduler/cups-lpd.c | 10 +- scheduler/cupsd.h | 7 +- scheduler/dirsvc.c | 651 +- scheduler/dirsvc.h | 35 +- scheduler/filter.c | 6 +- scheduler/ipp.c | 7615 +++++++++--------- scheduler/job.c | 6 +- scheduler/log.c | 9 +- scheduler/main.c | 20 +- scheduler/printers.c | 396 +- scheduler/printers.h | 9 +- scheduler/server.c | 16 +- scheduler/testdirsvc.c | 76 +- scheduler/type.c | 12 +- scripting/java/src/com/easysw/cups/Cups.java | 16 +- scripting/php/Dependencies | 8 +- scripting/php/Example/phpcups.inc.php4 | 310 - scripting/php/Makefile | 15 +- scripting/php/README | 160 +- scripting/php/config.m4 | 60 - scripting/php/php_phpcups.h | 87 - scripting/php/phpcups.c | 1511 +--- scripting/php/phpcups.h | 79 + scripting/php/phpcups.php | 50 +- systemv/cupsaddsmb.c | 8 +- systemv/cupstestppd.c | 240 +- systemv/lpadmin.c | 80 +- systemv/lpstat.c | 8 +- templates/Makefile | 5 +- templates/maintenance.tmpl | 2 + templates/printers.tmpl | 6 +- templates/test-page.tmpl | 2 +- tools/makesrcdist | 2 +- 109 files changed, 8711 insertions(+), 10270 deletions(-) create mode 100644 config-scripts/cups-ldap.m4 create mode 100644 doc/help/api-raster.html create mode 100644 doc/help/spec-command.html create mode 100644 doc/images/clean-print-heads.gif create mode 100644 doc/images/print-self-test-page.gif create mode 100644 filter/api-raster.shtml delete mode 100644 locale/cups_fr.po create mode 100644 man/client.conf.man.in rename man/{lpoptions.man => lpoptions.man.in} (92%) delete mode 100644 scripting/php/Example/phpcups.inc.php4 delete mode 100644 scripting/php/config.m4 delete mode 100644 scripting/php/php_phpcups.h create mode 100644 scripting/php/phpcups.h mode change 100644 => 100755 scripting/php/phpcups.php create mode 100644 templates/maintenance.tmpl diff --git a/CHANGES.txt b/CHANGES.txt index a9d78226d..e684a4d2a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,8 +1,28 @@ -CHANGES.txt - 02/17/2006 +CHANGES.txt - 02/25/2006 ------------------------ CHANGES IN CUPS V1.2.0b1 + - The serial backend now supports Equinox 8-port serial + hubs (STR #526) + - The IPP backend now supports a compression option to + compress print files as they are sent to the remote + server (STR #956) + - The CUPS browse protocol now supports passing of + default options and browse timeout values from the + server to the clients (STR #800) + - Implicit classes that timed out could cause the + scheduler to crash (STR #1439) + - Added DragonFly support in local device backends (STR + #1362) + - Added LDAP printer browsing support (STR #338) + - Added official support for printer maintenance commands + via the CUPS Command file format and hooks in the + printer-type and web interfaces (STR #932) + - The HP-GL/2 filter could get in an infinite loop trying + to convert HP-PCL files (STR #1415) + - CUPS now implements the HTTP/1.1 Expect header (STR + #1407) - Options in PPD files are no longer automatically put in an "Extra" group; rather, all options that are not inside an Open/CloseGroup will be placed in the diff --git a/CREDITS.txt b/CREDITS.txt index 585072bb3..00d3fa448 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1,4 +1,4 @@ -CREDITS.txt - 02/17/2006 +CREDITS.txt - 02/23/2006 ------------------------ Few projects are completed by one person, and CUPS is no exception. We'd @@ -31,6 +31,7 @@ like to thank the following individuals for their contributions: Andrea Suatoni - IRIX desktop integration and testing. Tomohiro Kato - Japanese localization. Tim Waugh - Lots of patches, testing, and Linux integration. + Yugami - LDAP browsing support. If I've missed someone, please let me know by sending an email to "mike@easysw.com". diff --git a/Makedefs.in b/Makedefs.in index 06a2ceb9b..4520f8b2f 100644 --- a/Makedefs.in +++ b/Makedefs.in @@ -1,5 +1,5 @@ # -# "$Id: Makedefs.in 5136 2006-02-19 18:46:46Z mike $" +# "$Id: Makedefs.in 5194 2006-02-27 20:57:07Z mike $" # # Common makefile definitions for the Common UNIX Printing System (CUPS). # @@ -37,6 +37,7 @@ LD = @LD@ LIBTOOL = @LIBTOOL@ LN = @LN@ -sf MV = @MV@ +PHPCONFIG = @PHPCONFIG@ RANLIB = @RANLIB@ RM = @RM@ -f SED = @SED@ @@ -78,6 +79,7 @@ CUPS_LOG_FILE_PERM = @CUPS_LOG_FILE_PERM@ LIBCUPS = @LIBCUPS@ LIBCUPSIMAGE = @LIBCUPSIMAGE@ LIBJPEG = @LIBJPEG@ +LIBLDAP = @LIBLDAP@ LIBMALLOC = @LIBMALLOC@ LIBPAPER = @LIBPAPER@ LIBPNG = @LIBPNG@ @@ -102,11 +104,11 @@ INSTALLSTATIC = @INSTALLSTATIC@ ARFLAGS = @ARFLAGS@ BACKLIBS = @BACKLIBS@ CFLAGS = -I.. $(RC_CFLAGS) $(SSLFLAGS) @CPPFLAGS@ @CFLAGS@ \ - @LARGEFILE@ $(OPTIONS) + @LARGEFILE@ @PTHREAD_FLAGS@ $(OPTIONS) COMMONLIBS = @LIBS@ CUPSDLIBS = @CUPSDLIBS@ CXXFLAGS = -I.. $(RC_CFLAGS) $(SSLFLAGS) @CPPFLAGS@ @CXXFLAGS@ \ - @LARGEFILE@ $(OPTIONS) + @LARGEFILE@ @PTHREAD_FLAGS@ $(OPTIONS) CXXLIBS = @CXXLIBS@ DSOFLAGS = @DSOFLAGS@ DSOLIBS = @DSOLIBS@ $(COMMONLIBS) @@ -118,6 +120,7 @@ LIBS = $(LINKCUPS) $(COMMONLIBS) OPTIM = @OPTIM@ OPTIONS = PAMLIBS = @PAMLIBS@ +PHPDIR = @PHPDIR@ SSLFLAGS = @SSLFLAGS@ SSLLIBS = @SSLLIBS@ LAUNCHDLIBS = @LAUNCHDLIBS@ @@ -178,10 +181,10 @@ MAN7EXT = @MAN7EXT@ MAN8EXT = @MAN8EXT@ MAN8DIR = @MAN8DIR@ -PAMDIR = $(BUILDROOT)@PAMDIR@ +PAMDIR = @PAMDIR@ PAMFILE = @PAMFILE@ -DEFAULT_LAUNCHD_CONF = @DEFAULT_LAUNCHD_CONF@ +DEFAULT_LAUNCHD_CONF = @DEFAULT_LAUNCHD_CONF@ DBUSDIR = @DBUSDIR@ @@ -212,5 +215,5 @@ DBUSDIR = @DBUSDIR@ # -# End of "$Id: Makedefs.in 5136 2006-02-19 18:46:46Z mike $" +# End of "$Id: Makedefs.in 5194 2006-02-27 20:57:07Z mike $" # diff --git a/Makefile b/Makefile index 428bf20fe..053f65f7f 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile 5136 2006-02-19 18:46:46Z mike $" +# "$Id: Makefile 5185 2006-02-26 15:27:14Z mike $" # # Top-level Makefile for the Common UNIX Printing System (CUPS). # @@ -29,7 +29,8 @@ include Makedefs # DIRS = cups backend berkeley cgi-bin filter locale man monitor \ - notifier pdftops scheduler systemv test + notifier pdftops scheduler systemv test \ + $(PHPDIR) # @@ -117,6 +118,7 @@ install: installhdrs fi \ fi if test "x$(DBUSDIR)" != "x"; then \ + echo Installing cups.conf in $(DBUSDIR)...;\ $(INSTALL_DIR) $(BUILDROOT)$(DBUSDIR); \ $(INSTALL_DATA) packaging/cups-dbus.conf $(BUILDROOT)$(DBUSDIR)/cups.conf; \ fi @@ -175,5 +177,5 @@ tardist: # -# End of "$Id: Makefile 5136 2006-02-19 18:46:46Z mike $". +# End of "$Id: Makefile 5185 2006-02-26 15:27:14Z mike $". # diff --git a/backend/ieee1284.c b/backend/ieee1284.c index 6152c4c7a..52f27db18 100644 --- a/backend/ieee1284.c +++ b/backend/ieee1284.c @@ -1,5 +1,5 @@ /* - * "$Id: ieee1284.c 4903 2006-01-10 20:02:46Z mike $" + * "$Id: ieee1284.c 5198 2006-02-27 21:58:43Z mike $" * * IEEE-1284 support functions for the Common UNIX Printing System (CUPS). * @@ -76,9 +76,9 @@ get_device_id( #ifdef __linux int length; /* Length of device ID info */ #endif /* __linux */ -#ifdef __sun +#if defined(__sun) && defined(ECPPIOC_GETDEVID) struct ecpp_device_id did; /* Device ID buffer */ -#endif /* __sun */ +#endif /* __sun && ECPPIOC_GETDEVID */ DEBUG_printf(("get_device_id(fd=%d, device_id=%p, device_id_size=%d, " "make_model=%p, make_model_size=%d, scheme=\"%s\", " @@ -369,5 +369,5 @@ get_device_id( /* - * End of "$Id: ieee1284.c 4903 2006-01-10 20:02:46Z mike $". + * End of "$Id: ieee1284.c 5198 2006-02-27 21:58:43Z mike $". */ diff --git a/backend/ipp.c b/backend/ipp.c index 9feb672b0..07699d655 100644 --- a/backend/ipp.c +++ b/backend/ipp.c @@ -1,5 +1,5 @@ /* - * "$Id: ipp.c 5133 2006-02-19 15:01:12Z mike $" + * "$Id: ipp.c 5180 2006-02-26 01:31:45Z mike $" * * IPP backend for the Common UNIX Printing System (CUPS). * @@ -26,7 +26,9 @@ * 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_printer_state() - Report the printer state. @@ -74,6 +76,9 @@ static void cancel_job(http_t *http, const char *uri, int id, static void check_printer_state(http_t *http, const char *uri, const char *resource, const char *user, int version); +#ifdef HAVE_LIBZ +static void compress_files(int num_files, char **files); +#endif /* HAVE_LIBZ */ static const char *password_cb(const char *); static int report_printer_state(ipp_t *ipp); @@ -116,7 +121,8 @@ main(int argc, /* I - Number of command-line args */ ipp_t *request, /* IPP request */ *response, /* IPP response */ *supported; /* get-printer-attributes response */ - int waitjob, /* Wait for job complete? */ + 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 */ @@ -224,64 +230,11 @@ main(int argc, /* I - Number of command-line args */ if (!strcmp(method, "https")) cupsSetEncryption(HTTP_ENCRYPT_ALWAYS); - /* - * 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; /* Temporary file */ - char buffer[8192]; /* Buffer for copying */ - int bytes; /* Number of bytes read */ - - - if ((fd = cupsTempFd(tmpfilename, sizeof(tmpfilename))) < 0) - { - perror("ERROR: unable to create temporary file"); - return (CUPS_BACKEND_FAILED); - } - - while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0) - if (write(fd, buffer, bytes) < bytes) - { - perror("ERROR: unable to write to temporary file"); - close(fd); - unlink(tmpfilename); - return (CUPS_BACKEND_FAILED); - } - - close(fd); - - /* - * Point to the single file from stdin... - */ - - filename = tmpfilename; - files = &filename; - num_files = 1; - } - else - { - /* - * Point to the files on the command-line... - */ - - num_files = argc - 6; - files = argv + 6; - } - - fprintf(stderr, "DEBUG: %d files to send in job...\n", num_files); - /* * See if there are any options... */ + compression = 0; version = 1; waitjob = 1; waitprinter = 1; @@ -385,6 +338,15 @@ main(int argc, /* I - Number of command-line args */ 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 { /* @@ -397,6 +359,74 @@ main(int argc, /* I - Number of command-line args */ } } + /* + * 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 */ + cups_file_t *fp; /* Temporary file */ + char buffer[8192]; /* Buffer for copying */ + int bytes; /* Number of bytes read */ + + + if ((fd = cupsTempFd(tmpfilename, sizeof(tmpfilename))) < 0) + { + perror("ERROR: unable to create temporary file"); + return (CUPS_BACKEND_FAILED); + } + + if ((fp = cupsFileOpenFd(fd, compression ? "w9" : "w")) == NULL) + { + perror("ERROR: unable to open temporary file"); + close(fd); + unlink(tmpfilename); + return (CUPS_BACKEND_FAILED); + } + + while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0) + if (cupsFileWrite(fp, buffer, bytes) < bytes) + { + perror("ERROR: unable to write to temporary file"); + cupsFileClose(fp); + unlink(tmpfilename); + return (CUPS_BACKEND_FAILED); + } + + cupsFileClose(fp); + + /* + * Point to the single file from stdin... + */ + + filename = tmpfilename; + files = &filename; + num_files = 1; + } + else + { + /* + * Point to the files on the command-line... + */ + + num_files = argc - 6; + files = argv + 6; + +#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... */ @@ -745,6 +775,12 @@ main(int argc, /* I - Number of command-line args */ 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... */ @@ -1053,6 +1089,14 @@ main(int argc, /* I - Number of command-line args */ 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); @@ -1151,6 +1195,77 @@ check_printer_state( } +#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[65536]; /* 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) + { + perror("ERROR: Unable to create temporary compressed print file"); + exit(CUPS_BACKEND_FAILED); + } + + if ((out = cupsFileOpenFd(fd, "w9")) == NULL) + { + perror("ERROR: Unable to open temporary compressed print file"); + exit(CUPS_BACKEND_FAILED); + } + + if ((in = cupsFileOpen(files[i], "r")) == NULL) + { + fprintf(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) + { + fprintf(stderr, "ERROR: Unable to write %d bytes to \"%s\": %s\n", + 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, outinfo.st_size); + } +} +#endif /* HAVE_LIBZ */ + + /* * 'password_cb()' - Disable the password prompt for cupsDoFileRequest(). */ @@ -1500,5 +1615,5 @@ sigterm_handler(int sig) /* I - Signal */ /* - * End of "$Id: ipp.c 5133 2006-02-19 15:01:12Z mike $". + * End of "$Id: ipp.c 5180 2006-02-26 01:31:45Z mike $". */ diff --git a/backend/parallel.c b/backend/parallel.c index 1f559ffaf..3731b378c 100644 --- a/backend/parallel.c +++ b/backend/parallel.c @@ -1,5 +1,5 @@ /* - * "$Id: parallel.c 5099 2006-02-13 02:46:10Z mike $" + * "$Id: parallel.c 5194 2006-02-27 20:57:07Z mike $" * * Parallel port backend for the Common UNIX Printing System (CUPS). * @@ -40,9 +40,14 @@ #include #include #include -#include #include "ieee1284.c" +#ifdef __hpux +# include +#else +# include +#endif /* __hpux */ + #ifdef WIN32 # include #else @@ -686,7 +691,7 @@ list_devices(void) printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d\"\n", device, i + 1); } } -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) int i; /* Looping var */ int fd; /* File descriptor */ char device[255]; /* Device filename */ @@ -728,5 +733,5 @@ list_devices(void) /* - * End of "$Id: parallel.c 5099 2006-02-13 02:46:10Z mike $". + * End of "$Id: parallel.c 5194 2006-02-27 20:57:07Z mike $". */ diff --git a/backend/serial.c b/backend/serial.c index 66a0354cf..7d8abe786 100644 --- a/backend/serial.c +++ b/backend/serial.c @@ -1,5 +1,5 @@ /* - * "$Id: serial.c 5099 2006-02-13 02:46:10Z mike $" + * "$Id: serial.c 5194 2006-02-27 20:57:07Z mike $" * * Serial port backend for the Common UNIX Printing System (CUPS). * @@ -51,7 +51,11 @@ # include # include # include -# include +# ifdef __hpux +# include +# else +# include +# endif /* __hpux */ # ifdef HAVE_SYS_IOCTL_H # include # endif /* HAVE_SYS_IOCTL_H */ @@ -653,13 +657,13 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ void list_devices(void) { -#if defined(__hpux) || defined(__sgi) || defined(__sun) || defined(__FreeBSD__) || defined(__OpenBSD__) +#if defined(__hpux) || defined(__sgi) || defined(__sun) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) static char *funky_hex = "0123456789abcdefghijklmnopqrstuvwxyz"; /* Funky hex numbering used for some devices */ #endif /* __hpux || __sgi || __sun || __FreeBSD__ || __OpenBSD__ */ #if defined(__linux) || defined(linux) || defined(__linux__) - int i; /* Looping var */ + int i, j; /* Looping vars */ int fd; /* File descriptor */ char device[255]; /* Device filename */ @@ -690,6 +694,21 @@ list_devices(void) device, i + 1); } } + + for (i = 0; i < 64; i ++) + { + for (j = 0; j < 8; j ++) + { + sprintf(device, "/dev/ttyQ%02de%d", i, j); + if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) + { + close(fd); + printf("serial serial:%s?baud=115200 \"Unknown\" " + "\"Equinox ESP %d Port #%d\"\n", + device, i, j + 1); + } + } + } #elif defined(__sgi) int i, j, n; /* Looping vars */ char device[255]; /* Device filename */ @@ -903,7 +922,7 @@ list_devices(void) printf("serial serial:%s?baud=38400 \"Unknown\" \"Serial Port #%d\"\n", device, i + 1); } -#elif defined(__FreeBSD__) || defined(__OpenBSD__) +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) int i, j; /* Looping vars */ int fd; /* File descriptor */ char device[255]; /* Device filename */ @@ -1111,5 +1130,5 @@ list_devices(void) /* - * End of "$Id: serial.c 5099 2006-02-13 02:46:10Z mike $". + * End of "$Id: serial.c 5194 2006-02-27 20:57:07Z mike $". */ diff --git a/backend/usb-unix.c b/backend/usb-unix.c index b5aeb4548..b28222202 100644 --- a/backend/usb-unix.c +++ b/backend/usb-unix.c @@ -1,5 +1,5 @@ /* - * "$Id: usb-unix.c 5099 2006-02-13 02:46:10Z mike $" + * "$Id: usb-unix.c 5162 2006-02-24 03:15:13Z mike $" * * USB port backend for the Common UNIX Printing System (CUPS). * @@ -394,7 +394,7 @@ list_devices(void) } #elif defined(__hpux) #elif defined(__osf) -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) int i; /* Looping var */ char device[255]; /* Device filename */ @@ -616,5 +616,5 @@ open_device(const char *uri) /* I - Device URI */ /* - * End of "$Id: usb-unix.c 5099 2006-02-13 02:46:10Z mike $". + * End of "$Id: usb-unix.c 5162 2006-02-24 03:15:13Z mike $". */ diff --git a/backend/usb.c b/backend/usb.c index 92fae2edd..ede0292d7 100644 --- a/backend/usb.c +++ b/backend/usb.c @@ -1,5 +1,5 @@ /* - * "$Id: usb.c 5023 2006-01-29 14:39:44Z mike $" + * "$Id: usb.c 5162 2006-02-24 03:15:13Z mike $" * * USB port backend for the Common UNIX Printing System (CUPS). * @@ -72,7 +72,7 @@ int print_device(const char *uri, const char *hostname, #ifdef __APPLE__ # include "usb-darwin.c" -#elif defined(__linux) || defined(__sun) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#elif defined(__linux) || defined(__sun) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) # include "usb-unix.c" #else /* @@ -265,5 +265,5 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ /* - * End of "$Id: usb.c 5023 2006-01-29 14:39:44Z mike $". + * End of "$Id: usb.c 5162 2006-02-24 03:15:13Z mike $". */ diff --git a/cgi-bin/classes.c b/cgi-bin/classes.c index abf19ffff..2aa9bed78 100644 --- a/cgi-bin/classes.c +++ b/cgi-bin/classes.c @@ -1,5 +1,5 @@ /* - * "$Id: classes.c 5097 2006-02-10 04:06:23Z mike $" + * "$Id: classes.c 5160 2006-02-24 01:14:18Z mike $" * * Class status CGI for the Common UNIX Printing System (CUPS). * @@ -83,10 +83,8 @@ main(int argc, /* I - Number of command-line arguments */ * See if we are displaying a printer or all classes... */ - if (!strcmp(argv[0], "/") || strstr(argv[0], "classes.cgi")) - pclass = NULL; - else - pclass = argv[0]; + if ((pclass = getenv("PATH_INFO")) != NULL) + pclass ++; /* * See who is logged in... @@ -460,5 +458,5 @@ show_class(http_t *http, /* I - Connection to server */ /* - * End of "$Id: classes.c 5097 2006-02-10 04:06:23Z mike $". + * End of "$Id: classes.c 5160 2006-02-24 01:14:18Z mike $". */ diff --git a/cgi-bin/help.c b/cgi-bin/help.c index d616f28bd..efee0fe5b 100644 --- a/cgi-bin/help.c +++ b/cgi-bin/help.c @@ -111,11 +111,12 @@ main(int argc, /* I - Number of command-line arguments */ fprintf(stderr, "argv[%d]=\"%s\"\n", i, argv[i]); if ((helpfile = getenv("PATH_INFO")) != NULL) + { helpfile ++; - else if (strstr(argv[0], "help.cgi")) - helpfile = NULL; - else - helpfile = argv[0]; + + if (!*helpfile) + helpfile = NULL; + } if (helpfile) { @@ -180,6 +181,8 @@ main(int argc, /* I - Number of command-line arguments */ topic = cgiGetVariable("TOPIC"); si = helpSearchIndex(hi, query, topic, helpfile); + fprintf(stderr, "DEBUG: query=\"%s\", topic=\"%s\"\n", query, topic); + if (si) { help_node_t *nn; /* Parent node */ @@ -189,9 +192,9 @@ main(int argc, /* I - Number of command-line arguments */ "DEBUG: si=%p, si->sorted=%p, cupsArrayCount(si->sorted)=%d\n", si, si->sorted, cupsArrayCount(si->sorted)); - for (n = (help_node_t *)cupsArrayFirst(si->sorted); + for (i = 0, n = (help_node_t *)cupsArrayFirst(si->sorted); n; - n = (help_node_t *)cupsArrayNext(si->sorted)) + i ++, n = (help_node_t *)cupsArrayNext(si->sorted)) { if (helpfile && n->anchor) snprintf(line, sizeof(line), "#%s", n->anchor); diff --git a/cgi-bin/ipp-var.c b/cgi-bin/ipp-var.c index dbc2ea2a5..fb598f84f 100644 --- a/cgi-bin/ipp-var.c +++ b/cgi-bin/ipp-var.c @@ -1,5 +1,5 @@ /* - * "$Id: ipp-var.c 5097 2006-02-10 04:06:23Z mike $" + * "$Id: ipp-var.c 5184 2006-02-26 15:13:44Z mike $" * * CGI <-> IPP variable routines for the Common UNIX Printing System (CUPS). * @@ -896,7 +896,8 @@ cgiSetIPPObjectVars( break; case IPP_TAG_URI : - if (strchr(attr->values[i].string.text, ':') != NULL) + if (strchr(attr->values[i].string.text, ':') && + strcmp(name, "device_uri")) { /* * Rewrite URIs... @@ -1151,7 +1152,10 @@ cgiShowJobs(http_t *http, /* I - Connection to server */ if ((var = cgiGetVariable("ORDER")) != NULL) ascending = !strcasecmp(var, "asc"); else - ascending = 1; + { + ascending = !which_jobs || !strcasecmp(which_jobs, "not-completed"); + cgiSetVariable("ORDER", ascending ? "asc" : "dec"); + } if (ascending) { @@ -1273,5 +1277,5 @@ cgiText(const char *message) /* I - Message */ /* - * End of "$Id: ipp-var.c 5097 2006-02-10 04:06:23Z mike $". + * End of "$Id: ipp-var.c 5184 2006-02-26 15:13:44Z mike $". */ diff --git a/cgi-bin/printers.c b/cgi-bin/printers.c index b745e2336..0b4a3a8cb 100644 --- a/cgi-bin/printers.c +++ b/cgi-bin/printers.c @@ -1,5 +1,5 @@ /* - * "$Id: printers.c 5104 2006-02-15 03:21:04Z mike $" + * "$Id: printers.c 5160 2006-02-24 01:14:18Z mike $" * * Printer status CGI for the Common UNIX Printing System (CUPS). * @@ -24,6 +24,7 @@ * Contents: * * main() - Main entry for CGI. + * print_command() - Send a print command to the printer. * show_all_printers() - Show all printers... * show_printer() - Show a single printer. */ @@ -33,12 +34,14 @@ */ #include "cgi-private.h" +#include /* * Local functions... */ +void print_command(http_t *http, const char *printer, const char *command); void show_all_printers(http_t *http, const char *username); void show_printer(http_t *http, const char *printer); @@ -83,10 +86,8 @@ main(int argc, /* I - Number of command-line arguments */ * See if we are displaying a printer or all printers... */ - if (!strcmp(argv[0], "/") || strstr(argv[0], "printers.cgi")) - printer = NULL; - else - printer = argv[0]; + if ((printer = getenv("PATH_INFO")) != NULL) + printer ++; /* * See who is logged in... @@ -145,6 +146,10 @@ main(int argc, /* I - Number of command-line arguments */ else show_printer(http, printer); } + else if (!strcasecmp(op, "print-self-test-page") && printer) + print_command(http, printer, "PrintSelfTestPage"); + else if (!strcasecmp(op, "clean-print-heads") && printer) + print_command(http, printer, "Clean all"); else if (!strcasecmp(op, "print-test-page") && printer) cgiPrintTestPage(http, printer); else if (!strcasecmp(op, "move-jobs") && printer) @@ -178,6 +183,124 @@ main(int argc, /* I - Number of command-line arguments */ } +/* + * 'print_command()' - Send a print command to the printer. + */ + +void +print_command(http_t *http, /* I - Connection to server */ + const char *printer, /* I - Printer */ + const char *command) /* I - Command to send */ +{ + cups_file_t *fp; /* File pointer */ + char filename[1024]; /* Temporary file */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + char uri[HTTP_MAX_URI], /* Printer URI */ + resource[1024], /* POST resource path */ + refresh[1024]; /* Refresh URL */ + const char *user; /* Username */ + + + /* + * See who is logged in... + */ + + if ((user = getenv("REMOTE_USER")) == NULL) + user = "guest"; + + /* + * Create the CUPS command file to print... + */ + + if ((fp = cupsTempFile2(filename, sizeof(filename))) == NULL) + { + cgiStartHTML(cgiText(_("Printer Maintenance"))); + cgiSetVariable("MESSAGE", _("Unable to create temporary file:")); + cgiSetVariable("ERROR", strerror(errno)); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + return; + } + + cupsFilePuts(fp, "#CUPS-COMMAND\n"); + cupsFilePrintf(fp, "%s\n", command); + cupsFileClose(fp); + + /* + * Point to the printer... + */ + + snprintf(resource, sizeof(resource), "/printers/%s", printer); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", ippPort(), "/printers/%s", printer); + + /* + * Build an IPP_PRINT_JOB request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * requesting-user-name + * document-format + */ + + request = ippNewRequest(IPP_PRINT_JOB); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, user); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", + NULL, "Printer Maintenance"); + + ippAddString(request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format", + NULL, "application/postscript"); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoFileRequest(http, request, resource, + filename)) != NULL) + { + cgiSetIPPVars(response, NULL, NULL, NULL, 0); + + ippDelete(response); + } + + unlink(filename); + + if (cupsLastError() <= IPP_OK_CONFLICT) + { + /* + * Automatically reload the printer status page... + */ + + cgiFormEncode(uri, resource, sizeof(uri)); + snprintf(refresh, sizeof(refresh), "2;%s", uri); + cgiSetVariable("refresh_page", refresh); + } + + cgiStartHTML(cgiText(_("Printer Maintenance"))); + + if (cupsLastError() > IPP_OK_CONFLICT) + cgiShowIPPError(_("Unable to send maintenance job:")); + else + { + cgiSetVariable("PRINTER_NAME", printer); + + cgiCopyTemplateLang("maintenance.tmpl"); + } + + cgiEndHTML(); +} + + /* * 'show_all_printers()' - Show all printers... */ @@ -190,7 +313,8 @@ show_all_printers(http_t *http, /* I - Connection to server */ ipp_t *request, /* IPP request */ *response; /* IPP response */ cups_array_t *printers; /* Array of printer objects */ - ipp_attribute_t *printer; /* Printer object */ + ipp_attribute_t *printer, /* Printer object */ + *attr; /* Current attribute */ int ascending, /* Order of printers (0 = descending) */ first, /* First printer to show */ count; /* Number of printers */ @@ -284,14 +408,42 @@ show_all_printers(http_t *http, /* I - Connection to server */ for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, first); i < CUPS_PAGE_MAX && printer; i ++, printer = (ipp_attribute_t *)cupsArrayNext(printers)) + { cgiSetIPPObjectVars(printer, NULL, i); + + cgiSetArray("cupscommand", i, "0"); + + for (attr = printer; attr; attr = attr->next) + if (attr->group_tag != IPP_TAG_PRINTER || !attr->name) + break; + else if (!strcmp(attr->name, "printer-type")) + { + if (attr->values[0].integer & CUPS_PRINTER_COMMANDS) + cgiSetArray("cupscommand", i, "1"); + break; + } + } } else { for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, count - first - 1); i < CUPS_PAGE_MAX && printer; i ++, printer = (ipp_attribute_t *)cupsArrayPrev(printers)) + { cgiSetIPPObjectVars(printer, NULL, i); + + cgiSetArray("cupscommand", i, "0"); + + for (attr = printer; attr; attr = attr->next) + if (attr->group_tag == IPP_TAG_ZERO || !attr->name) + break; + else if (!strcmp(attr->name, "printer-type")) + { + if (attr->values[0].integer & CUPS_PRINTER_COMMANDS) + cgiSetArray("cupscommand", i, "1"); + break; + } + } } /* @@ -419,6 +571,14 @@ show_printer(http_t *http, /* I - Connection to server */ cgiSetIPPVars(response, NULL, NULL, NULL, 0); + if ((attr = ippFindAttribute(response, "printer-type", + IPP_TAG_ENUM)) != NULL) + { + cgiSetVariable("cupscommand", + (attr->values[0].integer & CUPS_PRINTER_COMMANDS) ? + "1" : "0"); + } + if (printer && (attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL && attr->values[0].integer == IPP_PRINTER_PROCESSING) @@ -473,5 +633,5 @@ show_printer(http_t *http, /* I - Connection to server */ /* - * End of "$Id: printers.c 5104 2006-02-15 03:21:04Z mike $". + * End of "$Id: printers.c 5160 2006-02-24 01:14:18Z mike $". */ diff --git a/conf/Makefile b/conf/Makefile index 6949cb3db..82a796509 100644 --- a/conf/Makefile +++ b/conf/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile 5126 2006-02-17 16:11:30Z mike $" +# "$Id: Makefile 5185 2006-02-26 15:27:14Z mike $" # # Configuration file makefile for the Common UNIX Printing System (CUPS). # @@ -70,16 +70,16 @@ install: all $(INSTALL_CONFIG) $$file $(SERVERROOT) ; \ chgrp $(CUPS_GROUP) $(SERVERROOT)/$$file || true; \ done - -if test x$(PAMDIR) != x$(BUILDROOT); then \ - $(INSTALL_DIR) -m 755 $(PAMDIR); \ - if test -r $(PAMDIR)/cups/$(PAMFILE) ; then \ - $(INSTALL_DATA) $(PAMFILE) $(PAMDIR)/cups.N ; \ + -if test x$(PAMDIR) != x; then \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(PAMDIR); \ + if test -r $(BUILDROOT)$(PAMDIR)/cups/$(PAMFILE) ; then \ + $(INSTALL_DATA) $(PAMFILE) $(BUILDROOT)$(PAMDIR)/cups.N ; \ else \ - $(INSTALL_DATA) $(PAMFILE) $(PAMDIR)/cups ; \ + $(INSTALL_DATA) $(PAMFILE) $(BUILDROOT)$(PAMDIR)/cups ; \ fi ; \ fi # -# End of "$Id: Makefile 5126 2006-02-17 16:11:30Z mike $". +# End of "$Id: Makefile 5185 2006-02-26 15:27:14Z mike $". # diff --git a/config-scripts/cups-ldap.m4 b/config-scripts/cups-ldap.m4 new file mode 100644 index 000000000..3c3e8ed1d --- /dev/null +++ b/config-scripts/cups-ldap.m4 @@ -0,0 +1,50 @@ +dnl +dnl "$Id$" +dnl +dnl LDAP configuration stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2003-2006 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Easy Software Products and are protected by Federal +dnl copyright law. Distribution and use rights are outlined in the file +dnl "LICENSE.txt" which should have been included with this file. If this +dnl file is missing or damaged please contact Easy Software Products +dnl at: +dnl +dnl Attn: CUPS Licensing Information +dnl Easy Software Products +dnl 44141 Airport View Drive, Suite 204 +dnl Hollywood, Maryland 20636 USA +dnl +dnl Voice: (301) 373-9600 +dnl EMail: cups-info@cups.org +dnl WWW: http://www.cups.org/ +dnl + +AC_ARG_ENABLE(ldap, [ --enable-ldap turn on LDAP support, default=yes]) +AC_ARG_WITH(openldap-libs, [ --with-openldap-libs set directory for OpenLDAP library], + LDFLAGS="-L$withval $LDFLAGS" + DSOFLAGS="-L$withval $DSOFLAGS",) +AC_ARG_WITH(openldap-includes, [ --with-openldap-includes + set directory for OpenLDAP includes], + CFLAGS="-I$withval $CFLAGS" + CXXFLAGS="-I$withval $CXXFLAGS" + CPPFLAGS="-I$withval $CPPFLAGS",) + +LIBLDAP="" + +if test x$enable_ldap != xno; then + AC_CHECK_HEADER(ldap.h, + AC_CHECK_LIB(ldap, ldap_value_free, + AC_DEFINE(HAVE_LDAP) + AC_DEFINE(HAVE_OPENLDAP) + LIBLDAP="-lldap")) +fi + +AC_SUBST(LIBLDAP) + + +dnl +dnl End of "$Id$". +dnl diff --git a/config-scripts/cups-scripting.m4 b/config-scripts/cups-scripting.m4 index e0c6832c6..68221a91e 100644 --- a/config-scripts/cups-scripting.m4 +++ b/config-scripts/cups-scripting.m4 @@ -1,9 +1,9 @@ dnl -dnl "$Id: cups-scripting.m4 4494 2005-02-18 02:18:11Z mike $" +dnl "$Id: cups-scripting.m4 5176 2006-02-25 18:14:10Z mike $" dnl dnl Scripting configuration stuff for the Common UNIX Printing System (CUPS). dnl -dnl Copyright 1997-2005 by Easy Software Products, all rights reserved. +dnl Copyright 1997-2006 by Easy Software Products, all rights reserved. dnl dnl These coded instructions, statements, and computer programs are the dnl property of Easy Software Products and are protected by Federal @@ -66,10 +66,23 @@ fi AC_DEFINE_UNQUOTED(CUPS_PHP, "$CUPS_PHP") -if test "x$CUPS_PHP" != x; then +if test "x$CUPS_PHP" = x; then + CUPS_PHP="no" +else AC_DEFINE(HAVE_PHP) fi +PHPDIR="" +if test "x$CUPS_PHP" != xno; then + AC_PATH_PROG(PHPCONFIG, php-config) + + if test "x$PHPCONFIG" != x; then + PHPDIR="scripting/php" + fi +fi + +AC_SUBST(PHPDIR) + dnl Do we have Python? AC_ARG_WITH(python, [ --with-python set Python interpreter for web interfaces ], CUPS_PYTHON="$withval", @@ -87,5 +100,5 @@ if test "x$CUPS_PYTHON" != x; then fi dnl -dnl End of "$Id: cups-scripting.m4 4494 2005-02-18 02:18:11Z mike $". +dnl End of "$Id: cups-scripting.m4 5176 2006-02-25 18:14:10Z mike $". dnl diff --git a/config-scripts/cups-threads.m4 b/config-scripts/cups-threads.m4 index 788ce838c..639eb7414 100644 --- a/config-scripts/cups-threads.m4 +++ b/config-scripts/cups-threads.m4 @@ -25,26 +25,32 @@ dnl AC_ARG_ENABLE(threads, [ --enable-threads enable multi-threading support]) have_pthread=no +PTHREAD_FLAGS="" if test "x$enable_threads" != xno; then AC_CHECK_HEADER(pthread.h, AC_DEFINE(HAVE_PTHREAD_H)) - AC_CHECK_LIB(pthread, pthread_create) - if test "x$ac_cv_lib_pthread_pthread_create" = xyes -a x$ac_cv_header_pthread_h = xyes; then - have_pthread=yes - else - dnl *BSD uses -pthread option... - AC_MSG_CHECKING([for pthread_create using -pthread]) - SAVELIBS="$LIBS" - LIBS="-pthread $LIBS" - AC_TRY_LINK([#include ], - [pthread_create(0, 0, 0, 0);], - have_pthread=yes, - LIBS="$SAVELIBS") - AC_MSG_RESULT([$have_pthread]) + if test x$ac_cv_header_pthread_h = xyes; then + dnl Check various threading options for the platforms we support + for flag in -lpthreads -lpthread -pthread; do + AC_MSG_CHECKING([for pthread_create using $flag]) + SAVELIBS="$LIBS" + LIBS="$flag $LIBS" + AC_TRY_LINK([#include ], + [pthread_create(0, 0, 0, 0);], + have_pthread=yes, + LIBS="$SAVELIBS") + AC_MSG_RESULT([$have_pthread]) + + if test $have_pthread = yes; then + PTHREAD_FLAGS="-D_THREAD_SAFE -D_REENTRANT" + break + fi + done fi fi +AC_SUBST(PTHREAD_FLAGS) dnl dnl End of "$Id$". diff --git a/config.h.in b/config.h.in index 4b81c2c57..911a9e8eb 100644 --- a/config.h.in +++ b/config.h.in @@ -1,5 +1,5 @@ /* - * "$Id: config.h.in 5144 2006-02-21 20:44:01Z mike $" + * "$Id: config.h.in 5157 2006-02-23 20:58:57Z mike $" * * Configuration file for the Common UNIX Printing System (CUPS). * @@ -254,12 +254,20 @@ /* - * Do we have the OpenSLP library? + * Do we have the SLP library? */ #undef HAVE_LIBSLP +/* + * Do we have an LDAP library? + */ + +#undef HAVE_LDAP +#undef HAVE_OPENLDAP + + /* * Do we have libpaper? */ @@ -417,5 +425,5 @@ #endif /* !_CUPS_CONFIG_H_ */ /* - * End of "$Id: config.h.in 5144 2006-02-21 20:44:01Z mike $". + * End of "$Id: config.h.in 5157 2006-02-23 20:58:57Z mike $". */ diff --git a/configure.in b/configure.in index 636edc724..6942e28a4 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl -dnl "$Id: configure.in 5124 2006-02-17 16:05:21Z mike $" +dnl "$Id: configure.in 5182 2006-02-26 04:10:27Z mike $" dnl dnl Configuration script for the Common UNIX Printing System (CUPS). dnl @@ -37,6 +37,7 @@ sinclude(config-scripts/cups-compiler.m4) sinclude(config-scripts/cups-image.m4) sinclude(config-scripts/cups-network.m4) sinclude(config-scripts/cups-slp.m4) +sinclude(config-scripts/cups-ldap.m4) sinclude(config-scripts/cups-ssl.m4) sinclude(config-scripts/cups-pam.m4) sinclude(config-scripts/cups-threads.m4) @@ -50,14 +51,14 @@ sinclude(config-scripts/cups-scripting.m4) AC_OUTPUT(Makedefs packaging/cups.list init/cups.sh cups-config conf/cupsd.conf conf/pam.std doc/index.html doc/ja/index.html - doc/help/standard.html man/cups-deviced.man + doc/help/standard.html man/client.conf.man man/cups-deviced.man man/cups-driverd.man man/cups-lpd.man man/cupsaddsmb.man - man/cupsd.man man/cupsd.conf.man + man/cupsd.man man/cupsd.conf.man man/lpoptions.man templates/edit-config.tmpl templates/header.tmpl templates/ja/header.tmpl) chmod +x cups-config dnl -dnl End of "$Id: configure.in 5124 2006-02-17 16:05:21Z mike $". +dnl End of "$Id: configure.in 5182 2006-02-26 04:10:27Z mike $". dnl diff --git a/cups/cups.h b/cups/cups.h index 9d4fe2fa9..17db3d1d0 100644 --- a/cups/cups.h +++ b/cups/cups.h @@ -1,5 +1,5 @@ /* - * "$Id: cups.h 5138 2006-02-21 10:49:06Z mike $" + * "$Id: cups.h 5156 2006-02-23 04:24:32Z mike $" * * API definitions for the Common UNIX Printing System (CUPS). * @@ -99,7 +99,8 @@ enum cups_ptype_e /* Not a typedef'd enum so we can OR */ CUPS_PRINTER_DELETE = 0x100000, /* Delete printer @since CUPS 1.2@ */ CUPS_PRINTER_NOT_SHARED = 0x200000, /* Printer is not shared @since CUPS 1.2@ */ CUPS_PRINTER_AUTHENTICATED = 0x400000,/* Printer requires authentication @since CUPS 1.2@ */ - CUPS_PRINTER_OPTIONS = 0x66fffc /* ~(CLASS | REMOTE | IMPLICIT) */ + CUPS_PRINTER_COMMANDS = 0x800000, /* Printer supports maintenance commands @since CUPS 1.2@ */ + CUPS_PRINTER_OPTIONS = 0xe6fffc /* ~(CLASS | REMOTE | IMPLICIT) */ }; typedef const char *(*cups_password_cb_t)(const char *); @@ -179,10 +180,10 @@ extern void cupsEncodeOptions(ipp_t *ipp, int num_options, extern void cupsFreeOptions(int num_options, cups_option_t *options); extern const char *cupsGetOption(const char *name, int num_options, cups_option_t *options); -extern int cupsParseOptions(const char *arg, int num_options, - cups_option_t **options); extern int cupsMarkOptions(ppd_file_t *ppd, int num_options, cups_option_t *options); +extern int cupsParseOptions(const char *arg, int num_options, + cups_option_t **options); extern const char *cupsGetPassword(const char *prompt); extern const char *cupsServer(void); @@ -231,6 +232,8 @@ extern void cupsEncodeOptions2(ipp_t *ipp, int num_options, extern const char *cupsLastErrorString(void); extern char *cupsNotifySubject(cups_lang_t *lang, ipp_t *event); extern char *cupsNotifyText(cups_lang_t *lang, ipp_t *event); +extern int cupsRemoveOption(const char *name, int num_options, + cups_option_t **options); extern cups_file_t *cupsTempFile2(char *filename, int len); @@ -241,5 +244,5 @@ extern cups_file_t *cupsTempFile2(char *filename, int len); #endif /* !_CUPS_CUPS_H_ */ /* - * End of "$Id: cups.h 5138 2006-02-21 10:49:06Z mike $". + * End of "$Id: cups.h 5156 2006-02-23 04:24:32Z mike $". */ diff --git a/cups/dest.c b/cups/dest.c index 0d8ffd95d..81e02faf8 100644 --- a/cups/dest.c +++ b/cups/dest.c @@ -1,5 +1,5 @@ /* - * "$Id: dest.c 5138 2006-02-21 10:49:06Z mike $" + * "$Id: dest.c 5182 2006-02-26 04:10:27Z mike $" * * User-defined destination (and option) support for the Common UNIX * Printing System (CUPS). @@ -44,6 +44,7 @@ #include "globals.h" #include #include +#include #ifdef HAVE_NOTIFY_H # include @@ -100,7 +101,7 @@ cupsAddDest(const char *name, /* I - Name of destination */ for (i = num_dests; i > 0; i --, dest ++) if (strcasecmp(name, dest->name) < 0) break; - else if (strcasecmp(name, dest->name) == 0 && + else if (!strcasecmp(name, dest->name) && instance != NULL && dest->instance != NULL && strcasecmp(instance, dest->instance) < 0) break; @@ -262,7 +263,7 @@ cupsGetDests2(http_t *http, /* I - HTTP connection */ int num_dests; /* Number of destinations */ cups_dest_t *dest; /* Destination pointer */ const char *home; /* HOME environment variable */ - char filename[1024]; /* Local ~/.lpoptions file */ + char filename[1024]; /* Local ~/.cups/lpoptions file */ const char *defprinter; /* Default printer */ char name[1024], /* Copy of printer name */ *instance; /* Pointer to instance name */ @@ -345,7 +346,7 @@ cupsGetDests2(http_t *http, /* I - HTTP connection */ } /* - * Load the /etc/cups/lpoptions and ~/.lpoptions files... + * Load the /etc/cups/lpoptions and ~/.cups/lpoptions files... */ snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot); @@ -353,13 +354,16 @@ cupsGetDests2(http_t *http, /* I - HTTP connection */ if ((home = getenv("HOME")) != NULL) { - snprintf(filename, sizeof(filename), "%s/.lpoptions", home); + snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home); + if (access(filename, 0)) + snprintf(filename, sizeof(filename), "%s/.lpoptions", home); + num_dests = cups_get_dests(filename, num_dests, dests); } /* * Validate the current default destination - this prevents old - * Default lines in /etc/cups/lpoptions and ~/.lpoptions from + * Default lines in /etc/cups/lpoptions and ~/.cups/lpoptions from * pointing to a non-existent printer or class... */ @@ -411,7 +415,7 @@ cupsGetDests2(http_t *http, /* I - HTTP connection */ * 'cupsSetDests()' - Save the list of destinations for the default server. * * This function saves the destinations to /etc/cups/lpoptions when run - * as root and ~/.lpoptions when run as a normal user. + * as root and ~/.cups/lpoptions when run as a normal user. */ void @@ -438,7 +442,7 @@ cupsSetDests(int num_dests, /* I - Number of destinations */ * 'cupsSetDests2()' - Save the list of destinations for the specified server. * * This function saves the destinations to /etc/cups/lpoptions when run - * as root and ~/.lpoptions when run as a normal user. + * as root and ~/.cups/lpoptions when run as a normal user. * * @since CUPS 1.1.21@ */ @@ -496,7 +500,24 @@ cupsSetDests2(http_t *http, /* I - HTTP connection */ */ if ((home = getenv("HOME")) != NULL) + { + /* + * Remove the old ~/.lpoptions file... + */ + snprintf(filename, sizeof(filename), "%s/.lpoptions", home); + unlink(filename); + + /* + * Create ~/.cups subdirectory... + */ + + snprintf(filename, sizeof(filename), "%s/.cups", home); + if (access(filename, 0)) + mkdir(filename, 0700); + + snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home); + } } #endif /* !WIN32 */ @@ -544,7 +565,7 @@ cupsSetDests2(http_t *http, /* I - HTTP connection */ if (temp && (val = cupsGetOption(option->name, temp->num_options, temp->options)) != NULL) { - if (strcasecmp(val, option->value) == 0) + if (!strcasecmp(val, option->value)) continue; } @@ -977,5 +998,5 @@ cups_get_sdests(http_t *http, /* I - HTTP connection */ /* - * End of "$Id: dest.c 5138 2006-02-21 10:49:06Z mike $". + * End of "$Id: dest.c 5182 2006-02-26 04:10:27Z mike $". */ diff --git a/cups/encode.c b/cups/encode.c index 071b29ea1..b0bbdda5a 100644 --- a/cups/encode.c +++ b/cups/encode.c @@ -1,5 +1,5 @@ /* - * "$Id: encode.c 5128 2006-02-17 18:59:03Z mike $" + * "$Id: encode.c 5151 2006-02-22 22:43:17Z mike $" * * Option encoding routines for the Common UNIX Printing System (CUPS). * @@ -59,14 +59,22 @@ typedef struct static const _ipp_option_t ipp_options[] = { { "blackplot", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, + { "blackplot-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, { "brightness", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { "brightness-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "columns", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { "columns-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "copies", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { "copies-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "document-format", IPP_TAG_MIMETYPE, IPP_TAG_OPERATION }, { "finishings", IPP_TAG_ENUM, IPP_TAG_JOB }, + { "finishings-default", IPP_TAG_ENUM, IPP_TAG_PRINTER }, { "fitplot", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, + { "fitplot-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, { "gamma", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { "gamma-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "hue", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { "hue-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "job-k-limit", IPP_TAG_INTEGER, IPP_TAG_JOB }, { "job-page-limit", IPP_TAG_INTEGER, IPP_TAG_JOB }, { "job-priority", IPP_TAG_INTEGER, IPP_TAG_JOB }, @@ -75,7 +83,9 @@ static const _ipp_option_t ipp_options[] = { "landscape", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, { "media", IPP_TAG_KEYWORD, IPP_TAG_JOB }, { "mirror", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, + { "mirror-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, { "natural-scaling", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { "natural-scaling-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "notify-charset", IPP_TAG_CHARSET, IPP_TAG_SUBSCRIPTION }, { "notify-events", IPP_TAG_KEYWORD, IPP_TAG_SUBSCRIPTION }, { "notify-lease-time", IPP_TAG_INTEGER, IPP_TAG_SUBSCRIPTION }, @@ -85,15 +95,25 @@ static const _ipp_option_t ipp_options[] = { "notify-time-interval", IPP_TAG_INTEGER, IPP_TAG_SUBSCRIPTION }, { "notify-user-data", IPP_TAG_STRING, IPP_TAG_SUBSCRIPTION }, { "number-up", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { "number-up-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "orientation-requested", IPP_TAG_ENUM, IPP_TAG_JOB }, + { "orientation-requested-default", IPP_TAG_ENUM, IPP_TAG_PRINTER }, { "page-bottom", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { "page-bottom-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "page-left", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { "page-left-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "page-ranges", IPP_TAG_RANGE, IPP_TAG_JOB }, + { "page-ranges-default", IPP_TAG_RANGE, IPP_TAG_PRINTER }, { "page-right", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { "page-right-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "page-top", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { "page-top-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "penwidth", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { "penwidth-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "ppi", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { "ppi-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "prettyprint", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, + { "prettyprint-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, { "printer-info", IPP_TAG_TEXT, IPP_TAG_PRINTER }, { "printer-is-accepting-jobs",IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, { "printer-is-shared", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, @@ -106,12 +126,19 @@ static const _ipp_option_t ipp_options[] = { "printer-type", IPP_TAG_ENUM, IPP_TAG_PRINTER }, { "printer-uri", IPP_TAG_URI, IPP_TAG_OPERATION }, { "print-quality", IPP_TAG_ENUM, IPP_TAG_JOB }, + { "print-quality-default", IPP_TAG_ENUM, IPP_TAG_PRINTER }, { "queued-job-count", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "raw", IPP_TAG_MIMETYPE, IPP_TAG_OPERATION }, + { "resolution", IPP_TAG_RESOLUTION, IPP_TAG_JOB }, + { "resolution-default", IPP_TAG_RESOLUTION, IPP_TAG_PRINTER }, { "saturation", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { "saturation-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "scaling", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { "scaling-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "sides", IPP_TAG_KEYWORD, IPP_TAG_JOB }, - { "wrap", IPP_TAG_BOOLEAN, IPP_TAG_JOB } + { "sides-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, + { "wrap", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, + { "wrap-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER } }; @@ -172,16 +199,17 @@ cupsEncodeOptions2( *sep; /* Option separator */ ipp_attribute_t *attr; /* IPP attribute */ ipp_tag_t value_tag; /* IPP value tag */ + cups_option_t *option; /* Current option */ - DEBUG_printf(("cupsEncodeOptions2(ipp=%p, num_options=%d, options=%p, group_tag=%x)\n", - ipp, num_options, options, group_tag)); + DEBUG_printf(("cupsEncodeOptions2(ipp=%p, num_options=%d, options=%p, " + "group_tag=%x)\n", ipp, num_options, options, group_tag)); /* * Range check input... */ - if (ipp == NULL || num_options < 1 || options == NULL) + if (!ipp || num_options < 1 || !options) return; /* @@ -209,7 +237,7 @@ cupsEncodeOptions2( * Then loop through the options... */ - for (i = 0; i < num_options; i ++) + for (i = num_options, option = options; i > 0; i --, option ++) { _ipp_option_t key, /* Search key */ *match; /* Matching attribute */ @@ -219,16 +247,16 @@ cupsEncodeOptions2( * Skip document format options that are handled above... */ - if (!strcasecmp(options[i].name, "raw") || - !strcasecmp(options[i].name, "document-format") || - !options[i].name[0]) + if (!strcasecmp(option->name, "raw") || + !strcasecmp(option->name, "document-format") || + !option->name[0]) continue; /* * Figure out the proper value and group tags for this option... */ - key.name = options[i].name; + key.name = option->name; match = (_ipp_option_t *)bsearch(&key, ipp_options, sizeof(ipp_options) / sizeof(ipp_options[0]), @@ -244,19 +272,33 @@ cupsEncodeOptions2( value_tag = match->value_tag; } - else if (group_tag != IPP_TAG_JOB) - continue; - else if (!strcasecmp(options[i].value, "true") || - !strcasecmp(options[i].value, "false")) - value_tag = IPP_TAG_BOOLEAN; else - value_tag = IPP_TAG_NAME; + { + int namelen; /* Length of name */ + + + namelen = strlen(option->name); + + if (namelen < 9 || strcmp(option->name + namelen - 8, "-default")) + { + if (group_tag != IPP_TAG_JOB) + continue; + } + else if (group_tag != IPP_TAG_PRINTER) + continue; + + if (!strcasecmp(option->value, "true") || + !strcasecmp(option->value, "false")) + value_tag = IPP_TAG_BOOLEAN; + else + value_tag = IPP_TAG_NAME; + } /* * Count the number of values... */ - for (count = 1, sep = options[i].value; *sep; sep ++) + for (count = 1, sep = option->value; *sep; sep ++) { if (*sep == '\'') { @@ -293,7 +335,7 @@ cupsEncodeOptions2( } DEBUG_printf(("cupsEncodeOptions2: option = \'%s\', count = %d\n", - options[i].name, count)); + option->name, count)); /* * Allocate memory for the attribute values... @@ -320,7 +362,7 @@ cupsEncodeOptions2( * Copy the name over... */ - if ((attr->name = strdup(options[i].name)) == NULL) + if ((attr->name = strdup(option->name)) == NULL) { /* * Ran out of memory! @@ -336,7 +378,7 @@ cupsEncodeOptions2( * Make a copy of the value we can fiddle with... */ - if ((copy = strdup(options[i].value)) == NULL) + if ((copy = strdup(option->value)) == NULL) { /* * Ran out of memory! @@ -354,7 +396,7 @@ cupsEncodeOptions2( * Since we have a single value, use the value directly... */ - val = options[i].value; + val = option->value; copy = NULL; } @@ -456,7 +498,7 @@ cupsEncodeOptions2( else attr->values[j].resolution.yres = attr->values[j].resolution.xres; - if (strcasecmp(s, "dpc") == 0) + if (!strcasecmp(s, "dpc")) attr->values[j].resolution.units = IPP_RES_PER_CM; else attr->values[j].resolution.units = IPP_RES_PER_INCH; @@ -510,5 +552,5 @@ compare_ipp_options(_ipp_option_t *a, /* I - First option */ /* - * End of "$Id: encode.c 5128 2006-02-17 18:59:03Z mike $". + * End of "$Id: encode.c 5151 2006-02-22 22:43:17Z mike $". */ diff --git a/cups/file.c b/cups/file.c index 791663a27..20aae7247 100644 --- a/cups/file.c +++ b/cups/file.c @@ -1,5 +1,5 @@ /* - * "$Id: file.c 5143 2006-02-21 19:13:01Z mike $" + * "$Id: file.c 5186 2006-02-26 18:56:05Z mike $" * * File functions for the Common UNIX Printing System (CUPS). * @@ -684,6 +684,9 @@ cupsFileOpen(const char *filename, /* I - Name of file */ http_addrlist_t *addrlist; /* Host address list */ + DEBUG_printf(("cupsFileOpen(filename=\"%s\", mode=\"%s\")\n", filename, + mode)); + /* * Range check input... */ @@ -774,6 +777,8 @@ cupsFileOpenFd(int fd, /* I - File descriptor */ cups_file_t *fp; /* New CUPS file */ + DEBUG_printf(("cupsFileOpenFd(fd=%d, mode=\"%s\")\n", fd, mode)); + /* * Range check input... */ @@ -1149,8 +1154,9 @@ cupsFileSeek(cups_file_t *fp, /* I - CUPS file */ size_t bytes; /* Number bytes in buffer */ - DEBUG_printf(("cupsFileSeek(fp=%p, pos=%ld)\n", fp, (long)pos)); - DEBUG_printf((" fp->pos=%ld\n", (long)fp->pos)); + DEBUG_printf(("cupsFileSeek(fp=%p, pos=" CUPS_LLFMT ")\n", fp, pos)); + DEBUG_printf((" fp->pos=" CUPS_LLFMT "\n", fp->pos)); + DEBUG_printf((" fp->ptr=%p, fp->end=%p\n", fp->ptr, fp->end)); /* * Range check input... @@ -1159,6 +1165,21 @@ cupsFileSeek(cups_file_t *fp, /* I - CUPS file */ if (!fp || pos < 0 || fp->mode != 'r') return (-1); + if (fp->pos == pos) + { + /* + * No seeking necessary... + */ + + if (fp->ptr) + { + fp->ptr = fp->buf; + fp->eof = 0; + } + + return (pos); + } + /* * Figure out the number of bytes in the current buffer, and then * see if we are outside of it... @@ -1206,7 +1227,7 @@ cupsFileSeek(cups_file_t *fp, /* I - CUPS file */ */ #ifdef HAVE_LIBZ - if (fp->compressed) + if (fp->compressed || !fp->ptr) { while ((bytes = cups_fill(fp)) > 0) if (pos >= fp->pos && pos < (fp->pos + bytes)) @@ -1219,7 +1240,7 @@ cupsFileSeek(cups_file_t *fp, /* I - CUPS file */ #endif /* HAVE_LIBZ */ { fp->pos = lseek(fp->fd, pos, SEEK_SET); - DEBUG_printf((" lseek() returned %ld...\n", (long)fp->pos)); + DEBUG_printf((" lseek() returned " CUPS_LLFMT "...\n", fp->pos)); fp->ptr = NULL; fp->end = NULL; } @@ -1400,8 +1421,9 @@ cups_fill(cups_file_t *fp) /* I - CUPS file */ DEBUG_printf(("cups_fill(fp=%p)\n", fp)); - DEBUG_printf((" fp->ptr=%p, fp->end=%p, fp->buf=%p, fp->pos=%ld\n", - fp->ptr, fp->end, fp->buf, (long)fp->pos)); + DEBUG_printf((" fp->ptr=%p, fp->end=%p, fp->buf=%p, " + "fp->pos=" CUPS_LLFMT ", fp->eof=%d\n", + fp->ptr, fp->end, fp->buf, fp->pos, fp->eof)); /* * Update the "pos" element as needed... @@ -1411,6 +1433,8 @@ cups_fill(cups_file_t *fp) /* I - CUPS file */ fp->pos += fp->end - fp->buf; #ifdef HAVE_LIBZ + DEBUG_printf((" fp->compressed=%d\n", fp->compressed)); + while (!fp->ptr || fp->compressed) { /* @@ -1425,7 +1449,6 @@ cups_fill(cups_file_t *fp) /* I - CUPS file */ */ fp->compressed = 0; - fp->pos = 0; /* * Read the first bytes in the file to determine if we have a gzip'd @@ -1438,6 +1461,9 @@ cups_fill(cups_file_t *fp) /* I - CUPS file */ * Can't read from file! */ + DEBUG_printf((" cups_read() returned " CUPS_LLFMT "!\n", + CUPS_LLCAST bytes)); + return (-1); } @@ -1452,6 +1478,8 @@ cups_fill(cups_file_t *fp) /* I - CUPS file */ fp->ptr = fp->buf; fp->end = fp->buf + bytes; + DEBUG_printf((" returning " CUPS_LLFMT "!\n", CUPS_LLCAST bytes)); + return (bytes); } @@ -1796,5 +1824,5 @@ cups_write(cups_file_t *fp, /* I - CUPS file */ /* - * End of "$Id: file.c 5143 2006-02-21 19:13:01Z mike $". + * End of "$Id: file.c 5186 2006-02-26 18:56:05Z mike $". */ diff --git a/cups/getputfile.c b/cups/getputfile.c index 4a78a42df..6c534a70f 100644 --- a/cups/getputfile.c +++ b/cups/getputfile.c @@ -1,5 +1,5 @@ /* - * "$Id: getputfile.c 5138 2006-02-21 10:49:06Z mike $" + * "$Id: getputfile.c 5147 2006-02-22 16:37:44Z mike $" * * Get/put file functions for the Common UNIX Printing System (CUPS). * @@ -295,6 +295,7 @@ cupsPutFd(http_t *http, /* I - HTTP connection to server */ httpClearFields(http); httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring); httpSetField(http, HTTP_FIELD_TRANSFER_ENCODING, "chunked"); + httpSetExpect(http, HTTP_CONTINUE); if (httpPut(http, resource)) { @@ -311,21 +312,31 @@ cupsPutFd(http_t *http, /* I - HTTP connection to server */ } /* - * Copy the file... + * Wait up to 1 second for a 100-continue response... */ - lseek(fd, 0, SEEK_SET); + if (httpWait(http, 1000)) + status = httpUpdate(http); + else + status = HTTP_CONTINUE; - status = HTTP_CONTINUE; + if (status == HTTP_CONTINUE) + { + /* + * Copy the file... + */ - while ((bytes = read(fd, buffer, sizeof(buffer))) > 0) - if (httpCheck(http)) - { - if ((status = httpUpdate(http)) != HTTP_CONTINUE) - break; - } - else - httpWrite2(http, buffer, bytes); + lseek(fd, 0, SEEK_SET); + + while ((bytes = read(fd, buffer, sizeof(buffer))) > 0) + if (httpCheck(http)) + { + if ((status = httpUpdate(http)) != HTTP_CONTINUE) + break; + } + else + httpWrite2(http, buffer, bytes); + } if (status == HTTP_CONTINUE) { @@ -471,5 +482,5 @@ cupsPutFile(http_t *http, /* I - HTTP connection to server */ /* - * End of "$Id: getputfile.c 5138 2006-02-21 10:49:06Z mike $". + * End of "$Id: getputfile.c 5147 2006-02-22 16:37:44Z mike $". */ diff --git a/cups/http-addr.c b/cups/http-addr.c index 4dd9064ea..ec0f7b269 100644 --- a/cups/http-addr.c +++ b/cups/http-addr.c @@ -1,5 +1,5 @@ /* - * "$Id: http-addr.c 5138 2006-02-21 10:49:06Z mike $" + * "$Id: http-addr.c 5161 2006-02-24 03:11:46Z mike $" * * HTTP address routines for the Common UNIX Printing System (CUPS). * @@ -191,11 +191,8 @@ httpAddrLookup( #endif /* AF_LOCAL */ #ifdef HAVE_GETNAMEINFO { - char servname[1024]; /* Service name (not used) */ - - if (getnameinfo(&addr->addr, httpAddrLength(addr), name, namelen, - servname, sizeof(servname), 0)) + NULL, 0, 0)) { /* * If we get an error back, then the address type is not supported @@ -270,13 +267,22 @@ httpAddrString(const http_addr_t *addr, /* I - Address to convert */ strlcpy(s, addr->un.sun_path, slen); else #endif /* AF_LOCAL */ -#ifdef HAVE_GETNAMEINFO + if (addr->addr.sa_family == AF_INET) { - char servname[1024]; /* Service name (not used) */ + unsigned temp; /* Temporary address */ + temp = ntohl(addr->ipv4.sin_addr.s_addr); + + snprintf(s, slen, "%d.%d.%d.%d", (temp >> 24) & 255, + (temp >> 16) & 255, (temp >> 8) & 255, temp & 255); + } +#ifdef AF_INET6 + else if (addr->addr.sa_family == AF_INET6) + { +# ifdef HAVE_GETNAMEINFO if (getnameinfo(&addr->addr, httpAddrLength(addr), s, slen, - servname, sizeof(servname), NI_NUMERICHOST)) + NULL, 0, NI_NUMERICHOST)) { /* * If we get an error back, then the address type is not supported @@ -287,104 +293,87 @@ httpAddrString(const http_addr_t *addr, /* I - Address to convert */ return (NULL); } - } -#else - { -#ifdef AF_INET6 - if (addr->addr.sa_family == AF_INET6) +# else + char *sptr; /* Pointer into string */ + int i; /* Looping var */ + unsigned temp; /* Current value */ + const char *prefix; /* Prefix for address */ + + + prefix = ""; + for (sptr = s, i = 0; i < 4 && addr->ipv6.sin6_addr.s6_addr32[i]; i ++) { - char *sptr; /* Pointer into string */ - int i; /* Looping var */ - unsigned temp; /* Current value */ - const char *prefix; /* Prefix for address */ + temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]); + snprintf(sptr, slen, "%s%x", prefix, (temp >> 16) & 0xffff); + prefix = ":"; + slen -= strlen(sptr); + sptr += strlen(sptr); - prefix = ""; - for (sptr = s, i = 0; i < 4 && addr->ipv6.sin6_addr.s6_addr32[i]; i ++) - { - temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]); + temp &= 0xffff; - snprintf(sptr, slen, "%s%x", prefix, (temp >> 16) & 0xffff); - prefix = ":"; + if (temp || i == 3 || addr->ipv6.sin6_addr.s6_addr32[i + 1]) + { + snprintf(sptr, slen, "%s%x", prefix, temp); slen -= strlen(sptr); sptr += strlen(sptr); - - temp &= 0xffff; - - if (temp || i == 3 || addr->ipv6.sin6_addr.s6_addr32[i + 1]) - { - snprintf(sptr, slen, "%s%x", prefix, temp); - slen -= strlen(sptr); - sptr += strlen(sptr); - } } + } + + if (i < 4) + { + while (i < 4 && !addr->ipv6.sin6_addr.s6_addr32[i]) + i ++; if (i < 4) { - while (i < 4 && !addr->ipv6.sin6_addr.s6_addr32[i]) - i ++; + snprintf(sptr, slen, "%s:", prefix); + prefix = ":"; + slen -= strlen(sptr); + sptr += strlen(sptr); - if (i < 4) + for (; i < 4; i ++) { - snprintf(sptr, slen, "%s:", prefix); - prefix = ":"; - slen -= strlen(sptr); - sptr += strlen(sptr); + temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]); - for (; i < 4; i ++) + if ((temp & 0xffff0000) || addr->ipv6.sin6_addr.s6_addr32[i - 1]) { - temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]); - - if ((temp & 0xffff0000) || addr->ipv6.sin6_addr.s6_addr32[i - 1]) - { - snprintf(sptr, slen, "%s%x", prefix, (temp >> 16) & 0xffff); - slen -= strlen(sptr); - sptr += strlen(sptr); - } - - snprintf(sptr, slen, "%s%x", prefix, temp & 0xffff); + snprintf(sptr, slen, "%s%x", prefix, (temp >> 16) & 0xffff); slen -= strlen(sptr); sptr += strlen(sptr); - } - } - else if (sptr == s) - { - /* - * Empty address... - */ + } - strlcpy(s, "::", slen); - sptr = s + 2; - slen -= 2; - } - else - { - /* - * Empty at end... - */ - - strlcpy(sptr, "::", slen); - sptr += 2; - slen -= 2; + snprintf(sptr, slen, "%s%x", prefix, temp & 0xffff); + slen -= strlen(sptr); + sptr += strlen(sptr); } } - } - else -#endif /* AF_INET6 */ - if (addr->addr.sa_family == AF_INET) - { - unsigned temp; /* Temporary address */ - + else if (sptr == s) + { + /* + * Empty address... + */ - temp = ntohl(addr->ipv4.sin_addr.s_addr); + strlcpy(s, "::", slen); + sptr = s + 2; + slen -= 2; + } + else + { + /* + * Empty at end... + */ - snprintf(s, slen, "%d.%d.%d.%d", (temp >> 24) & 255, - (temp >> 16) & 255, (temp >> 8) & 255, temp & 255); + strlcpy(sptr, "::", slen); + sptr += 2; + slen -= 2; + } } - else - strlcpy(s, "UNKNOWN", slen); +# endif /* HAVE_GETNAMEINFO */ } -#endif /* HAVE_GETNAMEINFO */ +#endif /* AF_INET6 */ + else + strlcpy(s, "UNKNOWN", slen); DEBUG_printf(("httpAddrString: returning \"%s\"...\n", s)); @@ -541,5 +530,5 @@ httpGetHostname(char *s, /* I - String buffer for name */ /* - * End of "$Id: http-addr.c 5138 2006-02-21 10:49:06Z mike $". + * End of "$Id: http-addr.c 5161 2006-02-24 03:11:46Z mike $". */ diff --git a/cups/http-support.c b/cups/http-support.c index a73807692..ea5e06de1 100644 --- a/cups/http-support.c +++ b/cups/http-support.c @@ -1,5 +1,5 @@ /* - * "$Id: http-support.c 5138 2006-02-21 10:49:06Z mike $" + * "$Id: http-support.c 5149 2006-02-22 19:10:22Z mike $" * * HTTP support routines for the Common UNIX Printing System (CUPS) scheduler. * @@ -1003,7 +1003,25 @@ httpSeparateURI( else { /* - * Grab hostname or IPv4 address... + * Validate the hostname or IPv4 address first... + */ + + for (ptr = (char *)uri; *ptr; ptr ++) + if (strchr(":?/", *ptr)) + break; + else if (!strchr("abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "-._~" + "%" + "!$&'()*+,;=", *ptr)) + { + *host = '\0'; + return (HTTP_URI_BAD_HOSTNAME); + } + + /* + * Then copy the hostname or IPv4 address to the buffer... */ uri = http_copy_decode(host, uri, hostlen, ":?/", @@ -1014,21 +1032,6 @@ httpSeparateURI( *host = '\0'; return (HTTP_URI_BAD_HOSTNAME); } - - /* - * Validate value... - */ - - for (ptr = host; *ptr; ptr ++) - if (!strchr("abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789" - "-._~" - "!$&'()*+,;=", *ptr)) - { - *host = '\0'; - return (HTTP_URI_BAD_HOSTNAME); - } } /* @@ -1158,6 +1161,9 @@ httpStatus(http_status_t status) /* I - HTTP status code */ return ("Not Implemented"); case HTTP_NOT_SUPPORTED : return ("Not Supported"); + case HTTP_EXPECTATION_FAILED : + return ("Expectation Failed"); + default : return ("Unknown"); } @@ -1306,5 +1312,5 @@ http_copy_encode(char *dst, /* O - Destination buffer */ /* - * End of "$Id: http-support.c 5138 2006-02-21 10:49:06Z mike $". + * End of "$Id: http-support.c 5149 2006-02-22 19:10:22Z mike $". */ diff --git a/cups/http.c b/cups/http.c index 0b5c9c57e..da2279344 100644 --- a/cups/http.c +++ b/cups/http.c @@ -1,5 +1,5 @@ /* - * "$Id: http.c 5138 2006-02-21 10:49:06Z mike $" + * "$Id: http.c 5200 2006-02-28 00:10:32Z mike $" * * HTTP routines for the Common UNIX Printing System (CUPS). * @@ -63,6 +63,7 @@ * _httpReadCDSA() - Read function for CDSA decryption code. * httpReconnect() - Reconnect to a HTTP server... * httpSetCookie() - Set the cookie value(s)... + * httpSetExpect() - Set the Expect: header in a request. * httpSetField() - Set the value of an HTTP header. * httpSetLength() - Set the content-length and transfer-encoding. * httpTrace() - Send an TRACE request to the server. @@ -222,6 +223,8 @@ httpClearFields(http_t *http) /* I - HTTP connection */ { memset(http->fields, 0, sizeof(http->fields)); httpSetField(http, HTTP_FIELD_HOST, http->hostname); + + http->expect = (http_status_t)0; } } @@ -1386,31 +1389,32 @@ _httpReadCDSA( OSStatus result; /* Return value */ ssize_t bytes; /* Number of bytes read */ - - for (;;) - { + do bytes = recv((int)connection, data, *dataLength, 0); + while (bytes == -1 && errno == EINTR); - if (bytes > 0) - { - result = (bytes == *dataLength); - *dataLength = bytes; - - return (result); - } + if (bytes == *dataLength) + result = 0; + else if (bytes > 0) + { + *dataLength = bytes; + result = errSSLWouldBlock; + } + else + { + *dataLength = 0; if (bytes == 0) - return (errSSLClosedAbort); - - if (errno == EAGAIN) - return (errSSLWouldBlock); - - if (errno == EPIPE) - return (errSSLClosedAbort); - - if (errno != EINTR) - return (errSSLInternal); + result = errSSLClosedAbort; + else if (errno == EAGAIN) + result = errSSLWouldBlock; + else if (errno == EPIPE) + result = errSSLClosedAbort; + else + result = errSSLInternal; } + + return result; } #endif /* HAVE_SSL && HAVE_CDSASSL */ @@ -1523,6 +1527,23 @@ httpSetCookie(http_t *http, /* I - Connection */ } +/* + * 'httpSetExpect()' - Set the Expect: header in a request. + * + * Currently only HTTP_CONTINUE is supported for the "expect" argument. + * + * @since CUPS 1.2@ + */ + +void +httpSetExpect(http_t *http, /* I - HTTP connection */ + http_status_t expect) /* I - HTTP status to expect (HTTP_CONTINUE) */ +{ + if (http) + http->expect = expect; +} + + /* * 'httpSetField()' - Set the value of an HTTP header. */ @@ -1941,28 +1962,30 @@ _httpWriteCDSA( OSStatus result; /* Return value */ ssize_t bytes; /* Number of bytes read */ - - for (;;) - { + do bytes = write((int)connection, data, *dataLength); + while (bytes == -1 && errno == EINTR); - if (bytes >= 0) - { - result = (bytes == *dataLength) ? 0 : errSSLWouldBlock; - *dataLength = bytes; - - return (result); - } - + if (bytes == *dataLength) + result = 0; + else if (bytes >= 0) + { + *dataLength = bytes; + result = errSSLWouldBlock; + } + else + { + *dataLength = 0; + if (errno == EAGAIN) - return (errSSLWouldBlock); - - if (errno == EPIPE) - return (errSSLClosedAbort); - - if (errno != EINTR) - return (errSSLInternal); + result = errSSLWouldBlock; + else if (errno == EPIPE) + result = errSSLClosedAbort; + else + result = errSSLInternal; } + + return result; } #endif /* HAVE_SSL && HAVE_CDSASSL */ @@ -2018,8 +2041,13 @@ http_read_ssl(http_t *http, /* I - HTTP connection */ result = 0; break; case errSSLWouldBlock : - errno = EAGAIN; - result = -1; + if (processed) + result = (int)processed; + else + { + result = -1; + errno = EINTR; + } break; default : errno = EPIPE; @@ -2148,6 +2176,14 @@ http_send(http_t *http, /* I - HTTP connection */ return (-1); } + if (http->expect == HTTP_CONTINUE && + (http->state == HTTP_POST_RECV || http->state == HTTP_PUT_RECV)) + if (httpPrintf(http, "Expect: 100-continue\r\n") < 1) + { + http->status = HTTP_ERROR; + return (-1); + } + if (httpPrintf(http, "\r\n") < 1) { http->status = HTTP_ERROR; @@ -2270,7 +2306,10 @@ http_setup_ssl(http_t *http) /* I - HTTP connection */ error = SSLSetAllowsAnyRoot(conn, true); if (!error) - error = SSLHandshake(conn); + { + while ((error = SSLHandshake(conn)) == errSSLWouldBlock) + usleep(1000); + } if (error != 0) { @@ -2327,7 +2366,9 @@ http_shutdown_ssl(http_t *http) /* I - HTTP connection */ free(conn); # elif defined(HAVE_CDSASSL) - SSLClose((SSLContextRef)http->tls); + while (SSLClose((SSLContextRef)http->tls) == errSSLWouldBlock) + usleep(1000); + SSLDisposeContext((SSLContextRef)http->tls); # endif /* HAVE_LIBSSL */ @@ -2692,8 +2733,13 @@ http_write_ssl(http_t *http, /* I - HTTP connection */ result = 0; break; case errSSLWouldBlock : - errno = EAGAIN; - result = -1; + if (processed) + result = (int)processed; + else + { + result = -1; + errno = EINTR; + } break; default : errno = EPIPE; @@ -2708,5 +2754,5 @@ http_write_ssl(http_t *http, /* I - HTTP connection */ /* - * End of "$Id: http.c 5138 2006-02-21 10:49:06Z mike $". + * End of "$Id: http.c 5200 2006-02-28 00:10:32Z mike $". */ diff --git a/cups/http.h b/cups/http.h index 0b13ba6c1..6ff09a20f 100644 --- a/cups/http.h +++ b/cups/http.h @@ -1,5 +1,5 @@ /* - * "$Id: http.h 5138 2006-02-21 10:49:06Z mike $" + * "$Id: http.h 5147 2006-02-22 16:37:44Z mike $" * * Hyper-Text Transport Protocol definitions for the Common UNIX Printing * System (CUPS). @@ -242,6 +242,8 @@ typedef enum http_status_e /**** HTTP status codes ****/ HTTP_REQUEST_TOO_LARGE, /* Request entity too large */ HTTP_URI_TOO_LONG, /* URI too long */ HTTP_UNSUPPORTED_MEDIATYPE, /* The requested media type is unsupported */ + HTTP_REQUESTED_RANGE, /* The requested range is not satisfiable */ + HTTP_EXPECTATION_FAILED, /* The expectation given in an Expect header field was not met */ HTTP_UPGRADE_REQUIRED = 426, /* Upgrade to SSL/TLS required */ HTTP_SERVER_ERROR = 500, /* Internal server error */ @@ -473,6 +475,7 @@ extern http_uri_status_t httpSeparateURI(http_uri_coding_t decoding, char *username, int usernamelen, char *host, int hostlen, int *port, char *resource, int resourcelen); +extern void httpSetExpect(http_t *http, http_status_t expect); extern void httpSetLength(http_t *http, size_t length); extern ssize_t httpWrite2(http_t *http, const char *buffer, size_t length); @@ -488,5 +491,5 @@ extern ssize_t httpWrite2(http_t *http, const char *buffer, #endif /* !_CUPS_HTTP_H_ */ /* - * End of "$Id: http.h 5138 2006-02-21 10:49:06Z mike $". + * End of "$Id: http.h 5147 2006-02-22 16:37:44Z mike $". */ diff --git a/cups/mark.c b/cups/mark.c index c901781db..bb29bcbcf 100644 --- a/cups/mark.c +++ b/cups/mark.c @@ -1,5 +1,5 @@ /* - * "$Id: mark.c 5119 2006-02-16 15:52:06Z mike $" + * "$Id: mark.c 5190 2006-02-27 02:42:07Z mike $" * * Option marking routines for the Common UNIX Printing System (CUPS). * @@ -43,7 +43,7 @@ * Include necessary headers... */ -#include "ppd.h" +#include "cups.h" #include "string.h" #include "debug.h" @@ -355,7 +355,7 @@ ppdMarkOption(ppd_file_t *ppd, /* I - PPD file record */ return (0); - if (!strncasecmp(choice, "Custom.", 7) /* TODO || strchr(choice, '=') */ ) + if (!strncasecmp(choice, "Custom.", 7)) { /* * Handle a custom option... @@ -382,13 +382,6 @@ ppdMarkOption(ppd_file_t *ppd, /* I - PPD file record */ ppd_cparam_t *cparam; /* Custom parameter */ char units[33]; /* Custom points units */ - - /* - * TODO: Detect and support custom option values using the - * collection format "{Name1=foo Name2=bar}". For now, just - * support Custom.value for single-valued custom options. - */ - if ((coption = ppdFindCustomOption(ppd, option)) != NULL) { if ((cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params)) == NULL) @@ -435,6 +428,75 @@ ppdMarkOption(ppd_file_t *ppd, /* I - PPD file record */ } } } + else if (choice[0] == '{') + { + /* + * Handle multi-value custom options... + */ + + ppd_coption_t *coption; /* Custom option */ + ppd_cparam_t *cparam; /* Custom parameter */ + char units[33]; /* Custom points units */ + int num_vals; /* Number of values */ + cups_option_t *vals, /* Values */ + *val; /* Value */ + + + if ((c = ppdFindChoice(o, "Custom")) == NULL) + return (0); + + if ((coption = ppdFindCustomOption(ppd, option)) != NULL) + { + num_vals = cupsParseOptions(choice + 1, 0, &vals); + + for (i = 0, val = vals; i < num_vals; i ++, val ++) + { + if ((cparam = ppdFindCustomParam(coption, val->name)) == NULL) + continue; + + switch (cparam->type) + { + case PPD_CUSTOM_CURVE : + case PPD_CUSTOM_INVCURVE : + case PPD_CUSTOM_REAL : + cparam->current.custom_real = atof(val->value); + break; + + case PPD_CUSTOM_POINTS : + if (sscanf(val->value, "%f%s", &(cparam->current.custom_points), + units) < 2) + strcpy(units, "pt"); + + if (!strcasecmp(units, "cm")) + cparam->current.custom_points *= 72.0 / 2.54; + else if (!strcasecmp(units, "mm")) + cparam->current.custom_points *= 72.0 / 25.4; + else if (!strcasecmp(units, "m")) + cparam->current.custom_points *= 72.0 / 0.0254; + else if (!strcasecmp(units, "in")) + cparam->current.custom_points *= 72.0; + else if (!strcasecmp(units, "ft")) + cparam->current.custom_points *= 12 * 72.0; + break; + + case PPD_CUSTOM_INT : + cparam->current.custom_int = atoi(val->value); + break; + + case PPD_CUSTOM_PASSCODE : + case PPD_CUSTOM_PASSWORD : + case PPD_CUSTOM_STRING : + if (cparam->current.custom_string) + free(cparam->current.custom_string); + + cparam->current.custom_string = strdup(val->value); + break; + } + } + + cupsFreeOptions(num_vals, vals); + } + } else { for (i = o->num_choices, c = o->choices; i > 0; i --, c ++) @@ -586,5 +648,5 @@ ppd_defaults(ppd_file_t *ppd, /* I - PPD file */ /* - * End of "$Id: mark.c 5119 2006-02-16 15:52:06Z mike $". + * End of "$Id: mark.c 5190 2006-02-27 02:42:07Z mike $". */ diff --git a/cups/options.c b/cups/options.c index cbaa59190..e232caaad 100644 --- a/cups/options.c +++ b/cups/options.c @@ -1,9 +1,9 @@ /* - * "$Id: options.c 4980 2006-01-25 19:57:45Z mike $" + * "$Id: options.c 5151 2006-02-22 22:43:17Z mike $" * * Option routines for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2005 by Easy Software Products. + * Copyright 1997-2006 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -25,11 +25,12 @@ * * Contents: * - * cupsAddOption() - Add an option to an option array. - * cupsFreeOptions() - Free all memory used by options. - * cupsGetOption() - Get an option value. - * cupsParseOptions() - Parse options from a command-line argument. - * cupsMarkOptions() - Mark command-line options in a PPD file. + * cupsAddOption() - Add an option to an option array. + * cupsFreeOptions() - Free all memory used by options. + * cupsGetOption() - Get an option value. + * cupsMarkOptions() - Mark command-line options in a PPD file. + * cupsParseOptions() - Parse options from a command-line argument. + * cupsRemoveOptions() - Remove an option from an option array. */ /* @@ -152,206 +153,6 @@ cupsGetOption(const char *name, /* I - Name of option */ } -/* - * 'cupsParseOptions()' - Parse options from a command-line argument. - * - * This function converts space-delimited name/value pairs according - * to the PAPI text option ABNF specification. Collection values - * ("name={a=... b=... c=...}") are stored with the curley brackets - * intact - use cupsParseOptions() on the value to extract the collection - * attributes. - */ - -int /* O - Number of options found */ -cupsParseOptions( - const char *arg, /* I - Argument to parse */ - int num_options, /* I - Number of options */ - cups_option_t **options) /* O - Options found */ -{ - char *copyarg, /* Copy of input string */ - *ptr, /* Pointer into string */ - *name, /* Pointer to name */ - *value; /* Pointer to value */ - - - if (arg == NULL || options == NULL || num_options < 0) - return (0); - - /* - * Make a copy of the argument string and then divide it up... - */ - - copyarg = strdup(arg); - ptr = copyarg; - - /* - * Skip leading spaces... - */ - - while (isspace(*ptr & 255)) - ptr ++; - - /* - * Loop through the string... - */ - - while (*ptr != '\0') - { - /* - * Get the name up to a SPACE, =, or end-of-string... - */ - - name = ptr; - while (!isspace(*ptr & 255) && *ptr != '=' && *ptr != '\0') - ptr ++; - - /* - * Avoid an empty name... - */ - - if (ptr == name) - break; - - /* - * Skip trailing spaces... - */ - - while (isspace(*ptr & 255)) - *ptr++ = '\0'; - - if (*ptr != '=') - { - /* - * Start of another option... - */ - - if (strncasecmp(name, "no", 2) == 0) - num_options = cupsAddOption(name + 2, "false", num_options, - options); - else - num_options = cupsAddOption(name, "true", num_options, options); - - continue; - } - - /* - * Remove = and parse the value... - */ - - *ptr++ = '\0'; - - if (*ptr == '\'') - { - /* - * Quoted string constant... - */ - - ptr ++; - value = ptr; - - while (*ptr != '\'' && *ptr != '\0') - { - if (*ptr == '\\') - _cups_strcpy(ptr, ptr + 1); - - ptr ++; - } - - if (*ptr != '\0') - *ptr++ = '\0'; - } - else if (*ptr == '\"') - { - /* - * Double-quoted string constant... - */ - - ptr ++; - value = ptr; - - while (*ptr != '\"' && *ptr != '\0') - { - if (*ptr == '\\') - _cups_strcpy(ptr, ptr + 1); - - ptr ++; - } - - if (*ptr != '\0') - *ptr++ = '\0'; - } - else if (*ptr == '{') - { - /* - * Collection value... - */ - - int depth; - - value = ptr; - - for (depth = 1; *ptr; ptr ++) - if (*ptr == '{') - depth ++; - else if (*ptr == '}') - { - depth --; - if (!depth) - { - ptr ++; - - if (*ptr != ',') - break; - } - } - else if (*ptr == '\\') - _cups_strcpy(ptr, ptr + 1); - - if (*ptr != '\0') - *ptr++ = '\0'; - } - else - { - /* - * Normal space-delimited string... - */ - - value = ptr; - - while (!isspace(*ptr & 255) && *ptr != '\0') - { - if (*ptr == '\\') - _cups_strcpy(ptr, ptr + 1); - - ptr ++; - } - } - - /* - * Skip trailing whitespace... - */ - - while (isspace(*ptr & 255)) - *ptr++ = '\0'; - - /* - * Add the string value... - */ - - num_options = cupsAddOption(name, value, num_options, options); - } - - /* - * Free the copy of the argument we made and return the number of options - * found. - */ - - free(copyarg); - - return (num_options); -} - - /* * 'cupsMarkOptions()' - Mark command-line options in a PPD file. */ @@ -577,5 +378,261 @@ cupsMarkOptions( /* - * End of "$Id: options.c 4980 2006-01-25 19:57:45Z mike $". + * 'cupsParseOptions()' - Parse options from a command-line argument. + * + * This function converts space-delimited name/value pairs according + * to the PAPI text option ABNF specification. Collection values + * ("name={a=... b=... c=...}") are stored with the curley brackets + * intact - use cupsParseOptions() on the value to extract the collection + * attributes. + */ + +int /* O - Number of options found */ +cupsParseOptions( + const char *arg, /* I - Argument to parse */ + int num_options, /* I - Number of options */ + cups_option_t **options) /* O - Options found */ +{ + char *copyarg, /* Copy of input string */ + *ptr, /* Pointer into string */ + *name, /* Pointer to name */ + *value; /* Pointer to value */ + + + if (arg == NULL || options == NULL || num_options < 0) + return (0); + + /* + * Make a copy of the argument string and then divide it up... + */ + + copyarg = strdup(arg); + ptr = copyarg; + + /* + * Skip leading spaces... + */ + + while (isspace(*ptr & 255)) + ptr ++; + + /* + * Loop through the string... + */ + + while (*ptr != '\0') + { + /* + * Get the name up to a SPACE, =, or end-of-string... + */ + + name = ptr; + while (!isspace(*ptr & 255) && *ptr != '=' && *ptr != '\0') + ptr ++; + + /* + * Avoid an empty name... + */ + + if (ptr == name) + break; + + /* + * Skip trailing spaces... + */ + + while (isspace(*ptr & 255)) + *ptr++ = '\0'; + + if (*ptr != '=') + { + /* + * Start of another option... + */ + + if (strncasecmp(name, "no", 2) == 0) + num_options = cupsAddOption(name + 2, "false", num_options, + options); + else + num_options = cupsAddOption(name, "true", num_options, options); + + continue; + } + + /* + * Remove = and parse the value... + */ + + *ptr++ = '\0'; + + if (*ptr == '\'') + { + /* + * Quoted string constant... + */ + + ptr ++; + value = ptr; + + while (*ptr != '\'' && *ptr != '\0') + { + if (*ptr == '\\') + _cups_strcpy(ptr, ptr + 1); + + ptr ++; + } + + if (*ptr != '\0') + *ptr++ = '\0'; + } + else if (*ptr == '\"') + { + /* + * Double-quoted string constant... + */ + + ptr ++; + value = ptr; + + while (*ptr != '\"' && *ptr != '\0') + { + if (*ptr == '\\') + _cups_strcpy(ptr, ptr + 1); + + ptr ++; + } + + if (*ptr != '\0') + *ptr++ = '\0'; + } + else if (*ptr == '{') + { + /* + * Collection value... + */ + + int depth; + + value = ptr; + + for (depth = 1; *ptr; ptr ++) + if (*ptr == '{') + depth ++; + else if (*ptr == '}') + { + depth --; + if (!depth) + { + ptr ++; + + if (*ptr != ',') + break; + } + } + else if (*ptr == '\\') + _cups_strcpy(ptr, ptr + 1); + + if (*ptr != '\0') + *ptr++ = '\0'; + } + else + { + /* + * Normal space-delimited string... + */ + + value = ptr; + + while (!isspace(*ptr & 255) && *ptr != '\0') + { + if (*ptr == '\\') + _cups_strcpy(ptr, ptr + 1); + + ptr ++; + } + } + + /* + * Skip trailing whitespace... + */ + + while (isspace(*ptr & 255)) + *ptr++ = '\0'; + + /* + * Add the string value... + */ + + num_options = cupsAddOption(name, value, num_options, options); + } + + /* + * Free the copy of the argument we made and return the number of options + * found. + */ + + free(copyarg); + + return (num_options); +} + + +/* + * 'cupsRemoveOptions()' - Remove an option from an option array. + * + * @since CUPS 1.2@ + */ + +int /* O - New number of options */ +cupsRemoveOption( + const char *name, /* I - Option name */ + int num_options, /* I - Current number of options */ + cups_option_t **options) /* IO - Options */ +{ + int i; /* Looping var */ + cups_option_t *option; /* Current option */ + + + /* + * Range check input... + */ + + if (!name || num_options < 1 || !options) + return (num_options); + + /* + * Loop for the option... + */ + + for (i = num_options, option = *options; i > 0; i --, option ++) + if (!strcasecmp(name, option->name)) + break; + + if (i) + { + /* + * Remove this option from the array... + */ + + num_options --; + i --; + + free(option->name); + if (option->value) + free(option->value); + + if (i > 0) + memmove(option, option + 1, i * sizeof(cups_option_t *)); + } + + /* + * Return the new number of options... + */ + + return (num_options); +} + + +/* + * End of "$Id: options.c 5151 2006-02-22 22:43:17Z mike $". */ diff --git a/cups/ppd.c b/cups/ppd.c index 1b0ed6471..c13149320 100644 --- a/cups/ppd.c +++ b/cups/ppd.c @@ -1,5 +1,5 @@ /* - * "$Id: ppd.c 5119 2006-02-16 15:52:06Z mike $" + * "$Id: ppd.c 5200 2006-02-28 00:10:32Z mike $" * * PPD file routines for the Common UNIX Printing System (CUPS). * @@ -244,6 +244,8 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ ppd_free(ppd->attrs); } + cupsArrayDelete(ppd->sorted_attrs); + /* * Free custom options... */ @@ -262,8 +264,6 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ case PPD_CUSTOM_PASSWORD : case PPD_CUSTOM_STRING : ppd_free(cparam->current.custom_string); - ppd_free(cparam->minimum.custom_string); - ppd_free(cparam->maximum.custom_string); break; default : @@ -832,17 +832,6 @@ ppdOpen2(cups_file_t *fp) /* I - File to read from */ ppd->fonts[ppd->num_fonts] = strdup(name); ppd->num_fonts ++; } -#if 0 - else if (!strcmp(keyword, "ParamCustomPageSize")) - { - if (!strcmp(name, "Width")) - sscanf(string, "%*s%*s%f%f", ppd->custom_min + 0, - ppd->custom_max + 0); - else if (!strcmp(name, "Height")) - sscanf(string, "%*s%*s%f%f", ppd->custom_min + 1, - ppd->custom_max + 1); - } -#endif /* 0 */ else if (!strncmp(keyword, "ParamCustom", 11)) { ppd_coption_t *coption; /* Custom option */ @@ -906,14 +895,14 @@ ppdOpen2(cups_file_t *fp) /* I - File to read from */ else if (!strcmp(ctype, "passcode")) { cparam->type = PPD_CUSTOM_PASSCODE; - cparam->minimum.custom_passcode = strdup(cminimum); - cparam->maximum.custom_passcode = strdup(cmaximum); + cparam->minimum.custom_passcode = atoi(cminimum); + cparam->maximum.custom_passcode = atoi(cmaximum); } else if (!strcmp(ctype, "password")) { cparam->type = PPD_CUSTOM_PASSWORD; - cparam->minimum.custom_password = strdup(cminimum); - cparam->maximum.custom_password = strdup(cmaximum); + cparam->minimum.custom_password = atoi(cminimum); + cparam->maximum.custom_password = atoi(cmaximum); } else if (!strcmp(ctype, "points")) { @@ -930,8 +919,8 @@ ppdOpen2(cups_file_t *fp) /* I - File to read from */ else if (!strcmp(ctype, "string")) { cparam->type = PPD_CUSTOM_STRING; - cparam->minimum.custom_string = strdup(cminimum); - cparam->maximum.custom_string = strdup(cmaximum); + cparam->minimum.custom_string = atoi(cminimum); + cparam->maximum.custom_string = atoi(cmaximum); } else { @@ -2896,5 +2885,5 @@ ppd_read(cups_file_t *fp, /* I - File to read from */ /* - * End of "$Id: ppd.c 5119 2006-02-16 15:52:06Z mike $". + * End of "$Id: ppd.c 5200 2006-02-28 00:10:32Z mike $". */ diff --git a/cups/ppd.h b/cups/ppd.h index 196394dea..2ec40c21f 100644 --- a/cups/ppd.h +++ b/cups/ppd.h @@ -1,5 +1,5 @@ /* - * "$Id: ppd.h 5139 2006-02-21 12:56:27Z mike $" + * "$Id: ppd.h 5190 2006-02-27 02:42:07Z mike $" * * PostScript Printer Description definitions for the Common UNIX Printing * System (CUPS). @@ -232,6 +232,18 @@ typedef enum ppd_cptype_e /**** Custom Parameter Type @since CUPS 1.2@ ****/ PPD_CUSTOM_STRING /* String of characters */ } ppd_cptype_t; +typedef union ppd_cplimit_u /**** Custom Parameter Limit @since CUPS 1.2@ ****/ +{ + float custom_curve; /* Gamma value */ + int custom_int; /* Integer value */ + float custom_invcurve; /* Gamma value */ + int custom_passcode; /* Passcode length */ + int custom_password; /* Password length */ + float custom_points; /* Measurement value */ + float custom_real; /* Real value */ + int custom_string; /* String length */ +} ppd_cplimit_t; + typedef union ppd_cpvalue_u /**** Custom Parameter Value @since CUPS 1.2@ ****/ { float custom_curve; /* Gamma value */ @@ -250,9 +262,9 @@ typedef struct ppd_cparam_s /**** Custom Parameter @since CUPS 1.2@ ****/ char text[PPD_MAX_TEXT]; /* Human-readable text */ int order; /* Order (0 to N) */ ppd_cptype_t type; /* Parameter type */ - ppd_cpvalue_t minimum, /* Minimum value */ - maximum, /* Maximum value */ - current; /* Current value */ + ppd_cplimit_t minimum, /* Minimum value */ + maximum; /* Maximum value */ + ppd_cpvalue_t current; /* Current value */ } ppd_cparam_t; typedef struct ppd_coption_s /**** Custom Option @since CUPS 1.2@ ****/ @@ -391,5 +403,5 @@ extern ppd_file_t *ppdOpen2(cups_file_t *fp); #endif /* !_CUPS_PPD_H_ */ /* - * End of "$Id: ppd.h 5139 2006-02-21 12:56:27Z mike $". + * End of "$Id: ppd.h 5190 2006-02-27 02:42:07Z mike $". */ diff --git a/cups/request.c b/cups/request.c index 14e83f4da..5f44ad961 100644 --- a/cups/request.c +++ b/cups/request.c @@ -1,5 +1,5 @@ /* - * "$Id: request.c 5139 2006-02-21 12:56:27Z mike $" + * "$Id: request.c 5147 2006-02-22 16:37:44Z mike $" * * IPP utilities for the Common UNIX Printing System (CUPS). * @@ -64,6 +64,7 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */ ipp_t *response; /* IPP response data */ size_t length; /* Content-Length value */ http_status_t status; /* Status of HTTP request */ + ipp_state_t state; /* State of IPP processing */ FILE *file; /* File to send */ struct stat fileinfo; /* File information */ int bytes; /* Number of bytes read/written */ @@ -161,6 +162,7 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */ httpSetLength(http, length); httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp"); httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring); + httpSetExpect(http, HTTP_CONTINUE); DEBUG_printf(("cupsDoFileRequest: authstring=\"%s\"\n", http->authstring)); @@ -182,16 +184,34 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */ } /* - * Send the IPP data and wait for the response... + * Wait up to 1 second for a 100-continue response... */ - DEBUG_puts("cupsDoFileRequest: ipp write..."); + if (httpWait(http, 1000)) + status = httpUpdate(http); + else + status = HTTP_CONTINUE; + + if (status == HTTP_CONTINUE) + { + /* + * Send the IPP data... + */ - request->state = IPP_IDLE; - status = HTTP_CONTINUE; + DEBUG_puts("cupsDoFileRequest: ipp write..."); - if (ippWrite(http, request) != IPP_ERROR) - if (filename != NULL) + request->state = IPP_IDLE; + + while ((state = ippWrite(http, request)) != IPP_DATA) + if (state == IPP_ERROR) + break; + else if (httpCheck(http)) + { + if ((status = httpUpdate(http)) != HTTP_CONTINUE) + break; + } + + if (state == IPP_DATA && filename) { DEBUG_puts("cupsDoFileRequest: file write..."); @@ -213,6 +233,7 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */ break; } } + } /* * Get the server's return status... @@ -437,5 +458,5 @@ _cupsSetError(ipp_status_t status, /* I - IPP status code */ /* - * End of "$Id: request.c 5139 2006-02-21 12:56:27Z mike $". + * End of "$Id: request.c 5147 2006-02-22 16:37:44Z mike $". */ diff --git a/cups/testfile.c b/cups/testfile.c index aa4a6fd7a..7bd0c2b14 100644 --- a/cups/testfile.c +++ b/cups/testfile.c @@ -1,5 +1,5 @@ /* - * "$Id: testfile.c 5057 2006-02-02 20:38:29Z mike $" + * "$Id: testfile.c 5194 2006-02-27 20:57:07Z mike $" * * File test program for the Common UNIX Printing System (CUPS). * @@ -39,7 +39,9 @@ #include "string.h" #include "file.h" #include "debug.h" -#include +#ifdef HAVE_LIBZ +# include +#endif /* HAVE_LIBZ */ /* @@ -442,5 +444,5 @@ read_write_tests(int compression) /* I - Use compression? */ /* - * End of "$Id: testfile.c 5057 2006-02-02 20:38:29Z mike $". + * End of "$Id: testfile.c 5194 2006-02-27 20:57:07Z mike $". */ diff --git a/cups/testi18n.c b/cups/testi18n.c index a141d80f4..8b0fbad2f 100644 --- a/cups/testi18n.c +++ b/cups/testi18n.c @@ -1,5 +1,5 @@ /* - * "$Id: testi18n.c 4767 2005-10-10 19:23:23Z mike $" + * "$Id: testi18n.c 5195 2006-02-27 21:05:46Z mike $" * * Internationalization test for Common UNIX Printing System (CUPS). * @@ -156,7 +156,7 @@ print_synopsis(void) * 'print_utf8()' - Print UTF-8 string with (optional) message. */ -void +static void print_utf8(const char *msg, /* I - Message String */ const cups_utf8_t *src) /* I - UTF-8 Source String */ { @@ -174,7 +174,7 @@ print_utf8(const char *msg, /* I - Message String */ * 'print_utf16()' - Print UTF-16 string with (optional) message. */ -void +static void print_utf16(const char *msg, /* I - Message String */ const cups_utf16_t *src) /* I - UTF-16 Source String */ { @@ -191,7 +191,7 @@ print_utf16(const char *msg, /* I - Message String */ * 'print_utf32()' - Print UTF-32 string with (optional) message. */ -void +static void print_utf32(const char *msg, /* I - Message String */ const cups_utf32_t *src) /* I - UTF-32 Source String */ { @@ -787,5 +787,5 @@ test_normalize(const int verbose) /* I - Verbose flag */ /* - * End of "$Id: testi18n.c 4767 2005-10-10 19:23:23Z mike $" + * End of "$Id: testi18n.c 5195 2006-02-27 21:05:46Z mike $" */ diff --git a/cups/usersys.c b/cups/usersys.c index 2dbcbdd44..b75dc3790 100644 --- a/cups/usersys.c +++ b/cups/usersys.c @@ -1,5 +1,5 @@ /* - * "$Id: usersys.c 5138 2006-02-21 10:49:06Z mike $" + * "$Id: usersys.c 5182 2006-02-26 04:10:27Z mike $" * * User, system, and password routines for the Common UNIX Printing * System (CUPS). @@ -26,15 +26,16 @@ * * Contents: * - * cupsEncryption() - Get the default encryption settings. - * cupsGetPassword() - Get a password from the user. - * cupsServer() - Return the hostname of the default server. - * cupsSetEncryption() - Set the encryption preference. - * cupsSetPasswordCB() - Set the password callback for CUPS. - * cupsSetServer() - Set the default server name. - * cupsSetUser() - Set the default user name. - * cupsUser() - Return the current users name. - * _cupsGetPassword() - Get a password from the user. + * cupsEncryption() - Get the default encryption settings. + * cupsGetPassword() - Get a password from the user. + * cupsServer() - Return the hostname of the default server. + * cupsSetEncryption() - Set the encryption preference. + * cupsSetPasswordCB() - Set the password callback for CUPS. + * cupsSetServer() - Set the default server name. + * cupsSetUser() - Set the default user name. + * cupsUser() - Return the current users name. + * _cupsGetPassword() - Get a password from the user. + * cups_open_client_conf() - Open the client.conf file. */ /* @@ -50,6 +51,13 @@ #endif /* WIN32 */ +/* + * Local functions... + */ + +static cups_file_t *cups_open_client_conf(void); + + /* * 'cupsEncryption()' - Get the default encryption settings. * @@ -64,7 +72,6 @@ cupsEncryption(void) { cups_file_t *fp; /* client.conf file */ char *encryption; /* CUPS_ENCRYPTION variable */ - const char *home; /* Home directory of user */ char line[1024], /* Line from file */ *value; /* Value on line */ int linenum; /* Line number */ @@ -84,26 +91,13 @@ cupsEncryption(void) if ((encryption = getenv("CUPS_ENCRYPTION")) == NULL) { /* - * Next check to see if we have a $HOME/.cupsrc or client.conf file... + * No, open the client.conf file... */ - if ((home = getenv("HOME")) != NULL) - { - snprintf(line, sizeof(line), "%s/.cupsrc", home); - fp = cupsFileOpen(line, "r"); - } - else - fp = NULL; - - if (fp == NULL) - { - snprintf(line, sizeof(line), "%s/client.conf", cg->cups_serverroot); - fp = cupsFileOpen(line, "r"); - } - + fp = cups_open_client_conf(); encryption = "IfRequested"; - if (fp != NULL) + if (fp) { /* * Read the config file and look for an Encryption line... @@ -181,7 +175,6 @@ cupsServer(void) { cups_file_t *fp; /* client.conf file */ char *server; /* Pointer to server name */ - const char *home; /* Home directory of user */ char *port; /* Port number */ char line[1024], /* Line from file */ *value; /* Value on line */ @@ -205,22 +198,10 @@ cupsServer(void) if ((server = getenv("CUPS_SERVER")) == NULL) { /* - * Next check to see if we have a $HOME/.cupsrc or client.conf file... + * No environment variable, try the client.conf file... */ - if ((home = getenv("HOME")) != NULL) - { - snprintf(line, sizeof(line), "%s/.cupsrc", home); - fp = cupsFileOpen(line, "r"); - } - else - fp = NULL; - - if (fp == NULL) - { - snprintf(line, sizeof(line), "%s/client.conf", cg->cups_serverroot); - fp = cupsFileOpen(line, "r"); - } + fp = cups_open_client_conf(); #ifdef CUPS_DEFAULT_DOMAINSOCKET /* @@ -235,7 +216,7 @@ cupsServer(void) #endif /* CUPS_DEFAULT_DOMAINSOCKET */ server = "localhost"; - if (fp != NULL) + if (fp) { /* * Read the config file and look for a ServerName line... @@ -470,5 +451,38 @@ _cupsGetPassword(const char *prompt) /* I - Prompt string */ /* - * End of "$Id: usersys.c 5138 2006-02-21 10:49:06Z mike $". + * 'cups_open_client_conf()' - Open the client.conf file. + */ + +static cups_file_t * /* O - File or NULL */ +cups_open_client_conf(void) +{ + cups_file_t *fp; /* File */ + const char *home; /* Home directory of user */ + char filename[1024]; /* Filename */ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + if ((home = getenv("HOME")) != NULL) + { + /* + * Look for ~/.cups/client.conf or ~/.cupsrc... + */ + + snprintf(filename, sizeof(filename), "%s/.cups/client.conf", home); + if ((fp = cupsFileOpen(filename, "r")) != NULL) + return (fp); + + snprintf(filename, sizeof(filename), "%s/.cupsrc", home); + if ((fp = cupsFileOpen(filename, "r")) != NULL) + return (fp); + } + + snprintf(filename, sizeof(filename), "%s/client.conf", cg->cups_serverroot); + return (cupsFileOpen(filename, "r")); +} + + +/* + * End of "$Id: usersys.c 5182 2006-02-26 04:10:27Z mike $". */ diff --git a/cups/util.c b/cups/util.c index 255650737..5a018b66f 100644 --- a/cups/util.c +++ b/cups/util.c @@ -1,5 +1,5 @@ /* - * "$Id: util.c 5138 2006-02-21 10:49:06Z mike $" + * "$Id: util.c 5165 2006-02-24 21:20:30Z mike $" * * Printing utilities for the Common UNIX Printing System (CUPS). * @@ -819,7 +819,10 @@ cupsGetPPD2(http_t *http, /* I - HTTP connection */ if (!http || !name) { - _cupsSetError(IPP_INTERNAL_ERROR, NULL); + if (!http) + _cupsSetError(IPP_INTERNAL_ERROR, "No HTTP connection!"); + else + _cupsSetError(IPP_INTERNAL_ERROR, "No printer name!"); return (NULL); } @@ -1491,7 +1494,7 @@ cups_get_printer_uri( if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", name) != HTTP_URI_OK) { - _cupsSetError(IPP_INTERNAL_ERROR, NULL); + _cupsSetError(IPP_INTERNAL_ERROR, "Unable to create printer-uri!"); *host = '\0'; *resource = '\0'; @@ -1628,6 +1631,8 @@ cups_get_printer_uri( ippDelete(response); } + _cupsSetError(IPP_INTERNAL_ERROR, "No printer-uri found!"); + *host = '\0'; *resource = '\0'; @@ -1636,5 +1641,5 @@ cups_get_printer_uri( /* - * End of "$Id: util.c 5138 2006-02-21 10:49:06Z mike $". + * End of "$Id: util.c 5165 2006-02-24 21:20:30Z mike $". */ diff --git a/doc/Makefile b/doc/Makefile index 373f5b09c..443fda185 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -1,9 +1,9 @@ # -# "$Id: Makefile 5124 2006-02-17 16:05:21Z mike $" +# "$Id: Makefile 5192 2006-02-27 03:08:47Z mike $" # # Documentation makefile for the Common UNIX Printing System (CUPS). # -# Copyright 1993-2006 by Easy Software Products. +# Copyright 1997-2006 by Easy Software Products. # # These coded instructions, statements, and computer programs are the # property of Easy Software Products and are protected by Federal @@ -39,6 +39,7 @@ WEBBUTTONS = \ images/cancel-all-jobs.gif \ images/cancel-job.gif \ images/change-settings.gif \ + images/clean-print-heads.gif \ images/continue.gif \ images/delete-class.gif \ images/delete-printer.gif \ @@ -54,6 +55,7 @@ WEBBUTTONS = \ images/modify-printer.gif \ images/move-job.gif \ images/move-jobs.gif \ + images/print-self-test-page.gif \ images/print-test-page.gif \ images/publish-printer.gif \ images/reject-jobs.gif \ @@ -104,6 +106,7 @@ HELPFILES = \ help/api-filter.html \ help/api-httpipp.html \ help/api-ppd.html \ + help/api-raster.html \ help/classes-conf-reference.html \ help/client-conf-reference.html \ help/cupsd-conf-reference.html \ @@ -115,6 +118,7 @@ HELPFILES = \ help/man-backend.html \ help/man-cancel.html \ help/man-classes.conf.html \ + help/man-client.conf.html \ help/man-cupsaddsmb.html \ help/man-cups-config.html \ help/man-cupsd.html \ @@ -140,6 +144,7 @@ HELPFILES = \ help/man-printers.conf.html \ help/network.html \ help/overview.html \ + help/spec-command.html \ help/spec-ipp.html \ help/spec-ppd.html \ help/standard.html \ diff --git a/doc/help/api-array.html b/doc/help/api-array.html index a9e4ca979..bc77e7d61 100644 --- a/doc/help/api-array.html +++ b/doc/help/api-array.html @@ -16,7 +16,7 @@ + + Raster API + + + + + + + +

Introduction

+ +

The CUPS raster API provides a standard interface for reading +and writing CUPS raster streams which are used for printing to +raster printers. Because the raster format is updated from time +to time, it is important to use this API to avoid +incompatibilities with newer versions of CUPS.

+ +

General Usage

+ +

The <cups/raster.h> header file must be +included to use the cupsRaster functions.

+ +

Programs using these functions must be linked to the CUPS +imaging library: libcupsimage.a, +libcupsimage.so.2, libcupsimage.2.dylib, +libcupsimage_s.a, or libcupsimage2.lib +depending on the platform. The following command compiles +myprogram.c using GCC and the CUPS imaging +library:

+ +
+gcc -o myprogram myprogram.c -lcupsimage
+
+ +

Compatibility

+ +

Unless otherwise specified, the raster API functions require +CUPS 1.1 or higher.

+ +

Licensing

+ +

The CUPS raster API is provided under the terms of the GNU +General Public License, with exceptions for MacOS X-based +programs. Please see the CUPS license agreement for more +information.

+

Contents

+ + +

Enumerations

+ + +

cups_bool_e

+

Description

+

Types...

+

Values

+
+ + + + +
NameDescription
CUPS_FALSE Logical false
CUPS_TRUE Logical true
+ +

cups_mode_e

+

Description

+

Raster modes

+

Values

+
+ + + + +
NameDescription
CUPS_RASTER_READ Open stream for reading
CUPS_RASTER_WRITE Open stream for writing
+ +

Functions

+ + +

cupsRasterClose()

+

Description

+

Close a raster stream.

+

Syntax

+
+void
+cupsRasterClose(
+    cups_raster_t * r);
+
+

Arguments

+
+ + + +
NameDescription
rStream to close
+

Returns

+

Nothing.

+ +

 CUPS 1.2 cupsRasterInterpretPPD()

+

Description

+

Interpret PPD commands to create a page header. + +This function does not mark the options in the PPD using the "num_options" +and "options" arguments. Instead, mark the options prior to calling +cupsRasterInterpretPPD() - this allows you to do per-page options +without manipulating the options array. + +

+

Syntax

+
+int
+cupsRasterInterpretPPD(
+    cups_page_header2_t * h,
+    ppd_file_t * ppd,
+    int num_options,
+    cups_option_t * options);
+
+

Arguments

+
+ + + + + + +
NameDescription
hPage header
ppdPPD file
num_optionsNumber of options
optionsOptions
+

Returns

+

0 on success, -1 on failure

+ +

cupsRasterOpen()

+

Description

+

Open a raster stream.

+

Syntax

+
+cups_raster_t *
+cupsRasterOpen(
+    int fd,
+    cups_mode_t mode);
+
+

Arguments

+
+ + + + +
NameDescription
fdFile descriptor
modeMode
+

Returns

+

New stream

+ +

cupsRasterReadHeader()

+

Description

+

Read a raster page header and store it in a +V1 page header structure.

+

Syntax

+
+unsigned
+cupsRasterReadHeader(
+    cups_raster_t * r,
+    cups_page_header_t * h);
+
+

Arguments

+
+ + + + +
NameDescription
rRaster stream
hPointer to header data
+

Returns

+

1 on success, 0 on fail

+ +

 CUPS 1.2 cupsRasterReadHeader2()

+

Description

+

Read a raster page header and store it in a +V2 page header structure. + +

+

Syntax

+
+unsigned
+cupsRasterReadHeader2(
+    cups_raster_t * r,
+    cups_page_header2_t * h);
+
+

Arguments

+
+ + + + +
NameDescription
rRaster stream
hPointer to header data
+

Returns

+

1 on success, 0 on fail

+ +

cupsRasterReadPixels()

+

Description

+

Read raster pixels.

+

Syntax

+
+unsigned
+cupsRasterReadPixels(
+    cups_raster_t * r,
+    unsigned char * p,
+    unsigned len);
+
+

Arguments

+
+ + + + + +
NameDescription
rRaster stream
pPointer to pixel buffer
lenNumber of bytes to read
+

Returns

+

Number of bytes read

+ +

cupsRasterWriteHeader()

+

Description

+

Write a raster page header from a V1 page +header structure.

+

Syntax

+
+unsigned
+cupsRasterWriteHeader(
+    cups_raster_t * r,
+    cups_page_header_t * h);
+
+

Arguments

+
+ + + + +
NameDescription
rRaster stream
hRaster page header
+

Returns

+

1 on success, 0 on failure

+ +

 CUPS 1.2 cupsRasterWriteHeader2()

+

Description

+

Write a raster page header from a V2 page +header structure. + +

+

Syntax

+
+unsigned
+cupsRasterWriteHeader2(
+    cups_raster_t * r,
+    cups_page_header2_t * h);
+
+

Arguments

+
+ + + + +
NameDescription
rRaster stream
hRaster page header
+

Returns

+

1 on success, 0 on failure

+ +

cupsRasterWritePixels()

+

Description

+

Write raster pixels.

+

Syntax

+
+unsigned
+cupsRasterWritePixels(
+    cups_raster_t * r,
+    unsigned char * p,
+    unsigned len);
+
+

Arguments

+
+ + + + + +
NameDescription
rRaster stream
pBytes to write
lenNumber of bytes to write
+

Returns

+

Number of bytes written

+ +

Structures

+ + +

 CUPS 1.2 cups_page_header2_s

+

Description

+

Version 2 Page Header

+

Definition

+
+struct cups_page_header2_s
+{
+  unsigned AdvanceDistance;
+  cups_adv_t AdvanceMedia;
+  cups_bool_t Collate;
+  cups_cut_t CutMedia;
+  cups_bool_t Duplex;
+  unsigned HWResolution[2];
+  unsigned ImagingBoundingBox[4];
+  cups_bool_t InsertSheet;
+  cups_jog_t Jog;
+  cups_edge_t LeadingEdge;
+  cups_bool_t ManualFeed;
+  unsigned Margins[2];
+  char MediaClass[64];
+  char MediaColor[64];
+  unsigned MediaPosition;
+  char MediaType[64];
+  unsigned MediaWeight;
+  cups_bool_t MirrorPrint;
+  cups_bool_t NegativePrint;
+  unsigned NumCopies;
+  cups_orient_t Orientation;
+  cups_bool_t OutputFaceUp;
+  char OutputType[64];
+  unsigned PageSize[2];
+  cups_bool_t Separations;
+  cups_bool_t TraySwitch;
+  cups_bool_t Tumble;
+  unsigned cupsBitsPerColor;
+  unsigned cupsBitsPerPixel;
+  float cupsBorderlessScalingFactor;
+  unsigned cupsBytesPerLine;
+  cups_order_t cupsColorOrder;
+  cups_cspace_t cupsColorSpace;
+  unsigned cupsCompression;
+  unsigned cupsHeight;
+  float cupsImagingBBox[4];
+  unsigned cupsInteger[16];
+  char cupsMarkerType[64];
+  unsigned cupsMediaType;
+  unsigned cupsNumColors;
+  char cupsPageSizeName[64];
+  float cupsPageSize[2];
+  float cupsReal[16];
+  char cupsRenderingIntent[64];
+  unsigned cupsRowCount;
+  unsigned cupsRowFeed;
+  unsigned cupsRowStep;
+  char cupsString[16][64];
+  unsigned cupsWidth;
+};
+
+

Members

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescription
AdvanceDistance AdvanceDistance value in points
AdvanceMedia AdvanceMedia value (see above)
Collate Collated copies value
CutMedia CutMedia value (see above)
Duplex Duplexed (double-sided) value
HWResolution[2] Resolution in dots-per-inch
ImagingBoundingBox[4] Pixel region that is painted (points)
InsertSheet InsertSheet value
Jog Jog value (see above)
LeadingEdge LeadingEdge value (see above)
ManualFeed ManualFeed value
Margins[2] Lower-lefthand margins in points
MediaClass[64] MediaClass string
MediaColor[64] MediaColor string
MediaPosition MediaPosition value
MediaType[64] MediaType string
MediaWeight MediaWeight value in grams/m^2
MirrorPrint MirrorPrint value
NegativePrint NegativePrint value
NumCopies Number of copies to produce
Orientation Orientation value (see above)
OutputFaceUp OutputFaceUp value
OutputType[64] OutputType string
PageSize[2] Width and length of page in points
Separations Separations value
TraySwitch TraySwitch value
Tumble Tumble value
cupsBitsPerColor Number of bits for each color
cupsBitsPerPixel Number of bits for each pixel
cupsBorderlessScalingFactor  CUPS 1.2 Scaling that was applied to page data
cupsBytesPerLine Number of bytes per line
cupsColorOrder Order of colors
cupsColorSpace True colorspace
cupsCompression Device compression to use
cupsHeight Height of page image in pixels
cupsImagingBBox[4]  CUPS 1.2 Floating point ImagingBoundingBox * +(scaling factor not applied)
cupsInteger[16]  CUPS 1.2 User-defined integer values
cupsMarkerType[64]  CUPS 1.2 Ink/toner type
cupsMediaType Media type code
cupsNumColors  CUPS 1.2 Number of colors
cupsPageSizeName[64]  CUPS 1.2 PageSize name
cupsPageSize[2]  CUPS 1.2 Floating point PageSize (scaling * +factor not applied)
cupsReal[16]  CUPS 1.2 User-defined floating-point values
cupsRenderingIntent[64]  CUPS 1.2 Color rendering intent
cupsRowCount Rows per band
cupsRowFeed Feed between bands
cupsRowStep Spacing between lines
cupsString[16][64]  CUPS 1.2 User-defined string values
cupsWidth Width of page image in pixels
+ +

cups_page_header_s

+

Description

+

Version 1 Page Header

+

Definition

+
+struct cups_page_header_s
+{
+  unsigned AdvanceDistance;
+  cups_adv_t AdvanceMedia;
+  cups_bool_t Collate;
+  cups_cut_t CutMedia;
+  cups_bool_t Duplex;
+  unsigned HWResolution[2];
+  unsigned ImagingBoundingBox[4];
+  cups_bool_t InsertSheet;
+  cups_jog_t Jog;
+  cups_edge_t LeadingEdge;
+  cups_bool_t ManualFeed;
+  unsigned Margins[2];
+  char MediaClass[64];
+  char MediaColor[64];
+  unsigned MediaPosition;
+  char MediaType[64];
+  unsigned MediaWeight;
+  cups_bool_t MirrorPrint;
+  cups_bool_t NegativePrint;
+  unsigned NumCopies;
+  cups_orient_t Orientation;
+  cups_bool_t OutputFaceUp;
+  char OutputType[64];
+  unsigned PageSize[2];
+  cups_bool_t Separations;
+  cups_bool_t TraySwitch;
+  cups_bool_t Tumble;
+  unsigned cupsBitsPerColor;
+  unsigned cupsBitsPerPixel;
+  unsigned cupsBytesPerLine;
+  cups_order_t cupsColorOrder;
+  cups_cspace_t cupsColorSpace;
+  unsigned cupsCompression;
+  unsigned cupsHeight;
+  unsigned cupsMediaType;
+  unsigned cupsRowCount;
+  unsigned cupsRowFeed;
+  unsigned cupsRowStep;
+  unsigned cupsWidth;
+};
+
+

Members

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescription
AdvanceDistance AdvanceDistance value in points
AdvanceMedia AdvanceMedia value (see above)
Collate Collated copies value
CutMedia CutMedia value (see above)
Duplex Duplexed (double-sided) value
HWResolution[2] Resolution in dots-per-inch
ImagingBoundingBox[4] Pixel region that is painted (points)
InsertSheet InsertSheet value
Jog Jog value (see above)
LeadingEdge LeadingEdge value (see above)
ManualFeed ManualFeed value
Margins[2] Lower-lefthand margins in points
MediaClass[64] MediaClass string
MediaColor[64] MediaColor string
MediaPosition MediaPosition value
MediaType[64] MediaType string
MediaWeight MediaWeight value in grams/m^2
MirrorPrint MirrorPrint value
NegativePrint NegativePrint value
NumCopies Number of copies to produce
Orientation Orientation value (see above)
OutputFaceUp OutputFaceUp value
OutputType[64] OutputType string
PageSize[2] Width and length of page in points
Separations Separations value
TraySwitch TraySwitch value
Tumble Tumble value
cupsBitsPerColor Number of bits for each color
cupsBitsPerPixel Number of bits for each pixel
cupsBytesPerLine Number of bytes per line
cupsColorOrder Order of colors
cupsColorSpace True colorspace
cupsCompression Device compression to use
cupsHeight Height of page image in pixels
cupsMediaType Media type code
cupsRowCount Rows per band
cupsRowFeed Feed between bands
cupsRowStep Spacing between lines
cupsWidth Width of page image in pixels
+ +

Types

+ + +

 CUPS 1.2 cups_page_header2_t

+

Description

+

Version 2 Page Header

+

Definition

+
+typedef struct cups_page_header2_s cups_page_header2_t;
+
+ +

cups_page_header_t

+

Description

+

Version 1 Page Header

+

Definition

+
+typedef struct cups_page_header_s cups_page_header_t;
+
+ +

cups_raster_t

+

Description

+

Raster stream data

+

Definition

+
+typedef struct _cups_raster_s cups_raster_t;
+
+ + diff --git a/doc/help/cupsd-conf-reference.html b/doc/help/cupsd-conf-reference.html index a36626aff..ee69c1c05 100644 --- a/doc/help/cupsd-conf-reference.html +++ b/doc/help/cupsd-conf-reference.html @@ -7,6 +7,10 @@ + + CUPS Command File Format + + + + + + +

Introduction

+ +

This specification describes the CUPS command file format +(application/vnd.cups-command) which is used to send printer +maintenance commands to a printer in a device-independent way. +The current specification supports basic maintenance functions +such as head cleaning and self-test pages.

+ +

Printer drivers advertise support for the CUPS command file +format by providing a filter for the +application/vnd.cups-command file type. Applications +can determine if a printer supports printing of CUPS command +files by checking the printer-type attribute for the +CUPS_PRINTER_COMMANDS capability bit.

+ +

File Syntax

+ +

CUPS command files are ASCII text files. The first line of a +CUPS command file MUST contain:

+ +
+#CUPS-COMMAND
+
+ +

After that, each line is either a command or a comment. +Comments begin with the # character, e.g.:

+ +
+# This is a comment
+
+ +

The printer commands are described below. Printer commands are +case-insensitive, so "PRINTSELFTESTPAGE", "printselftestpage", +and "PrintSelfTestPage" are equivalent. Commands that accept +arguments have their arguments on the same line separated by +whitespace.

+ +

Commands

+ +

Clean

+ +

Clean colorname

+ +

Does a standard print head cleaning. If a printer does not +support cleaning of individual colors or cartridges, then all +print heads are cleaned. Command filters MUST support the "all" +colorname. Other standard color names include "black", "color", +"photo", "cyan", "magenta", "yellow", "light-cyan", +"light-magenta", "light-black", "light-gray", and +"dark-gray".

+ +

Example:

+ +
+#CUPS-COMMAND
+Clean all
+
+ +

PrintSelfTestPage

+ +

PrintSelfTestPage

+ +

Print a self-test page on the printer. Typically this page +shows if all jets on a print head are functioning properly.

+ +

Example:

+ +
+#CUPS-COMMAND
+PrintSelfTestPage
+
+ + + diff --git a/doc/help/spec-ppd.html b/doc/help/spec-ppd.html index 6dc27cb6b..51c35b925 100644 --- a/doc/help/spec-ppd.html +++ b/doc/help/spec-ppd.html @@ -8,7 +8,7 @@ + +

Introduction

+ +

The CUPS raster API provides a standard interface for reading +and writing CUPS raster streams which are used for printing to +raster printers. Because the raster format is updated from time +to time, it is important to use this API to avoid +incompatibilities with newer versions of CUPS.

+ +

General Usage

+ +

The <cups/raster.h> header file must be +included to use the cupsRaster functions.

+ +

Programs using these functions must be linked to the CUPS +imaging library: libcupsimage.a, +libcupsimage.so.2, libcupsimage.2.dylib, +libcupsimage_s.a, or libcupsimage2.lib +depending on the platform. The following command compiles +myprogram.c using GCC and the CUPS imaging +library:

+ +
+gcc -o myprogram myprogram.c -lcupsimage
+
+ +

Compatibility

+ +

Unless otherwise specified, the raster API functions require +CUPS 1.1 or higher.

+ +

Licensing

+ +

The CUPS raster API is provided under the terms of the GNU +General Public License, with exceptions for MacOS X-based +programs. Please see the CUPS license agreement for more +information.

diff --git a/filter/hpgl-input.c b/filter/hpgl-input.c index d6363e6fb..abfb63310 100644 --- a/filter/hpgl-input.c +++ b/filter/hpgl-input.c @@ -1,9 +1,9 @@ /* - * "$Id: hpgl-input.c 4494 2005-02-18 02:18:11Z mike $" + * "$Id: hpgl-input.c 5150 2006-02-22 19:21:50Z mike $" * * HP-GL/2 input processing for the Common UNIX Printing System (CUPS). * - * Copyright 1993-2005 by Easy Software Products. + * Copyright 1993-2006 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -125,6 +125,9 @@ ParseCommand(FILE *fp, /* I - File to read from */ default : /* HP RTL/PCL control */ while ((i = getc(fp)) != EOF && !isupper(i & 255)); + + if (i == EOF) + return (-1); break; } } while (ch < ' '); @@ -133,7 +136,19 @@ ParseCommand(FILE *fp, /* I - File to read from */ name[1] = getc(fp); name[2] = '\0'; - if (strcasecmp(name, "LB") == 0) + if (name[1] < ' ') + { + /* + * If we get here, then more than likely we are faced with a raw PCL + * file which we can't handle - abort! + */ + + fputs("ERROR: Invalid HP-GL/2 command seen, unable to print file!\n", + stderr); + return (-1); + } + + if (!strcasecmp(name, "LB")) { bufptr = buf; while ((ch = getc(fp)) != StringTerminator) @@ -145,7 +160,7 @@ ParseCommand(FILE *fp, /* I - File to read from */ p[num_params].value.string = strdup(buf); num_params ++; } - else if (strcasecmp(name, "SM") == 0) + else if (!strcasecmp(name, "SM")) { buf[0] = getc(fp); buf[1] = '\0'; @@ -153,7 +168,7 @@ ParseCommand(FILE *fp, /* I - File to read from */ p[num_params].value.string = strdup(buf); num_params ++; } - else if (strcasecmp(name, "DT") == 0) + else if (!strcasecmp(name, "DT")) { if ((buf[0] = getc(fp)) != ';') { @@ -163,7 +178,7 @@ ParseCommand(FILE *fp, /* I - File to read from */ num_params ++; } } - else if (strcasecmp(name, "PE") == 0) + else if (!strcasecmp(name, "PE")) { bufptr = buf; while ((ch = getc(fp)) != ';') @@ -254,5 +269,5 @@ FreeParameters(int num_params, /* I - Number of parameters */ /* - * End of "$Id: hpgl-input.c 4494 2005-02-18 02:18:11Z mike $". + * End of "$Id: hpgl-input.c 5150 2006-02-22 19:21:50Z mike $". */ diff --git a/filter/image-private.h b/filter/image-private.h index f87c41b4f..df7bed281 100644 --- a/filter/image-private.h +++ b/filter/image-private.h @@ -1,10 +1,10 @@ /* - * "$Id: image-private.h 4742 2005-10-02 23:01:43Z mike $" + * "$Id: image-private.h 5191 2006-02-27 02:47:56Z mike $" * * Private image library definitions for the Common UNIX Printing * System (CUPS). * - * Copyright 1993-2005 by Easy Software Products. + * Copyright 1993-2006 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -75,6 +75,13 @@ * Types and structures... */ +typedef enum cups_iztype_e /**** Image zoom type ****/ +{ + CUPS_IZOOM_FAST, /* Use nearest-neighbor sampling */ + CUPS_IZOOM_NORMAL, /* Use bilinear interpolation */ + CUPS_IZOOM_BEST /* Use bicubic interpolation */ +} cups_iztype_t; + struct cups_ic_s; typedef struct cups_itile_s /**** Image tile ****/ @@ -199,10 +206,16 @@ extern int _cupsImageReadTIFF(cups_image_t *img, FILE *fp, cups_icspace_t secondary, int saturation, int hue, const cups_ib_t *lut); +extern void _cupsImageZoomDelete(cups_izoom_t *z); +extern void _cupsImageZoomFill(cups_izoom_t *z, int iy); +extern cups_izoom_t *_cupsImageZoomNew(cups_image_t *img, int xc0, int yc0, + int xc1, int yc1, int xsize, + int ysize, int rotated, + cups_iztype_t type); #endif /* !_CUPS_IMAGE_PRIVATE_H_ */ /* - * End of "$Id: image-private.h 4742 2005-10-02 23:01:43Z mike $". + * End of "$Id: image-private.h 5191 2006-02-27 02:47:56Z mike $". */ diff --git a/filter/image-zoom.c b/filter/image-zoom.c index 42cc478ad..8dc67ec1e 100644 --- a/filter/image-zoom.c +++ b/filter/image-zoom.c @@ -1,9 +1,9 @@ /* - * "$Id: image-zoom.c 5086 2006-02-07 02:45:26Z mike $" + * "$Id: image-zoom.c 5191 2006-02-27 02:47:56Z mike $" * * cupsImage zoom routines for the Common UNIX Printing System (CUPS). * - * Copyright 1993-2005 by Easy Software Products. + * Copyright 1993-2006 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -25,13 +25,13 @@ * * Contents: * - * cupsImageZoomDelete() - Free a zoom record... - * cupsImageZoomFill() - Fill a zoom record... - * cupsImageZoomNew() - Allocate a pixel zoom record... - * zoom_bilinear() - Fill a zoom record with image data utilizing - * bilinear interpolation. - * zoom_nearest() - Fill a zoom record quickly using nearest-neighbor - * sampling. + * _cupsImageZoomDelete() - Free a zoom record... + * _cupsImageZoomFill() - Fill a zoom record... + * _cupsImageZoomNew() - Allocate a pixel zoom record... + * zoom_bilinear() - Fill a zoom record with image data utilizing + * bilinear interpolation. + * zoom_nearest() - Fill a zoom record quickly using nearest-neighbor + * sampling. */ /* @@ -50,11 +50,11 @@ static void zoom_nearest(cups_izoom_t *z, int iy); /* - * 'cupsImageZoomDelete()' - Free a zoom record... + * '_cupsImageZoomDelete()' - Free a zoom record... */ void -cupsImageZoomDelete(cups_izoom_t *z) /* I - Zoom record to free */ +_cupsImageZoomDelete(cups_izoom_t *z) /* I - Zoom record to free */ { free(z->rows[0]); free(z->rows[1]); @@ -64,13 +64,13 @@ cupsImageZoomDelete(cups_izoom_t *z) /* I - Zoom record to free */ /* - * 'cupsImageZoomFill()' - Fill a zoom record with image data utilizing bilinear + * '_cupsImageZoomFill()' - Fill a zoom record with image data utilizing bilinear * interpolation. */ void -cupsImageZoomFill(cups_izoom_t *z, /* I - Zoom record to fill */ - int iy) /* I - Zoom image row */ +_cupsImageZoomFill(cups_izoom_t *z, /* I - Zoom record to fill */ + int iy) /* I - Zoom image row */ { switch (z->type) { @@ -86,11 +86,11 @@ cupsImageZoomFill(cups_izoom_t *z, /* I - Zoom record to fill */ /* - * 'cupsImageZoomNew()' - Allocate a pixel zoom record... + * '_cupsImageZoomNew()' - Allocate a pixel zoom record... */ cups_izoom_t * -cupsImageZoomNew( +_cupsImageZoomNew( cups_image_t *img, /* I - cupsImage to zoom */ int xc0, /* I - Upper-lefthand corner */ int yc0, /* I - ... */ @@ -366,5 +366,5 @@ zoom_nearest(cups_izoom_t *z, /* I - Zoom record to fill */ /* - * End of "$Id: image-zoom.c 5086 2006-02-07 02:45:26Z mike $". + * End of "$Id: image-zoom.c 5191 2006-02-27 02:47:56Z mike $". */ diff --git a/filter/image.h b/filter/image.h index ae90b94fc..b77e6ddc3 100644 --- a/filter/image.h +++ b/filter/image.h @@ -1,9 +1,9 @@ /* - * "$Id: image.h 4741 2005-10-02 04:25:52Z mike $" + * "$Id: image.h 5191 2006-02-27 02:47:56Z mike $" * * Image library definitions for the Common UNIX Printing System (CUPS). * - * Copyright 1993-2005 by Easy Software Products. + * Copyright 1993-2006 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -52,13 +52,6 @@ typedef enum cups_icspace_e /**** Image colorspaces ****/ CUPS_IMAGE_RGB_CMYK = 4 /* Use RGB or CMYK */ } cups_icspace_t; -typedef enum cups_iztype_e /**** Image zoom type ****/ -{ - CUPS_IZOOM_FAST, /* Use nearest-neighbor sampling */ - CUPS_IZOOM_NORMAL, /* Use bilinear interpolation */ - CUPS_IZOOM_BEST /* Use bicubic interpolation */ -} cups_iztype_t; - /* * Types and structures... @@ -133,11 +126,6 @@ extern void cupsImageWhiteToRGB(const cups_ib_t *in, cups_ib_t *out, int count); extern void cupsImageWhiteToWhite(const cups_ib_t *in, cups_ib_t *out, int count); -extern void cupsImageZoomDelete(cups_izoom_t *z); -extern void cupsImageZoomFill(cups_izoom_t *z, int iy); -extern cups_izoom_t *cupsImageZoomNew(cups_image_t *img, int x0, int y0, - int x1, int y1, int xsize, int ysize, - int rotated, cups_iztype_t type); # ifdef __cplusplus @@ -147,5 +135,5 @@ extern cups_izoom_t *cupsImageZoomNew(cups_image_t *img, int x0, int y0, #endif /* !_CUPS_IMAGE_H_ */ /* - * End of "$Id: image.h 4741 2005-10-02 04:25:52Z mike $". + * End of "$Id: image.h 5191 2006-02-27 02:47:56Z mike $". */ diff --git a/filter/imagetoraster.c b/filter/imagetoraster.c index f0dce921c..affac6c0a 100644 --- a/filter/imagetoraster.c +++ b/filter/imagetoraster.c @@ -1,5 +1,5 @@ /* - * "$Id: imagetoraster.c 5099 2006-02-13 02:46:10Z mike $" + * "$Id: imagetoraster.c 5191 2006-02-27 02:47:56Z mike $" * * Image file to raster filter for the Common UNIX Printing System (CUPS). * @@ -1286,10 +1286,10 @@ main(int argc, /* I - Number of command-line arguments */ */ if (Flip) - z = cupsImageZoomNew(img, xc0, yc0, xc1, yc1, -xtemp, ytemp, + z = _cupsImageZoomNew(img, xc0, yc0, xc1, yc1, -xtemp, ytemp, Orientation & 1, zoom_type); else - z = cupsImageZoomNew(img, xc0, yc0, xc1, yc1, xtemp, ytemp, + z = _cupsImageZoomNew(img, xc0, yc0, xc1, yc1, xtemp, ytemp, Orientation & 1, zoom_type); /* @@ -1327,9 +1327,9 @@ main(int argc, /* I - Number of command-line arguments */ if (iy != last_iy) { if (zoom_type != CUPS_IZOOM_FAST && (iy - last_iy) > 1) - cupsImageZoomFill(z, iy); + _cupsImageZoomFill(z, iy); - cupsImageZoomFill(z, iy + z->yincr); + _cupsImageZoomFill(z, iy + z->yincr); last_iy = iy; } @@ -1449,7 +1449,7 @@ main(int argc, /* I - Number of command-line arguments */ * Free memory used for the "zoom" engine... */ - cupsImageZoomDelete(z); + _cupsImageZoomDelete(z); } } @@ -4611,5 +4611,5 @@ make_lut(cups_ib_t *lut, /* I - Lookup table */ /* - * End of "$Id: imagetoraster.c 5099 2006-02-13 02:46:10Z mike $". + * End of "$Id: imagetoraster.c 5191 2006-02-27 02:47:56Z mike $". */ diff --git a/filter/raster.c b/filter/raster.c index 10d235012..607deb1a6 100644 --- a/filter/raster.c +++ b/filter/raster.c @@ -1,5 +1,5 @@ /* - * "$Id: raster.c 4981 2006-01-25 21:34:00Z mike $" + * "$Id: raster.c 5192 2006-02-27 03:08:47Z mike $" * * Raster file routines for the Common UNIX Printing System (CUPS). * @@ -36,11 +36,15 @@ * * cupsRasterClose() - Close a raster stream. * cupsRasterOpen() - Open a raster stream. - * cupsRasterReadHeader() - Read a V1 raster page header. - * cupsRasterReadHeader2() - Read a V2 raster page header. + * cupsRasterReadHeader() - Read a raster page header and store it in a + * V1 page header structure. + * cupsRasterReadHeader2() - Read a raster page header and store it in a + * V2 page header structure. * cupsRasterReadPixels() - Read raster pixels. - * cupsRasterWriteHeader() - Write a V1 raster page header. - * cupsRasterWriteHeader2() - Write a V2 raster page header. + * cupsRasterWriteHeader() - Write a raster page header from a V1 page + * header structure. + * cupsRasterWriteHeader2() - Write a raster page header from a V2 page + * header structure. * cupsRasterWritePixels() - Write raster pixels. * cups_raster_update() - Update the raster header and row count for the * current page. @@ -153,7 +157,8 @@ cupsRasterOpen(int fd, /* I - File descriptor */ /* - * 'cupsRasterReadHeader()' - Read a V1 raster page header. + * 'cupsRasterReadHeader()' - Read a raster page header and store it in a + * V1 page header structure. */ unsigned /* O - 1 on success, 0 on fail */ @@ -179,7 +184,8 @@ cupsRasterReadHeader( /* - * 'cupsRasterReadHeader2()' - Read a V2 raster page header. + * 'cupsRasterReadHeader2()' - Read a raster page header and store it in a + * V2 page header structure. * * @since CUPS 1.2@ */ @@ -395,7 +401,8 @@ cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */ /* - * 'cupsRasterWriteHeader()' - Write a V2 raster page header. + * 'cupsRasterWriteHeader()' - Write a raster page header from a V1 page + * header structure. */ unsigned /* O - 1 on success, 0 on failure */ @@ -426,7 +433,8 @@ cupsRasterWriteHeader( /* - * 'cupsRasterWriteHeader2()' - Write a V2 raster page header. + * 'cupsRasterWriteHeader2()' - Write a raster page header from a V2 page + * header structure. * * @since CUPS 1.2@ */ @@ -888,5 +896,5 @@ cups_write(int fd, /* I - File descriptor */ /* - * End of "$Id: raster.c 4981 2006-01-25 21:34:00Z mike $". + * End of "$Id: raster.c 5192 2006-02-27 03:08:47Z mike $". */ diff --git a/filter/raster.h b/filter/raster.h index 541e6ebf8..f970f5578 100644 --- a/filter/raster.h +++ b/filter/raster.h @@ -1,5 +1,5 @@ /* - * "$Id: raster.h 4998 2006-01-26 21:59:54Z mike $" + * "$Id: raster.h 5192 2006-02-27 03:08:47Z mike $" * * Raster file definitions for the Common UNIX Printing System (CUPS). * @@ -290,7 +290,7 @@ typedef struct cups_page_header2_s /**** Version 2 Page Header @since CUPS 1.2@ /**** Version 2 Dictionary Values ****/ unsigned cupsNumColors; /* Number of colors @since CUPS 1.2@ */ float cupsBorderlessScalingFactor; - /* Scaling that was applied to page data */ + /* Scaling that was applied to page data @since CUPS 1.2@ */ float cupsPageSize[2]; /* Floating point PageSize (scaling * * factor not applied) @since CUPS 1.2@ */ float cupsImagingBBox[4]; /* Floating point ImagingBoundingBox * @@ -350,5 +350,5 @@ extern unsigned cupsRasterWriteHeader2(cups_raster_t *r, #endif /* !_CUPS_RASTER_H_ */ /* - * End of "$Id: raster.h 4998 2006-01-26 21:59:54Z mike $". + * End of "$Id: raster.h 5192 2006-02-27 03:08:47Z mike $". */ diff --git a/locale/Makefile b/locale/Makefile index de9d14e7d..eb0a3d697 100644 --- a/locale/Makefile +++ b/locale/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile 5114 2006-02-16 12:28:29Z mike $" +# "$Id: Makefile 5193 2006-02-27 20:27:07Z mike $" # # Locale file makefile for the Common UNIX Printing System (CUPS). # @@ -28,7 +28,7 @@ include ../Makedefs # Locales... # -LOCALES = fr ja +LOCALES = ja # @@ -102,5 +102,5 @@ translate.o: ../cups/http.h ../cups/i18n.h ../cups/language.h ../cups/string.h # -# End of "$Id: Makefile 5114 2006-02-16 12:28:29Z mike $". +# End of "$Id: Makefile 5193 2006-02-27 20:27:07Z mike $". # diff --git a/locale/cups.pot b/locale/cups.pot index d1a0aeb8f..9697db30e 100644 --- a/locale/cups.pot +++ b/locale/cups.pot @@ -29,7 +29,7 @@ msgid "" msgstr "" "Project-Id-Version: CUPS 1.2\n" "Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" -"POT-Creation-Date: 2006-02-15 19:50-0500\n" +"POT-Creation-Date: 2006-02-26 20:42-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -54,27 +54,32 @@ msgid "Extra" msgstr "" #: cups/ppd.c:656 cups/ppd.c:881 cups/ppd.c:1047 cups/ppd.c:662 cups/ppd.c:996 -#: cups/ppd.c:1169 +#: cups/ppd.c:1169 cups/ppd.c:651 cups/ppd.c:983 cups/ppd.c:1148 msgid "General" msgstr "" #: cups/ppd.c:704 cups/ppd.c:1105 cups/ppd.c:710 cups/ppd.c:1224 +#: cups/ppd.c:697 cups/ppd.c:1201 msgid "Media Size" msgstr "" #: cups/ppd.c:706 cups/ppd.c:1107 cups/ppd.c:712 cups/ppd.c:1226 +#: cups/ppd.c:699 cups/ppd.c:1203 msgid "Media Type" msgstr "" #: cups/ppd.c:708 cups/ppd.c:1109 cups/ppd.c:714 cups/ppd.c:1228 +#: cups/ppd.c:701 cups/ppd.c:1205 msgid "Media Source" msgstr "" #: cups/ppd.c:710 cups/ppd.c:1111 cups/ppd.c:716 cups/ppd.c:1230 +#: cups/ppd.c:703 cups/ppd.c:1207 msgid "Output Mode" msgstr "" #: cups/ppd.c:712 cups/ppd.c:1113 cups/ppd.c:718 cups/ppd.c:1232 +#: cups/ppd.c:705 cups/ppd.c:1209 msgid "Resolution" msgstr "" @@ -82,11 +87,11 @@ msgstr "" msgid "Variable" msgstr "" -#: cups/ppd.c:1535 cups/ppd.c:1650 +#: cups/ppd.c:1535 cups/ppd.c:1650 cups/ppd.c:1627 msgid "Yes" msgstr "" -#: cups/ppd.c:1537 cups/ppd.c:1652 +#: cups/ppd.c:1537 cups/ppd.c:1652 cups/ppd.c:1629 msgid "No" msgstr "" @@ -95,32 +100,39 @@ msgid "Auto" msgstr "" #: scheduler/client.c:2247 scheduler/client.c:2251 scheduler/client.c:2274 +#: scheduler/client.c:2308 msgid "Enter your username and password or the root username and password to access this page." msgstr "" #: scheduler/client.c:2252 scheduler/client.c:2256 scheduler/client.c:2279 +#: scheduler/client.c:2313 msgid "You must use a https: URL to access this page." msgstr "" #: scheduler/ipp.c:236 scheduler/ipp.c:244 scheduler/ipp.c:246 +#: scheduler/ipp.c:260 #, c-format msgid "Bad request version number %d.%d!" msgstr "" #: scheduler/ipp.c:246 scheduler/ipp.c:254 scheduler/ipp.c:256 +#: scheduler/ipp.c:270 msgid "No attributes in request!" msgstr "" #: scheduler/ipp.c:269 scheduler/ipp.c:277 scheduler/ipp.c:279 +#: scheduler/ipp.c:293 #, c-format msgid "Attribute groups are out of order (%x < %x)!" msgstr "" #: scheduler/ipp.c:379 scheduler/ipp.c:389 scheduler/ipp.c:391 +#: scheduler/ipp.c:405 msgid "Missing required attributes!" msgstr "" #: scheduler/ipp.c:575 scheduler/ipp.c:585 scheduler/ipp.c:591 +#: scheduler/ipp.c:605 #, c-format msgid "%s not supported!" msgstr "" @@ -142,26 +154,36 @@ msgstr "" #: scheduler/ipp.c:5357 scheduler/ipp.c:5769 scheduler/ipp.c:6077 #: scheduler/ipp.c:6368 scheduler/ipp.c:6410 scheduler/ipp.c:6916 #: scheduler/ipp.c:7626 scheduler/ipp.c:8589 scheduler/ipp.c:9003 -#: scheduler/ipp.c:9084 scheduler/ipp.c:9259 +#: scheduler/ipp.c:9084 scheduler/ipp.c:9259 scheduler/ipp.c:716 +#: scheduler/ipp.c:1003 scheduler/ipp.c:1174 scheduler/ipp.c:2812 +#: scheduler/ipp.c:2927 scheduler/ipp.c:4699 scheduler/ipp.c:4942 +#: scheduler/ipp.c:5326 scheduler/ipp.c:5738 scheduler/ipp.c:6046 +#: scheduler/ipp.c:6337 scheduler/ipp.c:6379 scheduler/ipp.c:7116 +#: scheduler/ipp.c:8081 scheduler/ipp.c:8745 scheduler/ipp.c:8826 +#: scheduler/ipp.c:9001 msgid "The printer or class was not found." msgstr "" #: scheduler/ipp.c:762 scheduler/ipp.c:777 scheduler/ipp.c:784 +#: scheduler/ipp.c:799 msgid "The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." msgstr "" #: scheduler/ipp.c:778 scheduler/ipp.c:1454 scheduler/ipp.c:793 #: scheduler/ipp.c:1482 scheduler/ipp.c:800 scheduler/ipp.c:1515 +#: scheduler/ipp.c:815 scheduler/ipp.c:2031 #, c-format msgid "The printer-uri \"%s\" contains invalid characters." msgstr "" #: scheduler/ipp.c:811 scheduler/ipp.c:826 scheduler/ipp.c:833 +#: scheduler/ipp.c:848 #, c-format msgid "A printer named \"%s\" already exists!" msgstr "" #: scheduler/ipp.c:904 scheduler/ipp.c:924 scheduler/ipp.c:933 +#: scheduler/ipp.c:944 #, c-format msgid "Attempt to set %s printer-state to bad value %d!" msgstr "" @@ -177,81 +199,97 @@ msgid "add_class: Unknown printer-error-policy \"%s\"." msgstr "" #: scheduler/ipp.c:1144 scheduler/ipp.c:1168 scheduler/ipp.c:1200 +#: scheduler/ipp.c:1112 msgid "Unable to allocate memory for file types!" msgstr "" #: scheduler/ipp.c:1290 scheduler/ipp.c:4501 scheduler/ipp.c:1316 #: scheduler/ipp.c:4705 scheduler/ipp.c:1348 scheduler/ipp.c:4804 +#: scheduler/ipp.c:1810 scheduler/ipp.c:4773 #, c-format msgid "Character set \"%s\" not supported!" msgstr "" #: scheduler/ipp.c:1299 scheduler/ipp.c:4510 scheduler/ipp.c:1325 #: scheduler/ipp.c:4714 scheduler/ipp.c:1357 scheduler/ipp.c:4813 +#: scheduler/ipp.c:1819 scheduler/ipp.c:4782 #, c-format msgid "Language \"%s\" not supported!" msgstr "" #: scheduler/ipp.c:1309 scheduler/ipp.c:4520 scheduler/ipp.c:1335 #: scheduler/ipp.c:4724 scheduler/ipp.c:1367 scheduler/ipp.c:4823 +#: scheduler/ipp.c:1829 scheduler/ipp.c:4792 #, c-format msgid "The notify-user-data value is too large (%d > 63 octets)!" msgstr "" #: scheduler/ipp.c:1326 scheduler/ipp.c:1352 scheduler/ipp.c:1384 +#: scheduler/ipp.c:1846 msgid "The notify-lease-duration attribute cannot be used with job subscriptions." msgstr "" #: scheduler/ipp.c:1438 scheduler/ipp.c:1466 scheduler/ipp.c:1499 +#: scheduler/ipp.c:2015 msgid "The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." msgstr "" #: scheduler/ipp.c:1487 scheduler/ipp.c:1515 scheduler/ipp.c:1548 +#: scheduler/ipp.c:2064 #, c-format msgid "A class named \"%s\" already exists!" msgstr "" #: scheduler/ipp.c:1575 scheduler/ipp.c:1607 scheduler/ipp.c:1644 +#: scheduler/ipp.c:2157 #, c-format msgid "File device URIs have been disabled! To enable, see the FileDevice directive in \"%s/cupsd.conf\"." msgstr "" #: scheduler/ipp.c:1595 scheduler/ipp.c:1627 scheduler/ipp.c:1664 +#: scheduler/ipp.c:2177 #, c-format msgid "Bad device-uri \"%s\"!" msgstr "" #: scheduler/ipp.c:1626 scheduler/ipp.c:1659 scheduler/ipp.c:1698 +#: scheduler/ipp.c:2211 #, c-format msgid "Bad port-monitor \"%s\"!" msgstr "" #: scheduler/ipp.c:1669 scheduler/ipp.c:1705 scheduler/ipp.c:1744 +#: scheduler/ipp.c:2257 #, c-format msgid "Bad printer-state value %d!" msgstr "" #: scheduler/ipp.c:1762 scheduler/ipp.c:1800 scheduler/ipp.c:1842 +#: scheduler/ipp.c:8585 #, c-format msgid "Unknown printer-op-policy \"%s\"." msgstr "" #: scheduler/ipp.c:1775 scheduler/ipp.c:1813 scheduler/ipp.c:1855 +#: scheduler/ipp.c:8600 #, c-format msgid "Unknown printer-error-policy \"%s\"." msgstr "" #: scheduler/ipp.c:1837 scheduler/ipp.c:1875 scheduler/ipp.c:1919 +#: scheduler/ipp.c:2336 #, c-format msgid "Unable to copy interface script - %s!" msgstr "" #: scheduler/ipp.c:1862 scheduler/ipp.c:1900 scheduler/ipp.c:1944 +#: scheduler/ipp.c:2361 #, c-format msgid "Unable to copy PPD file - %s!" msgstr "" #: scheduler/ipp.c:1915 scheduler/ipp.c:1954 scheduler/ipp.c:2000 +#: scheduler/ipp.c:2417 msgid "Unable to copy PPD file!" msgstr "" @@ -263,7 +301,9 @@ msgstr "" #: scheduler/ipp.c:7839 scheduler/ipp.c:8334 scheduler/ipp.c:2158 #: scheduler/ipp.c:2451 scheduler/ipp.c:5220 scheduler/ipp.c:6210 #: scheduler/ipp.c:7713 scheduler/ipp.c:7928 scheduler/ipp.c:8167 -#: scheduler/ipp.c:8672 +#: scheduler/ipp.c:8672 scheduler/ipp.c:2613 scheduler/ipp.c:2906 +#: scheduler/ipp.c:5189 scheduler/ipp.c:6179 scheduler/ipp.c:7203 +#: scheduler/ipp.c:7418 scheduler/ipp.c:7657 scheduler/ipp.c:8164 msgid "Got a printer-uri attribute but no job-id!" msgstr "" @@ -276,6 +316,9 @@ msgstr "" #: scheduler/ipp.c:2180 scheduler/ipp.c:2523 scheduler/ipp.c:5243 #: scheduler/ipp.c:6233 scheduler/ipp.c:6456 scheduler/ipp.c:7736 #: scheduler/ipp.c:7951 scheduler/ipp.c:8190 scheduler/ipp.c:8695 +#: scheduler/ipp.c:2635 scheduler/ipp.c:2978 scheduler/ipp.c:5212 +#: scheduler/ipp.c:6202 scheduler/ipp.c:6425 scheduler/ipp.c:7226 +#: scheduler/ipp.c:7441 scheduler/ipp.c:7680 scheduler/ipp.c:8187 #, c-format msgid "Bad job-uri attribute \"%s\"!" msgstr "" @@ -288,6 +331,7 @@ msgid "Job #%d doesn't exist!" msgstr "" #: scheduler/ipp.c:2131 scheduler/ipp.c:2172 scheduler/ipp.c:2214 +#: scheduler/ipp.c:2669 #, c-format msgid "Job #%d is not held for authentication!" msgstr "" @@ -298,19 +342,23 @@ msgid "You are not authorized to authenticate job #%d owned by \"%s\"!" msgstr "" #: scheduler/ipp.c:2221 scheduler/ipp.c:2264 scheduler/ipp.c:2303 +#: scheduler/ipp.c:2758 msgid "The printer-uri attribute is required!" msgstr "" #: scheduler/ipp.c:2238 scheduler/ipp.c:2283 scheduler/ipp.c:2322 +#: scheduler/ipp.c:2777 msgid "Missing requesting-user-name attribute!" msgstr "" #: scheduler/ipp.c:2277 scheduler/ipp.c:2324 scheduler/ipp.c:2363 +#: scheduler/ipp.c:2818 #, c-format msgid "The printer-uri \"%s\" is not valid." msgstr "" #: scheduler/ipp.c:2410 scheduler/ipp.c:2460 scheduler/ipp.c:2499 +#: scheduler/ipp.c:2954 #, c-format msgid "No active jobs on %s!" msgstr "" @@ -321,83 +369,101 @@ msgid "You are not authorized to delete job #%d owned by \"%s\"!" msgstr "" #: scheduler/ipp.c:2476 scheduler/ipp.c:2527 scheduler/ipp.c:2563 +#: scheduler/ipp.c:3018 #, c-format msgid "Job #%d is already %s - can't cancel." msgstr "" #: scheduler/ipp.c:3720 scheduler/ipp.c:3914 scheduler/ipp.c:4006 +#: scheduler/ipp.c:1190 msgid "The printer or class is not shared!" msgstr "" #: scheduler/ipp.c:3746 scheduler/ipp.c:6647 scheduler/ipp.c:3940 #: scheduler/ipp.c:6695 scheduler/ipp.c:4032 scheduler/ipp.c:6954 +#: scheduler/ipp.c:1216 #, c-format msgid "Destination \"%s\" is not accepting jobs." msgstr "" #: scheduler/ipp.c:3759 scheduler/ipp.c:6443 scheduler/ipp.c:3954 #: scheduler/ipp.c:6487 scheduler/ipp.c:4046 scheduler/ipp.c:6739 +#: scheduler/ipp.c:1230 #, c-format msgid "Bad copies value %d." msgstr "" #: scheduler/ipp.c:3775 scheduler/ipp.c:6459 scheduler/ipp.c:3971 #: scheduler/ipp.c:6504 scheduler/ipp.c:4063 scheduler/ipp.c:6756 +#: scheduler/ipp.c:1247 #, c-format msgid "Bad page-ranges values %d-%d." msgstr "" #: scheduler/ipp.c:3795 scheduler/ipp.c:3991 scheduler/ipp.c:4083 +#: scheduler/ipp.c:1267 msgid "Too many active jobs." msgstr "" #: scheduler/ipp.c:3801 scheduler/ipp.c:6668 scheduler/ipp.c:3997 #: scheduler/ipp.c:6716 scheduler/ipp.c:4089 scheduler/ipp.c:6975 +#: scheduler/ipp.c:1273 msgid "Quota limit reached." msgstr "" #: scheduler/ipp.c:3824 scheduler/ipp.c:6691 scheduler/ipp.c:4022 #: scheduler/ipp.c:6741 scheduler/ipp.c:4114 scheduler/ipp.c:7000 +#: scheduler/ipp.c:1306 #, c-format msgid "Unable to add job for destination \"%s\"!" msgstr "" #: scheduler/ipp.c:4469 scheduler/ipp.c:4673 scheduler/ipp.c:4770 +#: scheduler/ipp.c:4739 msgid "No subscription attributes in request!" msgstr "" #: scheduler/ipp.c:4559 scheduler/ipp.c:4763 scheduler/ipp.c:4869 +#: scheduler/ipp.c:4838 msgid "notify-events not specified!" msgstr "" #: scheduler/ipp.c:4577 scheduler/ipp.c:4781 scheduler/ipp.c:4887 +#: scheduler/ipp.c:4856 #, c-format msgid "Job %d not found!" msgstr "" #: scheduler/ipp.c:4827 scheduler/ipp.c:4957 scheduler/ipp.c:5075 +#: scheduler/ipp.c:5044 msgid "No default printer" msgstr "" #: scheduler/ipp.c:4930 scheduler/ipp.c:5060 scheduler/ipp.c:5178 +#: scheduler/ipp.c:5147 msgid "cups-deviced failed to execute." msgstr "" #: scheduler/ipp.c:5393 scheduler/ipp.c:5479 scheduler/ipp.c:5722 +#: scheduler/ipp.c:5691 msgid "cups-driverd failed to execute." msgstr "" #: scheduler/ipp.c:5571 scheduler/ipp.c:5594 scheduler/ipp.c:5837 +#: scheduler/ipp.c:5806 msgid "No destinations added." msgstr "" #: scheduler/ipp.c:5794 scheduler/ipp.c:5736 scheduler/ipp.c:2615 #: scheduler/ipp.c:5530 scheduler/ipp.c:5979 scheduler/ipp.c:7840 +#: scheduler/ipp.c:3070 scheduler/ipp.c:5499 scheduler/ipp.c:5948 +#: scheduler/ipp.c:7330 #, c-format msgid "notify-subscription-id %d no good!" msgstr "" #: scheduler/ipp.c:5878 scheduler/ipp.c:5822 scheduler/ipp.c:6065 +#: scheduler/ipp.c:6034 #, c-format msgid "Job #%s does not exist!" msgstr "" @@ -412,12 +478,17 @@ msgstr "" #: scheduler/ipp.c:2199 scheduler/ipp.c:2541 scheduler/ipp.c:5261 #: scheduler/ipp.c:6087 scheduler/ipp.c:6251 scheduler/ipp.c:6429 #: scheduler/ipp.c:6474 scheduler/ipp.c:7754 scheduler/ipp.c:7969 -#: scheduler/ipp.c:8208 scheduler/ipp.c:8713 +#: scheduler/ipp.c:8208 scheduler/ipp.c:8713 scheduler/ipp.c:2654 +#: scheduler/ipp.c:2996 scheduler/ipp.c:5230 scheduler/ipp.c:6056 +#: scheduler/ipp.c:6220 scheduler/ipp.c:6398 scheduler/ipp.c:6443 +#: scheduler/ipp.c:7244 scheduler/ipp.c:7459 scheduler/ipp.c:7698 +#: scheduler/ipp.c:8205 #, c-format msgid "Job #%d does not exist!" msgstr "" #: scheduler/ipp.c:5969 scheduler/ipp.c:5915 scheduler/ipp.c:6150 +#: scheduler/ipp.c:6119 msgid "No subscriptions found." msgstr "" @@ -428,6 +499,7 @@ msgstr "" #: scheduler/ipp.c:6203 scheduler/ipp.c:8315 scheduler/ipp.c:6250 #: scheduler/ipp.c:8390 scheduler/ipp.c:6505 scheduler/ipp.c:8728 +#: scheduler/ipp.c:6474 scheduler/ipp.c:8220 #, c-format msgid "Job #%d is finished and cannot be altered!" msgstr "" @@ -438,27 +510,32 @@ msgid "You are not authorized to move job #%d owned by \"%s\"!" msgstr "" #: scheduler/ipp.c:6228 scheduler/ipp.c:6098 scheduler/ipp.c:6353 +#: scheduler/ipp.c:6322 msgid "job-printer-uri attribute missing!" msgstr "" #: scheduler/ipp.c:6485 scheduler/ipp.c:7847 scheduler/ipp.c:6531 #: scheduler/ipp.c:7913 scheduler/ipp.c:6783 scheduler/ipp.c:8238 +#: scheduler/ipp.c:6703 scheduler/ipp.c:7728 #, c-format msgid "Unsupported compression \"%s\"!" msgstr "" #: scheduler/ipp.c:6504 scheduler/ipp.c:7866 scheduler/ipp.c:6550 #: scheduler/ipp.c:7932 scheduler/ipp.c:6802 scheduler/ipp.c:8257 +#: scheduler/ipp.c:6722 scheduler/ipp.c:7747 msgid "No file!?!" msgstr "" #: scheduler/ipp.c:6522 scheduler/ipp.c:6568 scheduler/ipp.c:6820 +#: scheduler/ipp.c:6740 #, c-format msgid "Could not scan type \"%s\"!" msgstr "" #: scheduler/ipp.c:6574 scheduler/ipp.c:7936 scheduler/ipp.c:6620 #: scheduler/ipp.c:8001 scheduler/ipp.c:6879 scheduler/ipp.c:8332 +#: scheduler/ipp.c:6799 scheduler/ipp.c:7822 #, c-format msgid "Unsupported format '%s/%s'!" msgstr "" @@ -473,6 +550,7 @@ msgid "Too many jobs - %d jobs, max jobs is %d." msgstr "" #: scheduler/ipp.c:7448 scheduler/ipp.c:7507 scheduler/ipp.c:7768 +#: scheduler/ipp.c:7258 #, c-format msgid "Job #%d is not held!" msgstr "" @@ -483,11 +561,13 @@ msgid "You are not authorized to release job id %d owned by \"%s\"!" msgstr "" #: scheduler/ipp.c:7592 scheduler/ipp.c:7654 scheduler/ipp.c:7983 +#: scheduler/ipp.c:7473 #, c-format msgid "Job #%d is not complete!" msgstr "" #: scheduler/ipp.c:7608 scheduler/ipp.c:7670 scheduler/ipp.c:8001 +#: scheduler/ipp.c:7491 #, c-format msgid "Job #%d cannot be restarted - no files!" msgstr "" @@ -504,6 +584,7 @@ msgstr "" #: scheduler/ipp.c:7883 scheduler/ipp.c:8803 scheduler/ipp.c:7949 #: scheduler/ipp.c:8883 scheduler/ipp.c:8274 scheduler/ipp.c:9225 +#: scheduler/ipp.c:7764 scheduler/ipp.c:8967 #, c-format msgid "Bad document-format \"%s\"!" msgstr "" @@ -514,34 +595,41 @@ msgid "You are not authorized to alter job id %d owned by \"%s\"!" msgstr "" #: scheduler/ipp.c:8371 scheduler/ipp.c:8446 scheduler/ipp.c:8783 +#: scheduler/ipp.c:8275 #, c-format msgid "%s cannot be changed." msgstr "" #: scheduler/ipp.c:8387 scheduler/ipp.c:8462 scheduler/ipp.c:8799 +#: scheduler/ipp.c:8291 msgid "Bad job-priority value!" msgstr "" #: scheduler/ipp.c:8395 scheduler/ipp.c:8470 scheduler/ipp.c:8807 +#: scheduler/ipp.c:8299 msgid "Job is completed and cannot be changed." msgstr "" #: scheduler/ipp.c:8409 scheduler/ipp.c:8484 scheduler/ipp.c:8821 +#: scheduler/ipp.c:8313 msgid "Bad job-state value!" msgstr "" #: scheduler/ipp.c:8423 scheduler/ipp.c:8435 scheduler/ipp.c:8446 #: scheduler/ipp.c:8498 scheduler/ipp.c:8510 scheduler/ipp.c:8521 #: scheduler/ipp.c:8835 scheduler/ipp.c:8850 scheduler/ipp.c:8861 +#: scheduler/ipp.c:8327 scheduler/ipp.c:8342 scheduler/ipp.c:8353 msgid "Job state cannot be changed." msgstr "" #: scheduler/ipp.c:8787 scheduler/ipp.c:8867 scheduler/ipp.c:9209 +#: scheduler/ipp.c:8951 #, c-format msgid "Unsupported compression attribute %s!" msgstr "" #: scheduler/ipp.c:8815 scheduler/ipp.c:8894 scheduler/ipp.c:9236 +#: scheduler/ipp.c:8978 #, c-format msgid "Unsupported format \"%s\"!" msgstr "" @@ -1028,6 +1116,7 @@ msgid "" msgstr "" #: systemv/cupstestppd.c:307 systemv/cupstestppd.c:326 +#: systemv/cupstestppd.c:325 #, c-format msgid " WARN %s has no corresponding options!\n" msgstr "" @@ -1062,17 +1151,37 @@ msgstr "" #: systemv/cupstestppd.c:800 systemv/cupstestppd.c:820 #: systemv/cupstestppd.c:851 systemv/cupstestppd.c:873 #: systemv/cupstestppd.c:921 systemv/cupstestppd.c:950 -#: systemv/cupstestppd.c:971 +#: systemv/cupstestppd.c:971 systemv/cupstestppd.c:343 +#: systemv/cupstestppd.c:361 systemv/cupstestppd.c:376 +#: systemv/cupstestppd.c:412 systemv/cupstestppd.c:440 +#: systemv/cupstestppd.c:460 systemv/cupstestppd.c:482 +#: systemv/cupstestppd.c:502 systemv/cupstestppd.c:522 +#: systemv/cupstestppd.c:542 systemv/cupstestppd.c:560 +#: systemv/cupstestppd.c:578 systemv/cupstestppd.c:599 +#: systemv/cupstestppd.c:618 systemv/cupstestppd.c:638 +#: systemv/cupstestppd.c:658 systemv/cupstestppd.c:678 +#: systemv/cupstestppd.c:698 systemv/cupstestppd.c:716 +#: systemv/cupstestppd.c:733 systemv/cupstestppd.c:755 +#: systemv/cupstestppd.c:773 systemv/cupstestppd.c:790 +#: systemv/cupstestppd.c:808 systemv/cupstestppd.c:824 +#: systemv/cupstestppd.c:844 systemv/cupstestppd.c:875 +#: systemv/cupstestppd.c:897 systemv/cupstestppd.c:945 +#: systemv/cupstestppd.c:974 systemv/cupstestppd.c:995 +#: systemv/cupstestppd.c:1050 systemv/cupstestppd.c:1075 +#: systemv/cupstestppd.c:1095 systemv/cupstestppd.c:1116 +#: systemv/cupstestppd.c:1138 systemv/cupstestppd.c:1172 msgid " FAIL\n" msgstr "" #: systemv/cupstestppd.c:321 systemv/cupstestppd.c:340 +#: systemv/cupstestppd.c:364 msgid "" " **FAIL** REQUIRED DefaultImageableArea\n" " REF: Page 102, section 5.15.\n" msgstr "" #: systemv/cupstestppd.c:336 systemv/cupstestppd.c:355 +#: systemv/cupstestppd.c:379 #, c-format msgid "" " **FAIL** BAD DefaultImageableArea %s!\n" @@ -1080,16 +1189,19 @@ msgid "" msgstr "" #: systemv/cupstestppd.c:346 systemv/cupstestppd.c:365 +#: systemv/cupstestppd.c:389 msgid " PASS DefaultImageableArea\n" msgstr "" #: systemv/cupstestppd.c:357 systemv/cupstestppd.c:376 +#: systemv/cupstestppd.c:400 msgid "" " **FAIL** REQUIRED DefaultPaperDimension\n" " REF: Page 103, section 5.15.\n" msgstr "" #: systemv/cupstestppd.c:372 systemv/cupstestppd.c:391 +#: systemv/cupstestppd.c:415 #, c-format msgid "" " **FAIL** BAD DefaultPaperDimension %s!\n" @@ -1097,10 +1209,12 @@ msgid "" msgstr "" #: systemv/cupstestppd.c:380 systemv/cupstestppd.c:399 +#: systemv/cupstestppd.c:423 msgid " PASS DefaultPaperDimension\n" msgstr "" #: systemv/cupstestppd.c:400 systemv/cupstestppd.c:419 +#: systemv/cupstestppd.c:443 #, c-format msgid "" " **FAIL** BAD Default%s %s\n" @@ -1108,11 +1222,13 @@ msgid "" msgstr "" #: systemv/cupstestppd.c:409 systemv/cupstestppd.c:428 +#: systemv/cupstestppd.c:452 #, c-format msgid " PASS Default%s\n" msgstr "" #: systemv/cupstestppd.c:420 systemv/cupstestppd.c:439 +#: systemv/cupstestppd.c:463 #, c-format msgid "" " **FAIL** REQUIRED Default%s\n" @@ -1120,62 +1236,74 @@ msgid "" msgstr "" #: systemv/cupstestppd.c:432 systemv/cupstestppd.c:451 +#: systemv/cupstestppd.c:475 msgid " PASS FileVersion\n" msgstr "" #: systemv/cupstestppd.c:442 systemv/cupstestppd.c:461 +#: systemv/cupstestppd.c:485 msgid "" " **FAIL** REQUIRED FileVersion\n" " REF: Page 56, section 5.3.\n" msgstr "" #: systemv/cupstestppd.c:452 systemv/cupstestppd.c:471 +#: systemv/cupstestppd.c:495 msgid " PASS FormatVersion\n" msgstr "" #: systemv/cupstestppd.c:462 systemv/cupstestppd.c:481 +#: systemv/cupstestppd.c:505 msgid "" " **FAIL** REQUIRED FormatVersion\n" " REF: Page 56, section 5.3.\n" msgstr "" #: systemv/cupstestppd.c:472 systemv/cupstestppd.c:491 +#: systemv/cupstestppd.c:515 msgid " PASS LanguageEncoding\n" msgstr "" #: systemv/cupstestppd.c:482 systemv/cupstestppd.c:501 +#: systemv/cupstestppd.c:525 msgid "" " **FAIL** REQUIRED LanguageEncoding\n" " REF: Pages 56-57, section 5.3.\n" msgstr "" #: systemv/cupstestppd.c:492 systemv/cupstestppd.c:511 +#: systemv/cupstestppd.c:535 msgid " PASS LanguageVersion\n" msgstr "" #: systemv/cupstestppd.c:502 systemv/cupstestppd.c:521 +#: systemv/cupstestppd.c:545 msgid "" " **FAIL** REQUIRED LanguageVersion\n" " REF: Pages 57-58, section 5.3.\n" msgstr "" #: systemv/cupstestppd.c:520 systemv/cupstestppd.c:539 +#: systemv/cupstestppd.c:563 msgid "" " **FAIL** BAD Manufacturer (should be \"HP\")\n" " REF: Page 211, table D.1.\n" msgstr "" #: systemv/cupstestppd.c:528 systemv/cupstestppd.c:547 +#: systemv/cupstestppd.c:571 msgid " PASS Manufacturer\n" msgstr "" #: systemv/cupstestppd.c:538 systemv/cupstestppd.c:557 +#: systemv/cupstestppd.c:581 msgid "" " **FAIL** REQUIRED Manufacturer\n" " REF: Pages 58-59, section 5.3.\n" msgstr "" #: systemv/cupstestppd.c:559 systemv/cupstestppd.c:578 +#: systemv/cupstestppd.c:602 #, c-format msgid "" " **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" @@ -1183,110 +1311,131 @@ msgid "" msgstr "" #: systemv/cupstestppd.c:568 systemv/cupstestppd.c:587 +#: systemv/cupstestppd.c:611 msgid " PASS ModelName\n" msgstr "" #: systemv/cupstestppd.c:578 systemv/cupstestppd.c:597 +#: systemv/cupstestppd.c:621 msgid "" " **FAIL** REQUIRED ModelName\n" " REF: Pages 59-60, section 5.3.\n" msgstr "" #: systemv/cupstestppd.c:588 systemv/cupstestppd.c:607 +#: systemv/cupstestppd.c:631 msgid " PASS NickName\n" msgstr "" #: systemv/cupstestppd.c:598 systemv/cupstestppd.c:617 +#: systemv/cupstestppd.c:641 msgid "" " **FAIL** REQUIRED NickName\n" " REF: Page 60, section 5.3.\n" msgstr "" #: systemv/cupstestppd.c:608 systemv/cupstestppd.c:627 +#: systemv/cupstestppd.c:651 msgid " PASS PageSize\n" msgstr "" #: systemv/cupstestppd.c:618 systemv/cupstestppd.c:637 +#: systemv/cupstestppd.c:661 msgid "" " **FAIL** REQUIRED PageSize\n" " REF: Pages 99-100, section 5.14.\n" msgstr "" #: systemv/cupstestppd.c:628 systemv/cupstestppd.c:647 +#: systemv/cupstestppd.c:671 msgid " PASS PageRegion\n" msgstr "" #: systemv/cupstestppd.c:638 systemv/cupstestppd.c:657 +#: systemv/cupstestppd.c:681 msgid "" " **FAIL** REQUIRED PageRegion\n" " REF: Page 100, section 5.14.\n" msgstr "" #: systemv/cupstestppd.c:648 systemv/cupstestppd.c:667 +#: systemv/cupstestppd.c:691 msgid " PASS PCFileName\n" msgstr "" #: systemv/cupstestppd.c:658 systemv/cupstestppd.c:677 +#: systemv/cupstestppd.c:701 msgid "" " **FAIL** REQUIRED PCFileName\n" " REF: Pages 61-62, section 5.3.\n" msgstr "" #: systemv/cupstestppd.c:676 systemv/cupstestppd.c:695 +#: systemv/cupstestppd.c:719 msgid "" " **FAIL** BAD Product - not \"(string)\".\n" " REF: Page 62, section 5.3.\n" msgstr "" #: systemv/cupstestppd.c:683 systemv/cupstestppd.c:702 +#: systemv/cupstestppd.c:726 msgid " PASS Product\n" msgstr "" #: systemv/cupstestppd.c:693 systemv/cupstestppd.c:712 +#: systemv/cupstestppd.c:736 msgid "" " **FAIL** REQUIRED Product\n" " REF: Page 62, section 5.3.\n" msgstr "" #: systemv/cupstestppd.c:715 systemv/cupstestppd.c:734 +#: systemv/cupstestppd.c:758 msgid "" " **FAIL** BAD PSVersion - not \"(string) int\".\n" " REF: Pages 62-64, section 5.3.\n" msgstr "" #: systemv/cupstestppd.c:723 systemv/cupstestppd.c:742 +#: systemv/cupstestppd.c:766 msgid " PASS PSVersion\n" msgstr "" #: systemv/cupstestppd.c:733 systemv/cupstestppd.c:752 +#: systemv/cupstestppd.c:776 msgid "" " **FAIL** REQUIRED PSVersion\n" " REF: Pages 62-64, section 5.3.\n" msgstr "" #: systemv/cupstestppd.c:750 systemv/cupstestppd.c:769 +#: systemv/cupstestppd.c:793 msgid "" " **FAIL** BAD ShortNickName - longer than 31 chars.\n" " REF: Pages 64-65, section 5.3.\n" msgstr "" #: systemv/cupstestppd.c:758 systemv/cupstestppd.c:777 +#: systemv/cupstestppd.c:801 msgid " PASS ShortNickName\n" msgstr "" #: systemv/cupstestppd.c:768 systemv/cupstestppd.c:787 +#: systemv/cupstestppd.c:811 msgid "" " **FAIL** REQUIRED ShortNickName\n" " REF: Page 64-65, section 5.3.\n" msgstr "" #: systemv/cupstestppd.c:784 systemv/cupstestppd.c:803 +#: systemv/cupstestppd.c:827 msgid "" " **FAIL** BAD JobPatchFile attribute in file\n" " REF: Page 24, section 3.4.\n" msgstr "" #: systemv/cupstestppd.c:804 systemv/cupstestppd.c:823 +#: systemv/cupstestppd.c:847 msgid "" " **FAIL** REQUIRED PageSize\n" " REF: Page 41, section 5.\n" @@ -1294,6 +1443,7 @@ msgid "" msgstr "" #: systemv/cupstestppd.c:835 systemv/cupstestppd.c:854 +#: systemv/cupstestppd.c:878 #, c-format msgid "" " **FAIL** REQUIRED ImageableArea for PageSize %s\n" @@ -1302,6 +1452,7 @@ msgid "" msgstr "" #: systemv/cupstestppd.c:857 systemv/cupstestppd.c:876 +#: systemv/cupstestppd.c:900 #, c-format msgid "" " **FAIL** REQUIRED PaperDimension for PageSize %s\n" @@ -1310,6 +1461,7 @@ msgid "" msgstr "" #: systemv/cupstestppd.c:905 systemv/cupstestppd.c:924 +#: systemv/cupstestppd.c:948 #, c-format msgid "" " **FAIL** Bad %s choice %s!\n" @@ -1317,6 +1469,7 @@ msgid "" msgstr "" #: systemv/cupstestppd.c:934 systemv/cupstestppd.c:953 +#: systemv/cupstestppd.c:977 #, c-format msgid "" " **FAIL** REQUIRED %s does not define choice None!\n" @@ -1324,6 +1477,7 @@ msgid "" msgstr "" #: systemv/cupstestppd.c:955 systemv/cupstestppd.c:974 +#: systemv/cupstestppd.c:998 #, c-format msgid "" " **FAIL** Bad %s choice %s!\n" @@ -1331,10 +1485,12 @@ msgid "" msgstr "" #: systemv/cupstestppd.c:967 systemv/cupstestppd.c:986 +#: systemv/cupstestppd.c:1186 msgid " PASS\n" msgstr "" #: systemv/cupstestppd.c:976 systemv/cupstestppd.c:997 +#: systemv/cupstestppd.c:1197 #, c-format msgid "" " WARN Duplex option keyword %s should be named Duplex or JCLDuplex!\n" @@ -1342,10 +1498,12 @@ msgid "" msgstr "" #: systemv/cupstestppd.c:986 systemv/cupstestppd.c:1007 +#: systemv/cupstestppd.c:1207 msgid " WARN Default choices conflicting!\n" msgstr "" #: systemv/cupstestppd.c:994 systemv/cupstestppd.c:1015 +#: systemv/cupstestppd.c:1215 #, c-format msgid "" " WARN Obsolete PPD version %.1f!\n" @@ -1353,42 +1511,49 @@ msgid "" msgstr "" #: systemv/cupstestppd.c:1002 systemv/cupstestppd.c:1023 +#: systemv/cupstestppd.c:1223 msgid "" " WARN LanguageEncoding required by PPD 4.3 spec.\n" " REF: Pages 56-57, section 5.3.\n" msgstr "" #: systemv/cupstestppd.c:1010 systemv/cupstestppd.c:1031 +#: systemv/cupstestppd.c:1231 msgid "" " WARN Manufacturer required by PPD 4.3 spec.\n" " REF: Pages 58-59, section 5.3.\n" msgstr "" #: systemv/cupstestppd.c:1023 systemv/cupstestppd.c:1044 +#: systemv/cupstestppd.c:1244 msgid "" " WARN PCFileName longer than 8.3 in violation of PPD spec.\n" " REF: Pages 61-62, section 5.3.\n" msgstr "" #: systemv/cupstestppd.c:1031 systemv/cupstestppd.c:1052 +#: systemv/cupstestppd.c:1252 msgid "" " WARN ShortNickName required by PPD 4.3 spec.\n" " REF: Pages 64-65, section 5.3.\n" msgstr "" #: systemv/cupstestppd.c:1048 systemv/cupstestppd.c:1069 +#: systemv/cupstestppd.c:1269 msgid "" " WARN Protocols contains both PJL and BCP; expected TBCP.\n" " REF: Pages 78-79, section 5.7.\n" msgstr "" #: systemv/cupstestppd.c:1057 systemv/cupstestppd.c:1078 +#: systemv/cupstestppd.c:1278 msgid "" " WARN Protocols contains PJL but JCL attributes are not set.\n" " REF: Pages 78-79, section 5.7.\n" msgstr "" #: systemv/cupstestppd.c:1085 systemv/cupstestppd.c:1106 +#: systemv/cupstestppd.c:1306 #, c-format msgid "" " WARN %s shares a common prefix with %s\n" @@ -1396,15 +1561,18 @@ msgid "" msgstr "" #: systemv/cupstestppd.c:1097 systemv/cupstestppd.c:1118 +#: systemv/cupstestppd.c:1318 #, c-format msgid " %d ERROR%s FOUND\n" msgstr "" #: systemv/cupstestppd.c:1100 systemv/cupstestppd.c:1121 +#: systemv/cupstestppd.c:1321 msgid " NO ERRORS FOUND\n" msgstr "" #: systemv/cupstestppd.c:1360 systemv/cupstestppd.c:1465 +#: systemv/cupstestppd.c:1665 #, c-format msgid "" " WARN \"%s %s\" conflicts with \"%s %s\"\n" @@ -1412,6 +1580,7 @@ msgid "" msgstr "" #: systemv/cupstestppd.c:1376 systemv/cupstestppd.c:1481 +#: systemv/cupstestppd.c:1681 msgid "" "Usage: cupstestppd [-q] [-r] [-v[v]] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" " program | cupstestppd [-q] [-r] [-v[v]] -\n" @@ -1942,12 +2111,12 @@ msgstr "" msgid "lpadmin: add-printer (set location) failed: %s\n" msgstr "" -#: systemv/lpadmin.c:2021 systemv/lpadmin.c:1814 +#: systemv/lpadmin.c:2021 systemv/lpadmin.c:1814 systemv/lpadmin.c:1831 #, c-format msgid "lpadmin: Unable to create temporary file - %s\n" msgstr "" -#: systemv/lpadmin.c:2031 systemv/lpadmin.c:1824 +#: systemv/lpadmin.c:2031 systemv/lpadmin.c:1824 systemv/lpadmin.c:1841 #, c-format msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" msgstr "" @@ -2439,7 +2608,7 @@ msgid "Edit Configuration File" msgstr "" #: cgi-bin/admin.c:2135 cgi-bin/admin.c:2147 cgi-bin/admin.c:2179 -#: cgi-bin/admin.c:2191 +#: cgi-bin/admin.c:2191 cgi-bin/printers.c:219 msgid "Unable to create temporary file:" msgstr "" @@ -2562,15 +2731,16 @@ msgstr "" msgid "Unable to change printer-is-shared attribute:" msgstr "" -#: cgi-bin/classes.c:161 cgi-bin/classes.c:208 +#: cgi-bin/classes.c:161 cgi-bin/classes.c:208 cgi-bin/classes.c:159 +#: cgi-bin/classes.c:206 msgid "Classes" msgstr "" -#: cgi-bin/classes.c:355 cgi-bin/classes.c:356 +#: cgi-bin/classes.c:355 cgi-bin/classes.c:356 cgi-bin/classes.c:354 msgid "Unable to get class list:" msgstr "" -#: cgi-bin/classes.c:454 cgi-bin/classes.c:455 +#: cgi-bin/classes.c:454 cgi-bin/classes.c:455 cgi-bin/classes.c:453 msgid "Unable to get class status:" msgstr "" @@ -2612,114 +2782,115 @@ msgid "Job operation failed:" msgstr "" #: cgi-bin/printers.c:161 cgi-bin/printers.c:208 cgi-bin/printers.c:211 +#: cgi-bin/printers.c:166 cgi-bin/printers.c:335 msgid "Printers" msgstr "" -#: cgi-bin/printers.c:362 cgi-bin/printers.c:366 +#: cgi-bin/printers.c:362 cgi-bin/printers.c:366 cgi-bin/printers.c:518 msgid "Unable to get printer list:" msgstr "" -#: cgi-bin/printers.c:461 cgi-bin/printers.c:468 +#: cgi-bin/printers.c:461 cgi-bin/printers.c:468 cgi-bin/printers.c:628 msgid "Unable to get printer status:" msgstr "" -#: cups/ppd.c:319 +#: cups/ppd.c:319 cups/ppd.c:302 msgid "OK" msgstr "" -#: cups/ppd.c:320 +#: cups/ppd.c:320 cups/ppd.c:303 msgid "Unable to open PPD file" msgstr "" -#: cups/ppd.c:321 +#: cups/ppd.c:321 cups/ppd.c:304 msgid "NULL PPD file pointer" msgstr "" -#: cups/ppd.c:322 +#: cups/ppd.c:322 cups/ppd.c:305 msgid "Memory allocation error" msgstr "" -#: cups/ppd.c:323 +#: cups/ppd.c:323 cups/ppd.c:306 msgid "Missing PPD-Adobe-4.x header" msgstr "" -#: cups/ppd.c:324 +#: cups/ppd.c:324 cups/ppd.c:307 msgid "Missing value string" msgstr "" -#: cups/ppd.c:325 +#: cups/ppd.c:325 cups/ppd.c:308 msgid "Internal error" msgstr "" -#: cups/ppd.c:326 +#: cups/ppd.c:326 cups/ppd.c:309 msgid "Bad OpenGroup" msgstr "" -#: cups/ppd.c:327 +#: cups/ppd.c:327 cups/ppd.c:310 msgid "OpenGroup without a CloseGroup first" msgstr "" -#: cups/ppd.c:328 +#: cups/ppd.c:328 cups/ppd.c:311 msgid "Bad OpenUI/JCLOpenUI" msgstr "" -#: cups/ppd.c:329 +#: cups/ppd.c:329 cups/ppd.c:312 msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" msgstr "" -#: cups/ppd.c:330 +#: cups/ppd.c:330 cups/ppd.c:313 msgid "Bad OrderDependency" msgstr "" -#: cups/ppd.c:331 +#: cups/ppd.c:331 cups/ppd.c:314 msgid "Bad UIConstraints" msgstr "" -#: cups/ppd.c:332 +#: cups/ppd.c:332 cups/ppd.c:315 msgid "Missing asterisk in column 1" msgstr "" -#: cups/ppd.c:333 +#: cups/ppd.c:333 cups/ppd.c:316 msgid "Line longer than the maximum allowed (255 characters)" msgstr "" -#: cups/ppd.c:334 +#: cups/ppd.c:334 cups/ppd.c:317 msgid "Illegal control character" msgstr "" -#: cups/ppd.c:335 +#: cups/ppd.c:335 cups/ppd.c:318 msgid "Illegal main keyword string" msgstr "" -#: cups/ppd.c:336 +#: cups/ppd.c:336 cups/ppd.c:319 msgid "Illegal option keyword string" msgstr "" -#: cups/ppd.c:337 +#: cups/ppd.c:337 cups/ppd.c:320 msgid "Illegal translation string" msgstr "" -#: cups/ppd.c:338 +#: cups/ppd.c:338 cups/ppd.c:321 msgid "Illegal whitespace character" msgstr "" -#: cups/ppd.c:339 +#: cups/ppd.c:339 cups/ppd.c:322 msgid "Bad custom parameter" msgstr "" -#: cups/ppd.c:344 +#: cups/ppd.c:344 cups/ppd.c:327 msgid "Unknown" msgstr "" -#: cups/ppd.c:1033 +#: cups/ppd.c:1033 cups/ppd.c:1020 msgid "Custom" msgstr "" -#: cups/ppd.c:1259 +#: cups/ppd.c:1259 cups/ppd.c:1236 msgid "JCL" msgstr "" -#: scheduler/ipp.c:2184 scheduler/ipp.c:2226 +#: scheduler/ipp.c:2184 scheduler/ipp.c:2226 scheduler/ipp.c:2681 msgid "No authentication information provided!" msgstr "" @@ -3133,11 +3304,11 @@ msgstr "" msgid "idle" msgstr "" -#: scheduler/ipp.c:5513 +#: scheduler/ipp.c:5513 scheduler/ipp.c:5482 msgid "Missing notify-subscription-ids attribute!" msgstr "" -#: scheduler/ipp.c:7851 +#: scheduler/ipp.c:7851 scheduler/ipp.c:7341 msgid "Job subscriptions cannot be renewed!" msgstr "" @@ -3159,7 +3330,7 @@ msgstr "" msgid "cupsd: Unknown argument \"%s\" - aborting!\n" msgstr "" -#: scheduler/main.c:2315 +#: scheduler/main.c:2315 scheduler/main.c:2329 msgid "" "Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" "\n" @@ -3170,19 +3341,67 @@ msgid "" "-l Run cupsd from launchd(8)\n" msgstr "" -#: systemv/cupstestppd.c:1343 +#: systemv/cupstestppd.c:1343 systemv/cupstestppd.c:1543 #, c-format msgid " WARN Line %d only contains whitespace!\n" msgstr "" -#: systemv/cupstestppd.c:1361 +#: systemv/cupstestppd.c:1361 systemv/cupstestppd.c:1561 msgid " WARN File contains a mix of CR, LF, and CR LF line endings!\n" msgstr "" -#: systemv/cupstestppd.c:1366 +#: systemv/cupstestppd.c:1366 systemv/cupstestppd.c:1566 msgid " WARN Non-Windows PPD files should use lines ending with only LF, not CR LF!\n" msgstr "" +#: cgi-bin/printers.c:218 cgi-bin/printers.c:289 +msgid "Printer Maintenance" +msgstr "" + +#: cgi-bin/printers.c:292 +msgid "Unable to send maintenance job:" +msgstr "" + +#: systemv/cupsaddsmb.c:566 +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "" + +#: systemv/cupstestppd.c:346 +#, c-format +msgid " **FAIL** %s %s does not exist!\n" +msgstr "" + +#: systemv/cupstestppd.c:1053 +#, c-format +msgid " **FAIL** Bad language \"%s\"!\n" +msgstr "" + +#: systemv/cupstestppd.c:1078 +#, c-format +msgid " **FAIL** Missing \"%s\" translation string for option %s!\n" +msgstr "" + +#: systemv/cupstestppd.c:1098 +#, c-format +msgid " **FAIL** Default translation string for option %s contains 8-bit characters!\n" +msgstr "" + +#: systemv/cupstestppd.c:1119 +#, c-format +msgid " **FAIL** Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr "" + +#: systemv/cupstestppd.c:1141 +#, c-format +msgid " **FAIL** Default translation string for option %s choice %s contains 8-bit characters!\n" +msgstr "" + +#: systemv/cupstestppd.c:1175 +#, c-format +msgid " **FAIL** Bad cupsFilter value \"%s\"!\n" +msgstr "" + # # End of "$Id$". diff --git a/locale/cups_fr.po b/locale/cups_fr.po deleted file mode 100644 index c5a5e6c86..000000000 --- a/locale/cups_fr.po +++ /dev/null @@ -1,3245 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: CUPS 1.2\n" -"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" -"POT-Creation-Date: 2006-02-15 19:50-0500\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: cgi-bin/admin.c:1276 cgi-bin/admin.c:1154 cgi-bin/admin.c:1195 -msgid "Options Installed" -msgstr "Options Installées" - -#: cgi-bin/classes.c:103 -msgid "Class" -msgstr "Classe" - -#: cgi-bin/printers.c:104 -msgid "Printer" -msgstr "Imprimeur" - -#: cups/ppd.c:654 cups/ppd.c:1045 cups/ppd.c:660 cups/ppd.c:1167 -msgid "Extra" -msgstr "Supplémentaire" - -#: cups/ppd.c:656 cups/ppd.c:881 cups/ppd.c:1047 cups/ppd.c:662 cups/ppd.c:996 -#: cups/ppd.c:1169 -msgid "General" -msgstr "Généralités" - -#: cups/ppd.c:704 cups/ppd.c:1105 cups/ppd.c:710 cups/ppd.c:1224 -msgid "Media Size" -msgstr "Taille De Médias" - -#: cups/ppd.c:706 cups/ppd.c:1107 cups/ppd.c:712 cups/ppd.c:1226 -msgid "Media Type" -msgstr "Type De Supports" - -#: cups/ppd.c:708 cups/ppd.c:1109 cups/ppd.c:714 cups/ppd.c:1228 -msgid "Media Source" -msgstr "Source De Médias" - -#: cups/ppd.c:710 cups/ppd.c:1111 cups/ppd.c:716 cups/ppd.c:1230 -msgid "Output Mode" -msgstr "Mode De Rendement" - -#: cups/ppd.c:712 cups/ppd.c:1113 cups/ppd.c:718 cups/ppd.c:1232 -msgid "Resolution" -msgstr "Résolution" - -#: cups/ppd.c:907 -msgid "Variable" -msgstr "Variable" - -#: cups/ppd.c:1535 cups/ppd.c:1650 -msgid "Yes" -msgstr "Oui" - -#: cups/ppd.c:1537 cups/ppd.c:1652 -msgid "No" -msgstr "Non" - -#: cups/ppd.c:1824 -msgid "Auto" -msgstr "Automobile" - -#: scheduler/client.c:2247 scheduler/client.c:2251 scheduler/client.c:2274 -msgid "" -"Enter your username and password or the root username and password to access " -"this page." -msgstr "" -"Entrez votre username et mot de passe ou le username de racine et le mot de " -"passe pour accéder à cette page." - -#: scheduler/client.c:2252 scheduler/client.c:2256 scheduler/client.c:2279 -msgid "You must use a https: URL to access this page." -msgstr "Vous devez employer des https: URL pour accéder à cette page." - -#: scheduler/ipp.c:236 scheduler/ipp.c:244 scheduler/ipp.c:246 -#, c-format -msgid "Bad request version number %d.%d!" -msgstr "Mauvais nombre de version de demande %d.%d!" - -#: scheduler/ipp.c:246 scheduler/ipp.c:254 scheduler/ipp.c:256 -msgid "No attributes in request!" -msgstr "Aucuns attributs dans la demande!" - -#: scheduler/ipp.c:269 scheduler/ipp.c:277 scheduler/ipp.c:279 -#, c-format -msgid "Attribute groups are out of order (%x < %x)!" -msgstr "Les groupes d'attribut sont en panne (%x < %x)!" - -#: scheduler/ipp.c:379 scheduler/ipp.c:389 scheduler/ipp.c:391 -msgid "Missing required attributes!" -msgstr "Attributs requis manquants!" - -#: scheduler/ipp.c:575 scheduler/ipp.c:585 scheduler/ipp.c:591 -#, c-format -msgid "%s not supported!" -msgstr "%s non soutenu!" - -#: scheduler/ipp.c:684 scheduler/ipp.c:1055 scheduler/ipp.c:2271 -#: scheduler/ipp.c:2383 scheduler/ipp.c:3707 scheduler/ipp.c:4417 -#: scheduler/ipp.c:4649 scheduler/ipp.c:5002 scheduler/ipp.c:5445 -#: scheduler/ipp.c:5890 scheduler/ipp.c:6245 scheduler/ipp.c:6609 -#: scheduler/ipp.c:7308 scheduler/ipp.c:8179 scheduler/ipp.c:8585 -#: scheduler/ipp.c:8663 scheduler/ipp.c:8836 scheduler/ipp.c:696 -#: scheduler/ipp.c:1079 scheduler/ipp.c:2318 scheduler/ipp.c:2433 -#: scheduler/ipp.c:3901 scheduler/ipp.c:4621 scheduler/ipp.c:4855 -#: scheduler/ipp.c:5237 scheduler/ipp.c:5526 scheduler/ipp.c:5834 -#: scheduler/ipp.c:6113 scheduler/ipp.c:6155 scheduler/ipp.c:6657 -#: scheduler/ipp.c:7365 scheduler/ipp.c:8251 scheduler/ipp.c:8662 -#: scheduler/ipp.c:8742 scheduler/ipp.c:8917 scheduler/ipp.c:702 -#: scheduler/ipp.c:1093 scheduler/ipp.c:2357 scheduler/ipp.c:2472 -#: scheduler/ipp.c:3993 scheduler/ipp.c:4730 scheduler/ipp.c:4973 -#: scheduler/ipp.c:5357 scheduler/ipp.c:5769 scheduler/ipp.c:6077 -#: scheduler/ipp.c:6368 scheduler/ipp.c:6410 scheduler/ipp.c:6916 -#: scheduler/ipp.c:7626 scheduler/ipp.c:8589 scheduler/ipp.c:9003 -#: scheduler/ipp.c:9084 scheduler/ipp.c:9259 -msgid "The printer or class was not found." -msgstr "L'imprimeur ou la classe n'a pas été trouvé." - -#: scheduler/ipp.c:762 scheduler/ipp.c:777 scheduler/ipp.c:784 -msgid "" -"The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." -msgstr "" -"L'printer-uri doit être de la forme \"ipp://HOSTNAME/classes/CLASSNAME\"." - -#: scheduler/ipp.c:778 scheduler/ipp.c:1454 scheduler/ipp.c:793 -#: scheduler/ipp.c:1482 scheduler/ipp.c:800 scheduler/ipp.c:1515 -#, c-format -msgid "The printer-uri \"%s\" contains invalid characters." -msgstr "L'printer-uri \"%s\" contient les caractères inadmissibles." - -#: scheduler/ipp.c:811 scheduler/ipp.c:826 scheduler/ipp.c:833 -#, c-format -msgid "A printer named \"%s\" already exists!" -msgstr "Un imprimeur appelé \"%s\" existe déjà!" - -#: scheduler/ipp.c:904 scheduler/ipp.c:924 scheduler/ipp.c:933 -#, c-format -msgid "Attempt to set %s printer-state to bad value %d!" -msgstr "Essayez de placer l'imprimeur-état de %s à la mauvaise valeur %d!" - -#: scheduler/ipp.c:1000 scheduler/ipp.c:1022 scheduler/ipp.c:1034 -#, c-format -msgid "add_class: Unknown printer-op-policy \"%s\"." -msgstr "add_class: printer-op-policy inconnue \"%s\"." - -#: scheduler/ipp.c:1013 scheduler/ipp.c:1035 scheduler/ipp.c:1047 -#, c-format -msgid "add_class: Unknown printer-error-policy \"%s\"." -msgstr "add_class: printer-error-policy inconnue \"%s\"." - -#: scheduler/ipp.c:1144 scheduler/ipp.c:1168 scheduler/ipp.c:1200 -msgid "Unable to allocate memory for file types!" -msgstr "Incapable d'assigner la mémoire pour des types de dossier!" - -#: scheduler/ipp.c:1290 scheduler/ipp.c:4501 scheduler/ipp.c:1316 -#: scheduler/ipp.c:4705 scheduler/ipp.c:1348 scheduler/ipp.c:4804 -#, c-format -msgid "Character set \"%s\" not supported!" -msgstr "Jeu de caractères \"%s\" non soutenu!" - -#: scheduler/ipp.c:1299 scheduler/ipp.c:4510 scheduler/ipp.c:1325 -#: scheduler/ipp.c:4714 scheduler/ipp.c:1357 scheduler/ipp.c:4813 -#, c-format -msgid "Language \"%s\" not supported!" -msgstr "Langue \"%s\" non soutenue!" - -#: scheduler/ipp.c:1309 scheduler/ipp.c:4520 scheduler/ipp.c:1335 -#: scheduler/ipp.c:4724 scheduler/ipp.c:1367 scheduler/ipp.c:4823 -#, c-format -msgid "The notify-user-data value is too large (%d > 63 octets)!" -msgstr "La valeur de notify-user-data est trop grande (%d > 63 octets)!" - -#: scheduler/ipp.c:1326 scheduler/ipp.c:1352 scheduler/ipp.c:1384 -msgid "" -"The notify-lease-duration attribute cannot be used with job subscriptions." -msgstr "" -"L'attribut de notify-lease-duration ne peut pas être employé avec des " -"abonnements du travail." - -#: scheduler/ipp.c:1438 scheduler/ipp.c:1466 scheduler/ipp.c:1499 -msgid "" -"The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." -msgstr "" -"L'printer-uri doit être de la forme \"ipp://HOSTNAME/printers/PRINTERNAME\"." - -#: scheduler/ipp.c:1487 scheduler/ipp.c:1515 scheduler/ipp.c:1548 -#, c-format -msgid "A class named \"%s\" already exists!" -msgstr "Une classe appelée \"%s\" existe déjà!" - -#: scheduler/ipp.c:1575 scheduler/ipp.c:1607 scheduler/ipp.c:1644 -#, c-format -msgid "" -"File device URIs have been disabled! To enable, see the FileDevice directive " -"in \"%s/cupsd.conf\"." -msgstr "" -"Le dispositif URIs de dossier ont été neutralisés! Pour permettre, voyez la " -"directive de FileDevice dans \"%s/cupsd.conf\"." - -#: scheduler/ipp.c:1595 scheduler/ipp.c:1627 scheduler/ipp.c:1664 -#, c-format -msgid "Bad device-uri \"%s\"!" -msgstr "Mauvais device-uri \"%s\"!" - -#: scheduler/ipp.c:1626 scheduler/ipp.c:1659 scheduler/ipp.c:1698 -#, c-format -msgid "Bad port-monitor \"%s\"!" -msgstr "Mauvais port-monitor \"%s\"!" - -#: scheduler/ipp.c:1669 scheduler/ipp.c:1705 scheduler/ipp.c:1744 -#, c-format -msgid "Bad printer-state value %d!" -msgstr "Mauvaise valeur %d de printer-state!" - -#: scheduler/ipp.c:1762 scheduler/ipp.c:1800 scheduler/ipp.c:1842 -#, c-format -msgid "Unknown printer-op-policy \"%s\"." -msgstr "printer-op-policy inconnue \"%s\"." - -#: scheduler/ipp.c:1775 scheduler/ipp.c:1813 scheduler/ipp.c:1855 -#, c-format -msgid "Unknown printer-error-policy \"%s\"." -msgstr "printer-error-policy inconnue \"%s\"." - -#: scheduler/ipp.c:1837 scheduler/ipp.c:1875 scheduler/ipp.c:1919 -#, c-format -msgid "Unable to copy interface script - %s!" -msgstr "Incapable de copier le manuscrit d'interface - %s!" - -#: scheduler/ipp.c:1862 scheduler/ipp.c:1900 scheduler/ipp.c:1944 -#, c-format -msgid "Unable to copy PPD file - %s!" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: scheduler/ipp.c:1915 scheduler/ipp.c:1954 scheduler/ipp.c:2000 -msgid "Unable to copy PPD file!" -msgstr "Incapable de copier le dossier de PPD!" - -#: scheduler/ipp.c:2076 scheduler/ipp.c:2364 scheduler/ipp.c:5188 -#: scheduler/ipp.c:6008 scheduler/ipp.c:6147 scheduler/ipp.c:7394 -#: scheduler/ipp.c:7538 scheduler/ipp.c:7776 scheduler/ipp.c:8261 -#: scheduler/ipp.c:2116 scheduler/ipp.c:2412 scheduler/ipp.c:5102 -#: scheduler/ipp.c:5955 scheduler/ipp.c:7452 scheduler/ipp.c:7599 -#: scheduler/ipp.c:7839 scheduler/ipp.c:8334 scheduler/ipp.c:2158 -#: scheduler/ipp.c:2451 scheduler/ipp.c:5220 scheduler/ipp.c:6210 -#: scheduler/ipp.c:7713 scheduler/ipp.c:7928 scheduler/ipp.c:8167 -#: scheduler/ipp.c:8672 -msgid "Got a printer-uri attribute but no job-id!" -msgstr "N'a obtenu un attribut de printer-uri mais aucune job-id!" - -#: scheduler/ipp.c:2097 scheduler/ipp.c:2433 scheduler/ipp.c:5210 -#: scheduler/ipp.c:6029 scheduler/ipp.c:6169 scheduler/ipp.c:7416 -#: scheduler/ipp.c:7560 scheduler/ipp.c:7797 scheduler/ipp.c:8282 -#: scheduler/ipp.c:2138 scheduler/ipp.c:2484 scheduler/ipp.c:5125 -#: scheduler/ipp.c:5978 scheduler/ipp.c:6201 scheduler/ipp.c:7475 -#: scheduler/ipp.c:7622 scheduler/ipp.c:7862 scheduler/ipp.c:8357 -#: scheduler/ipp.c:2180 scheduler/ipp.c:2523 scheduler/ipp.c:5243 -#: scheduler/ipp.c:6233 scheduler/ipp.c:6456 scheduler/ipp.c:7736 -#: scheduler/ipp.c:7951 scheduler/ipp.c:8190 scheduler/ipp.c:8695 -#, c-format -msgid "Bad job-uri attribute \"%s\"!" -msgstr "Mauvais attribut \"%s\" de job-uri!" - -#: scheduler/ipp.c:2116 scheduler/ipp.c:2451 scheduler/ipp.c:5228 -#: scheduler/ipp.c:6047 scheduler/ipp.c:6188 scheduler/ipp.c:7434 -#: scheduler/ipp.c:7578 scheduler/ipp.c:7815 scheduler/ipp.c:8300 -#, c-format -msgid "Job #%d doesn't exist!" -msgstr "Le travail # %d n'existe pas!" - -#: scheduler/ipp.c:2131 scheduler/ipp.c:2172 scheduler/ipp.c:2214 -#, c-format -msgid "Job #%d is not held for authentication!" -msgstr "Le travail # %d n'est pas tenu pour l'authentification!" - -#: scheduler/ipp.c:2153 scheduler/ipp.c:2195 -#, c-format -msgid "You are not authorized to authenticate job #%d owned by \"%s\"!" -msgstr "" -"Vous n'êtes pas autorisés à authentifier le travail # %d possédés par \"%s\"!" - -#: scheduler/ipp.c:2221 scheduler/ipp.c:2264 scheduler/ipp.c:2303 -msgid "The printer-uri attribute is required!" -msgstr "L'attribut de printer-uri est exigé!" - -#: scheduler/ipp.c:2238 scheduler/ipp.c:2283 scheduler/ipp.c:2322 -msgid "Missing requesting-user-name attribute!" -msgstr "Attribut absent de requesting-user-name!" - -#: scheduler/ipp.c:2277 scheduler/ipp.c:2324 scheduler/ipp.c:2363 -#, c-format -msgid "The printer-uri \"%s\" is not valid." -msgstr "L'printer-uri \"%s\" est inadmissible." - -#: scheduler/ipp.c:2410 scheduler/ipp.c:2460 scheduler/ipp.c:2499 -#, c-format -msgid "No active jobs on %s!" -msgstr "Aucuns JOBS actifs sur %s!" - -#: scheduler/ipp.c:2462 scheduler/ipp.c:2513 -#, c-format -msgid "You are not authorized to delete job #%d owned by \"%s\"!" -msgstr "" -"Vous n'êtes pas autorisés à supprimer le travail # %d possédés par \"%s\"!" - -#: scheduler/ipp.c:2476 scheduler/ipp.c:2527 scheduler/ipp.c:2563 -#, c-format -msgid "Job #%d is already %s - can't cancel." -msgstr "Le travail # %d est déjà %s - ne peut pas décommander." - -#: scheduler/ipp.c:3720 scheduler/ipp.c:3914 scheduler/ipp.c:4006 -msgid "The printer or class is not shared!" -msgstr "L'imprimeur ou la classe n'est pas partagé!" - -#: scheduler/ipp.c:3746 scheduler/ipp.c:6647 scheduler/ipp.c:3940 -#: scheduler/ipp.c:6695 scheduler/ipp.c:4032 scheduler/ipp.c:6954 -#, c-format -msgid "Destination \"%s\" is not accepting jobs." -msgstr "La destination \"%s\" n'accepte pas les travaux." - -#: scheduler/ipp.c:3759 scheduler/ipp.c:6443 scheduler/ipp.c:3954 -#: scheduler/ipp.c:6487 scheduler/ipp.c:4046 scheduler/ipp.c:6739 -#, c-format -msgid "Bad copies value %d." -msgstr "Mauvaise valeur %d de copies." - -#: scheduler/ipp.c:3775 scheduler/ipp.c:6459 scheduler/ipp.c:3971 -#: scheduler/ipp.c:6504 scheduler/ipp.c:4063 scheduler/ipp.c:6756 -#, c-format -msgid "Bad page-ranges values %d-%d." -msgstr "Mauvaises valeurs %d-%d de page-ranges." - -#: scheduler/ipp.c:3795 scheduler/ipp.c:3991 scheduler/ipp.c:4083 -msgid "Too many active jobs." -msgstr "Trop de JOBS actifs." - -#: scheduler/ipp.c:3801 scheduler/ipp.c:6668 scheduler/ipp.c:3997 -#: scheduler/ipp.c:6716 scheduler/ipp.c:4089 scheduler/ipp.c:6975 -msgid "Quota limit reached." -msgstr "La limite de quote-part a atteint." - -#: scheduler/ipp.c:3824 scheduler/ipp.c:6691 scheduler/ipp.c:4022 -#: scheduler/ipp.c:6741 scheduler/ipp.c:4114 scheduler/ipp.c:7000 -#, c-format -msgid "Unable to add job for destination \"%s\"!" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: scheduler/ipp.c:4469 scheduler/ipp.c:4673 scheduler/ipp.c:4770 -msgid "No subscription attributes in request!" -msgstr "Aucuns attributs d'abonnement dans la demande!" - -#: scheduler/ipp.c:4559 scheduler/ipp.c:4763 scheduler/ipp.c:4869 -msgid "notify-events not specified!" -msgstr "notify-events non indiqués!" - -#: scheduler/ipp.c:4577 scheduler/ipp.c:4781 scheduler/ipp.c:4887 -#, c-format -msgid "Job %d not found!" -msgstr "Le travail %d non trouvé!" - -#: scheduler/ipp.c:4827 scheduler/ipp.c:4957 scheduler/ipp.c:5075 -msgid "No default printer" -msgstr "Aucun imprimeur de défaut" - -#: scheduler/ipp.c:4930 scheduler/ipp.c:5060 scheduler/ipp.c:5178 -msgid "cups-deviced failed to execute." -msgstr "les cups-deviced ne se sont pas exécutées." - -#: scheduler/ipp.c:5393 scheduler/ipp.c:5479 scheduler/ipp.c:5722 -msgid "cups-driverd failed to execute." -msgstr "les cups-driverd ne se sont pas exécutées." - -#: scheduler/ipp.c:5571 scheduler/ipp.c:5594 scheduler/ipp.c:5837 -msgid "No destinations added." -msgstr "Aucunes destinations supplémentaires." - -#: scheduler/ipp.c:5794 scheduler/ipp.c:5736 scheduler/ipp.c:2615 -#: scheduler/ipp.c:5530 scheduler/ipp.c:5979 scheduler/ipp.c:7840 -#, c-format -msgid "notify-subscription-id %d no good!" -msgstr "notify-subscription-id %d aucun bon!" - -#: scheduler/ipp.c:5878 scheduler/ipp.c:5822 scheduler/ipp.c:6065 -#, c-format -msgid "Job #%s does not exist!" -msgstr "Le travail # %s n'existe pas!" - -#: scheduler/ipp.c:5900 scheduler/ipp.c:2116 scheduler/ipp.c:2451 -#: scheduler/ipp.c:5228 scheduler/ipp.c:6047 scheduler/ipp.c:6188 -#: scheduler/ipp.c:7434 scheduler/ipp.c:7578 scheduler/ipp.c:7815 -#: scheduler/ipp.c:8300 scheduler/ipp.c:2157 scheduler/ipp.c:2502 -#: scheduler/ipp.c:5143 scheduler/ipp.c:5844 scheduler/ipp.c:5996 -#: scheduler/ipp.c:6174 scheduler/ipp.c:6219 scheduler/ipp.c:7493 -#: scheduler/ipp.c:7640 scheduler/ipp.c:7880 scheduler/ipp.c:8375 -#: scheduler/ipp.c:2199 scheduler/ipp.c:2541 scheduler/ipp.c:5261 -#: scheduler/ipp.c:6087 scheduler/ipp.c:6251 scheduler/ipp.c:6429 -#: scheduler/ipp.c:6474 scheduler/ipp.c:7754 scheduler/ipp.c:7969 -#: scheduler/ipp.c:8208 scheduler/ipp.c:8713 -#, c-format -msgid "Job #%d does not exist!" -msgstr "Le travail # %d n'existe pas!" - -#: scheduler/ipp.c:5969 scheduler/ipp.c:5915 scheduler/ipp.c:6150 -msgid "No subscriptions found." -msgstr "Abonnement n'a pas trouvé." - -#: scheduler/ipp.c:6058 scheduler/ipp.c:6007 -#, c-format -msgid "Not authorized to hold job #%d owned by \"%s\"!" -msgstr "Non autorisé à juger le travail # %d possédés par \"%s\"!" - -#: scheduler/ipp.c:6203 scheduler/ipp.c:8315 scheduler/ipp.c:6250 -#: scheduler/ipp.c:8390 scheduler/ipp.c:6505 scheduler/ipp.c:8728 -#, c-format -msgid "Job #%d is finished and cannot be altered!" -msgstr "Le travail # %d est fini et ne peut pas être changé!" - -#: scheduler/ipp.c:6215 scheduler/ipp.c:6262 -#, c-format -msgid "You are not authorized to move job #%d owned by \"%s\"!" -msgstr "" -"Vous n'êtes pas autorisés à déplacer le travail # %d possédés par \"%s\"!" - -#: scheduler/ipp.c:6228 scheduler/ipp.c:6098 scheduler/ipp.c:6353 -msgid "job-printer-uri attribute missing!" -msgstr "disparus d'attribut de job-printer-uri!" - -#: scheduler/ipp.c:6485 scheduler/ipp.c:7847 scheduler/ipp.c:6531 -#: scheduler/ipp.c:7913 scheduler/ipp.c:6783 scheduler/ipp.c:8238 -#, c-format -msgid "Unsupported compression \"%s\"!" -msgstr "Compression non soutenue \"%s\"!" - -#: scheduler/ipp.c:6504 scheduler/ipp.c:7866 scheduler/ipp.c:6550 -#: scheduler/ipp.c:7932 scheduler/ipp.c:6802 scheduler/ipp.c:8257 -msgid "No file!?!" -msgstr "Aucun dossier!?!" - -#: scheduler/ipp.c:6522 scheduler/ipp.c:6568 scheduler/ipp.c:6820 -#, c-format -msgid "Could not scan type \"%s\"!" -msgstr "N'a pas pu balayer le type \"%s\"!" - -#: scheduler/ipp.c:6574 scheduler/ipp.c:7936 scheduler/ipp.c:6620 -#: scheduler/ipp.c:8001 scheduler/ipp.c:6879 scheduler/ipp.c:8332 -#, c-format -msgid "Unsupported format '%s/%s'!" -msgstr "Format non soutenu '%s/%s '!" - -#: scheduler/ipp.c:6621 scheduler/ipp.c:6669 scheduler/ipp.c:6928 -msgid "Printer not shared!" -msgstr "Imprimeur non partagé!" - -#: scheduler/ipp.c:6661 scheduler/ipp.c:6709 scheduler/ipp.c:6968 -#, c-format -msgid "Too many jobs - %d jobs, max jobs is %d." -msgstr "Trop de travaux - les travaux de %d, les travaux maximum est %d." - -#: scheduler/ipp.c:7448 scheduler/ipp.c:7507 scheduler/ipp.c:7768 -#, c-format -msgid "Job #%d is not held!" -msgstr "Le travail # %d n'est pas tenu!" - -#: scheduler/ipp.c:7459 scheduler/ipp.c:7518 -#, c-format -msgid "You are not authorized to release job id %d owned by \"%s\"!" -msgstr "" -"Vous n'êtes pas autorisés à libérer l'identification de travail %d possédée " -"par \"%s\"!" - -#: scheduler/ipp.c:7592 scheduler/ipp.c:7654 scheduler/ipp.c:7983 -#, c-format -msgid "Job #%d is not complete!" -msgstr "Le travail # %d n'est pas complet!" - -#: scheduler/ipp.c:7608 scheduler/ipp.c:7670 scheduler/ipp.c:8001 -#, c-format -msgid "Job #%d cannot be restarted - no files!" -msgstr "Le travail # %d ne peuvent pas être remis en marche - aucuns dossiers!" - -#: scheduler/ipp.c:7619 scheduler/ipp.c:7681 -#, c-format -msgid "You are not authorized to restart job id %d owned by \"%s\"!" -msgstr "" -"Vous n'êtes pas autorisés à remettre en marche l'identification de travail %" -"d possédée par \"%s\"!" - -#: scheduler/ipp.c:7826 scheduler/ipp.c:7891 -#, c-format -msgid "You are not authorized to send document for job #%d owned by \"%s\"!" -msgstr "" -"Vous n'êtes pas autorisés à envoyer le document pour le travail # %d " -"possédés par \"%s\"!" - -#: scheduler/ipp.c:7883 scheduler/ipp.c:8803 scheduler/ipp.c:7949 -#: scheduler/ipp.c:8883 scheduler/ipp.c:8274 scheduler/ipp.c:9225 -#, c-format -msgid "Bad document-format \"%s\"!" -msgstr "Mauvais document-format \"%s\"!" - -#: scheduler/ipp.c:8326 scheduler/ipp.c:8401 -#, c-format -msgid "You are not authorized to alter job id %d owned by \"%s\"!" -msgstr "" -"Vous n'êtes pas autorisés à changer l'identification de travail %d possédée " -"par \"%s\"!" - -#: scheduler/ipp.c:8371 scheduler/ipp.c:8446 scheduler/ipp.c:8783 -#, c-format -msgid "%s cannot be changed." -msgstr "%s ne peut pas être changé." - -#: scheduler/ipp.c:8387 scheduler/ipp.c:8462 scheduler/ipp.c:8799 -msgid "Bad job-priority value!" -msgstr "Mauvaise valeur de job-priority!" - -#: scheduler/ipp.c:8395 scheduler/ipp.c:8470 scheduler/ipp.c:8807 -msgid "Job is completed and cannot be changed." -msgstr "Le travail est accompli et ne peut pas être changé." - -#: scheduler/ipp.c:8409 scheduler/ipp.c:8484 scheduler/ipp.c:8821 -msgid "Bad job-state value!" -msgstr "Mauvaise valeur de job-state!" - -#: scheduler/ipp.c:8423 scheduler/ipp.c:8435 scheduler/ipp.c:8446 -#: scheduler/ipp.c:8498 scheduler/ipp.c:8510 scheduler/ipp.c:8521 -#: scheduler/ipp.c:8835 scheduler/ipp.c:8850 scheduler/ipp.c:8861 -msgid "Job state cannot be changed." -msgstr "L'état du travail ne peut pas être changé." - -#: scheduler/ipp.c:8787 scheduler/ipp.c:8867 scheduler/ipp.c:9209 -#, c-format -msgid "Unsupported compression attribute %s!" -msgstr "Attribut non soutenu %s de compression!" - -#: scheduler/ipp.c:8815 scheduler/ipp.c:8894 scheduler/ipp.c:9236 -#, c-format -msgid "Unsupported format \"%s\"!" -msgstr "Format non soutenu \"%s\"!" - -#: berkeley/lpc.c:201 -#, c-format -msgid "%s is not implemented by the CUPS version of lpc.\n" -msgstr "" - -#: berkeley/lpc.c:216 -msgid "" -"Commands may be abbreviated. Commands are:\n" -"\n" -"exit help quit status ?\n" -msgstr "" - -#: berkeley/lpc.c:222 berkeley/lpc.c:221 -msgid "help\t\tget help on commands\n" -msgstr "" - -#: berkeley/lpc.c:225 berkeley/lpc.c:223 -msgid "status\t\tshow status of daemon and queue\n" -msgstr "" - -#: berkeley/lpc.c:228 berkeley/lpc.c:225 -msgid "?Invalid help command unknown\n" -msgstr "" - -#: berkeley/lpc.c:478 berkeley/lpc.c:490 berkeley/lpc.c:475 berkeley/lpc.c:487 -#: berkeley/lpc.c:476 berkeley/lpc.c:488 -#, c-format -msgid "\tprinter is on device '%s' speed -1\n" -msgstr "" - -#: berkeley/lpc.c:496 berkeley/lpc.c:493 berkeley/lpc.c:494 -msgid "\tqueuing is enabled\n" -msgstr "" - -#: berkeley/lpc.c:498 berkeley/lpc.c:495 berkeley/lpc.c:496 -msgid "\tqueuing is disabled\n" -msgstr "" - -#: berkeley/lpc.c:501 berkeley/lpc.c:498 berkeley/lpc.c:499 -msgid "\tprinting is enabled\n" -msgstr "" - -#: berkeley/lpc.c:503 berkeley/lpc.c:500 berkeley/lpc.c:501 -msgid "\tprinting is disabled\n" -msgstr "" - -#: berkeley/lpc.c:506 berkeley/lpc.c:503 berkeley/lpc.c:504 -msgid "\tno entries\n" -msgstr "" - -#: berkeley/lpc.c:508 berkeley/lpc.c:505 berkeley/lpc.c:506 -#, c-format -msgid "\t%d entries\n" -msgstr "" - -#: berkeley/lpc.c:510 berkeley/lpc.c:507 berkeley/lpc.c:508 -msgid "\tdaemon present\n" -msgstr "" - -#: berkeley/lpq.c:94 -msgid "lpq: Unable to contact server!\n" -msgstr "" - -#: berkeley/lpq.c:125 berkeley/lpr.c:114 berkeley/lprm.c:107 -#: systemv/accept.c:108 systemv/cancel.c:95 systemv/lpstat.c:115 -#: systemv/lpadmin.c:284 systemv/lp.c:135 systemv/lpinfo.c:80 -#: systemv/lpmove.c:84 systemv/accept.c:106 systemv/cancel.c:93 -#: systemv/lpmove.c:89 berkeley/lpq.c:124 systemv/lp.c:136 -#: systemv/lpstat.c:116 berkeley/lpr.c:116 systemv/lp.c:140 -#, c-format -msgid "%s: Sorry, no encryption support compiled in!\n" -msgstr "" - -#: berkeley/lpq.c:155 -#, c-format -msgid "lpq: Unknown destination \"%s/%s\"!\n" -msgstr "" - -#: berkeley/lpq.c:159 -#, fuzzy, c-format -msgid "lpq: Unknown destination \"%s\"!\n" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: berkeley/lpq.c:211 systemv/lp.c:564 -#, c-format -msgid "" -"lp: error - %s environment variable names non-existent destination \"%s\"!\n" -msgstr "" - -#: berkeley/lpq.c:216 -msgid "lpq: error - no default destination available.\n" -msgstr "" - -#: berkeley/lpq.c:363 berkeley/lpq.c:523 -#, c-format -msgid "lpq: get-jobs failed: %s\n" -msgstr "" - -#: berkeley/lpq.c:457 berkeley/lpq.c:444 berkeley/lpq.c:488 -msgid "" -"Rank Owner Pri Job Files Total Size\n" -msgstr "" - -#: berkeley/lpq.c:461 berkeley/lpq.c:448 berkeley/lpq.c:492 -msgid "Rank Owner Job File(s) Total Size\n" -msgstr "" - -#: berkeley/lpq.c:498 berkeley/lpq.c:485 berkeley/lpq.c:529 -#, c-format -msgid "%s: %-33.33s [job %d localhost]\n" -msgstr "" - -#: berkeley/lpq.c:500 berkeley/lpq.c:487 berkeley/lpq.c:531 -#, c-format -msgid " %-39.39s %.0f bytes\n" -msgstr "" - -#: berkeley/lpq.c:506 berkeley/lpq.c:493 berkeley/lpq.c:537 -#, c-format -msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" -msgstr "" - -#: berkeley/lpq.c:511 berkeley/lpq.c:498 berkeley/lpq.c:542 -#, c-format -msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" -msgstr "" - -#: berkeley/lpq.c:529 berkeley/lpq.c:515 berkeley/lpq.c:559 -msgid "no entries\n" -msgstr "" - -#: berkeley/lpq.c:591 berkeley/lpq.c:620 -#, c-format -msgid "lpq: get-printer-attributes failed: %s\n" -msgstr "" - -#: berkeley/lpq.c:605 berkeley/lpq.c:576 berkeley/lpq.c:621 -#, c-format -msgid "%s is ready\n" -msgstr "" - -#: berkeley/lpq.c:608 berkeley/lpq.c:579 berkeley/lpq.c:624 -#, c-format -msgid "%s is ready and printing\n" -msgstr "" - -#: berkeley/lpq.c:612 berkeley/lpq.c:583 berkeley/lpq.c:628 -#, fuzzy, c-format -msgid "%s is not ready\n" -msgstr "Le travail # %d n'est pas tenu!" - -#: berkeley/lpq.c:633 berkeley/lpq.c:601 -msgid "Usage: lpq [-P dest] [-l] [+interval]\n" -msgstr "" - -#: berkeley/lpr.c:132 -#, c-format -msgid "lpr: error - expected value after -%c option!\n" -msgstr "" - -#: berkeley/lpr.c:146 -#, c-format -msgid "" -"lpr: warning - '%c' format modifier not supported - output may not be " -"correct!\n" -msgstr "" - -#: berkeley/lpr.c:159 -msgid "lpr: error - expected option=value after -o option!\n" -msgstr "" - -#: berkeley/lpr.c:185 -msgid "lpr: warning - email notification is not currently supported!\n" -msgstr "" - -#: berkeley/lpr.c:207 -msgid "lpr: error - expected destination after -P option!\n" -msgstr "" - -#: berkeley/lpr.c:240 -msgid "lpr: error - expected copy count after -# option!\n" -msgstr "" - -#: berkeley/lpr.c:263 -#, c-format -msgid "lpr: error - expected name after -%c option!\n" -msgstr "" - -#: berkeley/lpr.c:281 -msgid "lpr: error - expected username after -U option!\n" -msgstr "" - -#: berkeley/lpr.c:292 -#, c-format -msgid "lpr: error - unknown option '%c'!\n" -msgstr "" - -#: berkeley/lpr.c:305 -#, c-format -msgid "lpr: error - unable to access \"%s\" - %s\n" -msgstr "" - -#: berkeley/lpr.c:323 -#, c-format -msgid "lpr: error - too many files - \"%s\"\n" -msgstr "" - -#: berkeley/lpr.c:364 -#, c-format -msgid "" -"lpr: error - %s environment variable names non-existent destination \"%s\"!\n" -msgstr "" - -#: berkeley/lpr.c:369 -msgid "lpr: error - no default destination available.\n" -msgstr "" - -#: berkeley/lpr.c:372 -msgid "lpr: error - scheduler not responding!\n" -msgstr "" - -#: berkeley/lpr.c:421 -#, c-format -msgid "lpr: error - unable to create temporary file \"%s\" - %s\n" -msgstr "" - -#: berkeley/lpr.c:431 -#, c-format -msgid "lpr: error - unable to write to temporary file \"%s\" - %s\n" -msgstr "" - -#: berkeley/lpr.c:445 -msgid "lpr: error - stdin is empty, so no job has been sent.\n" -msgstr "" - -#: berkeley/lpr.c:461 berkeley/lpr.c:460 -#, c-format -msgid "lpr: error - unable to print file: %s\n" -msgstr "" - -#: berkeley/lprm.c:87 -msgid "lprm: Unable to contact server!\n" -msgstr "" - -#: berkeley/lprm.c:127 -#, c-format -msgid "lprm: Unknown destination \"%s\"!\n" -msgstr "" - -#: berkeley/lprm.c:136 -#, c-format -msgid "lprm: Unknown option '%c'!\n" -msgstr "" - -#: berkeley/lprm.c:223 -#, fuzzy -msgid "lprm: Job or printer not found!\n" -msgstr "Le travail %d non trouvé!" - -#: berkeley/lprm.c:227 -#, fuzzy -msgid "lprm: Not authorized to lprm job(s)!\n" -msgstr "Non autorisé à juger le travail # %d possédés par \"%s\"!" - -#: berkeley/lprm.c:231 -#, c-format -msgid "lprm: You don't own job ID %d!\n" -msgstr "" - -#: berkeley/lprm.c:236 -msgid "lprm: Unable to lprm job(s)!\n" -msgstr "" - -#: berkeley/lprm.c:253 berkeley/lprm.c:269 -msgid "lprm: Unable to cancel job(s)!\n" -msgstr "" - -#: systemv/accept.c:84 systemv/accept.c:82 -#, c-format -msgid "%s: Don't know what to do!\n" -msgstr "" - -#: systemv/accept.c:129 systemv/accept.c:127 -#, c-format -msgid "%s: Expected server name after -h!\n" -msgstr "" - -#: systemv/accept.c:147 systemv/accept.c:145 -#, c-format -msgid "%s: Expected reason text after -r!\n" -msgstr "" - -#: systemv/accept.c:157 systemv/accept.c:155 -#, c-format -msgid "%s: Unknown option '%c'!\n" -msgstr "" - -#: systemv/accept.c:173 systemv/accept.c:171 systemv/accept.c:192 -#, c-format -msgid "%s: Unable to connect to server: %s\n" -msgstr "" - -#: systemv/accept.c:217 systemv/accept.c:227 systemv/accept.c:268 -#: systemv/accept.c:278 systemv/accept.c:206 systemv/accept.c:230 -#, c-format -msgid "%s: Operation failed: %s\n" -msgstr "" - -#: systemv/cancel.c:118 systemv/cancel.c:116 -msgid "cancel: Error - expected hostname after '-h' option!\n" -msgstr "" - -#: systemv/cancel.c:139 systemv/cancel.c:137 -msgid "cancel: Error - expected username after '-u' option!\n" -msgstr "" - -#: systemv/cancel.c:150 systemv/cancel.c:148 -#, c-format -msgid "cancel: Unknown option '%c'!\n" -msgstr "" - -#: systemv/cancel.c:207 systemv/cancel.c:205 -#, fuzzy, c-format -msgid "cancel: Unknown destination \"%s\"!\n" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: systemv/cancel.c:229 systemv/cancel.c:319 systemv/cancel.c:227 -#: systemv/cancel.c:308 -msgid "cancel: Unable to contact server!\n" -msgstr "" - -#: systemv/cancel.c:295 systemv/cancel.c:370 systemv/cancel.c:284 -#: systemv/cancel.c:348 -#, c-format -msgid "cancel: %s failed: %s\n" -msgstr "" - -#: systemv/cupsaddsmb.c:290 systemv/cupsaddsmb.c:311 -#, c-format -msgid "cupsaddsmb: Missing value on line %d!\n" -msgstr "" - -#: systemv/cupsaddsmb.c:301 systemv/cupsaddsmb.c:322 -#, c-format -msgid "cupsaddsmb: Missing double quote on line %d!\n" -msgstr "" - -#: systemv/cupsaddsmb.c:313 systemv/cupsaddsmb.c:334 -#, c-format -msgid "cupsaddsmb: Bad option + choice on line %d!\n" -msgstr "" - -#: systemv/cupsaddsmb.c:496 systemv/cupsaddsmb.c:553 -#, c-format -msgid "cupsaddsmb: Unable to connect to server \"%s\" for %s - %s\n" -msgstr "" - -#: systemv/cupsaddsmb.c:509 systemv/cupsaddsmb.c:566 -#, c-format -msgid "cupsaddsmb: No PPD file for printer \"%s\" - skipping!\n" -msgstr "" - -#: systemv/cupsaddsmb.c:548 systemv/cupsaddsmb.c:562 -#, c-format -msgid "cupsaddsmb: get-printer-attributes failed for \"%s\": %s\n" -msgstr "" - -#: systemv/cupsaddsmb.c:578 systemv/cupsaddsmb.c:620 -#, fuzzy, c-format -msgid "cupsaddsmb: Unable to convert PPD file for %s - %s\n" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: systemv/cupsaddsmb.c:633 systemv/cupsaddsmb.c:677 -#, c-format -msgid "cupsaddsmb: Unable to copy Windows 2000 printer driver files (%d)!\n" -msgstr "" - -#: systemv/cupsaddsmb.c:660 systemv/cupsaddsmb.c:704 -#, c-format -msgid "cupsaddsmb: Unable to copy CUPS printer driver files (%d)!\n" -msgstr "" - -#: systemv/cupsaddsmb.c:697 systemv/cupsaddsmb.c:739 -#, c-format -msgid "cupsaddsmb: Unable to install Windows 2000 printer driver files (%d)!\n" -msgstr "" - -#: systemv/cupsaddsmb.c:727 systemv/cupsaddsmb.c:771 -#, c-format -msgid "cupsaddsmb: Unable to copy Windows 9x printer driver files (%d)!\n" -msgstr "" - -#: systemv/cupsaddsmb.c:750 systemv/cupsaddsmb.c:792 -#, c-format -msgid "cupsaddsmb: Unable to install Windows 9x printer driver files (%d)!\n" -msgstr "" - -#: systemv/cupsaddsmb.c:771 systemv/cupsaddsmb.c:822 -#, c-format -msgid "cupsaddsmb: Unable to set Windows printer driver (%d)!\n" -msgstr "" - -#: systemv/cupsaddsmb.c:854 systemv/cupsaddsmb.c:905 -msgid "" -"Usage: cupsaddsmb [options] printer1 ... printerN\n" -" cupsaddsmb [options] -a\n" -"\n" -"Options:\n" -" -H samba-server Use the named SAMBA server\n" -" -U samba-user Authenticate using the named SAMBA user\n" -" -a Export all printers\n" -" -h cups-server Use the named CUPS server\n" -" -v Be verbose (show commands)\n" -msgstr "" - -#: systemv/cupstestppd.c:120 systemv/cupstestppd.c:137 -msgid "cupstestppd: The -q option is incompatible with the -v option.\n" -msgstr "" - -#: systemv/cupstestppd.c:136 systemv/cupstestppd.c:153 -msgid "cupstestppd: The -v option is incompatible with the -q option.\n" -msgstr "" - -#: systemv/cupstestppd.c:193 systemv/cupstestppd.c:210 -#, fuzzy, c-format -msgid "" -" FAIL\n" -" **FAIL** Unable to open PPD file - %s\n" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: systemv/cupstestppd.c:204 systemv/cupstestppd.c:221 -#, c-format -msgid "" -" FAIL\n" -" **FAIL** Unable to open PPD file - %s on line %d.\n" -msgstr "" - -#: systemv/cupstestppd.c:213 systemv/cupstestppd.c:230 -msgid " REF: Page 42, section 5.2.\n" -msgstr "" - -#: systemv/cupstestppd.c:217 systemv/cupstestppd.c:234 -msgid " REF: Page 20, section 3.4.\n" -msgstr "" - -#: systemv/cupstestppd.c:222 systemv/cupstestppd.c:239 -msgid " REF: Pages 45-46, section 5.2.\n" -msgstr "" - -#: systemv/cupstestppd.c:227 systemv/cupstestppd.c:244 -msgid " REF: Pages 42-45, section 5.2.\n" -msgstr "" - -#: systemv/cupstestppd.c:231 systemv/cupstestppd.c:248 -msgid " REF: Pages 48-49, section 5.2.\n" -msgstr "" - -#: systemv/cupstestppd.c:235 systemv/cupstestppd.c:252 -msgid " REF: Pages 52-54, section 5.2.\n" -msgstr "" - -#: systemv/cupstestppd.c:239 systemv/cupstestppd.c:256 -msgid " REF: Page 15, section 3.2.\n" -msgstr "" - -#: systemv/cupstestppd.c:243 systemv/cupstestppd.c:247 -#: systemv/cupstestppd.c:260 systemv/cupstestppd.c:264 -msgid " REF: Page 15, section 3.1.\n" -msgstr "" - -#: systemv/cupstestppd.c:251 systemv/cupstestppd.c:268 -msgid " REF: Pages 16-17, section 3.2.\n" -msgstr "" - -#: systemv/cupstestppd.c:255 systemv/cupstestppd.c:272 -msgid " REF: Page 19, section 3.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:259 systemv/cupstestppd.c:276 -msgid " REF: Page 27, section 3.5.\n" -msgstr "" - -#: systemv/cupstestppd.c:280 systemv/cupstestppd.c:299 -msgid "" -"\n" -" DETAILED CONFORMANCE TEST RESULTS\n" -msgstr "" - -#: systemv/cupstestppd.c:307 systemv/cupstestppd.c:326 -#, c-format -msgid " WARN %s has no corresponding options!\n" -msgstr "" - -#: systemv/cupstestppd.c:318 systemv/cupstestppd.c:333 -#: systemv/cupstestppd.c:354 systemv/cupstestppd.c:369 -#: systemv/cupstestppd.c:397 systemv/cupstestppd.c:417 -#: systemv/cupstestppd.c:439 systemv/cupstestppd.c:459 -#: systemv/cupstestppd.c:479 systemv/cupstestppd.c:499 -#: systemv/cupstestppd.c:517 systemv/cupstestppd.c:535 -#: systemv/cupstestppd.c:556 systemv/cupstestppd.c:575 -#: systemv/cupstestppd.c:595 systemv/cupstestppd.c:615 -#: systemv/cupstestppd.c:635 systemv/cupstestppd.c:655 -#: systemv/cupstestppd.c:673 systemv/cupstestppd.c:690 -#: systemv/cupstestppd.c:712 systemv/cupstestppd.c:730 -#: systemv/cupstestppd.c:747 systemv/cupstestppd.c:765 -#: systemv/cupstestppd.c:781 systemv/cupstestppd.c:801 -#: systemv/cupstestppd.c:832 systemv/cupstestppd.c:854 -#: systemv/cupstestppd.c:902 systemv/cupstestppd.c:931 -#: systemv/cupstestppd.c:952 systemv/cupstestppd.c:337 -#: systemv/cupstestppd.c:352 systemv/cupstestppd.c:373 -#: systemv/cupstestppd.c:388 systemv/cupstestppd.c:416 -#: systemv/cupstestppd.c:436 systemv/cupstestppd.c:458 -#: systemv/cupstestppd.c:478 systemv/cupstestppd.c:498 -#: systemv/cupstestppd.c:518 systemv/cupstestppd.c:536 -#: systemv/cupstestppd.c:554 systemv/cupstestppd.c:594 -#: systemv/cupstestppd.c:614 systemv/cupstestppd.c:634 -#: systemv/cupstestppd.c:654 systemv/cupstestppd.c:674 -#: systemv/cupstestppd.c:692 systemv/cupstestppd.c:709 -#: systemv/cupstestppd.c:731 systemv/cupstestppd.c:749 -#: systemv/cupstestppd.c:766 systemv/cupstestppd.c:784 -#: systemv/cupstestppd.c:800 systemv/cupstestppd.c:820 -#: systemv/cupstestppd.c:851 systemv/cupstestppd.c:873 -#: systemv/cupstestppd.c:921 systemv/cupstestppd.c:950 -#: systemv/cupstestppd.c:971 -msgid " FAIL\n" -msgstr "" - -#: systemv/cupstestppd.c:321 systemv/cupstestppd.c:340 -msgid "" -" **FAIL** REQUIRED DefaultImageableArea\n" -" REF: Page 102, section 5.15.\n" -msgstr "" - -#: systemv/cupstestppd.c:336 systemv/cupstestppd.c:355 -#, c-format -msgid "" -" **FAIL** BAD DefaultImageableArea %s!\n" -" REF: Page 102, section 5.15.\n" -msgstr "" - -#: systemv/cupstestppd.c:346 systemv/cupstestppd.c:365 -msgid " PASS DefaultImageableArea\n" -msgstr "" - -#: systemv/cupstestppd.c:357 systemv/cupstestppd.c:376 -msgid "" -" **FAIL** REQUIRED DefaultPaperDimension\n" -" REF: Page 103, section 5.15.\n" -msgstr "" - -#: systemv/cupstestppd.c:372 systemv/cupstestppd.c:391 -#, c-format -msgid "" -" **FAIL** BAD DefaultPaperDimension %s!\n" -" REF: Page 103, section 5.15.\n" -msgstr "" - -#: systemv/cupstestppd.c:380 systemv/cupstestppd.c:399 -msgid " PASS DefaultPaperDimension\n" -msgstr "" - -#: systemv/cupstestppd.c:400 systemv/cupstestppd.c:419 -#, c-format -msgid "" -" **FAIL** BAD Default%s %s\n" -" REF: Page 40, section 4.5.\n" -msgstr "" - -#: systemv/cupstestppd.c:409 systemv/cupstestppd.c:428 -#, c-format -msgid " PASS Default%s\n" -msgstr "" - -#: systemv/cupstestppd.c:420 systemv/cupstestppd.c:439 -#, c-format -msgid "" -" **FAIL** REQUIRED Default%s\n" -" REF: Page 40, section 4.5.\n" -msgstr "" - -#: systemv/cupstestppd.c:432 systemv/cupstestppd.c:451 -msgid " PASS FileVersion\n" -msgstr "" - -#: systemv/cupstestppd.c:442 systemv/cupstestppd.c:461 -msgid "" -" **FAIL** REQUIRED FileVersion\n" -" REF: Page 56, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:452 systemv/cupstestppd.c:471 -msgid " PASS FormatVersion\n" -msgstr "" - -#: systemv/cupstestppd.c:462 systemv/cupstestppd.c:481 -msgid "" -" **FAIL** REQUIRED FormatVersion\n" -" REF: Page 56, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:472 systemv/cupstestppd.c:491 -msgid " PASS LanguageEncoding\n" -msgstr "" - -#: systemv/cupstestppd.c:482 systemv/cupstestppd.c:501 -msgid "" -" **FAIL** REQUIRED LanguageEncoding\n" -" REF: Pages 56-57, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:492 systemv/cupstestppd.c:511 -msgid " PASS LanguageVersion\n" -msgstr "" - -#: systemv/cupstestppd.c:502 systemv/cupstestppd.c:521 -msgid "" -" **FAIL** REQUIRED LanguageVersion\n" -" REF: Pages 57-58, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:520 systemv/cupstestppd.c:539 -msgid "" -" **FAIL** BAD Manufacturer (should be \"HP\")\n" -" REF: Page 211, table D.1.\n" -msgstr "" - -#: systemv/cupstestppd.c:528 systemv/cupstestppd.c:547 -msgid " PASS Manufacturer\n" -msgstr "" - -#: systemv/cupstestppd.c:538 systemv/cupstestppd.c:557 -msgid "" -" **FAIL** REQUIRED Manufacturer\n" -" REF: Pages 58-59, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:559 systemv/cupstestppd.c:578 -#, c-format -msgid "" -" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" -" REF: Pages 59-60, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:568 systemv/cupstestppd.c:587 -msgid " PASS ModelName\n" -msgstr "" - -#: systemv/cupstestppd.c:578 systemv/cupstestppd.c:597 -msgid "" -" **FAIL** REQUIRED ModelName\n" -" REF: Pages 59-60, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:588 systemv/cupstestppd.c:607 -msgid " PASS NickName\n" -msgstr "" - -#: systemv/cupstestppd.c:598 systemv/cupstestppd.c:617 -msgid "" -" **FAIL** REQUIRED NickName\n" -" REF: Page 60, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:608 systemv/cupstestppd.c:627 -msgid " PASS PageSize\n" -msgstr "" - -#: systemv/cupstestppd.c:618 systemv/cupstestppd.c:637 -msgid "" -" **FAIL** REQUIRED PageSize\n" -" REF: Pages 99-100, section 5.14.\n" -msgstr "" - -#: systemv/cupstestppd.c:628 systemv/cupstestppd.c:647 -msgid " PASS PageRegion\n" -msgstr "" - -#: systemv/cupstestppd.c:638 systemv/cupstestppd.c:657 -msgid "" -" **FAIL** REQUIRED PageRegion\n" -" REF: Page 100, section 5.14.\n" -msgstr "" - -#: systemv/cupstestppd.c:648 systemv/cupstestppd.c:667 -msgid " PASS PCFileName\n" -msgstr "" - -#: systemv/cupstestppd.c:658 systemv/cupstestppd.c:677 -msgid "" -" **FAIL** REQUIRED PCFileName\n" -" REF: Pages 61-62, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:676 systemv/cupstestppd.c:695 -msgid "" -" **FAIL** BAD Product - not \"(string)\".\n" -" REF: Page 62, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:683 systemv/cupstestppd.c:702 -msgid " PASS Product\n" -msgstr "" - -#: systemv/cupstestppd.c:693 systemv/cupstestppd.c:712 -msgid "" -" **FAIL** REQUIRED Product\n" -" REF: Page 62, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:715 systemv/cupstestppd.c:734 -msgid "" -" **FAIL** BAD PSVersion - not \"(string) int\".\n" -" REF: Pages 62-64, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:723 systemv/cupstestppd.c:742 -msgid " PASS PSVersion\n" -msgstr "" - -#: systemv/cupstestppd.c:733 systemv/cupstestppd.c:752 -msgid "" -" **FAIL** REQUIRED PSVersion\n" -" REF: Pages 62-64, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:750 systemv/cupstestppd.c:769 -msgid "" -" **FAIL** BAD ShortNickName - longer than 31 chars.\n" -" REF: Pages 64-65, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:758 systemv/cupstestppd.c:777 -msgid " PASS ShortNickName\n" -msgstr "" - -#: systemv/cupstestppd.c:768 systemv/cupstestppd.c:787 -msgid "" -" **FAIL** REQUIRED ShortNickName\n" -" REF: Page 64-65, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:784 systemv/cupstestppd.c:803 -msgid "" -" **FAIL** BAD JobPatchFile attribute in file\n" -" REF: Page 24, section 3.4.\n" -msgstr "" - -#: systemv/cupstestppd.c:804 systemv/cupstestppd.c:823 -msgid "" -" **FAIL** REQUIRED PageSize\n" -" REF: Page 41, section 5.\n" -" REF: Page 99, section 5.14.\n" -msgstr "" - -#: systemv/cupstestppd.c:835 systemv/cupstestppd.c:854 -#, c-format -msgid "" -" **FAIL** REQUIRED ImageableArea for PageSize %s\n" -" REF: Page 41, section 5.\n" -" REF: Page 102, section 5.15.\n" -msgstr "" - -#: systemv/cupstestppd.c:857 systemv/cupstestppd.c:876 -#, c-format -msgid "" -" **FAIL** REQUIRED PaperDimension for PageSize %s\n" -" REF: Page 41, section 5.\n" -" REF: Page 103, section 5.15.\n" -msgstr "" - -#: systemv/cupstestppd.c:905 systemv/cupstestppd.c:924 -#, c-format -msgid "" -" **FAIL** Bad %s choice %s!\n" -" REF: Page 84, section 5.9\n" -msgstr "" - -#: systemv/cupstestppd.c:934 systemv/cupstestppd.c:953 -#, c-format -msgid "" -" **FAIL** REQUIRED %s does not define choice None!\n" -" REF: Page 122, section 5.17\n" -msgstr "" - -#: systemv/cupstestppd.c:955 systemv/cupstestppd.c:974 -#, c-format -msgid "" -" **FAIL** Bad %s choice %s!\n" -" REF: Page 122, section 5.17\n" -msgstr "" - -#: systemv/cupstestppd.c:967 systemv/cupstestppd.c:986 -msgid " PASS\n" -msgstr "" - -#: systemv/cupstestppd.c:976 systemv/cupstestppd.c:997 -#, c-format -msgid "" -" WARN Duplex option keyword %s should be named Duplex or " -"JCLDuplex!\n" -" REF: Page 122, section 5.17\n" -msgstr "" - -#: systemv/cupstestppd.c:986 systemv/cupstestppd.c:1007 -msgid " WARN Default choices conflicting!\n" -msgstr "" - -#: systemv/cupstestppd.c:994 systemv/cupstestppd.c:1015 -#, c-format -msgid "" -" WARN Obsolete PPD version %.1f!\n" -" REF: Page 42, section 5.2.\n" -msgstr "" - -#: systemv/cupstestppd.c:1002 systemv/cupstestppd.c:1023 -msgid "" -" WARN LanguageEncoding required by PPD 4.3 spec.\n" -" REF: Pages 56-57, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:1010 systemv/cupstestppd.c:1031 -msgid "" -" WARN Manufacturer required by PPD 4.3 spec.\n" -" REF: Pages 58-59, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:1023 systemv/cupstestppd.c:1044 -msgid "" -" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" -" REF: Pages 61-62, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:1031 systemv/cupstestppd.c:1052 -msgid "" -" WARN ShortNickName required by PPD 4.3 spec.\n" -" REF: Pages 64-65, section 5.3.\n" -msgstr "" - -#: systemv/cupstestppd.c:1048 systemv/cupstestppd.c:1069 -msgid "" -" WARN Protocols contains both PJL and BCP; expected TBCP.\n" -" REF: Pages 78-79, section 5.7.\n" -msgstr "" - -#: systemv/cupstestppd.c:1057 systemv/cupstestppd.c:1078 -msgid "" -" WARN Protocols contains PJL but JCL attributes are not set.\n" -" REF: Pages 78-79, section 5.7.\n" -msgstr "" - -#: systemv/cupstestppd.c:1085 systemv/cupstestppd.c:1106 -#, c-format -msgid "" -" WARN %s shares a common prefix with %s\n" -" REF: Page 15, section 3.2.\n" -msgstr "" - -#: systemv/cupstestppd.c:1097 systemv/cupstestppd.c:1118 -#, c-format -msgid " %d ERROR%s FOUND\n" -msgstr "" - -#: systemv/cupstestppd.c:1100 systemv/cupstestppd.c:1121 -msgid " NO ERRORS FOUND\n" -msgstr "" - -#: systemv/cupstestppd.c:1360 systemv/cupstestppd.c:1465 -#, c-format -msgid "" -" WARN \"%s %s\" conflicts with \"%s %s\"\n" -" (constraint=\"%s %s %s %s\")\n" -msgstr "" - -#: systemv/cupstestppd.c:1376 systemv/cupstestppd.c:1481 -msgid "" -"Usage: cupstestppd [-q] [-r] [-v[v]] filename1.ppd[.gz] [... filenameN.ppd[." -"gz]]\n" -" program | cupstestppd [-q] [-r] [-v[v]] -\n" -msgstr "" - -#: systemv/lpstat.c:144 systemv/lpstat.c:155 -msgid "lpstat: Need \"completed\" or \"not-completed\" after -W!\n" -msgstr "" - -#: systemv/lpstat.c:212 systemv/lpstat.c:213 -msgid "lpstat: The -b option requires a destination argument.\n" -msgstr "" - -#: systemv/lpstat.c:274 systemv/lpinfo.c:143 systemv/lpmove.c:105 -#: systemv/lpmove.c:110 systemv/lpstat.c:275 -msgid "Error: need hostname after '-h' option!\n" -msgstr "" - -#: systemv/lpstat.c:433 systemv/lpstat.c:434 -#, c-format -msgid "lpstat: Unknown option '%c'!\n" -msgstr "" - -#: systemv/lpstat.c:504 systemv/lpstat.c:505 -#, c-format -msgid "lpstat: Invalid destination name in list \"%s\"!\n" -msgstr "" - -#: systemv/lpstat.c:519 systemv/lpstat.c:520 -#, fuzzy, c-format -msgid "lpstat: Unknown destination \"%s\"!\n" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: systemv/lpstat.c:541 systemv/lpstat.c:542 -#, c-format -msgid "lpstat: Unable to connect to server %s on port %d: %s\n" -msgstr "" - -#: systemv/lpstat.c:625 systemv/lpstat.c:773 systemv/lpstat.c:1187 -#: systemv/lpstat.c:1379 systemv/lpstat.c:1809 systemv/lpstat.c:2262 -#, c-format -msgid "lpstat: get-printers failed: %s\n" -msgstr "" - -#: systemv/lpstat.c:741 -#, c-format -msgid "%s accepting requests since Jan 01 00:00\n" -msgstr "" - -#: systemv/lpstat.c:745 -#, c-format -msgid "" -"%s not accepting requests since Jan 01 00:00 -\n" -"\t%s\n" -msgstr "" - -#: systemv/lpstat.c:754 -#, c-format -msgid "%s/%s accepting requests since Jan 01 00:00\n" -msgstr "" - -#: systemv/lpstat.c:758 -#, c-format -msgid "" -"%s/%s not accepting requests since Jan 01 00:00 -\n" -"\t%s\n" -msgstr "" - -#: systemv/lpstat.c:861 systemv/lpstat.c:1056 -#, c-format -msgid "lpstat: get-classes failed: %s\n" -msgstr "" - -#: systemv/lpstat.c:1033 systemv/lpstat.c:1011 systemv/lpstat.c:1039 -#, c-format -msgid "members of class %s:\n" -msgstr "" - -#: systemv/lpstat.c:1080 systemv/lpstat.c:1057 systemv/lpstat.c:1085 -#, c-format -msgid "system default destination: %s/%s\n" -msgstr "" - -#: systemv/lpstat.c:1083 systemv/lpstat.c:1060 systemv/lpstat.c:1088 -#, c-format -msgid "system default destination: %s\n" -msgstr "" - -#: systemv/lpstat.c:1105 systemv/lpstat.c:1082 systemv/lpstat.c:1110 -#, c-format -msgid "" -"lpstat: error - %s environment variable names non-existent destination \"%s" -"\"!\n" -msgstr "" - -#: systemv/lpstat.c:1109 systemv/lpstat.c:1086 systemv/lpstat.c:1114 -msgid "no system default destination\n" -msgstr "" - -#: systemv/lpstat.c:1313 systemv/lpstat.c:1281 systemv/lpstat.c:1309 -#: systemv/lpstat.c:1311 -#, c-format -msgid "Output for printer %s is sent to remote printer %s on %s\n" -msgstr "" - -#: systemv/lpstat.c:1319 systemv/lpstat.c:1323 systemv/lpstat.c:1287 -#: systemv/lpstat.c:1291 systemv/lpstat.c:1315 systemv/lpstat.c:1317 -#: systemv/lpstat.c:1321 -#, c-format -msgid "Output for printer %s is sent to %s\n" -msgstr "" - -#: systemv/lpstat.c:1331 systemv/lpstat.c:1299 systemv/lpstat.c:1327 -#: systemv/lpstat.c:1329 -#, c-format -msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" -msgstr "" - -#: systemv/lpstat.c:1337 systemv/lpstat.c:1341 systemv/lpstat.c:1305 -#: systemv/lpstat.c:1309 systemv/lpstat.c:1333 systemv/lpstat.c:1335 -#: systemv/lpstat.c:1339 -#, c-format -msgid "Output for printer %s/%s is sent to %s\n" -msgstr "" - -#: systemv/lpstat.c:1346 systemv/lpstat.c:1349 systemv/lpstat.c:1352 -#: systemv/lpstat.c:1314 systemv/lpstat.c:1317 systemv/lpstat.c:1320 -#: systemv/lpstat.c:1342 systemv/lpstat.c:1345 systemv/lpstat.c:1348 -#: systemv/lpstat.c:1344 systemv/lpstat.c:1347 systemv/lpstat.c:1350 -#, c-format -msgid "device for %s: %s\n" -msgstr "" - -#: systemv/lpstat.c:1359 systemv/lpstat.c:1362 systemv/lpstat.c:1365 -#: systemv/lpstat.c:1327 systemv/lpstat.c:1330 systemv/lpstat.c:1333 -#: systemv/lpstat.c:1355 systemv/lpstat.c:1358 systemv/lpstat.c:1361 -#: systemv/lpstat.c:1357 systemv/lpstat.c:1360 systemv/lpstat.c:1363 -#, c-format -msgid "device for %s/%s: %s\n" -msgstr "" - -#: systemv/lpstat.c:1481 systemv/lpstat.c:1693 -#, c-format -msgid "lpstat: get-jobs failed: %s\n" -msgstr "" - -#: systemv/lpstat.c:1681 systemv/lpstat.c:1635 systemv/lpstat.c:1663 -#: systemv/lpstat.c:1665 -#, c-format -msgid "\tqueued for %s\n" -msgstr "" - -#: systemv/lpstat.c:2037 systemv/lpstat.c:1971 systemv/lpstat.c:1999 -#: systemv/lpstat.c:2001 -#, c-format -msgid "printer %s is idle. enabled since %s\n" -msgstr "" - -#: systemv/lpstat.c:2042 systemv/lpstat.c:1976 systemv/lpstat.c:2004 -#: systemv/lpstat.c:2006 -#, c-format -msgid "printer %s now printing %s-%d. enabled since %s\n" -msgstr "" - -#: systemv/lpstat.c:2048 systemv/lpstat.c:1982 systemv/lpstat.c:2010 -#: systemv/lpstat.c:2012 -#, c-format -msgid "printer %s disabled since %s -\n" -msgstr "" - -#: systemv/lpstat.c:2056 systemv/lpstat.c:2169 systemv/lpstat.c:1990 -#: systemv/lpstat.c:2103 systemv/lpstat.c:2018 systemv/lpstat.c:2131 -#: systemv/lpstat.c:2020 systemv/lpstat.c:2133 -msgid "\treason unknown\n" -msgstr "" - -#: systemv/lpstat.c:2063 systemv/lpstat.c:2176 systemv/lpstat.c:1997 -#: systemv/lpstat.c:2110 systemv/lpstat.c:2025 systemv/lpstat.c:2138 -#: systemv/lpstat.c:2027 systemv/lpstat.c:2140 -msgid "" -"\tForm mounted:\n" -"\tContent types: any\n" -"\tPrinter types: unknown\n" -msgstr "" - -#: systemv/lpstat.c:2069 systemv/lpstat.c:2182 systemv/lpstat.c:2003 -#: systemv/lpstat.c:2116 systemv/lpstat.c:2031 systemv/lpstat.c:2144 -#: systemv/lpstat.c:2033 systemv/lpstat.c:2146 -#, c-format -msgid "\tDescription: %s\n" -msgstr "" - -#: systemv/lpstat.c:2074 systemv/lpstat.c:2187 systemv/lpstat.c:2008 -#: systemv/lpstat.c:2121 systemv/lpstat.c:2036 systemv/lpstat.c:2149 -#: systemv/lpstat.c:2038 systemv/lpstat.c:2151 -msgid "\tAlerts:" -msgstr "" - -#: systemv/lpstat.c:2083 systemv/lpstat.c:2196 systemv/lpstat.c:2017 -#: systemv/lpstat.c:2130 systemv/lpstat.c:2045 systemv/lpstat.c:2158 -#: systemv/lpstat.c:2047 systemv/lpstat.c:2160 -#, c-format -msgid "\tLocation: %s\n" -msgstr "" - -#: systemv/lpstat.c:2088 systemv/lpstat.c:2201 systemv/lpstat.c:2022 -#: systemv/lpstat.c:2135 systemv/lpstat.c:2050 systemv/lpstat.c:2163 -#: systemv/lpstat.c:2052 systemv/lpstat.c:2165 -msgid "\tConnection: remote\n" -msgstr "" - -#: systemv/lpstat.c:2092 systemv/lpstat.c:2205 systemv/lpstat.c:2026 -#: systemv/lpstat.c:2139 systemv/lpstat.c:2054 systemv/lpstat.c:2167 -#: systemv/lpstat.c:2056 systemv/lpstat.c:2169 -#, c-format -msgid "\tInterface: %s.ppd\n" -msgstr "" - -#: systemv/lpstat.c:2097 systemv/lpstat.c:2210 systemv/lpstat.c:2031 -#: systemv/lpstat.c:2144 systemv/lpstat.c:2059 systemv/lpstat.c:2172 -#: systemv/lpstat.c:2061 systemv/lpstat.c:2174 -msgid "\tConnection: direct\n" -msgstr "" - -#: systemv/lpstat.c:2101 systemv/lpstat.c:2214 systemv/lpstat.c:2035 -#: systemv/lpstat.c:2148 systemv/lpstat.c:2063 systemv/lpstat.c:2176 -#: systemv/lpstat.c:2065 systemv/lpstat.c:2178 -#, c-format -msgid "\tInterface: %s/interfaces/%s\n" -msgstr "" - -#: systemv/lpstat.c:2105 systemv/lpstat.c:2218 systemv/lpstat.c:2039 -#: systemv/lpstat.c:2152 systemv/lpstat.c:2067 systemv/lpstat.c:2180 -#: systemv/lpstat.c:2069 systemv/lpstat.c:2182 -#, c-format -msgid "\tInterface: %s/ppd/%s.ppd\n" -msgstr "" - -#: systemv/lpstat.c:2107 systemv/lpstat.c:2220 systemv/lpstat.c:2041 -#: systemv/lpstat.c:2154 systemv/lpstat.c:2069 systemv/lpstat.c:2182 -#: systemv/lpstat.c:2071 systemv/lpstat.c:2184 -msgid "\tOn fault: no alert\n" -msgstr "" - -#: systemv/lpstat.c:2108 systemv/lpstat.c:2221 systemv/lpstat.c:2042 -#: systemv/lpstat.c:2155 systemv/lpstat.c:2070 systemv/lpstat.c:2183 -#: systemv/lpstat.c:2072 systemv/lpstat.c:2185 -msgid "\tAfter fault: continue\n" -msgstr "" - -#: systemv/lpstat.c:2112 systemv/lpstat.c:2126 systemv/lpstat.c:2225 -#: systemv/lpstat.c:2239 systemv/lpstat.c:2046 systemv/lpstat.c:2060 -#: systemv/lpstat.c:2159 systemv/lpstat.c:2173 systemv/lpstat.c:2074 -#: systemv/lpstat.c:2088 systemv/lpstat.c:2187 systemv/lpstat.c:2201 -#: systemv/lpstat.c:2076 systemv/lpstat.c:2090 systemv/lpstat.c:2189 -#: systemv/lpstat.c:2203 -msgid "\tUsers allowed:\n" -msgstr "" - -#: systemv/lpstat.c:2119 systemv/lpstat.c:2232 systemv/lpstat.c:2053 -#: systemv/lpstat.c:2166 systemv/lpstat.c:2081 systemv/lpstat.c:2194 -#: systemv/lpstat.c:2083 systemv/lpstat.c:2196 -msgid "\tUsers denied:\n" -msgstr "" - -#: systemv/lpstat.c:2127 systemv/lpstat.c:2240 systemv/lpstat.c:2061 -#: systemv/lpstat.c:2174 systemv/lpstat.c:2089 systemv/lpstat.c:2202 -#: systemv/lpstat.c:2091 systemv/lpstat.c:2204 -msgid "\t\t(all)\n" -msgstr "" - -#: systemv/lpstat.c:2129 systemv/lpstat.c:2242 systemv/lpstat.c:2063 -#: systemv/lpstat.c:2176 systemv/lpstat.c:2091 systemv/lpstat.c:2204 -#: systemv/lpstat.c:2093 systemv/lpstat.c:2206 -msgid "\tForms allowed:\n" -msgstr "" - -#: systemv/lpstat.c:2130 systemv/lpstat.c:2133 systemv/lpstat.c:2243 -#: systemv/lpstat.c:2246 systemv/lpstat.c:2064 systemv/lpstat.c:2067 -#: systemv/lpstat.c:2177 systemv/lpstat.c:2180 systemv/lpstat.c:2092 -#: systemv/lpstat.c:2095 systemv/lpstat.c:2205 systemv/lpstat.c:2208 -#: systemv/lpstat.c:2094 systemv/lpstat.c:2097 systemv/lpstat.c:2207 -#: systemv/lpstat.c:2210 -msgid "\t\t(none)\n" -msgstr "" - -#: systemv/lpstat.c:2131 systemv/lpstat.c:2244 systemv/lpstat.c:2065 -#: systemv/lpstat.c:2178 systemv/lpstat.c:2093 systemv/lpstat.c:2206 -#: systemv/lpstat.c:2095 systemv/lpstat.c:2208 -msgid "\tBanner required\n" -msgstr "" - -#: systemv/lpstat.c:2132 systemv/lpstat.c:2245 systemv/lpstat.c:2066 -#: systemv/lpstat.c:2179 systemv/lpstat.c:2094 systemv/lpstat.c:2207 -#: systemv/lpstat.c:2096 systemv/lpstat.c:2209 -msgid "\tCharset sets:\n" -msgstr "" - -#: systemv/lpstat.c:2134 systemv/lpstat.c:2247 systemv/lpstat.c:2068 -#: systemv/lpstat.c:2181 systemv/lpstat.c:2096 systemv/lpstat.c:2209 -#: systemv/lpstat.c:2098 systemv/lpstat.c:2211 -msgid "\tDefault pitch:\n" -msgstr "" - -#: systemv/lpstat.c:2135 systemv/lpstat.c:2248 systemv/lpstat.c:2069 -#: systemv/lpstat.c:2182 systemv/lpstat.c:2097 systemv/lpstat.c:2210 -#: systemv/lpstat.c:2099 systemv/lpstat.c:2212 -msgid "\tDefault page size:\n" -msgstr "" - -#: systemv/lpstat.c:2136 systemv/lpstat.c:2249 systemv/lpstat.c:2070 -#: systemv/lpstat.c:2183 systemv/lpstat.c:2098 systemv/lpstat.c:2211 -#: systemv/lpstat.c:2100 systemv/lpstat.c:2213 -msgid "\tDefault port settings:\n" -msgstr "" - -#: systemv/lpstat.c:2146 systemv/lpstat.c:2080 systemv/lpstat.c:2108 -#: systemv/lpstat.c:2110 -#, c-format -msgid "printer %s/%s is idle. enabled since %s\n" -msgstr "" - -#: systemv/lpstat.c:2153 systemv/lpstat.c:2087 systemv/lpstat.c:2115 -#: systemv/lpstat.c:2117 -#, c-format -msgid "printer %s/%s now printing %s-%d. enabled since %s\n" -msgstr "" - -#: systemv/lpstat.c:2160 systemv/lpstat.c:2094 systemv/lpstat.c:2122 -#: systemv/lpstat.c:2124 -#, c-format -msgid "printer %s/%s disabled since %s -\n" -msgstr "" - -#: systemv/lpstat.c:2279 systemv/lpstat.c:2212 systemv/lpstat.c:2240 -#: systemv/lpstat.c:2242 -msgid "scheduler is running\n" -msgstr "" - -#: systemv/lpstat.c:2281 systemv/lpstat.c:2214 systemv/lpstat.c:2242 -#: systemv/lpstat.c:2244 -msgid "scheduler is not running\n" -msgstr "" - -#: systemv/lpadmin.c:113 systemv/lpadmin.c:166 systemv/lpadmin.c:237 -#: systemv/lpadmin.c:298 systemv/lpadmin.c:317 systemv/lpadmin.c:383 -#: systemv/lpadmin.c:424 systemv/lpadmin.c:511 systemv/lpadmin.c:557 -#: systemv/lpadmin.c:603 systemv/lpadmin.c:665 systemv/lpadmin.c:711 -#: systemv/lpadmin.c:772 -#, fuzzy, c-format -msgid "lpadmin: Unable to connect to server: %s\n" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: systemv/lpadmin.c:122 -msgid "" -"lpadmin: Unable to add a printer to the class:\n" -" You must specify a printer name first!\n" -msgstr "" - -#: systemv/lpadmin.c:137 -msgid "lpadmin: Expected class name after '-c' option!\n" -msgstr "" - -#: systemv/lpadmin.c:148 systemv/lpadmin.c:460 -msgid "lpadmin: Class name can only contain printable characters!\n" -msgstr "" - -#: systemv/lpadmin.c:181 -msgid "lpadmin: Expected printer name after '-d' option!\n" -msgstr "" - -#: systemv/lpadmin.c:192 systemv/lpadmin.c:409 systemv/lpadmin.c:583 -msgid "lpadmin: Printer name can only contain printable characters!\n" -msgstr "" - -#: systemv/lpadmin.c:219 -msgid "lpadmin: Expected hostname after '-h' option!\n" -msgstr "" - -#: systemv/lpadmin.c:246 -msgid "" -"lpadmin: Unable to set the interface script:\n" -" You must specify a printer name first!\n" -msgstr "" - -#: systemv/lpadmin.c:264 -msgid "lpadmin: Expected interface after '-i' option!\n" -msgstr "" - -#: systemv/lpadmin.c:326 -msgid "" -"lpadmin: Unable to set the interface script or PPD file:\n" -" You must specify a printer name first!\n" -msgstr "" - -#: systemv/lpadmin.c:345 -msgid "lpadmin: Expected model after '-m' option!\n" -msgstr "" - -#: systemv/lpadmin.c:365 -msgid "lpadmin: Expected name=value after '-o' option!\n" -msgstr "" - -#: systemv/lpadmin.c:398 -msgid "lpadmin: Expected printer after '-p' option!\n" -msgstr "" - -#: systemv/lpadmin.c:433 -msgid "" -"lpadmin: Unable to remove a printer from the class:\n" -" You must specify a printer name first!\n" -msgstr "" - -#: systemv/lpadmin.c:449 -msgid "lpadmin: Expected class after '-r' option!\n" -msgstr "" - -#: systemv/lpadmin.c:479 -msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" -msgstr "" - -#: systemv/lpadmin.c:496 -#, fuzzy, c-format -msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: systemv/lpadmin.c:520 -msgid "" -"lpadmin: Unable to set the device URI:\n" -" You must specify a printer name first!\n" -msgstr "" - -#: systemv/lpadmin.c:538 -msgid "lpadmin: Expected device URI after '-v' option!\n" -msgstr "" - -#: systemv/lpadmin.c:572 -msgid "lpadmin: Expected printer or class after '-x' option!\n" -msgstr "" - -#: systemv/lpadmin.c:612 -msgid "" -"lpadmin: Unable to set the printer description:\n" -" You must specify a printer name first!\n" -msgstr "" - -#: systemv/lpadmin.c:631 -msgid "lpadmin: Expected description after '-D' option!\n" -msgstr "" - -#: systemv/lpadmin.c:647 -msgid "lpadmin: Expected file type(s) after '-I' option!\n" -msgstr "" - -#: systemv/lpadmin.c:653 -msgid "lpadmin: Warning - content type list ignored!\n" -msgstr "" - -#: systemv/lpadmin.c:674 -msgid "" -"lpadmin: Unable to set the printer location:\n" -" You must specify a printer name first!\n" -msgstr "" - -#: systemv/lpadmin.c:692 -msgid "lpadmin: Expected location after '-L' option!\n" -msgstr "" - -#: systemv/lpadmin.c:720 -msgid "" -"lpadmin: Unable to set the PPD file:\n" -" You must specify a printer name first!\n" -msgstr "" - -#: systemv/lpadmin.c:738 -msgid "lpadmin: Expected PPD after '-P' option!\n" -msgstr "" - -#: systemv/lpadmin.c:749 -#, fuzzy, c-format -msgid "lpadmin: Unknown option '%c'!\n" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: systemv/lpadmin.c:754 -#, fuzzy, c-format -msgid "lpadmin: Unknown argument '%s'!\n" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: systemv/lpadmin.c:781 -msgid "" -"lpadmin: Unable to set the printer options:\n" -" You must specify a printer name first!\n" -msgstr "" - -#: systemv/lpadmin.c:793 -msgid "" -"Usage:\n" -"\n" -" lpadmin [-h server] -d destination\n" -" lpadmin [-h server] -x destination\n" -" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" -" [-r remove-class] [-v device] [-D description]\n" -" [-P ppd-file] [-o name=value]\n" -" [-u allow:user,user] [-u deny:user,user]\n" -"\n" -msgstr "" - -#: systemv/lpadmin.c:1554 systemv/lpadmin.c:1440 -#, fuzzy, c-format -msgid "lpadmin: Unable to create temporary file: %s\n" -msgstr "Incapable d'assigner la mémoire pour des types de dossier!" - -#: systemv/lpadmin.c:1562 systemv/lpadmin.c:1448 -#, fuzzy, c-format -msgid "lpadmin: Unable to open file \"%s\": %s\n" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: systemv/lpadmin.c:1631 systemv/lpadmin.c:1862 systemv/lpadmin.c:1870 -#, c-format -msgid "lpadmin: add-printer (set model) failed: %s\n" -msgstr "" - -#: systemv/lpadmin.c:1701 systemv/lpadmin.c:1708 -#, c-format -msgid "lpadmin: add-printer (set description) failed: %s\n" -msgstr "" - -#: systemv/lpadmin.c:1784 systemv/lpadmin.c:1792 -#, c-format -msgid "lpadmin: add-printer (set location) failed: %s\n" -msgstr "" - -#: systemv/lpadmin.c:2021 systemv/lpadmin.c:1814 -#, fuzzy, c-format -msgid "lpadmin: Unable to create temporary file - %s\n" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: systemv/lpadmin.c:2031 systemv/lpadmin.c:1824 -#, fuzzy, c-format -msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: systemv/lpadmin.c:2117 systemv/lpadmin.c:2125 -#, c-format -msgid "lpadmin: %s failed: %s\n" -msgstr "" - -#: systemv/lp.c:153 -msgid "lp: Expected destination after -d option!\n" -msgstr "" - -#: systemv/lp.c:184 -msgid "lp: Expected form after -f option!\n" -msgstr "" - -#: systemv/lp.c:202 -msgid "lp: Expected hostname after -h option!\n" -msgstr "" - -#: systemv/lp.c:220 -msgid "lp: Expected job ID after -i option!\n" -msgstr "" - -#: systemv/lp.c:230 -msgid "lp: Error - cannot print files and alter jobs simultaneously!\n" -msgstr "" - -#: systemv/lp.c:242 -msgid "lp: Error - bad job ID!\n" -msgstr "" - -#: systemv/lp.c:264 -msgid "lp: Expected copies after -n option!\n" -msgstr "" - -#: systemv/lp.c:285 -msgid "lp: Expected option string after -o option!\n" -msgstr "" - -#: systemv/lp.c:304 -#, c-format -msgid "lp: Expected priority after -%c option!\n" -msgstr "" - -#: systemv/lp.c:326 -msgid "lp: Priority must be between 1 and 100.\n" -msgstr "" - -#: systemv/lp.c:348 -msgid "lp: Expected title after -t option!\n" -msgstr "" - -#: systemv/lp.c:364 -msgid "lp: Expected mode list after -y option!\n" -msgstr "" - -#: systemv/lp.c:370 -msgid "lp: Warning - mode option ignored!\n" -msgstr "" - -#: systemv/lp.c:383 -msgid "lp: Expected hold name after -H option!\n" -msgstr "" - -#: systemv/lp.c:405 -msgid "lp: Need job ID (-i) before \"-H restart\"!\n" -msgstr "" - -#: systemv/lp.c:427 -msgid "lp: Expected page list after -P option!\n" -msgstr "" - -#: systemv/lp.c:446 -msgid "lp: Expected character set after -S option!\n" -msgstr "" - -#: systemv/lp.c:452 -msgid "lp: Warning - character set option ignored!\n" -msgstr "" - -#: systemv/lp.c:463 -msgid "lp: Expected content type after -T option!\n" -msgstr "" - -#: systemv/lp.c:469 -msgid "lp: Warning - content type option ignored!\n" -msgstr "" - -#: systemv/lp.c:473 -#, fuzzy, c-format -msgid "lp: Unknown option '%c'!\n" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: systemv/lp.c:482 -msgid "" -"lp: Error - cannot print from stdin if files or a job ID are provided!\n" -msgstr "" - -#: systemv/lp.c:497 -#, c-format -msgid "lp: Unable to access \"%s\" - %s\n" -msgstr "" - -#: systemv/lp.c:514 -#, c-format -msgid "lp: Too many files - \"%s\"\n" -msgstr "" - -#: systemv/lp.c:569 -msgid "lp: error - no default destination available.\n" -msgstr "" - -#: systemv/lp.c:572 -msgid "lp: error - scheduler not responding!\n" -msgstr "" - -#: systemv/lp.c:611 -#, fuzzy, c-format -msgid "lp: unable to create temporary file \"%s\" - %s\n" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: systemv/lp.c:620 -#, c-format -msgid "lp: error - unable to write to temporary file \"%s\" - %s\n" -msgstr "" - -#: systemv/lp.c:634 -msgid "lp: stdin is empty, so no job has been sent.\n" -msgstr "" - -#: systemv/lp.c:650 -#, fuzzy, c-format -msgid "lp: unable to print file: %s\n" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: systemv/lp.c:656 systemv/lp.c:653 systemv/lp.c:713 systemv/lp.c:729 -#, c-format -msgid "request id is %s-%d (%d file(s))\n" -msgstr "" - -#: systemv/lp.c:703 systemv/lp.c:713 -#, c-format -msgid "lp: restart-job failed: %s\n" -msgstr "" - -#: systemv/lp.c:769 systemv/lp.c:779 -#, c-format -msgid "lp: set-job-attributes failed: %s\n" -msgstr "" - -#: systemv/lpinfo.c:98 systemv/lpinfo.c:117 -#, c-format -msgid "lpinfo: Unable to connect to server: %s\n" -msgstr "" - -#: systemv/lpinfo.c:152 -#, fuzzy, c-format -msgid "lpinfo: Unknown option '%c'!\n" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: systemv/lpinfo.c:158 -#, fuzzy, c-format -msgid "lpinfo: Unknown argument '%s'!\n" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: systemv/lpinfo.c:225 systemv/lpinfo.c:310 -#, c-format -msgid "lpinfo: cups-get-devices failed: %s\n" -msgstr "" - -#: systemv/lpinfo.c:293 -#, c-format -msgid "" -"Device: uri = %s\n" -" class = %s\n" -" info = %s\n" -" make-and-model = %s\n" -msgstr "" - -#: systemv/lpinfo.c:376 systemv/lpinfo.c:454 -#, c-format -msgid "lpinfo: cups-get-ppds failed: %s\n" -msgstr "" - -#: systemv/lpinfo.c:438 -#, c-format -msgid "" -"Model: name = %s\n" -" natural_language = %s\n" -" make-and-model = %s\n" -msgstr "" - -#: systemv/lpmove.c:114 systemv/lpmove.c:119 -#, fuzzy, c-format -msgid "lpmove: Unknown option '%c'!\n" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: systemv/lpmove.c:133 systemv/lpmove.c:138 -#, fuzzy, c-format -msgid "lpmove: Unknown argument '%s'!\n" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: systemv/lpmove.c:140 -msgid "Usage: lpmove job dest\n" -msgstr "" - -#: systemv/lpmove.c:151 systemv/lpmove.c:156 -#, c-format -msgid "lpmove: Unable to connect to server: %s\n" -msgstr "" - -#: systemv/lpmove.c:225 systemv/lpmove.c:234 -#, c-format -msgid "lpmove: move-job failed: %s\n" -msgstr "" - -#: systemv/lpoptions.c:109 -msgid "lpoptions: Unknown printer or class!\n" -msgstr "" - -#: systemv/lpoptions.c:159 -msgid "lpoptions: No printers!?!\n" -msgstr "" - -#: systemv/lpoptions.c:207 -#, c-format -msgid "lpoptions: Unable to add printer or instance: %s\n" -msgstr "" - -#: systemv/lpoptions.c:411 -#, c-format -msgid "lpoptions: Destination %s has no PPD file!\n" -msgstr "" - -#: systemv/lpoptions.c:420 -#, fuzzy, c-format -msgid "lpoptions: Unable to open PPD file for %s!\n" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: systemv/lpoptions.c:444 -msgid "" -"Usage: lpoptions [-h server] [-E] -d printer\n" -" lpoptions [-h server] [-E] [-p printer] -l\n" -" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" -" lpoptions [-h server] [-E] -x printer\n" -msgstr "" - -#: systemv/lppasswd.c:192 -msgid "lppasswd: Only root can add or delete passwords!\n" -msgstr "" - -#: systemv/lppasswd.c:212 -msgid "Enter old password:" -msgstr "" - -#: systemv/lppasswd.c:218 systemv/lppasswd.c:236 -#, c-format -msgid "lppasswd: Unable to copy password string: %s\n" -msgstr "" - -#: systemv/lppasswd.c:230 -msgid "Enter password:" -msgstr "" - -#: systemv/lppasswd.c:241 -msgid "Enter password again:" -msgstr "" - -#: systemv/lppasswd.c:247 -msgid "lppasswd: Sorry, passwords don't match!\n" -msgstr "" - -#: systemv/lppasswd.c:271 -msgid "" -"lppasswd: Sorry, password rejected.\n" -"Your password must be at least 6 characters long, cannot contain\n" -"your username, and must contain at least one letter and number.\n" -msgstr "" - -#: systemv/lppasswd.c:321 -msgid "lppasswd: Password file busy!\n" -msgstr "" - -#: systemv/lppasswd.c:324 systemv/lppasswd.c:333 systemv/lppasswd.c:351 -#, c-format -msgid "lppasswd: Unable to open password file: %s\n" -msgstr "" - -#: systemv/lppasswd.c:386 systemv/lppasswd.c:399 systemv/lppasswd.c:431 -#, c-format -msgid "lppasswd: Unable to write to password file: %s\n" -msgstr "" - -#: systemv/lppasswd.c:411 -#, c-format -msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" -msgstr "" - -#: systemv/lppasswd.c:421 -msgid "lppasswd: Sorry, password doesn't match!\n" -msgstr "" - -#: systemv/lppasswd.c:454 -msgid "lppasswd: Password file not updated!\n" -msgstr "" - -#: systemv/lppasswd.c:469 -#, c-format -msgid "lppasswd: failed to backup old password file: %s\n" -msgstr "" - -#: systemv/lppasswd.c:482 -#, c-format -msgid "lppasswd: failed to rename password file: %s\n" -msgstr "" - -#: systemv/lppasswd.c:501 systemv/lppasswd.c:500 -msgid "Usage: lppasswd [-g groupname]\n" -msgstr "" - -#: systemv/lppasswd.c:506 systemv/lppasswd.c:503 -msgid "" -"Usage: lppasswd [-g groupname] [username]\n" -" lppasswd [-g groupname] -a [username]\n" -" lppasswd [-g groupname] -x [username]\n" -msgstr "" - -#: cgi-bin/admin.c:125 cgi-bin/admin.c:142 -#, fuzzy -msgid "Start Printer" -msgstr "Imprimeur" - -#: cgi-bin/admin.c:127 cgi-bin/admin.c:144 -#, fuzzy -msgid "Stop Printer" -msgstr "Imprimeur" - -#: cgi-bin/admin.c:129 cgi-bin/admin.c:146 -#, fuzzy -msgid "Start Class" -msgstr "Classe" - -#: cgi-bin/admin.c:131 cgi-bin/admin.c:148 -#, fuzzy -msgid "Stop Class" -msgstr "Classe" - -#: cgi-bin/admin.c:133 cgi-bin/admin.c:150 -msgid "Accept Jobs" -msgstr "" - -#: cgi-bin/admin.c:135 cgi-bin/admin.c:152 -msgid "Reject Jobs" -msgstr "" - -#: cgi-bin/admin.c:137 cgi-bin/admin.c:154 -msgid "Purge Jobs" -msgstr "" - -#: cgi-bin/admin.c:141 cgi-bin/admin.c:158 -msgid "Set As Default" -msgstr "" - -#: cgi-bin/admin.c:168 cgi-bin/admin.c:179 cgi-bin/admin.c:2690 -#: cgi-bin/admin.c:185 cgi-bin/admin.c:196 cgi-bin/admin.c:2734 -msgid "Administration" -msgstr "" - -#: cgi-bin/admin.c:224 cgi-bin/admin.c:241 -msgid "Modify Class" -msgstr "" - -#: cgi-bin/admin.c:224 cgi-bin/admin.c:241 -#, fuzzy -msgid "Add Class" -msgstr "Classe" - -#: cgi-bin/admin.c:385 cgi-bin/admin.c:402 -msgid "" -"The class name may only contain up to 127 printable characters and may not " -"contain spaces, slashes (/), or the pound sign (#)." -msgstr "" - -#: cgi-bin/admin.c:444 cgi-bin/admin.c:462 -msgid "Unable to modify class:" -msgstr "" - -#: cgi-bin/admin.c:445 cgi-bin/admin.c:463 -msgid "Unable to add class:" -msgstr "" - -#: cgi-bin/admin.c:514 cgi-bin/admin.c:532 -#, fuzzy -msgid "Modify Printer" -msgstr "Imprimeur" - -#: cgi-bin/admin.c:514 cgi-bin/admin.c:532 -#, fuzzy -msgid "Add Printer" -msgstr "Imprimeur" - -#: cgi-bin/admin.c:583 cgi-bin/admin.c:602 -msgid "" -"The printer name may only contain up to 127 printable characters and may not " -"contain spaces, slashes (/), or the pound sign (#)." -msgstr "" - -#: cgi-bin/admin.c:900 cgi-bin/admin.c:930 -msgid "Unable to get list of printer drivers:" -msgstr "" - -#: cgi-bin/admin.c:983 cgi-bin/admin.c:1014 -#, fuzzy -msgid "Unable to modify printer:" -msgstr "Incapable de copier le dossier de PPD!" - -#: cgi-bin/admin.c:984 cgi-bin/admin.c:1015 -#, fuzzy -msgid "Unable to add printer:" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: cgi-bin/admin.c:1051 cgi-bin/admin.c:1082 -msgid "Set Printer Options" -msgstr "" - -#: cgi-bin/admin.c:1062 cgi-bin/admin.c:2330 cgi-bin/admin.c:2391 -#: cgi-bin/admin.c:3112 cgi-bin/admin.c:3213 cgi-bin/admin.c:3449 -#: cgi-bin/admin.c:1095 cgi-bin/admin.c:2374 cgi-bin/admin.c:2435 -#: cgi-bin/admin.c:3156 cgi-bin/admin.c:3258 cgi-bin/admin.c:3496 -#, fuzzy -msgid "Missing form variable!" -msgstr "Attributs requis manquants!" - -#: cgi-bin/admin.c:1076 cgi-bin/admin.c:1113 -#, fuzzy -msgid "Unable to get PPD file!" -msgstr "Incapable de copier le dossier de PPD!" - -#: cgi-bin/admin.c:1084 cgi-bin/admin.c:1123 -#, fuzzy -msgid "Unable to open PPD file:" -msgstr "Incapable de copier le dossier de PPD!" - -#: cgi-bin/admin.c:1241 cgi-bin/admin.c:1282 -msgid "Banners" -msgstr "" - -#: cgi-bin/admin.c:1255 cgi-bin/admin.c:1296 -msgid "Starting Banner" -msgstr "" - -#: cgi-bin/admin.c:1262 cgi-bin/admin.c:1303 -msgid "Ending Banner" -msgstr "" - -#: cgi-bin/admin.c:1280 cgi-bin/admin.c:1321 -msgid "Policies" -msgstr "" - -#: cgi-bin/admin.c:1304 cgi-bin/admin.c:1345 -msgid "Error Policy" -msgstr "" - -#: cgi-bin/admin.c:1331 cgi-bin/admin.c:1372 -msgid "Operation Policy" -msgstr "" - -#: cgi-bin/admin.c:1352 cgi-bin/admin.c:1372 cgi-bin/admin.c:1393 -#: cgi-bin/admin.c:1413 -msgid "PS Binary Protocol" -msgstr "" - -#: cgi-bin/admin.c:1358 cgi-bin/admin.c:1399 -#, fuzzy -msgid "None" -msgstr "Non" - -#: cgi-bin/admin.c:1490 cgi-bin/admin.c:1534 -msgid "Unable to set options:" -msgstr "" - -#: cgi-bin/admin.c:1591 cgi-bin/admin.c:1607 cgi-bin/admin.c:1620 -#: cgi-bin/admin.c:2099 cgi-bin/admin.c:2106 cgi-bin/admin.c:1635 -#: cgi-bin/admin.c:1651 cgi-bin/admin.c:1664 cgi-bin/admin.c:2143 -#: cgi-bin/admin.c:2150 -msgid "Change Settings" -msgstr "" - -#: cgi-bin/admin.c:1592 cgi-bin/admin.c:1608 cgi-bin/admin.c:1621 -#: cgi-bin/admin.c:1636 cgi-bin/admin.c:1652 cgi-bin/admin.c:1665 -msgid "Unable to change server settings:" -msgstr "" - -#: cgi-bin/admin.c:2097 cgi-bin/admin.c:2190 cgi-bin/admin.c:2141 -#: cgi-bin/admin.c:2234 -msgid "Unable to upload cupsd.conf file:" -msgstr "" - -#: cgi-bin/admin.c:2134 cgi-bin/admin.c:2146 cgi-bin/admin.c:2193 -#: cgi-bin/admin.c:2200 cgi-bin/admin.c:2232 cgi-bin/admin.c:2244 -#: cgi-bin/admin.c:2267 cgi-bin/admin.c:2178 cgi-bin/admin.c:2190 -#: cgi-bin/admin.c:2237 cgi-bin/admin.c:2276 cgi-bin/admin.c:2288 -#: cgi-bin/admin.c:2311 -msgid "Edit Configuration File" -msgstr "" - -#: cgi-bin/admin.c:2135 cgi-bin/admin.c:2147 cgi-bin/admin.c:2179 -#: cgi-bin/admin.c:2191 -#, fuzzy -msgid "Unable to create temporary file:" -msgstr "Incapable d'assigner la mémoire pour des types de dossier!" - -#: cgi-bin/admin.c:2233 cgi-bin/admin.c:2245 cgi-bin/admin.c:2268 -#: cgi-bin/admin.c:2277 cgi-bin/admin.c:2289 cgi-bin/admin.c:2312 -msgid "Unable to access cupsd.conf file:" -msgstr "" - -#: cgi-bin/admin.c:2247 cgi-bin/admin.c:2291 -msgid "Unable to edit cupsd.conf files larger than 1MB!" -msgstr "" - -#: cgi-bin/admin.c:2316 cgi-bin/admin.c:2360 -msgid "Delete Class" -msgstr "" - -#: cgi-bin/admin.c:2357 cgi-bin/admin.c:2401 -msgid "Unable to delete class:" -msgstr "" - -#: cgi-bin/admin.c:2377 cgi-bin/admin.c:2421 -#, fuzzy -msgid "Delete Printer" -msgstr "Imprimeur" - -#: cgi-bin/admin.c:2418 cgi-bin/admin.c:2462 -#, fuzzy -msgid "Unable to delete printer:" -msgstr "Aucun imprimeur de défaut" - -#: cgi-bin/admin.c:2447 cgi-bin/admin.c:2491 -msgid "Export Printers to Samba" -msgstr "" - -#: cgi-bin/admin.c:2515 cgi-bin/admin.c:2559 -#, fuzzy -msgid "Unable to fork process!" -msgstr "Incapable de copier le manuscrit d'interface - %s!" - -#: cgi-bin/admin.c:2534 cgi-bin/admin.c:2578 -#, fuzzy -msgid "Unable to connect to server!" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: cgi-bin/admin.c:2538 cgi-bin/admin.c:2582 -#, fuzzy -msgid "Unable to get printer attributes!" -msgstr "Incapable de copier le manuscrit d'interface - %s!" - -#: cgi-bin/admin.c:2543 cgi-bin/admin.c:2587 -#, fuzzy -msgid "Unable to convert PPD file!" -msgstr "Incapable de copier le dossier de PPD!" - -#: cgi-bin/admin.c:2547 cgi-bin/admin.c:2591 -#, fuzzy -msgid "Unable to copy Windows 2000 printer driver files!" -msgstr "Incapable de copier le manuscrit d'interface - %s!" - -#: cgi-bin/admin.c:2552 cgi-bin/admin.c:2596 -msgid "Unable to install Windows 2000 printer driver files!" -msgstr "" - -#: cgi-bin/admin.c:2557 cgi-bin/admin.c:2601 -#, fuzzy -msgid "Unable to copy Windows 9x printer driver files!" -msgstr "Incapable de copier le manuscrit d'interface - %s!" - -#: cgi-bin/admin.c:2562 cgi-bin/admin.c:2606 -msgid "Unable to install Windows 9x printer driver files!" -msgstr "" - -#: cgi-bin/admin.c:2567 cgi-bin/admin.c:2611 -msgid "Unable to set Windows printer driver!" -msgstr "" - -#: cgi-bin/admin.c:2572 cgi-bin/admin.c:2616 -msgid "No printer drivers found!" -msgstr "" - -#: cgi-bin/admin.c:2576 cgi-bin/admin.c:2620 -msgid "Unable to execute cupsaddsmb command!" -msgstr "" - -#: cgi-bin/admin.c:2582 cgi-bin/admin.c:2626 -#, c-format -msgid "cupsaddsmb failed with status %d" -msgstr "" - -#: cgi-bin/admin.c:2592 cgi-bin/admin.c:2636 -#, c-format -msgid "cupsaddsmb crashed on signal %d" -msgstr "" - -#: cgi-bin/admin.c:2608 cgi-bin/admin.c:2652 -msgid "A Samba username is required to export printer drivers!" -msgstr "" - -#: cgi-bin/admin.c:2612 cgi-bin/admin.c:2656 -msgid "A Samba password is required to export printer drivers!" -msgstr "" - -#: cgi-bin/admin.c:2704 cgi-bin/admin.c:2748 -#, fuzzy -msgid "Unable to open cupsd.conf file:" -msgstr "Incapable de copier le dossier de PPD!" - -#: cgi-bin/admin.c:3144 cgi-bin/admin.c:3400 cgi-bin/admin.c:3189 -#: cgi-bin/admin.c:3447 -msgid "Unable to change printer:" -msgstr "" - -#: cgi-bin/admin.c:3214 cgi-bin/admin.c:3259 cgi-bin/admin.c:3399 -#: cgi-bin/admin.c:3417 cgi-bin/admin.c:3305 cgi-bin/admin.c:3446 -#: cgi-bin/admin.c:3464 -msgid "Set Allowed Users" -msgstr "" - -#: cgi-bin/admin.c:3262 cgi-bin/admin.c:3308 -#, fuzzy -msgid "Unable to get printer attributes:" -msgstr "Incapable de copier le manuscrit d'interface - %s!" - -#: cgi-bin/admin.c:3450 cgi-bin/admin.c:3488 cgi-bin/admin.c:3506 -#: cgi-bin/admin.c:3497 cgi-bin/admin.c:3536 cgi-bin/admin.c:3554 -msgid "Set Publishing" -msgstr "" - -#: cgi-bin/admin.c:3489 cgi-bin/admin.c:3537 -msgid "Unable to change printer-is-shared attribute:" -msgstr "" - -#: cgi-bin/classes.c:161 cgi-bin/classes.c:208 -#, fuzzy -msgid "Classes" -msgstr "Classe" - -#: cgi-bin/classes.c:355 cgi-bin/classes.c:356 -msgid "Unable to get class list:" -msgstr "" - -#: cgi-bin/classes.c:454 cgi-bin/classes.c:455 -msgid "Unable to get class status:" -msgstr "" - -#: cgi-bin/ipp-var.c:366 cgi-bin/ipp-var.c:419 cgi-bin/ipp-var.c:489 -#: cgi-bin/ipp-var.c:490 -msgid "Move Job" -msgstr "" - -#: cgi-bin/ipp-var.c:367 -#, fuzzy -msgid "Unable to find destination for job!" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: cgi-bin/ipp-var.c:421 cgi-bin/ipp-var.c:491 cgi-bin/ipp-var.c:492 -msgid "Move All Jobs" -msgstr "" - -#: cgi-bin/ipp-var.c:496 cgi-bin/ipp-var.c:497 -msgid "Unable to move job" -msgstr "" - -#: cgi-bin/ipp-var.c:498 cgi-bin/ipp-var.c:499 -msgid "Unable to move jobs" -msgstr "" - -#: cgi-bin/ipp-var.c:603 cgi-bin/ipp-var.c:605 -msgid "Print Test Page" -msgstr "" - -#: cgi-bin/ipp-var.c:606 cgi-bin/ipp-var.c:608 -#, fuzzy -msgid "Unable to print test page:" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: cgi-bin/jobs.c:111 cgi-bin/jobs.c:122 cgi-bin/jobs.c:184 -msgid "Jobs" -msgstr "" - -#: cgi-bin/jobs.c:187 -msgid "Job operation failed:" -msgstr "" - -#: cgi-bin/printers.c:161 cgi-bin/printers.c:208 cgi-bin/printers.c:211 -#, fuzzy -msgid "Printers" -msgstr "Imprimeur" - -#: cgi-bin/printers.c:362 cgi-bin/printers.c:366 -#, fuzzy -msgid "Unable to get printer list:" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: cgi-bin/printers.c:461 cgi-bin/printers.c:468 -#, fuzzy -msgid "Unable to get printer status:" -msgstr "Incapable de copier le manuscrit d'interface - %s!" - -#: cups/ppd.c:319 -msgid "OK" -msgstr "" - -#: cups/ppd.c:320 -#, fuzzy -msgid "Unable to open PPD file" -msgstr "Incapable de copier le dossier de PPD!" - -#: cups/ppd.c:321 -msgid "NULL PPD file pointer" -msgstr "" - -#: cups/ppd.c:322 -msgid "Memory allocation error" -msgstr "" - -#: cups/ppd.c:323 -msgid "Missing PPD-Adobe-4.x header" -msgstr "" - -#: cups/ppd.c:324 -msgid "Missing value string" -msgstr "" - -#: cups/ppd.c:325 -msgid "Internal error" -msgstr "" - -#: cups/ppd.c:326 -msgid "Bad OpenGroup" -msgstr "" - -#: cups/ppd.c:327 -msgid "OpenGroup without a CloseGroup first" -msgstr "" - -#: cups/ppd.c:328 -msgid "Bad OpenUI/JCLOpenUI" -msgstr "" - -#: cups/ppd.c:329 -msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" -msgstr "" - -#: cups/ppd.c:330 -msgid "Bad OrderDependency" -msgstr "" - -#: cups/ppd.c:331 -msgid "Bad UIConstraints" -msgstr "" - -#: cups/ppd.c:332 -msgid "Missing asterisk in column 1" -msgstr "" - -#: cups/ppd.c:333 -msgid "Line longer than the maximum allowed (255 characters)" -msgstr "" - -#: cups/ppd.c:334 -msgid "Illegal control character" -msgstr "" - -#: cups/ppd.c:335 -msgid "Illegal main keyword string" -msgstr "" - -#: cups/ppd.c:336 -msgid "Illegal option keyword string" -msgstr "" - -#: cups/ppd.c:337 -msgid "Illegal translation string" -msgstr "" - -#: cups/ppd.c:338 -msgid "Illegal whitespace character" -msgstr "" - -#: cups/ppd.c:339 -msgid "Bad custom parameter" -msgstr "" - -#: cups/ppd.c:344 -msgid "Unknown" -msgstr "" - -#: cups/ppd.c:1033 -#, fuzzy -msgid "Custom" -msgstr "Automobile" - -#: cups/ppd.c:1259 -msgid "JCL" -msgstr "" - -#: scheduler/ipp.c:2184 scheduler/ipp.c:2226 -msgid "No authentication information provided!" -msgstr "" - -#: systemv/cupsaddsmb.c:440 -#, c-format -msgid "Password for %s required to access %s via SAMBA: " -msgstr "" - -#: systemv/cupsaddsmb.c:451 -#, c-format -msgid "Running command: %s %s -N -U '%s%%%s' -c '%s'\n" -msgstr "" - -#: systemv/cupsaddsmb.c:479 -#, fuzzy, c-format -msgid "cupsaddsmb: Unable to run \"%s\": %s\n" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: systemv/cupsaddsmb.c:805 -msgid "cupsaddsmb: No Windows printer drivers are installed!\n" -msgstr "" - -#: systemv/cupsaddsmb.c:810 -msgid "cupsaddsmb: Warning, no Windows 2000 printer drivers are installed!\n" -msgstr "" - -#: systemv/lpadmin.c:881 -#, c-format -msgid "lpadmin: Printer %s is already a member of class %s.\n" -msgstr "" - -#: systemv/lpadmin.c:1115 -msgid "lpadmin: No member names were seen!\n" -msgstr "" - -#: systemv/lpadmin.c:1129 -#, c-format -msgid "lpadmin: Printer %s is not a member of class %s.\n" -msgstr "" - -#: systemv/lpinfo.c:278 -#, c-format -msgid "" -"Device: uri = %s\n" -" class = %s\n" -" info = %s\n" -" make-and-model = %s\n" -" device-id = %s\n" -msgstr "" - -#: systemv/lpinfo.c:410 -#, c-format -msgid "" -"Model: name = %s\n" -" natural_language = %s\n" -" make-and-model = %s\n" -" device-id = %s\n" -msgstr "" - -#: systemv/lpmove.c:145 -msgid "Usage: lpmove job/src dest\n" -msgstr "" - -#: systemv/lpstat.c:144 systemv/lpstat.c:156 -msgid "lpstat: Need \"completed\", \"not-completed\", or \"all\" after -W!\n" -msgstr "" - -#: systemv/lpstat.c:740 systemv/lpstat.c:768 -#, c-format -msgid "%s accepting requests since %s\n" -msgstr "" - -#: systemv/lpstat.c:743 systemv/lpstat.c:771 -#, c-format -msgid "" -"%s not accepting requests since %s -\n" -"\t%s\n" -msgstr "" - -#: systemv/lpstat.c:752 systemv/lpstat.c:780 -#, c-format -msgid "%s/%s accepting requests since %s\n" -msgstr "" - -#: systemv/lpstat.c:755 systemv/lpstat.c:783 -#, c-format -msgid "" -"%s/%s not accepting requests since %s -\n" -"\t%s\n" -msgstr "" - -#: berkeley/lpc.c:88 berkeley/lpc.c:116 berkeley/lpc.c:152 -msgid "lpc> " -msgstr "" - -#: berkeley/lpq.c:93 systemv/cancel.c:250 systemv/cancel.c:332 -#: systemv/cancel.c:331 -#, fuzzy, c-format -msgid "%s: Unable to contact server!\n" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: berkeley/lpq.c:138 berkeley/lpr.c:128 berkeley/lprm.c:144 -#: systemv/accept.c:120 systemv/cancel.c:107 systemv/lp.c:150 -#: systemv/lpstat.c:144 berkeley/lpr.c:130 systemv/lp.c:154 -#, c-format -msgid "%s: Error - expected username after '-U' option!\n" -msgstr "" - -#: berkeley/lpq.c:173 -#, fuzzy, c-format -msgid "%s: Error - unknown destination \"%s/%s\"!\n" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: berkeley/lpq.c:177 systemv/lpstat.c:549 -#, fuzzy, c-format -msgid "%s: Unknown destination \"%s\"!\n" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: berkeley/lpq.c:201 berkeley/lprm.c:167 systemv/accept.c:146 -#: systemv/cancel.c:135 systemv/lp.c:227 systemv/lpstat.c:300 systemv/lp.c:231 -#, c-format -msgid "%s: Error - expected hostname after '-h' option!\n" -msgstr "" - -#: berkeley/lpq.c:253 -#, c-format -msgid "" -"%s: error - %s environment variable names non-existent destination \"%s\"!\n" -msgstr "" - -#: berkeley/lpq.c:258 -#, c-format -msgid "%s: error - no default destination available.\n" -msgstr "" - -#: berkeley/lpq.c:647 -msgid "" -"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" -msgstr "" - -#: berkeley/lpr.c:148 berkeley/lpr.c:150 -#, c-format -msgid "%s: Error - expected hostname after '-H' option!\n" -msgstr "" - -#: berkeley/lpr.c:171 berkeley/lpr.c:173 -#, c-format -msgid "%s: Error - expected value after '-%c' option!\n" -msgstr "" - -#: berkeley/lpr.c:185 berkeley/lpr.c:187 -#, c-format -msgid "" -"%s: Warning - '%c' format modifier not supported - output may not be " -"correct!\n" -msgstr "" - -#: berkeley/lpr.c:199 berkeley/lpr.c:201 -#, c-format -msgid "%s: error - expected option=value after '-o' option!\n" -msgstr "" - -#: berkeley/lpr.c:250 berkeley/lpr.c:258 -#, c-format -msgid "%s: Error - expected destination after '-P' option!\n" -msgstr "" - -#: berkeley/lpr.c:285 berkeley/lpr.c:293 -#, c-format -msgid "%s: Error - expected copy count after '-#' option!\n" -msgstr "" - -#: berkeley/lpr.c:309 berkeley/lpr.c:317 -#, c-format -msgid "%s: Error - expected name after '-%c' option!\n" -msgstr "" - -#: berkeley/lpr.c:320 berkeley/lprm.c:179 systemv/accept.c:176 -#: systemv/cancel.c:169 systemv/lp.c:529 systemv/lpstat.c:461 -#: berkeley/lpr.c:328 systemv/lp.c:545 -#, fuzzy, c-format -msgid "%s: Error - unknown option '%c'!\n" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: berkeley/lpr.c:333 systemv/lp.c:554 berkeley/lpr.c:341 systemv/lp.c:570 -#, c-format -msgid "%s: Error - unable to access \"%s\" - %s\n" -msgstr "" - -#: berkeley/lpr.c:351 systemv/lp.c:571 berkeley/lpr.c:359 systemv/lp.c:587 -#, c-format -msgid "%s: Error - too many files - \"%s\"\n" -msgstr "" - -#: berkeley/lpr.c:393 systemv/lp.c:621 berkeley/lpr.c:401 systemv/lp.c:637 -#, c-format -msgid "" -"%s: Error - %s environment variable names non-existent destination \"%s\"!\n" -msgstr "" - -#: berkeley/lpr.c:398 systemv/lp.c:626 berkeley/lpr.c:406 systemv/lp.c:642 -#, c-format -msgid "%s: Error - no default destination available.\n" -msgstr "" - -#: berkeley/lpr.c:402 systemv/lp.c:630 berkeley/lpr.c:410 systemv/lp.c:646 -#, c-format -msgid "%s: Error - scheduler not responding!\n" -msgstr "" - -#: berkeley/lpr.c:452 systemv/lp.c:670 berkeley/lpr.c:460 systemv/lp.c:686 -#, fuzzy, c-format -msgid "%s: Error - unable to create temporary file \"%s\" - %s\n" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: berkeley/lpr.c:462 systemv/lp.c:679 berkeley/lpr.c:470 systemv/lp.c:695 -#, fuzzy, c-format -msgid "%s: Error - unable to write to temporary file \"%s\" - %s\n" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: berkeley/lpr.c:476 systemv/lp.c:693 berkeley/lpr.c:484 systemv/lp.c:709 -#, c-format -msgid "%s: Error - stdin is empty, so no job has been sent.\n" -msgstr "" - -#: berkeley/lprm.c:127 systemv/cancel.c:227 -#, fuzzy, c-format -msgid "%s: Error - unknown destination \"%s\"!\n" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: systemv/accept.c:165 -#, c-format -msgid "%s: Error - expected reason text after '-r' option!\n" -msgstr "" - -#: systemv/cancel.c:157 -#, c-format -msgid "%s: Error - expected username after '-u' option!\n" -msgstr "" - -#: systemv/cancel.c:308 systemv/cancel.c:373 systemv/cancel.c:372 -#, c-format -msgid "%s: %s failed: %s\n" -msgstr "" - -#: systemv/lp.c:173 systemv/lp.c:177 -#, c-format -msgid "%s: Error - expected destination after '-d' option!\n" -msgstr "" - -#: systemv/lp.c:206 systemv/lp.c:210 -#, c-format -msgid "%s: Error - expected form after '-f' option!\n" -msgstr "" - -#: systemv/lp.c:213 systemv/lp.c:217 -#, c-format -msgid "%s: Warning - form option ignored!\n" -msgstr "" - -#: systemv/lp.c:247 systemv/lp.c:251 -#, c-format -msgid "%s: Expected job ID after '-i' option!\n" -msgstr "" - -#: systemv/lp.c:258 systemv/lp.c:262 -#, c-format -msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" -msgstr "" - -#: systemv/lp.c:271 systemv/lp.c:275 -#, c-format -msgid "%s: Error - bad job ID!\n" -msgstr "" - -#: systemv/lp.c:296 systemv/lp.c:308 -#, c-format -msgid "%s: Error - expected copies after '-n' option!\n" -msgstr "" - -#: systemv/lp.c:319 systemv/lp.c:331 -#, c-format -msgid "%s: Error - expected option string after '-o' option!\n" -msgstr "" - -#: systemv/lp.c:340 systemv/lp.c:352 -#, c-format -msgid "%s: Error - expected priority after '-%c' option!\n" -msgstr "" - -#: systemv/lp.c:363 systemv/lp.c:375 -#, c-format -msgid "%s: Error - priority must be between 1 and 100.\n" -msgstr "" - -#: systemv/lp.c:387 systemv/lp.c:399 -#, c-format -msgid "%s: Error - expected title after '-t' option!\n" -msgstr "" - -#: systemv/lp.c:405 systemv/lp.c:417 -#, c-format -msgid "%s: Error - expected mode list after '-y' option!\n" -msgstr "" - -#: systemv/lp.c:413 systemv/lp.c:425 -#, c-format -msgid "%s: Warning - mode option ignored!\n" -msgstr "" - -#: systemv/lp.c:427 systemv/lp.c:439 -#, c-format -msgid "%s: Error - expected hold name after '-H' option!\n" -msgstr "" - -#: systemv/lp.c:451 systemv/lp.c:463 -#, c-format -msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" -msgstr "" - -#: systemv/lp.c:475 systemv/lp.c:487 -#, c-format -msgid "%s: Error - expected page list after '-P' option!\n" -msgstr "" - -#: systemv/lp.c:496 systemv/lp.c:508 -#, c-format -msgid "%s: Error - expected character set after '-S' option!\n" -msgstr "" - -#: systemv/lp.c:504 systemv/lp.c:516 -#, c-format -msgid "%s: Warning - character set option ignored!\n" -msgstr "" - -#: systemv/lp.c:516 systemv/lp.c:528 -#, c-format -msgid "%s: Error - expected content type after '-T' option!\n" -msgstr "" - -#: systemv/lp.c:524 systemv/lp.c:536 -#, c-format -msgid "%s: Warning - content type option ignored!\n" -msgstr "" - -#: systemv/lp.c:538 systemv/lp.c:554 -#, c-format -msgid "" -"%s: Error - cannot print from stdin if files or a job ID are provided!\n" -msgstr "" - -#: systemv/lpstat.c:164 systemv/lpstat.c:178 -#, c-format -msgid "" -"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' " -"option!\n" -msgstr "" - -#: systemv/lpstat.c:237 -#, c-format -msgid "%s: Error - expected destination after '-b' option!\n" -msgstr "" - -#: systemv/lpstat.c:534 -#, c-format -msgid "%s: Invalid destination name in list \"%s\"!\n" -msgstr "" - -#: systemv/lpstat.c:571 -#, fuzzy, c-format -msgid "%s: Unable to connect to server\n" -msgstr "Incapable de copier le dossier de PPD - %s!" - -#: cups/notify.c:91 -msgid "Print Job:" -msgstr "" - -#: cups/notify.c:96 -msgid "pending" -msgstr "" - -#: cups/notify.c:99 -msgid "held" -msgstr "" - -#: cups/notify.c:102 cups/notify.c:143 -msgid "processing" -msgstr "" - -#: cups/notify.c:105 cups/notify.c:146 -msgid "stopped" -msgstr "" - -#: cups/notify.c:108 -msgid "canceled" -msgstr "" - -#: cups/notify.c:111 -msgid "aborted" -msgstr "" - -#: cups/notify.c:114 -msgid "completed" -msgstr "" - -#: cups/notify.c:117 cups/notify.c:149 -msgid "unknown" -msgstr "" - -#: cups/notify.c:126 -msgid "untitled" -msgstr "" - -#: cups/notify.c:135 -#, fuzzy -msgid "Printer:" -msgstr "Imprimeur" - -#: cups/notify.c:140 -msgid "idle" -msgstr "" - -#: scheduler/ipp.c:5513 -#, fuzzy -msgid "Missing notify-subscription-ids attribute!" -msgstr "Attribut absent de requesting-user-name!" - -#: scheduler/ipp.c:7851 -#, fuzzy -msgid "Job subscriptions cannot be renewed!" -msgstr "Aucuns attributs d'abonnement dans la demande!" - -#: scheduler/main.c:163 -msgid "cupsd: Expected config filename after \"-c\" option!\n" -msgstr "" - -#: scheduler/main.c:218 -msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" -msgstr "" - -#: scheduler/main.c:225 -#, fuzzy, c-format -msgid "cupsd: Unknown option \"%c\" - aborting!\n" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: scheduler/main.c:232 -#, fuzzy, c-format -msgid "cupsd: Unknown argument \"%s\" - aborting!\n" -msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!" - -#: scheduler/main.c:2315 -msgid "" -"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" -"\n" -"-c config-file Load alternate configuration file\n" -"-f Run in the foreground\n" -"-F Run in the foreground but detach\n" -"-h Show this usage message\n" -"-l Run cupsd from launchd(8)\n" -msgstr "" - -#: systemv/cupstestppd.c:1343 -#, c-format -msgid " WARN Line %d only contains whitespace!\n" -msgstr "" - -#: systemv/cupstestppd.c:1361 -msgid "" -" WARN File contains a mix of CR, LF, and CR LF line endings!\n" -msgstr "" - -#: systemv/cupstestppd.c:1366 -msgid "" -" WARN Non-Windows PPD files should use lines ending with only LF, " -"not CR LF!\n" -msgstr "" diff --git a/locale/cups_ja.po b/locale/cups_ja.po index b05ac2966..cf0517f09 100644 --- a/locale/cups_ja.po +++ b/locale/cups_ja.po @@ -25,7 +25,7 @@ msgid "" msgstr "" "Project-Id-Version: CUPS 1.2\n" "Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" -"POT-Creation-Date: 2006-02-15 19:50-0500\n" +"POT-Creation-Date: 2006-02-26 20:42-0500\n" "PO-Revision-Date: 2006-02-17 11:17+0900\n" "Last-Translator: Kenshi Muto \n" "Language-Team: Japanese \n" @@ -50,27 +50,32 @@ msgid "Extra" msgstr "補助" #: cups/ppd.c:656 cups/ppd.c:881 cups/ppd.c:1047 cups/ppd.c:662 cups/ppd.c:996 -#: cups/ppd.c:1169 +#: cups/ppd.c:1169 cups/ppd.c:651 cups/ppd.c:983 cups/ppd.c:1148 msgid "General" msgstr "一般" #: cups/ppd.c:704 cups/ppd.c:1105 cups/ppd.c:710 cups/ppd.c:1224 +#: cups/ppd.c:697 cups/ppd.c:1201 msgid "Media Size" msgstr "用紙サイズ" #: cups/ppd.c:706 cups/ppd.c:1107 cups/ppd.c:712 cups/ppd.c:1226 +#: cups/ppd.c:699 cups/ppd.c:1203 msgid "Media Type" msgstr "用紙形式" #: cups/ppd.c:708 cups/ppd.c:1109 cups/ppd.c:714 cups/ppd.c:1228 +#: cups/ppd.c:701 cups/ppd.c:1205 msgid "Media Source" msgstr "給紙" #: cups/ppd.c:710 cups/ppd.c:1111 cups/ppd.c:716 cups/ppd.c:1230 +#: cups/ppd.c:703 cups/ppd.c:1207 msgid "Output Mode" msgstr "出力モード" #: cups/ppd.c:712 cups/ppd.c:1113 cups/ppd.c:718 cups/ppd.c:1232 +#: cups/ppd.c:705 cups/ppd.c:1209 msgid "Resolution" msgstr "解像度" @@ -78,11 +83,11 @@ msgstr "解像度" msgid "Variable" msgstr "可変" -#: cups/ppd.c:1535 cups/ppd.c:1650 +#: cups/ppd.c:1535 cups/ppd.c:1650 cups/ppd.c:1627 msgid "Yes" msgstr "はい" -#: cups/ppd.c:1537 cups/ppd.c:1652 +#: cups/ppd.c:1537 cups/ppd.c:1652 cups/ppd.c:1629 msgid "No" msgstr "いいえ" @@ -91,6 +96,7 @@ msgid "Auto" msgstr "自動" #: scheduler/client.c:2247 scheduler/client.c:2251 scheduler/client.c:2274 +#: scheduler/client.c:2308 msgid "" "Enter your username and password or the root username and password to access " "this page." @@ -99,28 +105,34 @@ msgstr "" "のユーザ名とパスワードを入力してください。" #: scheduler/client.c:2252 scheduler/client.c:2256 scheduler/client.c:2279 +#: scheduler/client.c:2313 msgid "You must use a https: URL to access this page." msgstr "このページにアクセスするためには、https: URL を使う必要があります。" #: scheduler/ipp.c:236 scheduler/ipp.c:244 scheduler/ipp.c:246 +#: scheduler/ipp.c:260 #, c-format msgid "Bad request version number %d.%d!" msgstr "バージョン番号 %d.%d は無効なリクエストです!" #: scheduler/ipp.c:246 scheduler/ipp.c:254 scheduler/ipp.c:256 +#: scheduler/ipp.c:270 msgid "No attributes in request!" msgstr "リクエストに属性がありません!" #: scheduler/ipp.c:269 scheduler/ipp.c:277 scheduler/ipp.c:279 +#: scheduler/ipp.c:293 #, c-format msgid "Attribute groups are out of order (%x < %x)!" msgstr "属性グループは範囲外です (%x < %x)!" #: scheduler/ipp.c:379 scheduler/ipp.c:389 scheduler/ipp.c:391 +#: scheduler/ipp.c:405 msgid "Missing required attributes!" msgstr "必須の属性が設定されていません!" #: scheduler/ipp.c:575 scheduler/ipp.c:585 scheduler/ipp.c:591 +#: scheduler/ipp.c:605 #, c-format msgid "%s not supported!" msgstr "%s はサポートされていません!" @@ -142,11 +154,18 @@ msgstr "%s はサポートされていません!" #: scheduler/ipp.c:5357 scheduler/ipp.c:5769 scheduler/ipp.c:6077 #: scheduler/ipp.c:6368 scheduler/ipp.c:6410 scheduler/ipp.c:6916 #: scheduler/ipp.c:7626 scheduler/ipp.c:8589 scheduler/ipp.c:9003 -#: scheduler/ipp.c:9084 scheduler/ipp.c:9259 +#: scheduler/ipp.c:9084 scheduler/ipp.c:9259 scheduler/ipp.c:716 +#: scheduler/ipp.c:1003 scheduler/ipp.c:1174 scheduler/ipp.c:2812 +#: scheduler/ipp.c:2927 scheduler/ipp.c:4699 scheduler/ipp.c:4942 +#: scheduler/ipp.c:5326 scheduler/ipp.c:5738 scheduler/ipp.c:6046 +#: scheduler/ipp.c:6337 scheduler/ipp.c:6379 scheduler/ipp.c:7116 +#: scheduler/ipp.c:8081 scheduler/ipp.c:8745 scheduler/ipp.c:8826 +#: scheduler/ipp.c:9001 msgid "The printer or class was not found." msgstr "プリンタまたはクラスが見つかりませんでした。" #: scheduler/ipp.c:762 scheduler/ipp.c:777 scheduler/ipp.c:784 +#: scheduler/ipp.c:799 msgid "" "The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." msgstr "" @@ -155,16 +174,19 @@ msgstr "" #: scheduler/ipp.c:778 scheduler/ipp.c:1454 scheduler/ipp.c:793 #: scheduler/ipp.c:1482 scheduler/ipp.c:800 scheduler/ipp.c:1515 +#: scheduler/ipp.c:815 scheduler/ipp.c:2031 #, c-format msgid "The printer-uri \"%s\" contains invalid characters." msgstr "printer-uri \"%s\" には、無効な文字が含まれています。" #: scheduler/ipp.c:811 scheduler/ipp.c:826 scheduler/ipp.c:833 +#: scheduler/ipp.c:848 #, c-format msgid "A printer named \"%s\" already exists!" msgstr "プリンタ名 \"%s\" はすでに存在します!" #: scheduler/ipp.c:904 scheduler/ipp.c:924 scheduler/ipp.c:933 +#: scheduler/ipp.c:944 #, c-format msgid "Attempt to set %s printer-state to bad value %d!" msgstr "%s printer-state に 不正な値 %d を設定しようとしています!" @@ -180,28 +202,33 @@ msgid "add_class: Unknown printer-error-policy \"%s\"." msgstr "add_class: \"%s\" は未知の printer-error-policy です。" #: scheduler/ipp.c:1144 scheduler/ipp.c:1168 scheduler/ipp.c:1200 +#: scheduler/ipp.c:1112 msgid "Unable to allocate memory for file types!" msgstr "ファイルタイプ用にメモリを割り当てられません!" #: scheduler/ipp.c:1290 scheduler/ipp.c:4501 scheduler/ipp.c:1316 #: scheduler/ipp.c:4705 scheduler/ipp.c:1348 scheduler/ipp.c:4804 +#: scheduler/ipp.c:1810 scheduler/ipp.c:4773 #, c-format msgid "Character set \"%s\" not supported!" msgstr "文字セット \"%s\" はサポートされていません!" #: scheduler/ipp.c:1299 scheduler/ipp.c:4510 scheduler/ipp.c:1325 #: scheduler/ipp.c:4714 scheduler/ipp.c:1357 scheduler/ipp.c:4813 +#: scheduler/ipp.c:1819 scheduler/ipp.c:4782 #, c-format msgid "Language \"%s\" not supported!" msgstr "言語 \"%s\" はサポートされていません!" #: scheduler/ipp.c:1309 scheduler/ipp.c:4520 scheduler/ipp.c:1335 #: scheduler/ipp.c:4724 scheduler/ipp.c:1367 scheduler/ipp.c:4823 +#: scheduler/ipp.c:1829 scheduler/ipp.c:4792 #, c-format msgid "The notify-user-data value is too large (%d > 63 octets)!" msgstr "notify-user-data 値が大きすぎます (%d > 63 オクテット)!" #: scheduler/ipp.c:1326 scheduler/ipp.c:1352 scheduler/ipp.c:1384 +#: scheduler/ipp.c:1846 msgid "" "The notify-lease-duration attribute cannot be used with job subscriptions." msgstr "" @@ -209,6 +236,7 @@ msgstr "" "ません。" #: scheduler/ipp.c:1438 scheduler/ipp.c:1466 scheduler/ipp.c:1499 +#: scheduler/ipp.c:2015 msgid "" "The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." msgstr "" @@ -216,11 +244,13 @@ msgstr "" "ん。" #: scheduler/ipp.c:1487 scheduler/ipp.c:1515 scheduler/ipp.c:1548 +#: scheduler/ipp.c:2064 #, c-format msgid "A class named \"%s\" already exists!" msgstr "クラス名 \"%s\" はすでに存在します!" #: scheduler/ipp.c:1575 scheduler/ipp.c:1607 scheduler/ipp.c:1644 +#: scheduler/ipp.c:2157 #, c-format msgid "" "File device URIs have been disabled! To enable, see the FileDevice directive " @@ -230,41 +260,49 @@ msgstr "" "\" の FileDevice ディレクティブを確認してください。" #: scheduler/ipp.c:1595 scheduler/ipp.c:1627 scheduler/ipp.c:1664 +#: scheduler/ipp.c:2177 #, c-format msgid "Bad device-uri \"%s\"!" msgstr "\"%s\" は無効な device-uri です!" #: scheduler/ipp.c:1626 scheduler/ipp.c:1659 scheduler/ipp.c:1698 +#: scheduler/ipp.c:2211 #, c-format msgid "Bad port-monitor \"%s\"!" msgstr "\"%s\" は無効な port-monitor です!" #: scheduler/ipp.c:1669 scheduler/ipp.c:1705 scheduler/ipp.c:1744 +#: scheduler/ipp.c:2257 #, c-format msgid "Bad printer-state value %d!" msgstr "%d は無効な printer-state 値です!" #: scheduler/ipp.c:1762 scheduler/ipp.c:1800 scheduler/ipp.c:1842 +#: scheduler/ipp.c:8585 #, c-format msgid "Unknown printer-op-policy \"%s\"." msgstr "\"%s\" は未知の printer-op-policy です。" #: scheduler/ipp.c:1775 scheduler/ipp.c:1813 scheduler/ipp.c:1855 +#: scheduler/ipp.c:8600 #, c-format msgid "Unknown printer-error-policy \"%s\"." msgstr "\"%s\" は未知の printer-error-policy です。" #: scheduler/ipp.c:1837 scheduler/ipp.c:1875 scheduler/ipp.c:1919 +#: scheduler/ipp.c:2336 #, c-format msgid "Unable to copy interface script - %s!" msgstr "インターフェイススクリプトをコピーできません - %s!" #: scheduler/ipp.c:1862 scheduler/ipp.c:1900 scheduler/ipp.c:1944 +#: scheduler/ipp.c:2361 #, c-format msgid "Unable to copy PPD file - %s!" msgstr " PPD ファイルをコピーできません - %s!" #: scheduler/ipp.c:1915 scheduler/ipp.c:1954 scheduler/ipp.c:2000 +#: scheduler/ipp.c:2417 msgid "Unable to copy PPD file!" msgstr "PPD ファイルをコピーできません!" @@ -276,7 +314,9 @@ msgstr "PPD ファイルをコピーできません!" #: scheduler/ipp.c:7839 scheduler/ipp.c:8334 scheduler/ipp.c:2158 #: scheduler/ipp.c:2451 scheduler/ipp.c:5220 scheduler/ipp.c:6210 #: scheduler/ipp.c:7713 scheduler/ipp.c:7928 scheduler/ipp.c:8167 -#: scheduler/ipp.c:8672 +#: scheduler/ipp.c:8672 scheduler/ipp.c:2613 scheduler/ipp.c:2906 +#: scheduler/ipp.c:5189 scheduler/ipp.c:6179 scheduler/ipp.c:7203 +#: scheduler/ipp.c:7418 scheduler/ipp.c:7657 scheduler/ipp.c:8164 msgid "Got a printer-uri attribute but no job-id!" msgstr "printer-uri 属性を取得しましたが、job-id を取得できませんでした!" @@ -289,6 +329,9 @@ msgstr "printer-uri 属性を取得しましたが、job-id を取得できま #: scheduler/ipp.c:2180 scheduler/ipp.c:2523 scheduler/ipp.c:5243 #: scheduler/ipp.c:6233 scheduler/ipp.c:6456 scheduler/ipp.c:7736 #: scheduler/ipp.c:7951 scheduler/ipp.c:8190 scheduler/ipp.c:8695 +#: scheduler/ipp.c:2635 scheduler/ipp.c:2978 scheduler/ipp.c:5212 +#: scheduler/ipp.c:6202 scheduler/ipp.c:6425 scheduler/ipp.c:7226 +#: scheduler/ipp.c:7441 scheduler/ipp.c:7680 scheduler/ipp.c:8187 #, c-format msgid "Bad job-uri attribute \"%s\"!" msgstr "\"%s\" は無効な job-uri 属性です!" @@ -301,6 +344,7 @@ msgid "Job #%d doesn't exist!" msgstr "ジョブ #%d は存在しません!" #: scheduler/ipp.c:2131 scheduler/ipp.c:2172 scheduler/ipp.c:2214 +#: scheduler/ipp.c:2669 #, c-format msgid "Job #%d is not held for authentication!" msgstr "ジョブ #%d は認証が行われていません!" @@ -313,19 +357,23 @@ msgstr "" "ん!" #: scheduler/ipp.c:2221 scheduler/ipp.c:2264 scheduler/ipp.c:2303 +#: scheduler/ipp.c:2758 msgid "The printer-uri attribute is required!" msgstr "printer-uri 属性は必須です!" #: scheduler/ipp.c:2238 scheduler/ipp.c:2283 scheduler/ipp.c:2322 +#: scheduler/ipp.c:2777 msgid "Missing requesting-user-name attribute!" msgstr "requesting-user-name 属性が設定されていません!" #: scheduler/ipp.c:2277 scheduler/ipp.c:2324 scheduler/ipp.c:2363 +#: scheduler/ipp.c:2818 #, c-format msgid "The printer-uri \"%s\" is not valid." msgstr "printer-uri \"%s\" は有効ではありません。" #: scheduler/ipp.c:2410 scheduler/ipp.c:2460 scheduler/ipp.c:2499 +#: scheduler/ipp.c:2954 #, c-format msgid "No active jobs on %s!" msgstr "%s にはアクティブなジョブはありません!" @@ -338,83 +386,101 @@ msgstr "" "ん!" #: scheduler/ipp.c:2476 scheduler/ipp.c:2527 scheduler/ipp.c:2563 +#: scheduler/ipp.c:3018 #, c-format msgid "Job #%d is already %s - can't cancel." msgstr "ジョブ #%d はすでに %s です - キャンセルできません。" #: scheduler/ipp.c:3720 scheduler/ipp.c:3914 scheduler/ipp.c:4006 +#: scheduler/ipp.c:1190 msgid "The printer or class is not shared!" msgstr "プリンタまたはクラスは共有できません!" #: scheduler/ipp.c:3746 scheduler/ipp.c:6647 scheduler/ipp.c:3940 #: scheduler/ipp.c:6695 scheduler/ipp.c:4032 scheduler/ipp.c:6954 +#: scheduler/ipp.c:1216 #, c-format msgid "Destination \"%s\" is not accepting jobs." msgstr "宛先 \"%s\" はジョブを受け付けていません。" #: scheduler/ipp.c:3759 scheduler/ipp.c:6443 scheduler/ipp.c:3954 #: scheduler/ipp.c:6487 scheduler/ipp.c:4046 scheduler/ipp.c:6739 +#: scheduler/ipp.c:1230 #, c-format msgid "Bad copies value %d." msgstr "%d は不正なコピー値です。" #: scheduler/ipp.c:3775 scheduler/ipp.c:6459 scheduler/ipp.c:3971 #: scheduler/ipp.c:6504 scheduler/ipp.c:4063 scheduler/ipp.c:6756 +#: scheduler/ipp.c:1247 #, c-format msgid "Bad page-ranges values %d-%d." msgstr "%d-%d は不正な page-ranges 値です。" #: scheduler/ipp.c:3795 scheduler/ipp.c:3991 scheduler/ipp.c:4083 +#: scheduler/ipp.c:1267 msgid "Too many active jobs." msgstr "アクティブなジョブが多すぎます。" #: scheduler/ipp.c:3801 scheduler/ipp.c:6668 scheduler/ipp.c:3997 #: scheduler/ipp.c:6716 scheduler/ipp.c:4089 scheduler/ipp.c:6975 +#: scheduler/ipp.c:1273 msgid "Quota limit reached." msgstr "Quota の制限に達しました。" #: scheduler/ipp.c:3824 scheduler/ipp.c:6691 scheduler/ipp.c:4022 #: scheduler/ipp.c:6741 scheduler/ipp.c:4114 scheduler/ipp.c:7000 +#: scheduler/ipp.c:1306 #, c-format msgid "Unable to add job for destination \"%s\"!" msgstr "宛先 \"%s\" にジョブを追加できません!" #: scheduler/ipp.c:4469 scheduler/ipp.c:4673 scheduler/ipp.c:4770 +#: scheduler/ipp.c:4739 msgid "No subscription attributes in request!" msgstr "リクエストにサブスクリプション属性がありません!" #: scheduler/ipp.c:4559 scheduler/ipp.c:4763 scheduler/ipp.c:4869 +#: scheduler/ipp.c:4838 msgid "notify-events not specified!" msgstr "notify-events が指定されていません!" #: scheduler/ipp.c:4577 scheduler/ipp.c:4781 scheduler/ipp.c:4887 +#: scheduler/ipp.c:4856 #, c-format msgid "Job %d not found!" msgstr "ジョブ %d は見つかりません!" #: scheduler/ipp.c:4827 scheduler/ipp.c:4957 scheduler/ipp.c:5075 +#: scheduler/ipp.c:5044 msgid "No default printer" msgstr "デフォルトプリンタはありません" #: scheduler/ipp.c:4930 scheduler/ipp.c:5060 scheduler/ipp.c:5178 +#: scheduler/ipp.c:5147 msgid "cups-deviced failed to execute." msgstr "cups-deviced の実行に失敗しました。" #: scheduler/ipp.c:5393 scheduler/ipp.c:5479 scheduler/ipp.c:5722 +#: scheduler/ipp.c:5691 msgid "cups-driverd failed to execute." msgstr "cups-driverd の実行に失敗しました。" #: scheduler/ipp.c:5571 scheduler/ipp.c:5594 scheduler/ipp.c:5837 +#: scheduler/ipp.c:5806 msgid "No destinations added." msgstr "追加された宛先はありません。" #: scheduler/ipp.c:5794 scheduler/ipp.c:5736 scheduler/ipp.c:2615 #: scheduler/ipp.c:5530 scheduler/ipp.c:5979 scheduler/ipp.c:7840 +#: scheduler/ipp.c:3070 scheduler/ipp.c:5499 scheduler/ipp.c:5948 +#: scheduler/ipp.c:7330 #, c-format msgid "notify-subscription-id %d no good!" msgstr "notify-subscription-id %d は良くありません!" #: scheduler/ipp.c:5878 scheduler/ipp.c:5822 scheduler/ipp.c:6065 +#: scheduler/ipp.c:6034 #, c-format msgid "Job #%s does not exist!" msgstr "ジョブ #%s は存在しません!" @@ -429,12 +495,17 @@ msgstr "ジョブ #%s は存在しません!" #: scheduler/ipp.c:2199 scheduler/ipp.c:2541 scheduler/ipp.c:5261 #: scheduler/ipp.c:6087 scheduler/ipp.c:6251 scheduler/ipp.c:6429 #: scheduler/ipp.c:6474 scheduler/ipp.c:7754 scheduler/ipp.c:7969 -#: scheduler/ipp.c:8208 scheduler/ipp.c:8713 +#: scheduler/ipp.c:8208 scheduler/ipp.c:8713 scheduler/ipp.c:2654 +#: scheduler/ipp.c:2996 scheduler/ipp.c:5230 scheduler/ipp.c:6056 +#: scheduler/ipp.c:6220 scheduler/ipp.c:6398 scheduler/ipp.c:6443 +#: scheduler/ipp.c:7244 scheduler/ipp.c:7459 scheduler/ipp.c:7698 +#: scheduler/ipp.c:8205 #, c-format msgid "Job #%d does not exist!" msgstr "ジョブ #%d は存在しません!" #: scheduler/ipp.c:5969 scheduler/ipp.c:5915 scheduler/ipp.c:6150 +#: scheduler/ipp.c:6119 msgid "No subscriptions found." msgstr "サブスクリプションが見つかりません。" @@ -446,6 +517,7 @@ msgstr "" #: scheduler/ipp.c:6203 scheduler/ipp.c:8315 scheduler/ipp.c:6250 #: scheduler/ipp.c:8390 scheduler/ipp.c:6505 scheduler/ipp.c:8728 +#: scheduler/ipp.c:6474 scheduler/ipp.c:8220 #, c-format msgid "Job #%d is finished and cannot be altered!" msgstr "ジョブ #%d は完了し、変更することはできません!" @@ -458,27 +530,32 @@ msgstr "" "ん!" #: scheduler/ipp.c:6228 scheduler/ipp.c:6098 scheduler/ipp.c:6353 +#: scheduler/ipp.c:6322 msgid "job-printer-uri attribute missing!" msgstr "job-printer-uri 属性がありません!" #: scheduler/ipp.c:6485 scheduler/ipp.c:7847 scheduler/ipp.c:6531 #: scheduler/ipp.c:7913 scheduler/ipp.c:6783 scheduler/ipp.c:8238 +#: scheduler/ipp.c:6703 scheduler/ipp.c:7728 #, c-format msgid "Unsupported compression \"%s\"!" msgstr "\"%s\" はサポートされていない圧縮です!" #: scheduler/ipp.c:6504 scheduler/ipp.c:7866 scheduler/ipp.c:6550 #: scheduler/ipp.c:7932 scheduler/ipp.c:6802 scheduler/ipp.c:8257 +#: scheduler/ipp.c:6722 scheduler/ipp.c:7747 msgid "No file!?!" msgstr "ファイルがありません!?!" #: scheduler/ipp.c:6522 scheduler/ipp.c:6568 scheduler/ipp.c:6820 +#: scheduler/ipp.c:6740 #, c-format msgid "Could not scan type \"%s\"!" msgstr "タイプ \"%s\" を検査できませんでした!" #: scheduler/ipp.c:6574 scheduler/ipp.c:7936 scheduler/ipp.c:6620 #: scheduler/ipp.c:8001 scheduler/ipp.c:6879 scheduler/ipp.c:8332 +#: scheduler/ipp.c:6799 scheduler/ipp.c:7822 #, c-format msgid "Unsupported format '%s/%s'!" msgstr "'%s/%s' はサポートされていない形式です!" @@ -493,6 +570,7 @@ msgid "Too many jobs - %d jobs, max jobs is %d." msgstr "ジョブが多すぎます - %d ジョブ。最大ジョブ数は %d です。" #: scheduler/ipp.c:7448 scheduler/ipp.c:7507 scheduler/ipp.c:7768 +#: scheduler/ipp.c:7258 #, c-format msgid "Job #%d is not held!" msgstr "ジョブ #%d はホールドされていません!" @@ -505,11 +583,13 @@ msgstr "" "せん!" #: scheduler/ipp.c:7592 scheduler/ipp.c:7654 scheduler/ipp.c:7983 +#: scheduler/ipp.c:7473 #, c-format msgid "Job #%d is not complete!" msgstr "ジョブ #%d は完結していません!" #: scheduler/ipp.c:7608 scheduler/ipp.c:7670 scheduler/ipp.c:8001 +#: scheduler/ipp.c:7491 #, c-format msgid "Job #%d cannot be restarted - no files!" msgstr "ジョブ #%d は再起動できません - ファイルがありません!" @@ -530,6 +610,7 @@ msgstr "" #: scheduler/ipp.c:7883 scheduler/ipp.c:8803 scheduler/ipp.c:7949 #: scheduler/ipp.c:8883 scheduler/ipp.c:8274 scheduler/ipp.c:9225 +#: scheduler/ipp.c:7764 scheduler/ipp.c:8967 #, c-format msgid "Bad document-format \"%s\"!" msgstr "\"%s\" は不正な document-format です!" @@ -542,34 +623,41 @@ msgstr "" "せん!" #: scheduler/ipp.c:8371 scheduler/ipp.c:8446 scheduler/ipp.c:8783 +#: scheduler/ipp.c:8275 #, c-format msgid "%s cannot be changed." msgstr "%s は変更できません。" #: scheduler/ipp.c:8387 scheduler/ipp.c:8462 scheduler/ipp.c:8799 +#: scheduler/ipp.c:8291 msgid "Bad job-priority value!" msgstr "不正な job-priority 値です!" #: scheduler/ipp.c:8395 scheduler/ipp.c:8470 scheduler/ipp.c:8807 +#: scheduler/ipp.c:8299 msgid "Job is completed and cannot be changed." msgstr "ジョブは完結し、変更できません。" #: scheduler/ipp.c:8409 scheduler/ipp.c:8484 scheduler/ipp.c:8821 +#: scheduler/ipp.c:8313 msgid "Bad job-state value!" msgstr "不正な job-state 値です!" #: scheduler/ipp.c:8423 scheduler/ipp.c:8435 scheduler/ipp.c:8446 #: scheduler/ipp.c:8498 scheduler/ipp.c:8510 scheduler/ipp.c:8521 #: scheduler/ipp.c:8835 scheduler/ipp.c:8850 scheduler/ipp.c:8861 +#: scheduler/ipp.c:8327 scheduler/ipp.c:8342 scheduler/ipp.c:8353 msgid "Job state cannot be changed." msgstr "ジョブの状態を変更できません。" #: scheduler/ipp.c:8787 scheduler/ipp.c:8867 scheduler/ipp.c:9209 +#: scheduler/ipp.c:8951 #, c-format msgid "Unsupported compression attribute %s!" msgstr "%s はサポートされていない圧縮属性です!" #: scheduler/ipp.c:8815 scheduler/ipp.c:8894 scheduler/ipp.c:9236 +#: scheduler/ipp.c:8978 #, c-format msgid "Unsupported format \"%s\"!" msgstr "\"%s\" はサポートされていない形式です!" @@ -1091,6 +1179,7 @@ msgstr "" " 適合テスト結果詳細\n" #: systemv/cupstestppd.c:307 systemv/cupstestppd.c:326 +#: systemv/cupstestppd.c:325 #, c-format msgid " WARN %s has no corresponding options!\n" msgstr " 警告 %s は相当するオプションがありません!\n" @@ -1125,11 +1214,30 @@ msgstr " 警告 %s は相当するオプションがありません!\n #: systemv/cupstestppd.c:800 systemv/cupstestppd.c:820 #: systemv/cupstestppd.c:851 systemv/cupstestppd.c:873 #: systemv/cupstestppd.c:921 systemv/cupstestppd.c:950 -#: systemv/cupstestppd.c:971 +#: systemv/cupstestppd.c:971 systemv/cupstestppd.c:343 +#: systemv/cupstestppd.c:361 systemv/cupstestppd.c:376 +#: systemv/cupstestppd.c:412 systemv/cupstestppd.c:440 +#: systemv/cupstestppd.c:460 systemv/cupstestppd.c:482 +#: systemv/cupstestppd.c:502 systemv/cupstestppd.c:522 +#: systemv/cupstestppd.c:542 systemv/cupstestppd.c:560 +#: systemv/cupstestppd.c:578 systemv/cupstestppd.c:599 +#: systemv/cupstestppd.c:618 systemv/cupstestppd.c:638 +#: systemv/cupstestppd.c:658 systemv/cupstestppd.c:678 +#: systemv/cupstestppd.c:698 systemv/cupstestppd.c:716 +#: systemv/cupstestppd.c:733 systemv/cupstestppd.c:755 +#: systemv/cupstestppd.c:773 systemv/cupstestppd.c:790 +#: systemv/cupstestppd.c:808 systemv/cupstestppd.c:824 +#: systemv/cupstestppd.c:844 systemv/cupstestppd.c:875 +#: systemv/cupstestppd.c:897 systemv/cupstestppd.c:945 +#: systemv/cupstestppd.c:974 systemv/cupstestppd.c:995 +#: systemv/cupstestppd.c:1050 systemv/cupstestppd.c:1075 +#: systemv/cupstestppd.c:1095 systemv/cupstestppd.c:1116 +#: systemv/cupstestppd.c:1138 systemv/cupstestppd.c:1172 msgid " FAIL\n" msgstr " 失敗\n" #: systemv/cupstestppd.c:321 systemv/cupstestppd.c:340 +#: systemv/cupstestppd.c:364 msgid "" " **FAIL** REQUIRED DefaultImageableArea\n" " REF: Page 102, section 5.15.\n" @@ -1138,6 +1246,7 @@ msgstr "" " REF: 102 ページ、セクション 5.15。\n" #: systemv/cupstestppd.c:336 systemv/cupstestppd.c:355 +#: systemv/cupstestppd.c:379 #, c-format msgid "" " **FAIL** BAD DefaultImageableArea %s!\n" @@ -1147,10 +1256,12 @@ msgstr "" " REF: 102 ページ、セクション 5.15。\n" #: systemv/cupstestppd.c:346 systemv/cupstestppd.c:365 +#: systemv/cupstestppd.c:389 msgid " PASS DefaultImageableArea\n" msgstr " 合格 DefaultImageableArea\n" #: systemv/cupstestppd.c:357 systemv/cupstestppd.c:376 +#: systemv/cupstestppd.c:400 msgid "" " **FAIL** REQUIRED DefaultPaperDimension\n" " REF: Page 103, section 5.15.\n" @@ -1159,6 +1270,7 @@ msgstr "" " REF: 103 ページ、セクション 5.15。\n" #: systemv/cupstestppd.c:372 systemv/cupstestppd.c:391 +#: systemv/cupstestppd.c:415 #, c-format msgid "" " **FAIL** BAD DefaultPaperDimension %s!\n" @@ -1168,10 +1280,12 @@ msgstr "" " REF: 103 ページ、セクション 5.15。\n" #: systemv/cupstestppd.c:380 systemv/cupstestppd.c:399 +#: systemv/cupstestppd.c:423 msgid " PASS DefaultPaperDimension\n" msgstr " 合格 DefaultPaperDimension\n" #: systemv/cupstestppd.c:400 systemv/cupstestppd.c:419 +#: systemv/cupstestppd.c:443 #, c-format msgid "" " **FAIL** BAD Default%s %s\n" @@ -1181,11 +1295,13 @@ msgstr "" " REF: 40 ページ、セクション 4.5。\n" #: systemv/cupstestppd.c:409 systemv/cupstestppd.c:428 +#: systemv/cupstestppd.c:452 #, c-format msgid " PASS Default%s\n" msgstr " 合格 Default%s\n" #: systemv/cupstestppd.c:420 systemv/cupstestppd.c:439 +#: systemv/cupstestppd.c:463 #, c-format msgid "" " **FAIL** REQUIRED Default%s\n" @@ -1195,10 +1311,12 @@ msgstr "" " REF: 40 ページ、セクション 4.5。\n" #: systemv/cupstestppd.c:432 systemv/cupstestppd.c:451 +#: systemv/cupstestppd.c:475 msgid " PASS FileVersion\n" msgstr " 合格 FileVersion\n" #: systemv/cupstestppd.c:442 systemv/cupstestppd.c:461 +#: systemv/cupstestppd.c:485 msgid "" " **FAIL** REQUIRED FileVersion\n" " REF: Page 56, section 5.3.\n" @@ -1207,10 +1325,12 @@ msgstr "" " REF: 56 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:452 systemv/cupstestppd.c:471 +#: systemv/cupstestppd.c:495 msgid " PASS FormatVersion\n" msgstr " 合格 FormatVersion\n" #: systemv/cupstestppd.c:462 systemv/cupstestppd.c:481 +#: systemv/cupstestppd.c:505 msgid "" " **FAIL** REQUIRED FormatVersion\n" " REF: Page 56, section 5.3.\n" @@ -1219,10 +1339,12 @@ msgstr "" " REF: 56 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:472 systemv/cupstestppd.c:491 +#: systemv/cupstestppd.c:515 msgid " PASS LanguageEncoding\n" msgstr " 合格 LanguageEncoding\n" #: systemv/cupstestppd.c:482 systemv/cupstestppd.c:501 +#: systemv/cupstestppd.c:525 msgid "" " **FAIL** REQUIRED LanguageEncoding\n" " REF: Pages 56-57, section 5.3.\n" @@ -1231,10 +1353,12 @@ msgstr "" " REF: 56-57 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:492 systemv/cupstestppd.c:511 +#: systemv/cupstestppd.c:535 msgid " PASS LanguageVersion\n" msgstr " 合格 LanguageVersion\n" #: systemv/cupstestppd.c:502 systemv/cupstestppd.c:521 +#: systemv/cupstestppd.c:545 msgid "" " **FAIL** REQUIRED LanguageVersion\n" " REF: Pages 57-58, section 5.3.\n" @@ -1243,6 +1367,7 @@ msgstr "" " REF: 57-58 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:520 systemv/cupstestppd.c:539 +#: systemv/cupstestppd.c:563 msgid "" " **FAIL** BAD Manufacturer (should be \"HP\")\n" " REF: Page 211, table D.1.\n" @@ -1251,10 +1376,12 @@ msgstr "" " REF: 211 ページ、表 D.1。\n" #: systemv/cupstestppd.c:528 systemv/cupstestppd.c:547 +#: systemv/cupstestppd.c:571 msgid " PASS Manufacturer\n" msgstr " 合格 Manufacturer\n" #: systemv/cupstestppd.c:538 systemv/cupstestppd.c:557 +#: systemv/cupstestppd.c:581 msgid "" " **FAIL** REQUIRED Manufacturer\n" " REF: Pages 58-59, section 5.3.\n" @@ -1263,6 +1390,7 @@ msgstr "" " REF: 58-59 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:559 systemv/cupstestppd.c:578 +#: systemv/cupstestppd.c:602 #, c-format msgid "" " **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" @@ -1272,10 +1400,12 @@ msgstr "" " REF: 59-60 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:568 systemv/cupstestppd.c:587 +#: systemv/cupstestppd.c:611 msgid " PASS ModelName\n" msgstr " 合格 ModelName\n" #: systemv/cupstestppd.c:578 systemv/cupstestppd.c:597 +#: systemv/cupstestppd.c:621 msgid "" " **FAIL** REQUIRED ModelName\n" " REF: Pages 59-60, section 5.3.\n" @@ -1284,10 +1414,12 @@ msgstr "" " REF: 59-60 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:588 systemv/cupstestppd.c:607 +#: systemv/cupstestppd.c:631 msgid " PASS NickName\n" msgstr " 合格 NickName\n" #: systemv/cupstestppd.c:598 systemv/cupstestppd.c:617 +#: systemv/cupstestppd.c:641 msgid "" " **FAIL** REQUIRED NickName\n" " REF: Page 60, section 5.3.\n" @@ -1296,10 +1428,12 @@ msgstr "" " REF: 60 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:608 systemv/cupstestppd.c:627 +#: systemv/cupstestppd.c:651 msgid " PASS PageSize\n" msgstr " 合格 PageSize\n" #: systemv/cupstestppd.c:618 systemv/cupstestppd.c:637 +#: systemv/cupstestppd.c:661 msgid "" " **FAIL** REQUIRED PageSize\n" " REF: Pages 99-100, section 5.14.\n" @@ -1308,10 +1442,12 @@ msgstr "" " REF: 99-100 ページ、セクション 5.14。\n" #: systemv/cupstestppd.c:628 systemv/cupstestppd.c:647 +#: systemv/cupstestppd.c:671 msgid " PASS PageRegion\n" msgstr " 合格 PageRegion\n" #: systemv/cupstestppd.c:638 systemv/cupstestppd.c:657 +#: systemv/cupstestppd.c:681 msgid "" " **FAIL** REQUIRED PageRegion\n" " REF: Page 100, section 5.14.\n" @@ -1320,10 +1456,12 @@ msgstr "" " REF: 100 ページ、セクション 5.14。\n" #: systemv/cupstestppd.c:648 systemv/cupstestppd.c:667 +#: systemv/cupstestppd.c:691 msgid " PASS PCFileName\n" msgstr " 合格 PCFileName\n" #: systemv/cupstestppd.c:658 systemv/cupstestppd.c:677 +#: systemv/cupstestppd.c:701 msgid "" " **FAIL** REQUIRED PCFileName\n" " REF: Pages 61-62, section 5.3.\n" @@ -1332,6 +1470,7 @@ msgstr "" " REF: 61-62 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:676 systemv/cupstestppd.c:695 +#: systemv/cupstestppd.c:719 msgid "" " **FAIL** BAD Product - not \"(string)\".\n" " REF: Page 62, section 5.3.\n" @@ -1340,10 +1479,12 @@ msgstr "" " REF: 62 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:683 systemv/cupstestppd.c:702 +#: systemv/cupstestppd.c:726 msgid " PASS Product\n" msgstr " 合格 Product\n" #: systemv/cupstestppd.c:693 systemv/cupstestppd.c:712 +#: systemv/cupstestppd.c:736 msgid "" " **FAIL** REQUIRED Product\n" " REF: Page 62, section 5.3.\n" @@ -1352,6 +1493,7 @@ msgstr "" " REF: 62 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:715 systemv/cupstestppd.c:734 +#: systemv/cupstestppd.c:758 msgid "" " **FAIL** BAD PSVersion - not \"(string) int\".\n" " REF: Pages 62-64, section 5.3.\n" @@ -1360,10 +1502,12 @@ msgstr "" " REF: 62-64 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:723 systemv/cupstestppd.c:742 +#: systemv/cupstestppd.c:766 msgid " PASS PSVersion\n" msgstr " 合格 PSVersion\n" #: systemv/cupstestppd.c:733 systemv/cupstestppd.c:752 +#: systemv/cupstestppd.c:776 msgid "" " **FAIL** REQUIRED PSVersion\n" " REF: Pages 62-64, section 5.3.\n" @@ -1372,6 +1516,7 @@ msgstr "" " REF: 62-64 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:750 systemv/cupstestppd.c:769 +#: systemv/cupstestppd.c:793 msgid "" " **FAIL** BAD ShortNickName - longer than 31 chars.\n" " REF: Pages 64-65, section 5.3.\n" @@ -1380,10 +1525,12 @@ msgstr "" " REF: 64-65 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:758 systemv/cupstestppd.c:777 +#: systemv/cupstestppd.c:801 msgid " PASS ShortNickName\n" msgstr " 合格 ShortNickName\n" #: systemv/cupstestppd.c:768 systemv/cupstestppd.c:787 +#: systemv/cupstestppd.c:811 msgid "" " **FAIL** REQUIRED ShortNickName\n" " REF: Page 64-65, section 5.3.\n" @@ -1392,6 +1539,7 @@ msgstr "" " REF: 64-65 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:784 systemv/cupstestppd.c:803 +#: systemv/cupstestppd.c:827 msgid "" " **FAIL** BAD JobPatchFile attribute in file\n" " REF: Page 24, section 3.4.\n" @@ -1400,6 +1548,7 @@ msgstr "" " REF: 24 ページ、セクション 3.4。\n" #: systemv/cupstestppd.c:804 systemv/cupstestppd.c:823 +#: systemv/cupstestppd.c:847 msgid "" " **FAIL** REQUIRED PageSize\n" " REF: Page 41, section 5.\n" @@ -1410,6 +1559,7 @@ msgstr "" " REF: 99 ページ、セクション 5.14。\n" #: systemv/cupstestppd.c:835 systemv/cupstestppd.c:854 +#: systemv/cupstestppd.c:878 #, c-format msgid "" " **FAIL** REQUIRED ImageableArea for PageSize %s\n" @@ -1421,6 +1571,7 @@ msgstr "" " REF: 102 ページ、セクション 5.15。\n" #: systemv/cupstestppd.c:857 systemv/cupstestppd.c:876 +#: systemv/cupstestppd.c:900 #, c-format msgid "" " **FAIL** REQUIRED PaperDimension for PageSize %s\n" @@ -1432,6 +1583,7 @@ msgstr "" " REF: 103 ページ、セクション 5.15。\n" #: systemv/cupstestppd.c:905 systemv/cupstestppd.c:924 +#: systemv/cupstestppd.c:948 #, c-format msgid "" " **FAIL** Bad %s choice %s!\n" @@ -1441,6 +1593,7 @@ msgstr "" " REF: 84 ページ、セクション 5.9\n" #: systemv/cupstestppd.c:934 systemv/cupstestppd.c:953 +#: systemv/cupstestppd.c:977 #, c-format msgid "" " **FAIL** REQUIRED %s does not define choice None!\n" @@ -1450,6 +1603,7 @@ msgstr "" " REF: 122 ページ、セクション 5.17\n" #: systemv/cupstestppd.c:955 systemv/cupstestppd.c:974 +#: systemv/cupstestppd.c:998 #, c-format msgid "" " **FAIL** Bad %s choice %s!\n" @@ -1459,10 +1613,12 @@ msgstr "" " REF: 122 ページ、セクション 5.17\n" #: systemv/cupstestppd.c:967 systemv/cupstestppd.c:986 +#: systemv/cupstestppd.c:1186 msgid " PASS\n" msgstr " 合格\n" #: systemv/cupstestppd.c:976 systemv/cupstestppd.c:997 +#: systemv/cupstestppd.c:1197 #, c-format msgid "" " WARN Duplex option keyword %s should be named Duplex or " @@ -1474,10 +1630,12 @@ msgstr "" " REF: 122 ページ、セクション 5.17\n" #: systemv/cupstestppd.c:986 systemv/cupstestppd.c:1007 +#: systemv/cupstestppd.c:1207 msgid " WARN Default choices conflicting!\n" msgstr " 警告 デフォルトの選択肢が衝突しています!\n" #: systemv/cupstestppd.c:994 systemv/cupstestppd.c:1015 +#: systemv/cupstestppd.c:1215 #, c-format msgid "" " WARN Obsolete PPD version %.1f!\n" @@ -1487,6 +1645,7 @@ msgstr "" " REF: 42 ページ、セクション 5.2。\n" #: systemv/cupstestppd.c:1002 systemv/cupstestppd.c:1023 +#: systemv/cupstestppd.c:1223 msgid "" " WARN LanguageEncoding required by PPD 4.3 spec.\n" " REF: Pages 56-57, section 5.3.\n" @@ -1495,6 +1654,7 @@ msgstr "" " REF: 56-57 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:1010 systemv/cupstestppd.c:1031 +#: systemv/cupstestppd.c:1231 msgid "" " WARN Manufacturer required by PPD 4.3 spec.\n" " REF: Pages 58-59, section 5.3.\n" @@ -1503,6 +1663,7 @@ msgstr "" " REF: 58-59 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:1023 systemv/cupstestppd.c:1044 +#: systemv/cupstestppd.c:1244 msgid "" " WARN PCFileName longer than 8.3 in violation of PPD spec.\n" " REF: Pages 61-62, section 5.3.\n" @@ -1511,6 +1672,7 @@ msgstr "" " REF: 61-62 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:1031 systemv/cupstestppd.c:1052 +#: systemv/cupstestppd.c:1252 msgid "" " WARN ShortNickName required by PPD 4.3 spec.\n" " REF: Pages 64-65, section 5.3.\n" @@ -1519,6 +1681,7 @@ msgstr "" " REF: 64-65 ページ、セクション 5.3。\n" #: systemv/cupstestppd.c:1048 systemv/cupstestppd.c:1069 +#: systemv/cupstestppd.c:1269 msgid "" " WARN Protocols contains both PJL and BCP; expected TBCP.\n" " REF: Pages 78-79, section 5.7.\n" @@ -1528,6 +1691,7 @@ msgstr "" " REF: 78-79 ページ、セクション 5.7。\n" #: systemv/cupstestppd.c:1057 systemv/cupstestppd.c:1078 +#: systemv/cupstestppd.c:1278 msgid "" " WARN Protocols contains PJL but JCL attributes are not set.\n" " REF: Pages 78-79, section 5.7.\n" @@ -1537,6 +1701,7 @@ msgstr "" " REF: 78-79 ページ、セクション 5.7。\n" #: systemv/cupstestppd.c:1085 systemv/cupstestppd.c:1106 +#: systemv/cupstestppd.c:1306 #, c-format msgid "" " WARN %s shares a common prefix with %s\n" @@ -1546,15 +1711,18 @@ msgstr "" " REF: 15 ページ、セクション 3.2。\n" #: systemv/cupstestppd.c:1097 systemv/cupstestppd.c:1118 +#: systemv/cupstestppd.c:1318 #, c-format msgid " %d ERROR%s FOUND\n" msgstr " %d 個のエラー%s が見つかりました\n" #: systemv/cupstestppd.c:1100 systemv/cupstestppd.c:1121 +#: systemv/cupstestppd.c:1321 msgid " NO ERRORS FOUND\n" msgstr " エラーは見つかりませんでした\n" #: systemv/cupstestppd.c:1360 systemv/cupstestppd.c:1465 +#: systemv/cupstestppd.c:1665 #, c-format msgid "" " WARN \"%s %s\" conflicts with \"%s %s\"\n" @@ -1564,6 +1732,7 @@ msgstr "" " (constraint=\"%s %s %s %s\")\n" #: systemv/cupstestppd.c:1376 systemv/cupstestppd.c:1481 +#: systemv/cupstestppd.c:1681 msgid "" "Usage: cupstestppd [-q] [-r] [-v[v]] filename1.ppd[.gz] [... filenameN.ppd[." "gz]]\n" @@ -2139,12 +2308,12 @@ msgstr "lpadmin: add-printer (説明の設定) に失敗しました: %s\n" msgid "lpadmin: add-printer (set location) failed: %s\n" msgstr "lpadmin: add-printer (場所の設定) に失敗しました: %s\n" -#: systemv/lpadmin.c:2021 systemv/lpadmin.c:1814 +#: systemv/lpadmin.c:2021 systemv/lpadmin.c:1814 systemv/lpadmin.c:1831 #, c-format msgid "lpadmin: Unable to create temporary file - %s\n" msgstr "lpadmin: テンポラリファイルを作成できません - %s\n" -#: systemv/lpadmin.c:2031 systemv/lpadmin.c:1824 +#: systemv/lpadmin.c:2031 systemv/lpadmin.c:1824 systemv/lpadmin.c:1841 #, c-format msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" msgstr "lpadmin: PPD ファイル \"%s\" を開くことができません - %s\n" @@ -2666,7 +2835,7 @@ msgid "Edit Configuration File" msgstr "設定ファイルの編集" #: cgi-bin/admin.c:2135 cgi-bin/admin.c:2147 cgi-bin/admin.c:2179 -#: cgi-bin/admin.c:2191 +#: cgi-bin/admin.c:2191 cgi-bin/printers.c:219 msgid "Unable to create temporary file:" msgstr "テンポラリファイルを作成できません:" @@ -2789,15 +2958,16 @@ msgstr "公開の設定" msgid "Unable to change printer-is-shared attribute:" msgstr "printer-is-shared 属性を変更できません:" -#: cgi-bin/classes.c:161 cgi-bin/classes.c:208 +#: cgi-bin/classes.c:161 cgi-bin/classes.c:208 cgi-bin/classes.c:159 +#: cgi-bin/classes.c:206 msgid "Classes" msgstr "クラス" -#: cgi-bin/classes.c:355 cgi-bin/classes.c:356 +#: cgi-bin/classes.c:355 cgi-bin/classes.c:356 cgi-bin/classes.c:354 msgid "Unable to get class list:" msgstr "クラスリストを取得できません:" -#: cgi-bin/classes.c:454 cgi-bin/classes.c:455 +#: cgi-bin/classes.c:454 cgi-bin/classes.c:455 cgi-bin/classes.c:453 msgid "Unable to get class status:" msgstr "クラスの状態を取得できません:" @@ -2839,114 +3009,115 @@ msgid "Job operation failed:" msgstr "ジョブ操作に失敗しました:" #: cgi-bin/printers.c:161 cgi-bin/printers.c:208 cgi-bin/printers.c:211 +#: cgi-bin/printers.c:166 cgi-bin/printers.c:335 msgid "Printers" msgstr "プリンタ" -#: cgi-bin/printers.c:362 cgi-bin/printers.c:366 +#: cgi-bin/printers.c:362 cgi-bin/printers.c:366 cgi-bin/printers.c:518 msgid "Unable to get printer list:" msgstr "プリンタリストを取得できません:" -#: cgi-bin/printers.c:461 cgi-bin/printers.c:468 +#: cgi-bin/printers.c:461 cgi-bin/printers.c:468 cgi-bin/printers.c:628 msgid "Unable to get printer status:" msgstr "プリンタの状態を取得できません:" -#: cups/ppd.c:319 +#: cups/ppd.c:319 cups/ppd.c:302 msgid "OK" msgstr "OK" -#: cups/ppd.c:320 +#: cups/ppd.c:320 cups/ppd.c:303 msgid "Unable to open PPD file" msgstr "PPD ファイルを開くことができません" -#: cups/ppd.c:321 +#: cups/ppd.c:321 cups/ppd.c:304 msgid "NULL PPD file pointer" msgstr "NULL PPD ファイルポインタ" -#: cups/ppd.c:322 +#: cups/ppd.c:322 cups/ppd.c:305 msgid "Memory allocation error" msgstr "メモリ割り当てエラー" -#: cups/ppd.c:323 +#: cups/ppd.c:323 cups/ppd.c:306 msgid "Missing PPD-Adobe-4.x header" msgstr "PPD-Adobe-4.x ヘッダがありません" -#: cups/ppd.c:324 +#: cups/ppd.c:324 cups/ppd.c:307 msgid "Missing value string" msgstr "値文字列がありません" -#: cups/ppd.c:325 +#: cups/ppd.c:325 cups/ppd.c:308 msgid "Internal error" msgstr "内部エラー" -#: cups/ppd.c:326 +#: cups/ppd.c:326 cups/ppd.c:309 msgid "Bad OpenGroup" msgstr "不正な OpenGroup" -#: cups/ppd.c:327 +#: cups/ppd.c:327 cups/ppd.c:310 msgid "OpenGroup without a CloseGroup first" msgstr "最初の CloseGroup なしの OpenGroup" -#: cups/ppd.c:328 +#: cups/ppd.c:328 cups/ppd.c:311 msgid "Bad OpenUI/JCLOpenUI" msgstr "不正な OpenUI/JCLOpenUI" -#: cups/ppd.c:329 +#: cups/ppd.c:329 cups/ppd.c:312 msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" msgstr "最初の CloseUI/JCLCloseUI なしの OpenUI/JCLOpenUI" -#: cups/ppd.c:330 +#: cups/ppd.c:330 cups/ppd.c:313 msgid "Bad OrderDependency" msgstr "不正な OrderDependency" -#: cups/ppd.c:331 +#: cups/ppd.c:331 cups/ppd.c:314 msgid "Bad UIConstraints" msgstr "不正な UIConstraints" -#: cups/ppd.c:332 +#: cups/ppd.c:332 cups/ppd.c:315 msgid "Missing asterisk in column 1" msgstr "1 列目にアスタリスクがありません" -#: cups/ppd.c:333 +#: cups/ppd.c:333 cups/ppd.c:316 msgid "Line longer than the maximum allowed (255 characters)" msgstr "1 行が最大許可値 (255 文字) を超えています" -#: cups/ppd.c:334 +#: cups/ppd.c:334 cups/ppd.c:317 msgid "Illegal control character" msgstr "不正な制御文字" -#: cups/ppd.c:335 +#: cups/ppd.c:335 cups/ppd.c:318 msgid "Illegal main keyword string" msgstr "不正なメインキーワード文字列" -#: cups/ppd.c:336 +#: cups/ppd.c:336 cups/ppd.c:319 msgid "Illegal option keyword string" msgstr "不正なオプションキーワード文字列" -#: cups/ppd.c:337 +#: cups/ppd.c:337 cups/ppd.c:320 msgid "Illegal translation string" msgstr "不正な翻訳文字列" -#: cups/ppd.c:338 +#: cups/ppd.c:338 cups/ppd.c:321 msgid "Illegal whitespace character" msgstr "不正な空白文字" -#: cups/ppd.c:339 +#: cups/ppd.c:339 cups/ppd.c:322 msgid "Bad custom parameter" msgstr "不正なカスタムパラメータ" -#: cups/ppd.c:344 +#: cups/ppd.c:344 cups/ppd.c:327 msgid "Unknown" msgstr "未知" -#: cups/ppd.c:1033 +#: cups/ppd.c:1033 cups/ppd.c:1020 msgid "Custom" msgstr "カスタム" -#: cups/ppd.c:1259 +#: cups/ppd.c:1259 cups/ppd.c:1236 msgid "JCL" msgstr "JCL" -#: scheduler/ipp.c:2184 scheduler/ipp.c:2226 +#: scheduler/ipp.c:2184 scheduler/ipp.c:2226 scheduler/ipp.c:2681 msgid "No authentication information provided!" msgstr "認証情報が提供されていません!" @@ -3394,11 +3565,11 @@ msgstr "プリンタ:" msgid "idle" msgstr "待機中" -#: scheduler/ipp.c:5513 +#: scheduler/ipp.c:5513 scheduler/ipp.c:5482 msgid "Missing notify-subscription-ids attribute!" msgstr "notify-subscription-ids 属性がありません!" -#: scheduler/ipp.c:7851 +#: scheduler/ipp.c:7851 scheduler/ipp.c:7341 msgid "Job subscriptions cannot be renewed!" msgstr "ジョブサブスクリプションが更新されていません!" @@ -3408,7 +3579,9 @@ msgstr "cupsd: -c オプションのあとには設定ファイル名が必要 #: scheduler/main.c:218 msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" -msgstr "cupsd: launchd(8) サポートがコンパイルされていないので、通常モードで動作します。\n" +msgstr "" +"cupsd: launchd(8) サポートがコンパイルされていないので、通常モードで動作しま" +"す。\n" #: scheduler/main.c:225 #, c-format @@ -3420,7 +3593,7 @@ msgstr "cupsd: \"%c\" は未知のオプションです - 停止します!\n" msgid "cupsd: Unknown argument \"%s\" - aborting!\n" msgstr "cupsd: \"%s\" は未知の引数です - 停止します!\n" -#: scheduler/main.c:2315 +#: scheduler/main.c:2315 scheduler/main.c:2329 msgid "" "Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" "\n" @@ -3438,18 +3611,77 @@ msgstr "" "-h この使用例を表示する\n" "-l launchd(8) から cupsd を実行する\n" -#: systemv/cupstestppd.c:1343 +#: systemv/cupstestppd.c:1343 systemv/cupstestppd.c:1543 #, c-format msgid " WARN Line %d only contains whitespace!\n" msgstr " 警告 %d 行が空白だけです!\n" -#: systemv/cupstestppd.c:1361 +#: systemv/cupstestppd.c:1361 systemv/cupstestppd.c:1561 msgid "" " WARN File contains a mix of CR, LF, and CR LF line endings!\n" -msgstr " 警告 ファイルが CR、LF、CR LF の行末を混在して含んでいます!\n" +msgstr "" +" 警告 ファイルが CR、LF、CR LF の行末を混在して含んでいます!\n" -#: systemv/cupstestppd.c:1366 +#: systemv/cupstestppd.c:1366 systemv/cupstestppd.c:1566 msgid "" " WARN Non-Windows PPD files should use lines ending with only LF, " "not CR LF!\n" -msgstr " 警告 非 Windows PPD ファイルは、CR LF でなく LF のみを行末に使うべきです!\n" +msgstr "" +" 警告 非 Windows PPD ファイルは、CR LF でなく LF のみを行末に使うべ" +"きです!\n" + +#: cgi-bin/printers.c:218 cgi-bin/printers.c:289 +#, fuzzy +msgid "Printer Maintenance" +msgstr "プリンタは共有されていません!" + +#: cgi-bin/printers.c:292 +#, fuzzy +msgid "Unable to send maintenance job:" +msgstr "ジョブを移動できません" + +#: systemv/cupsaddsmb.c:566 +#, fuzzy, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "" +"cupsaddsmb: プリンタ \"%s\" の PPD ファイルがありません - スキップします!\n" + +#: systemv/cupstestppd.c:346 +#, fuzzy, c-format +msgid " **FAIL** %s %s does not exist!\n" +msgstr "ジョブ #%s は存在しません!" + +#: systemv/cupstestppd.c:1053 +#, c-format +msgid " **FAIL** Bad language \"%s\"!\n" +msgstr "" + +#: systemv/cupstestppd.c:1078 +#, c-format +msgid " **FAIL** Missing \"%s\" translation string for option %s!\n" +msgstr "" + +#: systemv/cupstestppd.c:1098 +#, c-format +msgid "" +" **FAIL** Default translation string for option %s contains 8-bit " +"characters!\n" +msgstr "" + +#: systemv/cupstestppd.c:1119 +#, c-format +msgid "" +" **FAIL** Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr "" + +#: systemv/cupstestppd.c:1141 +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr "" + +#: systemv/cupstestppd.c:1175 +#, c-format +msgid " **FAIL** Bad cupsFilter value \"%s\"!\n" +msgstr "" diff --git a/man/Makefile b/man/Makefile index c64f3b666..62e551da8 100644 --- a/man/Makefile +++ b/man/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile 5099 2006-02-13 02:46:10Z mike $" +# "$Id: Makefile 5182 2006-02-26 04:10:27Z mike $" # # Man page makefile for the Common UNIX Printing System (CUPS). # @@ -40,6 +40,7 @@ MAN1 = cancel.$(MAN1EXT) \ lpr.$(MAN1EXT) \ lpstat.$(MAN1EXT) MAN5 = classes.conf.$(MAN5EXT) \ + client.conf.$(MAN5EXT) \ cupsd.conf.$(MAN5EXT) \ mime.convs.$(MAN5EXT) \ mime.types.$(MAN5EXT) \ @@ -154,5 +155,5 @@ mantohtml: mantohtml.o # -# End of "$Id: Makefile 5099 2006-02-13 02:46:10Z mike $". +# End of "$Id: Makefile 5182 2006-02-26 04:10:27Z mike $". # diff --git a/man/client.conf.man.in b/man/client.conf.man.in new file mode 100644 index 000000000..55b4c8e46 --- /dev/null +++ b/man/client.conf.man.in @@ -0,0 +1,58 @@ +.\" +.\" "$Id: client.conf.man.in 5182 2006-02-26 04:10:27Z mike $" +.\" +.\" client.conf man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636 USA +.\" +.\" Voice: (301) 373-9600 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH client.conf 5 "Common UNIX Printing System" "25 February 2006" "Easy Software Products" +.SH NAME +client.conf \- client configuration file for cups +.SH DESCRIPTION +The \fIclient.conf\fR file configures the CUPS client and is +normally located in the \fI@CUPS_SERVERROOT@\fR or \fI~/.cups\fR +directory. Each line in the file can be a configuration +directive, a blank line, or a comment. Comment lines start with +the # character. +.SH DIRECTIVES +The following directives are understood by the client. Consult the +on-line help for detailed descriptions: +.TP 5 +Encryption IfRequested +.TP 5 +Encryption Never +.TP 5 +Encryption Required +.br +Specifies the level of encryption that is required for a particular +location. +.TP 5 +ServerName hostname-or-ip-address[:port] +.TP 5 +ServerName /domain/socket +.br +Specifies the address and optionally the port to use when +connecting to the server +.SH SEE ALSO +http://localhost:631/help +.SH COPYRIGHT +Copyright 2006 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: client.conf.man.in 5182 2006-02-26 04:10:27Z mike $". +.\" diff --git a/man/lpoptions.man b/man/lpoptions.man.in similarity index 92% rename from man/lpoptions.man rename to man/lpoptions.man.in index 08e012bdd..1f6f3f0e0 100644 --- a/man/lpoptions.man +++ b/man/lpoptions.man.in @@ -1,5 +1,5 @@ .\" -.\" "$Id: lpoptions.man 5099 2006-02-13 02:46:10Z mike $" +.\" "$Id: lpoptions.man.in 5182 2006-02-26 04:10:27Z mike $" .\" .\" lpoptions man page for the Common UNIX Printing System (CUPS). .\" @@ -128,11 +128,11 @@ options and instances for \fIall users\fR in the .SH COMPATIBILITY The \fIlpoptions\fR command is unique to CUPS. .SH FILES -~/.lpoptions - user defaults and instances created by non-root +~/.cups/lpoptions - user defaults and instances created by non-root users. .br -/etc/cups/lpoptions - system-wide defaults and instances created -by the root user. +@CUPS_SERVERROOT@/lpoptions - system-wide defaults and instances +created by the root user. .SH SEE ALSO \fIcancel(1)\fR, \fIlp(1)\fR, \fIlpr(1)\fR, .br @@ -140,5 +140,5 @@ http://localhost:631/help .SH COPYRIGHT Copyright 1997-2006 by Easy Software Products, All Rights Reserved. .\" -.\" End of "$Id: lpoptions.man 5099 2006-02-13 02:46:10Z mike $". +.\" End of "$Id: lpoptions.man.in 5182 2006-02-26 04:10:27Z mike $". .\" diff --git a/packaging/cups.list.in b/packaging/cups.list.in index c2721216f..2f19c85ba 100644 --- a/packaging/cups.list.in +++ b/packaging/cups.list.in @@ -1,5 +1,5 @@ # -# "$Id: cups.list.in 5116 2006-02-16 12:52:32Z mike $" +# "$Id: cups.list.in 5193 2006-02-27 20:27:07Z mike $" # # ESP Package Manager (EPM) file list for the Common UNIX Printing # System (CUPS). @@ -294,8 +294,6 @@ d 0755 root $CUPS_GROUP $STATEDIR - d 0511 root $CUPS_PRIMARY_SYSTEM_GROUP $STATEDIR/certs - # Data files -f 0644 root sys $LOCALEDIR/fr/cups_fr.po locale/cups_fr.po - %subpackage ja f 0644 root sys $LOCALEDIR/ja/cups_ja.po locale/cups_ja.po %subpackage @@ -462,5 +460,5 @@ f 0644 root sys $AMANDIR/man$MAN8DIR/cups-lpd.$MAN8EXT man/cups-lpd.$MAN8EXT i 0755 root sys cups init/cups.sh # -# End of "$Id: cups.list.in 5116 2006-02-16 12:52:32Z mike $". +# End of "$Id: cups.list.in 5193 2006-02-27 20:27:07Z mike $". # diff --git a/packaging/cups.spec.in b/packaging/cups.spec.in index da7ca0794..1cdee7751 100644 --- a/packaging/cups.spec.in +++ b/packaging/cups.spec.in @@ -1,5 +1,5 @@ # -# "$Id: cups.spec.in 5146 2006-02-22 14:03:50Z mike $" +# "$Id: cups.spec.in 5193 2006-02-27 20:27:07Z mike $" # # RPM "spec" file for the Common UNIX Printing System (CUPS). # @@ -27,11 +27,14 @@ # Conditional build options (--with name/--without name): # # dbus - Enable/disable DBUS support (default = enable) +# php - Enable/disable PHP support (default = enable) %{!?_with_dbus: %{!?_without_dbus: %define _with_dbus --with-dbus}} %{?_with_dbus: %define _dbus --enable-dbus} %{!?_with_dbus: %define _dbus --disable-dbus} +%{!?_with_php: %{!?_without_php: %define _with_php --with-php}} + Summary: Common UNIX Printing System Name: cups Version: @CUPS_VERSION@ @@ -72,6 +75,13 @@ Summary: Common UNIX Printing System - Japanese support Group: System Environment/Daemons Requires: %{name} = %{epoch}:%{version} +%if %{?_with_php:1}%{!?_with_php:0} +%package php +Summary: Common UNIX Printing System - PHP support +Group: Development/Languages +Requires: %{name}-libs = %{epoch}:%{version} +%endif + %description The Common UNIX Printing System provides a portable printing layer for UNIX® operating systems. It has been developed by Easy Software Products @@ -95,11 +105,17 @@ UNIX The Common UNIX Printing System provides a portable printing layer for UNIX® operating systems. This package provides Japanese support. +%if %{?_with_php:1}%{!?_with_php:0} +%description php +The Common UNIX Printing System provides a portable printing layer for +UNIX® operating systems. This package provides PHP support. +%endif + %prep %setup %build -CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_OPT_FLAGS" ./configure %{_dbus} +CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_OPT_FLAGS" ./configure %{_dbus} %{_without_php} # If we got this far, all prerequisite libraries must be here. make @@ -224,7 +240,6 @@ rm -rf $RPM_BUILD_ROOT /usr/share/doc/cups/help/whatsnew.html %dir /usr/share/doc/cups/images /usr/share/doc/cups/images/* -/usr/share/locale/fr/cups_fr.po %dir /usr/share/man/man1 /usr/share/man/man1/cancel.1.gz @@ -300,6 +315,13 @@ rm -rf $RPM_BUILD_ROOT /usr/share/cups/templates/ja/* /usr/share/locale/ja/cups_ja.po +%if %{?_with_php:1}%{!?_with_php:0} +%files php +# PHP +/usr/lib/php* +%endif + + # -# End of "$Id: cups.spec.in 5146 2006-02-22 14:03:50Z mike $". +# End of "$Id: cups.spec.in 5193 2006-02-27 20:27:07Z mike $". # diff --git a/scheduler/Makefile b/scheduler/Makefile index adbebbf54..de9cecfbb 100644 --- a/scheduler/Makefile +++ b/scheduler/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile 5116 2006-02-16 12:52:32Z mike $" +# "$Id: Makefile 5157 2006-02-23 20:58:57Z mike $" # # Scheduler Makefile for the Common UNIX Printing System (CUPS). # @@ -155,14 +155,15 @@ install: all cupsd: $(CUPSDOBJS) libmime.a ../cups/$(LIBCUPS) echo Linking $@... $(CC) $(LDFLAGS) -o cupsd $(CUPSDOBJS) libmime.a \ - $(LIBZ) $(SSLLIBS) $(LIBSLP) $(PAMLIBS) \ + $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS) \ $(LIBPAPER) $(LIBMALLOC) $(CUPSDLIBS) $(LIBS) cupsd-static: $(CUPSDOBJS) libmime.a ../cups/libcups.a echo Linking $@... $(CC) $(LDFLAGS) -o cupsd-static $(CUPSDOBJS) libmime.a \ - $(LIBZ) $(SSLLIBS) $(LIBSLP) $(PAMLIBS) ../cups/libcups.a \ - $(COMMONLIBS) $(LIBZ) $(LIBPAPER) $(LIBMALLOC) $(CUPSDLIBS) + $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS) \ + ../cups/libcups.a $(COMMONLIBS) $(LIBZ) $(LIBPAPER) \ + $(LIBMALLOC) $(CUPSDLIBS) # @@ -248,5 +249,5 @@ include Dependencies # -# End of "$Id: Makefile 5116 2006-02-16 12:52:32Z mike $". +# End of "$Id: Makefile 5157 2006-02-23 20:58:57Z mike $". # diff --git a/scheduler/auth.c b/scheduler/auth.c index 89011f7db..bee2ad395 100644 --- a/scheduler/auth.c +++ b/scheduler/auth.c @@ -1,5 +1,5 @@ -;/* - * "$Id: auth.c 5083 2006-02-06 02:57:43Z mike $" +/* + * "$Id: auth.c 5197 2006-02-27 21:30:20Z mike $" * * Authorization routines for the Common UNIX Printing System (CUPS). * @@ -116,7 +116,7 @@ typedef struct cupsd_authdata_s /**** Authentication data ****/ */ #if defined(__hpux) && defined(HAVE_LIBPAM) -static cupsd_authdata_t *auth_datat; /* Current client being authenticated */ +static cupsd_authdata_t *auth_data; /* Current client being authenticated */ #endif /* __hpux && HAVE_LIBPAM */ @@ -2156,5 +2156,5 @@ to64(char *s, /* O - Output string */ /* - * End of "$Id: auth.c 5083 2006-02-06 02:57:43Z mike $". + * End of "$Id: auth.c 5197 2006-02-27 21:30:20Z mike $". */ diff --git a/scheduler/classes.c b/scheduler/classes.c index fe36555d8..749a1bda0 100644 --- a/scheduler/classes.c +++ b/scheduler/classes.c @@ -1,5 +1,5 @@ /* - * "$Id: classes.c 5083 2006-02-06 02:57:43Z mike $" + * "$Id: classes.c 5151 2006-02-22 22:43:17Z mike $" * * Printer class routines for the Common UNIX Printing System (CUPS). * @@ -410,6 +410,25 @@ cupsdLoadAllClasses(void) if (value) cupsdSetString(&p->location, value); } + else if (!strcasecmp(line, "Option") && value) + { + /* + * Option name value + */ + + for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++); + + if (!*valueptr) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of classes.conf.", linenum); + else + { + for (; *valueptr && isspace(*valueptr & 255); *valueptr++ = '\0'); + + p->num_options = cupsAddOption(value, valueptr, p->num_options, + &(p->options)); + } + } else if (!strcasecmp(line, "Printer")) { if (!value) @@ -683,6 +702,7 @@ cupsdSaveAllClasses(void) int i; /* Looping var */ time_t curtime; /* Current time */ struct tm *curdate; /* Current date */ + cups_option_t *option; /* Current option */ /* @@ -801,6 +821,11 @@ cupsdSaveAllClasses(void) if (pclass->error_policy) cupsFilePrintf(fp, "ErrorPolicy %s\n", pclass->error_policy); + for (i = pclass->num_options, option = pclass->options; + i > 0; + i --, option ++) + cupsFilePrintf(fp, "Option %s %s\n", option->name, option->value); + cupsFilePuts(fp, "\n"); } @@ -839,5 +864,5 @@ cupsdUpdateImplicitClasses(void) /* - * End of "$Id: classes.c 5083 2006-02-06 02:57:43Z mike $". + * End of "$Id: classes.c 5151 2006-02-22 22:43:17Z mike $". */ diff --git a/scheduler/client.c b/scheduler/client.c index b35ed9ba9..c9ae16f01 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -1,5 +1,5 @@ /* - * "$Id: client.c 5083 2006-02-06 02:57:43Z mike $" + * "$Id: client.c 5200 2006-02-28 00:10:32Z mike $" * * Client routines for the Common UNIX Printing System (CUPS) scheduler. * @@ -515,7 +515,9 @@ cupsdCloseClient(cupsd_client_t *con) /* I - Client to close */ free(conn); # elif defined(HAVE_CDSASSL) - SSLClose((SSLContextRef)con->http.tls); + while (SSLClose((SSLContextRef)con->http.tls) == errSSLWouldBlock) + usleep(1000); + SSLDisposeContext((SSLContextRef)con->http.tls); # endif /* HAVE_LIBSSL */ @@ -755,6 +757,7 @@ cupsdEncryptClient(cupsd_client_t *con) /* I - Client to encrypt */ #elif defined(HAVE_CDSASSL) OSStatus error; /* Error info */ SSLContextRef conn; /* New connection */ + CFArrayRef certificatesArray; /* Array containing certificates */ int allowExpired; /* Allow expired certificates? */ int allowAnyRoot; /* Allow any root certificate? */ @@ -764,10 +767,9 @@ cupsdEncryptClient(cupsd_client_t *con) /* I - Client to encrypt */ allowExpired = 1; allowAnyRoot = 1; - if (!ServerCertificatesArray) - ServerCertificatesArray = get_cdsa_server_certs(); + certificatesArray = get_cdsa_server_certs(); - if (!ServerCertificatesArray) + if (!certificatesArray) { cupsdLogMessage(CUPSD_LOG_ERROR, "EncryptClient: Could not find signing key in keychain " @@ -794,22 +796,23 @@ cupsdEncryptClient(cupsd_client_t *con) /* I - Client to encrypt */ if (!error && allowAnyRoot) error = SSLSetAllowsAnyRoot(conn, true); - if (!error && ServerCertificatesArray) + if (!error) + error = SSLSetCertificate(conn, certificatesArray); + + if (certificatesArray) { - error = SSLSetCertificate(conn, ServerCertificatesArray); + CFRelease(certificatesArray); + certificatesArray = NULL; + } + if (!error) + { /* * Perform SSL/TLS handshake */ - - if (!error) - { - do - { - error = SSLHandshake(conn); - } - while (error == errSSLWouldBlock); - } + + while ((error = SSLHandshake(conn)) == errSSLWouldBlock) + usleep(1000); } if (error) @@ -889,10 +892,7 @@ cupsdIsCGI(cupsd_client_t *con, /* I - Client connection */ filename = strrchr(filename, '/') + 1; /* Filename always absolute */ - if (options) - cupsdSetStringf(&con->options, "%s %s", filename, options); - else - cupsdSetStringf(&con->options, "%s", filename); + cupsdSetString(&con->options, options); cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsCGI: Returning 1 with command=\"%s\" and options=\"%s\"", @@ -910,9 +910,9 @@ cupsdIsCGI(cupsd_client_t *con, /* I - Client connection */ cupsdSetString(&con->command, CUPS_JAVA); if (options) - cupsdSetStringf(&con->options, "java %s %s", filename, options); + cupsdSetStringf(&con->options, "%s %s", filename, options); else - cupsdSetStringf(&con->options, "java %s", filename); + cupsdSetString(&con->options, filename); cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsCGI: Returning 1 with command=\"%s\" and options=\"%s\"", @@ -931,9 +931,9 @@ cupsdIsCGI(cupsd_client_t *con, /* I - Client connection */ cupsdSetString(&con->command, CUPS_PERL); if (options) - cupsdSetStringf(&con->options, "perl %s %s", filename, options); + cupsdSetStringf(&con->options, "%s %s", filename, options); else - cupsdSetStringf(&con->options, "perl %s", filename); + cupsdSetString(&con->options, filename); cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsCGI: Returning 1 with command=\"%s\" and options=\"%s\"", @@ -952,9 +952,9 @@ cupsdIsCGI(cupsd_client_t *con, /* I - Client connection */ cupsdSetString(&con->command, CUPS_PHP); if (options) - cupsdSetStringf(&con->options, "php %s %s", filename, options); + cupsdSetStringf(&con->options, "%s %s", filename, options); else - cupsdSetStringf(&con->options, "php %s", filename); + cupsdSetString(&con->options, filename); cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsCGI: Returning 1 with command=\"%s\" and options=\"%s\"", @@ -973,9 +973,9 @@ cupsdIsCGI(cupsd_client_t *con, /* I - Client connection */ cupsdSetString(&con->command, CUPS_PYTHON); if (options) - cupsdSetStringf(&con->options, "python %s %s", filename, options); + cupsdSetStringf(&con->options, "%s %s", filename, options); else - cupsdSetStringf(&con->options, "python %s", filename); + cupsdSetString(&con->options, filename); cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsCGI: Returning 1 with command=\"%s\" and options=\"%s\"", @@ -1346,11 +1346,6 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ #endif /* HAVE_SSL */ } - if (con->http.expect) - { - /**** TODO: send expected header ****/ - } - if (!cupsdSendHeader(con, HTTP_OK, NULL)) return (cupsdCloseClient(con)); @@ -1401,9 +1396,30 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ return (cupsdCloseClient(con)); } - if (con->http.expect) + if (con->http.expect && + (con->operation == HTTP_POST || con->operation == HTTP_PUT)) { - /**** TODO: send expected header ****/ + if (con->http.expect == HTTP_CONTINUE) + { + /* + * Send 100-continue header... + */ + + if (!cupsdSendHeader(con, HTTP_CONTINUE, NULL)) + return (cupsdCloseClient(con)); + } + else + { + /* + * Send 417-expectation-failed header... + */ + + if (!cupsdSendHeader(con, HTTP_EXPECTATION_FAILED, NULL)) + return (cupsdCloseClient(con)); + + httpPrintf(HTTP(con), "Content-Length: 0\r\n"); + httpPrintf(HTTP(con), "\r\n"); + } } switch (con->http.state) @@ -1447,38 +1463,48 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ cupsdSetStringf(&con->command, "%s/cgi-bin/admin.cgi", ServerBin); - if ((ptr = strchr(con->uri + 6, '?')) != NULL) - cupsdSetStringf(&con->options, "admin%s", ptr); - else - cupsdSetString(&con->options, "admin"); + cupsdSetString(&con->options, strchr(con->uri + 6, '?')); } else if (!strncmp(con->uri, "/printers", 9)) { cupsdSetStringf(&con->command, "%s/cgi-bin/printers.cgi", ServerBin); - cupsdSetString(&con->options, con->uri + 9); + + if (con->uri[9] && con->uri[10]) + cupsdSetString(&con->options, con->uri + 9); + else + cupsdSetString(&con->options, NULL); } else if (!strncmp(con->uri, "/classes", 8)) { cupsdSetStringf(&con->command, "%s/cgi-bin/classes.cgi", ServerBin); - cupsdSetString(&con->options, con->uri + 8); + + if (con->uri[8] && con->uri[9]) + cupsdSetString(&con->options, con->uri + 8); + else + cupsdSetString(&con->options, NULL); } else if (!strncmp(con->uri, "/jobs", 5)) { cupsdSetStringf(&con->command, "%s/cgi-bin/jobs.cgi", ServerBin); - cupsdSetString(&con->options, con->uri + 5); + + if (con->uri[5] && con->uri[6]) + cupsdSetString(&con->options, con->uri + 5); + else + cupsdSetString(&con->options, NULL); } else { cupsdSetStringf(&con->command, "%s/cgi-bin/help.cgi", ServerBin); - cupsdSetString(&con->options, con->uri + 5); - } - if (con->options[0] == '/') - _cups_strcpy(con->options, con->options + 1); + if (con->uri[5] && con->uri[6]) + cupsdSetString(&con->options, con->uri + 5); + else + cupsdSetString(&con->options, NULL); + } if (!cupsdSendCommand(con, con->command, con->options, 0)) { @@ -1623,41 +1649,52 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ cupsdSetStringf(&con->command, "%s/cgi-bin/admin.cgi", ServerBin); - if ((ptr = strchr(con->uri + 6, '?')) != NULL) - cupsdSetStringf(&con->options, "admin%s", ptr); - else - cupsdSetString(&con->options, "admin"); + cupsdSetString(&con->options, strchr(con->uri + 6, '?')); } else if (!strncmp(con->uri, "/printers", 9)) { cupsdSetStringf(&con->command, "%s/cgi-bin/printers.cgi", ServerBin); - cupsdSetString(&con->options, con->uri + 9); + + if (con->uri[9] && con->uri[10]) + cupsdSetString(&con->options, con->uri + 9); + else + cupsdSetString(&con->options, NULL); } else if (!strncmp(con->uri, "/classes", 8)) { cupsdSetStringf(&con->command, "%s/cgi-bin/classes.cgi", ServerBin); - cupsdSetString(&con->options, con->uri + 8); + + if (con->uri[8] && con->uri[9]) + cupsdSetString(&con->options, con->uri + 8); + else + cupsdSetString(&con->options, NULL); } else if (!strncmp(con->uri, "/jobs", 5)) { cupsdSetStringf(&con->command, "%s/cgi-bin/jobs.cgi", ServerBin); - cupsdSetString(&con->options, con->uri + 5); + + if (con->uri[5] && con->uri[6]) + cupsdSetString(&con->options, con->uri + 5); + else + cupsdSetString(&con->options, NULL); } else { cupsdSetStringf(&con->command, "%s/cgi-bin/help.cgi", ServerBin); - cupsdSetString(&con->options, con->uri + 5); - } - if (con->options[0] == '/') - _cups_strcpy(con->options, con->options + 1); + if (con->uri[5] && con->uri[6]) + cupsdSetString(&con->options, con->uri + 5); + else + cupsdSetString(&con->options, NULL); + } cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdReadClient: %d command=\"%s\", options = \"%s\"", + "cupsdReadClient: %d command=\"%s\", " + "options = \"%s\"", con->http.fd, con->command, con->options); if (con->http.version <= HTTP_1_0) @@ -2382,6 +2419,15 @@ cupsdSendHeader(cupsd_client_t *con, /* I - Client to send to */ if (httpPrintf(HTTP(con), "HTTP/%d.%d %d %s\r\n", con->http.version / 100, con->http.version % 100, code, httpStatus(code)) < 0) return (0); + + if (code == HTTP_CONTINUE) + { + if (httpPrintf(HTTP(con), "\r\n") < 0) + return (0); + else + return (1); + } + if (httpPrintf(HTTP(con), "Date: %s\r\n", httpGetDateString(time(NULL))) < 0) return (0); if (ServerHeader) @@ -2792,7 +2838,7 @@ check_if_modified( * To create a self-signed certificate for testing use the certtool. * Executing the following as root will do it: * - * certtool c c v k=CUPS + * certtool c k=/Library/Keychains/System.keychain */ static CFArrayRef /* O - Array of certificates */ @@ -2848,19 +2894,19 @@ get_cdsa_server_certs(void) * to array as well. */ - ca = CFArrayCreate(NULL, (const void **)&identity, 1, NULL); + ca = CFArrayCreate(NULL, (const void **)&identity, 1, &kCFTypeArrayCallBacks); if (ca == nil) cupsdLogMessage(CUPSD_LOG_ERROR, "CFArrayCreate error"); } - /*CFRelease(identity);*/ + CFRelease(identity); } - /*CFRelease(srchRef);*/ + CFRelease(srchRef); } - /*CFRelease(kcRef);*/ + CFRelease(kcRef); } return (ca); @@ -3215,19 +3261,21 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */ { int i; /* Looping var */ int pid; /* Process ID */ - char *commptr; /* Command string pointer */ + char *commptr, /* Command string pointer */ + commch; /* Command string character */ char *uriptr; /* URI string pointer */ int fds[2]; /* Pipe FDs */ int argc; /* Number of arguments */ int envc; /* Number of environment variables */ char argbuf[10240], /* Argument buffer */ *argv[100], /* Argument strings */ - *envp[MAX_ENV + 16]; /* Environment variables */ + *envp[MAX_ENV + 17]; /* Environment variables */ char content_length[1024], /* CONTENT_LENGTH environment variable */ content_type[1024], /* CONTENT_TYPE environment variable */ http_cookie[32768], /* HTTP_COOKIE environment variable */ http_user_agent[1024], /* HTTP_USER_AGENT environment variable */ lang[1024], /* LANG environment variable */ + path_info[1024], /* PATH_INFO environment variable */ *query_string, /* QUERY_STRING env variable */ remote_addr[1024], /* REMOTE_ADDR environment variable */ remote_host[1024], /* REMOTE_HOST environment variable */ @@ -3240,10 +3288,12 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */ /* * Parse a copy of the options string, which is of the form: * - * name argument+argument+argument - * name?argument+argument+argument - * name param=value¶m=value - * name?param=value¶m=value + * argument+argument+argument + * ?argument+argument+argument + * param=value¶m=value + * ?param=value¶m=value + * /name?argument+argument+argument + * /name?param=value¶m=value * * If the string contains an "=" character after the initial name, * then we treat it as a HTTP GET form request and make a copy of @@ -3257,87 +3307,100 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */ "pipe_command: command=\"%s\", options=\"%s\"", command, options); - strlcpy(argbuf, options, sizeof(argbuf)); - - argv[0] = argbuf; + argv[0] = command; query_string = NULL; - for (commptr = argbuf, argc = 1; *commptr != '\0' && argc < 99; commptr ++) + if (options) + strlcpy(argbuf, options, sizeof(argbuf)); + else + argbuf[0] = '\0'; + + if (argbuf[0] == '/') { /* - * Break arguments whenever we see a + or space... + * Found some trailing path information, set PATH_INFO... */ - if (*commptr == ' ' || *commptr == '+' || (*commptr == '?' && argc == 1)) - { - /* - * Terminate the current string and skip trailing whitespace... - */ + if ((commptr = strchr(argbuf, '?')) == NULL) + commptr = argbuf + strlen(argbuf); - *commptr++ = '\0'; + commch = *commptr; + *commptr = '\0'; + snprintf(path_info, sizeof(path_info), "PATH_INFO=%s", argbuf); + *commptr = commch; + } + else + { + commptr = argbuf; + path_info[0] = '\0'; + } - while (*commptr == ' ') - commptr ++; + if (*commptr == '?' && con->operation == HTTP_GET) + { + commptr ++; + cupsdSetStringf(&query_string, "QUERY_STRING=%s", commptr); + } - /* - * If we don't have a blank string, save it as another argument... - */ + argc = 1; - if (*commptr) - { - argv[argc] = commptr; - argc ++; - } - else - break; + if (*commptr) + { + argv[argc ++] = commptr; + for (; *commptr && argc < 99; commptr ++) + { /* - * If we see an "=" in the remaining string, make a copy of it since - * it will be query data... + * Break arguments whenever we see a + or space... */ - if (argc == 2 && strchr(commptr, '=') && con->operation == HTTP_GET) - cupsdSetStringf(&query_string, "QUERY_STRING=%s", commptr); + if (*commptr == ' ' || *commptr == '+') + { + while (*commptr == ' ' || *commptr == '+') + *commptr++ = '\0'; - /* - * Don't skip the first non-blank character... - */ + /* + * If we don't have a blank string, save it as another argument... + */ - commptr --; - } - else if (*commptr == '%' && isxdigit(commptr[1] & 255) && - isxdigit(commptr[2] & 255)) - { - /* - * Convert the %xx notation to the individual character. - */ + if (*commptr) + { + argv[argc] = commptr; + argc ++; + } + else + break; + } + else if (*commptr == '%' && isxdigit(commptr[1] & 255) && + isxdigit(commptr[2] & 255)) + { + /* + * Convert the %xx notation to the individual character. + */ - if (commptr[1] >= '0' && commptr[1] <= '9') - *commptr = (commptr[1] - '0') << 4; - else - *commptr = (tolower(commptr[1]) - 'a' + 10) << 4; + if (commptr[1] >= '0' && commptr[1] <= '9') + *commptr = (commptr[1] - '0') << 4; + else + *commptr = (tolower(commptr[1]) - 'a' + 10) << 4; - if (commptr[2] >= '0' && commptr[2] <= '9') - *commptr |= commptr[2] - '0'; - else - *commptr |= tolower(commptr[2]) - 'a' + 10; + if (commptr[2] >= '0' && commptr[2] <= '9') + *commptr |= commptr[2] - '0'; + else + *commptr |= tolower(commptr[2]) - 'a' + 10; - _cups_strcpy(commptr + 1, commptr + 3); + _cups_strcpy(commptr + 1, commptr + 3); - /* - * Check for a %00 and break if that is the case... - */ + /* + * Check for a %00 and break if that is the case... + */ - if (!*commptr) - break; + if (!*commptr) + break; + } } } argv[argc] = NULL; - if (argv[0][0] == '\0') - argv[0] = strrchr(command, '/') + 1; - /* * Setup the environment variables as needed... */ @@ -3373,6 +3436,9 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */ envp[envc ++] = remote_host; envp[envc ++] = script_name; + if (path_info[0]) + envp[envc ++] = path_info; + if (con->username[0]) { snprintf(remote_user, sizeof(remote_user), "REMOTE_USER=%s", con->username); @@ -3503,5 +3569,5 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */ /* - * End of "$Id: client.c 5083 2006-02-06 02:57:43Z mike $". + * End of "$Id: client.c 5200 2006-02-28 00:10:32Z mike $". */ diff --git a/scheduler/conf.c b/scheduler/conf.c index f76d86c91..cc8c782b4 100644 --- a/scheduler/conf.c +++ b/scheduler/conf.c @@ -1,5 +1,5 @@ /* - * "$Id: conf.c 5116 2006-02-16 12:52:32Z mike $" + * "$Id: conf.c 5167 2006-02-25 02:11:44Z mike $" * * Configuration routines for the Common UNIX Printing System (CUPS). * @@ -89,6 +89,12 @@ static cupsd_var_t variables[] = { "AccessLog", &AccessLog, CUPSD_VARTYPE_STRING }, { "AutoPurgeJobs", &JobAutoPurge, CUPSD_VARTYPE_BOOLEAN }, { "BrowseInterval", &BrowseInterval, CUPSD_VARTYPE_INTEGER }, +#ifdef HAVE_LDAP + { "BrowseLDAPBindDN", &BrowseLDAPBindDN, CUPSD_VARTYPE_STRING }, + { "BrowseLDAPDN", &BrowseLDAPDN, CUPSD_VARTYPE_STRING }, + { "BrowseLDAPPassword", &BrowseLDAPPassword, CUPSD_VARTYPE_STRING }, + { "BrowseLDAPServer", &BrowseLDAPServer, CUPSD_VARTYPE_STRING }, +#endif /* HAVE_LDAP */ { "BrowseLocalOptions", &BrowseLocalOptions, CUPSD_VARTYPE_STRING }, { "BrowsePort", &BrowsePort, CUPSD_VARTYPE_INTEGER }, { "BrowseRemoteOptions", &BrowseRemoteOptions, CUPSD_VARTYPE_STRING }, @@ -216,6 +222,9 @@ cupsdReadConfiguration(void) struct group *group; /* Default group */ char *old_serverroot, /* Old ServerRoot */ *old_requestroot; /* Old RequestRoot */ + const char *tmpdir; /* TMPDIR environment variable */ + struct stat tmpinfo; /* Temporary directory info */ + /* * Save the old root paths... @@ -309,10 +318,7 @@ cupsdReadConfiguration(void) cupsdSetString(&RIPCache, "8m"); - if (getenv("TMPDIR") == NULL) - cupsdSetString(&TempDir, CUPS_REQUESTS "/tmp"); - else - cupsdSetString(&TempDir, getenv("TMPDIR")); + cupsdSetString(&TempDir, NULL); /* * Find the default user... @@ -395,6 +401,13 @@ cupsdReadConfiguration(void) cupsdClearString(&BrowseLocalOptions); cupsdClearString(&BrowseRemoteOptions); +#ifdef HAVE_LDAP + cupsdClearString(&BrowseLDAPBindDN); + cupsdClearString(&BrowseLDAPDN); + cupsdClearString(&BrowseLDAPPassword); + cupsdClearString(&BrowseLDAPServer); +#endif /* HAVE_LDAP */ + JobHistory = DEFAULT_HISTORY; JobFiles = DEFAULT_FILES; JobAutoPurge = 0; @@ -615,6 +628,41 @@ cupsdReadConfiguration(void) check_permissions(ServerRoot, "printers.conf", 0600, RunUser, Group, 0, 0); check_permissions(ServerRoot, "passwd.md5", 0600, User, Group, 0, 0); + /* + * Update TempDir to the default if it hasn't been set already... + */ + + if (!TempDir) + { + if ((tmpdir = getenv("TMPDIR")) != NULL) + { + /* + * TMPDIR is defined, see if it is OK for us to use... + */ + + if (stat(tmpdir, &tmpinfo)) + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to access TMPDIR (%s): %s", + tmpdir, strerror(errno)); + else if (!S_ISDIR(tmpinfo.st_mode)) + cupsdLogMessage(CUPSD_LOG_ERROR, "TMPDIR (%s) is not a directory!", + tmpdir); + else if ((tmpinfo.st_uid != User || !(tmpinfo.st_mode & S_IWUSR)) && + (tmpinfo.st_gid != Group || !(tmpinfo.st_mode & S_IWGRP)) && + !(tmpinfo.st_mode & S_IWOTH)) + cupsdLogMessage(CUPSD_LOG_ERROR, + "TMPDIR (%s) has the wrong permissions!", tmpdir); + else + cupsdSetString(&TempDir, tmpdir); + + if (!TempDir) + cupsdLogMessage(CUPSD_LOG_INFO, "Using default TempDir of %s/tmp...", + RequestRoot); + } + + if (!TempDir) + cupsdSetStringf(&TempDir, "%s/tmp", RequestRoot); + } + /* * Make sure the request and temporary directories have the right * permissions... @@ -3169,5 +3217,5 @@ read_policy(cups_file_t *fp, /* I - Configuration file */ /* - * End of "$Id: conf.c 5116 2006-02-16 12:52:32Z mike $". + * End of "$Id: conf.c 5167 2006-02-25 02:11:44Z mike $". */ diff --git a/scheduler/conf.h b/scheduler/conf.h index 8e50f1135..ee151148c 100644 --- a/scheduler/conf.h +++ b/scheduler/conf.h @@ -1,5 +1,5 @@ /* - * "$Id: conf.h 5078 2006-02-05 03:36:35Z mike $" + * "$Id: conf.h 5200 2006-02-28 00:10:32Z mike $" * * Configuration file definitions for the Common UNIX Printing System (CUPS) * scheduler. @@ -186,9 +186,6 @@ VAR char *ServerCertificate VALUE(NULL); # if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS) VAR char *ServerKey VALUE(NULL); /* Server key file */ -# else -VAR CFArrayRef ServerCertificatesArray VALUE(NULL); - /* Array containing certificates */ # endif /* HAVE_LIBSSL || HAVE_GNUTLS */ #endif /* HAVE_SSL */ @@ -215,5 +212,5 @@ extern int cupsdLogPage(cupsd_job_t *job, const char *page); /* - * End of "$Id: conf.h 5078 2006-02-05 03:36:35Z mike $". + * End of "$Id: conf.h 5200 2006-02-28 00:10:32Z mike $". */ diff --git a/scheduler/cups-deviced.c b/scheduler/cups-deviced.c index d3cd41b93..a83c129ac 100644 --- a/scheduler/cups-deviced.c +++ b/scheduler/cups-deviced.c @@ -1,5 +1,5 @@ /* - * "$Id: cups-deviced.c 5099 2006-02-13 02:46:10Z mike $" + * "$Id: cups-deviced.c 5194 2006-02-27 20:57:07Z mike $" * * Device scanning mini-daemon for the Common UNIX Printing System (CUPS). * @@ -37,6 +37,10 @@ #include #include +#ifdef __hpux +# define seteuid(uid) setresuid(-1, (uid), -1) +#endif /* __hpux */ + /* * Device information structure... @@ -496,5 +500,5 @@ sigalrm_handler(int sig) /* I - Signal number */ /* - * End of "$Id: cups-deviced.c 5099 2006-02-13 02:46:10Z mike $". + * End of "$Id: cups-deviced.c 5194 2006-02-27 20:57:07Z mike $". */ diff --git a/scheduler/cups-lpd.c b/scheduler/cups-lpd.c index 37e897426..eda350c52 100644 --- a/scheduler/cups-lpd.c +++ b/scheduler/cups-lpd.c @@ -1,5 +1,5 @@ /* - * "$Id: cups-lpd.c 5137 2006-02-19 19:44:50Z mike $" + * "$Id: cups-lpd.c 5196 2006-02-27 21:23:00Z mike $" * * Line Printer Daemon interface for the Common UNIX Printing System (CUPS). * @@ -1307,7 +1307,7 @@ recv_print_job( * 'remove_jobs()' - Cancel one or more jobs. */ -int /* O - Command status */ +static int /* O - Command status */ remove_jobs(const char *dest, /* I - Destination */ const char *agent, /* I - User agent */ const char *list) /* I - List of jobs or users */ @@ -1392,7 +1392,7 @@ remove_jobs(const char *dest, /* I - Destination */ * 'send_state()' - Send the queue state. */ -int /* O - Command status */ +static int /* O - Command status */ send_state(const char *queue, /* I - Destination */ const char *list, /* I - Job or user */ int longstatus) /* I - List of jobs or users */ @@ -1657,7 +1657,7 @@ send_state(const char *queue, /* I - Destination */ * 'smart_gets()' - Get a line of text, removing the trailing CR and/or LF. */ -char * /* O - Line read or NULL */ +static char * /* O - Line read or NULL */ smart_gets(char *s, /* I - Pointer to line buffer */ int len, /* I - Size of line buffer */ FILE *fp) /* I - File to read from */ @@ -1708,5 +1708,5 @@ smart_gets(char *s, /* I - Pointer to line buffer */ /* - * End of "$Id: cups-lpd.c 5137 2006-02-19 19:44:50Z mike $". + * End of "$Id: cups-lpd.c 5196 2006-02-27 21:23:00Z mike $". */ diff --git a/scheduler/cupsd.h b/scheduler/cupsd.h index e543d5f94..d33ab5800 100644 --- a/scheduler/cupsd.h +++ b/scheduler/cupsd.h @@ -1,5 +1,5 @@ /* - * "$Id: cupsd.h 5053 2006-02-02 18:14:38Z mike $" + * "$Id: cupsd.h 5196 2006-02-27 21:23:00Z mike $" * * Main header file for the Common UNIX Printing System (CUPS) scheduler. * @@ -65,6 +65,9 @@ */ #ifndef HAVE_HSTRERROR +# ifdef hstrerror +# undef hstrerror +# endif /* hstrerror */ # define hstrerror cups_hstrerror extern const char *cups_hstrerror(int); @@ -204,5 +207,5 @@ extern int cupsdStartProcess(const char *command, char *argv[], /* - * End of "$Id: cupsd.h 5053 2006-02-02 18:14:38Z mike $". + * End of "$Id: cupsd.h 5196 2006-02-27 21:23:00Z mike $". */ diff --git a/scheduler/dirsvc.c b/scheduler/dirsvc.c index 8b59c68e2..f4c72b9ec 100644 --- a/scheduler/dirsvc.c +++ b/scheduler/dirsvc.c @@ -1,5 +1,5 @@ /* - * "$Id: dirsvc.c 5117 2006-02-16 14:10:43Z mike $" + * "$Id: dirsvc.c 5178 2006-02-26 00:24:23Z mike $" * * Directory services routines for the Common UNIX Printing System (CUPS). * @@ -64,13 +64,28 @@ */ static char *dequote(char *d, const char *s, int dlen); -static void process_browse_data(const char *uri, cups_ptype_t type, +static int is_local_queue(const char *uri, char *host, int hostlen, + char *resource, int resourcelen); +static void process_browse_data(const char *uri, const char *host, + const char *resource, cups_ptype_t type, ipp_pstate_t state, const char *location, const char *info, const char *make_model, int num_attrs, cups_option_t *attrs); static void process_implicit_classes(void); +#ifdef HAVE_OPENLDAP +static const char * const ldap_attrs[] =/* CUPS LDAP attributes */ + { + "printerDescription", + "printerLocation", + "printerMakeAndModel", + "printerType", + "printerURI", + NULL + }; +#endif /* HAVE_OPENLDAP */ + #ifdef HAVE_LIBSLP /* * SLP definitions... @@ -308,6 +323,25 @@ cupsdLoadRemoteCache(void) return; } } + else if (!strcasecmp(line, "Option") && value) + { + /* + * Option name value + */ + + for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++); + + if (!*valueptr) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of remote.cache.", linenum); + else + { + for (; *valueptr && isspace(*valueptr & 255); *valueptr++ = '\0'); + + p->num_options = cupsAddOption(value, valueptr, p->num_options, + &(p->options)); + } + } else if (!strcasecmp(line, "State")) { /* @@ -482,6 +516,7 @@ cupsdSaveRemoteCache(void) cupsd_printer_t *printer; /* Current printer class */ time_t curtime; /* Current time */ struct tm *curdate; /* Current date */ + cups_option_t *option; /* Current option */ /* @@ -582,6 +617,11 @@ cupsdSaveRemoteCache(void) cupsFilePrintf(fp, "%sUser %s\n", printer->deny_users ? "Deny" : "Allow", printer->users[i]); + for (i = printer->num_options, option = printer->options; + i > 0; + i --, option ++) + cupsFilePrintf(fp, "Option %s %s\n", option->name, option->value); + if (printer->type & CUPS_PRINTER_CLASS) cupsFilePuts(fp, "\n"); else @@ -646,8 +686,8 @@ cupsdSendBrowseList(void) * Compute the update and timeout times... */ - ut = time(NULL) - BrowseInterval; - to = time(NULL) - BrowseTimeout; + to = time(NULL); + ut = to - BrowseInterval; /* * Figure out how many printers need an update... @@ -715,6 +755,11 @@ cupsdSendBrowseList(void) if (BrowseLocalProtocols & BROWSE_SLP) cupsdSendSLPBrowse(p); #endif /* HAVE_LIBSLP */ + +#ifdef HAVE_LDAP + if (BrowseLocalProtocols & BROWSE_LDAP) + cupsdSendLDAPBrowse(p); +#endif /* HAVE_LDAP */ } } @@ -739,7 +784,7 @@ cupsdSendBrowseList(void) if (p->type & CUPS_PRINTER_REMOTE) { - if (p->browse_time < to) + if (p->browse_expire < to) { cupsdAddEvent(CUPSD_EVENT_PRINTER_DELETED, p, NULL, "%s \'%s\' deleted by directory services (timeout).", @@ -747,7 +792,8 @@ cupsdSendBrowseList(void) p->name); cupsdLogMessage(CUPSD_LOG_INFO, - "Remote destination \"%s\" has timed out; deleting it...", + "Remote destination \"%s\" has timed out; " + "deleting it...", p->name); cupsArraySave(Printers); @@ -760,7 +806,8 @@ cupsdSendBrowseList(void) /* - * 'cupsdSendCUPSBrowse()' - Send new browsing information using the CUPS protocol. + * 'cupsdSendCUPSBrowse()' - Send new browsing information using the CUPS + * protocol. */ void @@ -772,7 +819,6 @@ cupsdSendCUPSBrowse(cupsd_printer_t *p) /* I - Printer to send */ int bytes; /* Length of packet */ char packet[1453], /* Browse data packet */ uri[1024], /* Printer URI */ - options[1024], /* Browse local options */ location[1024], /* printer-location */ info[1024], /* printer-info */ make_model[1024]; @@ -792,15 +838,6 @@ cupsdSendCUPSBrowse(cupsd_printer_t *p) /* I - Printer to send */ if (p == DefaultPrinter) type |= CUPS_PRINTER_DEFAULT; - /* - * Initialize the browse options... - */ - - if (BrowseLocalOptions) - snprintf(options, sizeof(options), " ipp-options=%s", BrowseLocalOptions); - else - options[0] = '\0'; - /* * Remove quotes from printer-info, printer-location, and * printer-make-and-model attributes... @@ -847,8 +884,9 @@ cupsdSendCUPSBrowse(cupsd_printer_t *p) /* I - Printer to send */ (p->type & CUPS_PRINTER_CLASS) ? "/classes/%s%s" : "/printers/%s", p->name); - snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\"%s\n", - type, p->state, uri, location, info, make_model, options); + snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\" %s\n", + type, p->state, uri, location, info, make_model, + p->browse_attrs ? p->browse_attrs : ""); bytes = strlen(packet); @@ -887,8 +925,9 @@ cupsdSendCUPSBrowse(cupsd_printer_t *p) /* I - Printer to send */ (p->type & CUPS_PRINTER_CLASS) ? "/classes/%s%s" : "/printers/%s", p->name); - snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\"%s\n", - type, p->state, uri, location, info, make_model, options); + snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\" %s\n", + type, p->state, uri, location, info, make_model, + p->browse_attrs ? p->browse_attrs : ""); bytes = strlen(packet); @@ -911,8 +950,9 @@ cupsdSendCUPSBrowse(cupsd_printer_t *p) /* I - Printer to send */ * the default server name... */ - snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\"%s\n", - type, p->state, p->uri, location, info, make_model, options); + snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\" %s\n", + type, p->state, p->uri, location, info, make_model, + p->browse_attrs ? p->browse_attrs : ""); bytes = strlen(packet); cupsdLogMessage(CUPSD_LOG_DEBUG2, @@ -928,11 +968,12 @@ cupsdSendCUPSBrowse(cupsd_printer_t *p) /* I - Printer to send */ */ cupsdLogMessage(CUPSD_LOG_ERROR, - "cupsdSendBrowseList: sendto failed for browser %d - %s.", + "cupsdSendBrowseList: sendto failed for browser " + "%d - %s.", b - Browsers + 1, strerror(errno)); if (i > 1) - memcpy(b, b + 1, (i - 1) * sizeof(cupsd_dirsvc_addr_t)); + memmove(b, b + 1, (i - 1) * sizeof(cupsd_dirsvc_addr_t)); b --; NumBrowsers --; @@ -941,6 +982,131 @@ cupsdSendCUPSBrowse(cupsd_printer_t *p) /* I - Printer to send */ } +#ifdef HAVE_OPENLDAP +/* + * cupsdSendLDAPBrowse()' - Send LDAP printer registrations. + */ + +void +cupsdSendLDAPBrowse(cupsd_printer_t *p) /* I - Printer to register */ +{ + int i; /* Looping var... */ + LDAPMod mods[7]; /* The 7 attributes we will be adding */ + LDAPMod *pmods[8]; /* Pointers to the 7 attributes + NULL */ + LDAPMessage *res; /* Search result token */ + char *cn_value[2], /* Change records */ + *uri[2], + *info[2], + *location[2], + *make_model[2], + *type[2], + typestring[255], /* String to hold printer-type */ + filter[256], /* Search filter for possible UPDATEs */ + dn[1024]; /* DN of the printer we are adding */ + int rc; /* LDAP status */ + static const char * const objectClass_values[] = + { /* The 3 objectClass's we use in */ + "top", /* our LDAP entries */ + "device", + "cupsPrinter", + NULL + }; + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSendLDAPBrowse: %s\n", p->name); + + /* + * Everything in ldap is ** so we fudge around it... + */ + + sprintf(typestring, "%u", p->type); + + cn_value[0] = p->info; + cn_value[1] = NULL; + info[0] = p->info; + info[1] = NULL; + location[0] = p->location; + location[1] = NULL; + make_model[0] = p->make_model; + make_model[1] = NULL; + type[0] = typestring; + type[1] = NULL; + uri[0] = p->uri; + uri[1] = NULL; + + snprintf(filter, sizeof(filter), + "(&(objectclass=cupsPrinter)(printerDescription~=%s))", p->info); + + ldap_search_s(BrowseLDAPHandle, BrowseLDAPDN, LDAP_SCOPE_SUBTREE, + filter, (char **)ldap_attrs, 0, &res); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSendLDAPBrowse: Searching \"%s\"", + filter); + + mods[0].mod_type = "cn"; + mods[0].mod_values = cn_value; + mods[1].mod_type = "printerDescription"; + mods[1].mod_values = info; + mods[2].mod_type = "printerURI"; + mods[2].mod_values = uri; + mods[3].mod_type = "printerLocation"; + mods[3].mod_values = location; + mods[4].mod_type = "printerMakeAndModel"; + mods[4].mod_values = make_model; + mods[5].mod_type = "printerType"; + mods[5].mod_values = type; + mods[6].mod_type = "objectClass"; + mods[6].mod_values = (char **)objectClass_values; + + snprintf(dn, sizeof(dn), "cn=%s,ou=printers,%s", p->info, BrowseLDAPDN); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSendLDAPBrowse: dn=\"%s\"", dn); + + if (ldap_count_entries(BrowseLDAPHandle, res) > 0) + { + /* + * Printer has already been registered, modify the current + * registration... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdSendLDAPBrowse: Replacing entry..."); + + for (i = 0; i < 7; i ++) + { + pmods[i] = mods + i; + pmods[i]->mod_op = LDAP_MOD_REPLACE; + } + pmods[i] = NULL; + + if ((rc = ldap_modify_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS) + cupsdLogMessage(CUPSD_LOG_ERROR, + "LDAP modify for %s failed with status %d: %s", + p->name, rc, ldap_err2string(rc)); + } + else + { + /* + * Printer has already been registered, modify the current + * registration... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdSendLDAPBrowse: Adding entry..."); + + for (i = 0; i < 7; i ++) + { + pmods[i] = mods + i; + pmods[i]->mod_op = LDAP_MOD_REPLACE; + } + pmods[i] = NULL; + + if ((rc = ldap_modify_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS) + cupsdLogMessage(CUPSD_LOG_ERROR, + "LDAP add for %s failed with status %d: %s", + p->name, rc, ldap_err2string(rc)); + } +} +#endif /* HAVE_OPENLDAP */ + + #ifdef HAVE_LIBSLP /* * 'cupsdSendSLPBrowse()' - Register the specified printer with SLP. @@ -1090,6 +1256,7 @@ cupsdSendSLPBrowse(cupsd_printer_t *p) /* I - Printer to register */ "(printer-info=%s)," "(printer-more-info=%s)," "(printer-make-and-model=%s)," + "(printer-type=%d)," "(charset-supported=utf-8)," "(natural-language-configured=%s)," "(natural-language-supported=de,en,es,fr,it)," @@ -1099,7 +1266,7 @@ cupsdSendSLPBrowse(cupsd_printer_t *p) /* I - Printer to register */ "(multiple-document-jobs-supported=true)" "(ipp-versions-supported=1.0,1.1)", p->uri, authentication->values[0].string.text, p->name, location, - info, p->uri, make_model, DefaultLanguage, + info, p->uri, make_model, p->type, DefaultLanguage, p->type & CUPS_PRINTER_COLOR ? "true" : "false", finishings, p->type & CUPS_PRINTER_DUPLEX ? @@ -1243,6 +1410,79 @@ cupsdStartBrowsing(void) BrowseSLPRefresh = 0; } #endif /* HAVE_LIBSLP */ + +#ifdef HAVE_OPENLDAP + if ((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_LDAP) + { + if (!BrowseLDAPDN) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Need to set BrowseLDAPDN to use LDAP browsing!"); + BrowseLocalProtocols &= ~BROWSE_LDAP; + BrowseRemoteProtocols &= ~BROWSE_LDAP; + } + else + { + /* + * Open LDAP handle... + */ + + int rc; /* LDAP API status */ + int version = 3; /* LDAP version */ + struct berval bv = {0, ""}; /* SASL bind value */ + + + /* + * LDAP stuff currently only supports ldapi EXTERNAL SASL binds... + */ + + if (!BrowseLDAPServer || !strcasecmp(BrowseLDAPServer, "localhost")) + rc = ldap_initialize(&BrowseLDAPHandle, "ldapi:///"); + else + rc = ldap_initialize(&BrowseLDAPHandle, BrowseLDAPServer); + + if (rc != LDAP_SUCCESS) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to initialize LDAP; disabling LDAP browsing!"); + BrowseLocalProtocols &= ~BROWSE_LDAP; + BrowseRemoteProtocols &= ~BROWSE_LDAP; + } + else if (ldap_set_option(BrowseLDAPHandle, LDAP_OPT_PROTOCOL_VERSION, + (const void *)&version) != LDAP_SUCCESS) + { + ldap_unbind_ext(BrowseLDAPHandle, NULL, NULL); + BrowseLDAPHandle = NULL; + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to set LDAP protocol version; " + "disabling LDAP browsing!"); + BrowseLocalProtocols &= ~BROWSE_LDAP; + BrowseRemoteProtocols &= ~BROWSE_LDAP; + } + else + { + if (!BrowseLDAPServer || !strcasecmp(BrowseLDAPServer, "localhost")) + rc = ldap_sasl_bind_s(BrowseLDAPHandle, NULL, "EXTERNAL", &bv, NULL, + NULL, NULL); + else + rc = ldap_bind_s(BrowseLDAPHandle, BrowseLDAPBindDN, + BrowseLDAPPassword, LDAP_AUTH_SIMPLE); + + if (rc != LDAP_SUCCESS) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to bind to LDAP server; " + "disabling LDAP browsing!"); + ldap_unbind_ext(BrowseLDAPHandle, NULL, NULL); + BrowseLocalProtocols &= ~BROWSE_LDAP; + BrowseRemoteProtocols &= ~BROWSE_LDAP; + } + } + } + + BrowseLDAPRefresh = 0; + } +#endif /* HAVE_OPENLDAP */ } @@ -1384,15 +1624,26 @@ cupsdStopBrowsing(void) } #ifdef HAVE_LIBSLP - if ((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_SLP) + if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_SLP) && + BrowseSLPHandle) { /* * Close SLP handle... */ SLPClose(BrowseSLPHandle); + BrowseSLPHandle = NULL; } #endif /* HAVE_LIBSLP */ + +#ifdef HAVE_OPENDAP + if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_LDAP) && + BrowseLDAPHandle) + { + ldap_unbind(BrowseLDAPHandle); + BrowseLDAPHandle = NULL; + } +#endif /* HAVE_OPENLDAP */ } @@ -1446,15 +1697,11 @@ cupsdUpdateCUPSBrowse(void) unsigned type; /* Printer type */ unsigned state; /* Printer state */ char uri[HTTP_MAX_URI], /* Printer URI */ - method[HTTP_MAX_URI], /* Method portion of URI */ - username[HTTP_MAX_URI], /* Username portion of URI */ host[HTTP_MAX_URI], /* Host portion of URI */ resource[HTTP_MAX_URI], /* Resource portion of URI */ info[IPP_MAX_NAME], /* Information string */ location[IPP_MAX_NAME], /* Location string */ make_model[IPP_MAX_NAME];/* Make and model string */ - int port; /* Port portion of URI */ - cupsd_netif_t *iface; /* Network interface */ int num_attrs; /* Number of attributes */ cups_option_t *attrs; /* Attributes */ @@ -1670,33 +1917,12 @@ cupsdUpdateCUPSBrowse(void) * Pull the URI apart to see if this is a local or remote printer... */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri, method, sizeof(method), username, - sizeof(username), host, sizeof(host), &port, resource, - sizeof(resource)); - - DEBUG_printf(("host=\"%s\", ServerName=\"%s\"\n", host, ServerName)); - - /* - * Check for packets from the local server... - */ - - if (!strcasecmp(host, ServerName) && port == LocalPort) + if (is_local_queue(uri, host, sizeof(host), resource, sizeof(resource))) { cupsFreeOptions(num_attrs, attrs); return; } - cupsdNetIFUpdate(); - - for (iface = (cupsd_netif_t *)cupsArrayFirst(NetIFList); - iface; - iface = (cupsd_netif_t *)cupsArrayNext(NetIFList)) - if (!strcasecmp(host, iface->hostname) && port == iface->port) - { - cupsFreeOptions(num_attrs, attrs); - return; - } - /* * Do relaying... */ @@ -1718,12 +1944,99 @@ cupsdUpdateCUPSBrowse(void) * Process the browse data... */ - process_browse_data(uri, (cups_ptype_t)type, (ipp_pstate_t)state, location, - info, make_model, num_attrs, attrs); - cupsFreeOptions(num_attrs, attrs); + process_browse_data(uri, host, resource, (cups_ptype_t)type, + (ipp_pstate_t)state, location, info, make_model, + num_attrs, attrs); } +#ifdef HAVE_OPENLDAP +/* + * 'cupsdUpdateLDAPBrowse()' - Scan for new printers via LDAP... + */ + +void +cupsdUpdateLDAPBrowse(void) +{ + char uri[HTTP_MAX_URI], /* Printer URI */ + host[HTTP_MAX_URI], /* Hostname */ + resource[HTTP_MAX_URI], /* Resource path */ + location[1024], /* Printer location */ + info[1024], /* Printer information */ + make_model[1024], /* Printer make and model */ + **value; /* Holds the returned data from LDAP */ + int type; /* Printer type */ + int rc; /* LDAP status */ + int limit; /* Size limit */ + LDAPMessage *res, /* LDAP search results */ + *e; /* Current entry from search */ + + + /* + * Search for printers... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "UpdateLDAPBrowse: %s", ServerName); + + BrowseLDAPRefresh = time(NULL) + BrowseInterval; + + rc = ldap_search_s(BrowseLDAPHandle, BrowseLDAPDN, LDAP_SCOPE_SUBTREE, + "(objectclass=cupsPrinter)", (char **)ldap_attrs, 0, &res); + if (rc != LDAP_SUCCESS) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "LDAP search returned error %d: %s", rc, + ldap_err2string(rc)); + return; + } + + limit = ldap_count_entries(BrowseLDAPHandle, res); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "LDAP search returned %d entries", limit); + if (limit < 1) + return; + + /* + * Loop through the available printers... + */ + + if ((e = ldap_first_entry(BrowseLDAPHandle, res)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get LDAP printer entry!"); + return; + } + + while (e) + { + value = ldap_get_values(BrowseLDAPHandle, e, "printerDescription"); + strlcpy(info, *value, sizeof(info)); + ldap_value_free(value); + + value = ldap_get_values(BrowseLDAPHandle, e, "printerLocation"); + strlcpy(location, *value, sizeof(location)); + ldap_value_free(value); + + value = ldap_get_values(BrowseLDAPHandle, e, "printerMakeAndModel"); + strlcpy(make_model, *value, sizeof(make_model)); + ldap_value_free(value); + + value = ldap_get_values(BrowseLDAPHandle, e, "printerType"); + type = atoi(*value); + ldap_value_free(value); + + value = ldap_get_values(BrowseLDAPHandle, e, "printerURI"); + strlcpy(uri, *value, sizeof(uri)); + ldap_value_free(value); + + if (!is_local_queue(uri, host, sizeof(host), resource, sizeof(resource))) + process_browse_data(uri, host, resource, type, IPP_PRINTER_IDLE, + location, info, make_model, 0, NULL); + + e = ldap_next_entry(BrowseLDAPHandle, e); + } +} +#endif /* HAVE_OPENLDAP */ + + /* * 'cupsdUpdatePolling()' - Read status messages from the poll daemons. */ @@ -1762,22 +2075,13 @@ cupsdUpdatePolling(void) void cupsdUpdateSLPBrowse(void) { - slpsrvurl_t *s, /* Temporary list of service URLs */ - *next; /* Next service in list */ - cupsd_printer_t p; /* Printer information */ - const char *uri; /* Pointer to printer URI */ - char method[HTTP_MAX_URI], - /* Method portion of URI */ - username[HTTP_MAX_URI], - /* Username portion of URI */ - host[HTTP_MAX_URI], - /* Host portion of URI */ - resource[HTTP_MAX_URI]; - /* Resource portion of URI */ - int port; /* Port portion of URI */ - + slpsrvurl_t *s, /* Temporary list of service URLs */ + *next; /* Next service in list */ + cupsd_printer_t p; /* Printer information */ + const char *uri; /* Pointer to printer URI */ + char host[HTTP_MAX_URI], /* Host portion of URI */ + resource[HTTP_MAX_URI]; /* Resource portion of URI */ - cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdUpdateSLPBrowse() Start..."); /* * Reset the refresh time... @@ -1824,34 +2128,21 @@ cupsdUpdateSLPBrowse(void) * Pull the URI apart to see if this is a local or remote printer... */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri, method, sizeof(method), - username, sizeof(username), host, sizeof(host), &port, - resource, sizeof(resource)); - - if (!strcasecmp(host, ServerName)) - continue; - - /* - * OK, at least an IPP printer, see if it is a CUPS printer or - * class... - */ - - if (strstr(uri, "/printers/") != NULL) - process_browse_data(uri, p.type, IPP_PRINTER_IDLE, p.location, - p.info, p.make_model, 0, NULL); - else if (strstr(uri, "/classes/") != NULL) - process_browse_data(uri, p.type | CUPS_PRINTER_CLASS, IPP_PRINTER_IDLE, - p.location, p.info, p.make_model, 0, NULL); + if (!is_local_queue(uri, host, sizeof(host), resource, sizeof(resource))) + process_browse_data(uri, host, resource, p.type, IPP_PRINTER_IDLE, + p.location, p.info, p.make_model, 0, NULL); } /* * Free this listing... */ + cupsdClearString(&p.info); + cupsdClearString(&p.location); + cupsdClearString(&p.make_model); + free(s); } - - cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdUpdateSLPBrowse() End..."); } #endif /* HAVE_LIBSLP */ @@ -1886,6 +2177,57 @@ dequote(char *d, /* I - Destination string */ } +/* + * 'is_local_queue()' - Determine whether the URI points at a local queue. + */ + +static int /* O - 1 = local, 0 = remote, -1 = bad URI */ +is_local_queue(const char *uri, /* I - Printer URI */ + char *host, /* O - Host string */ + int hostlen, /* I - Length of host buffer */ + char *resource, /* O - Resource string */ + int resourcelen) /* I - Length of resource buffer */ +{ + char scheme[32], /* Scheme portion of URI */ + username[HTTP_MAX_URI]; /* Username portion of URI */ + int port; /* Port portion of URI */ + cupsd_netif_t *iface; /* Network interface */ + + + /* + * Pull the URI apart to see if this is a local or remote printer... + */ + + if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), + username, sizeof(username), host, hostlen, &port, + resource, resourcelen) < HTTP_URI_OK) + return (-1); + + DEBUG_printf(("host=\"%s\", ServerName=\"%s\"\n", host, ServerName)); + + /* + * Check for local server addresses... + */ + + if (!strcasecmp(host, ServerName) && port == LocalPort) + return (1); + + cupsdNetIFUpdate(); + + for (iface = (cupsd_netif_t *)cupsArrayFirst(NetIFList); + iface; + iface = (cupsd_netif_t *)cupsArrayNext(NetIFList)) + if (!strcasecmp(host, iface->hostname) && port == iface->port) + return (1); + + /* + * If we get here, the printer is remote... + */ + + return (0); +} + + /* * 'process_browse_data()' - Process new browse data. */ @@ -1893,6 +2235,8 @@ dequote(char *d, /* I - Destination string */ static void process_browse_data( const char *uri, /* I - URI of printer/class */ + const char *host, /* I - Hostname */ + const char *resource, /* I - Resource path */ cups_ptype_t type, /* I - Printer type */ ipp_pstate_t state, /* I - Printer state */ const char *location, /* I - Printer location */ @@ -1901,29 +2245,19 @@ process_browse_data( int num_attrs, /* I - Number of attributes */ cups_option_t *attrs) /* I - Attributes */ { + int i; /* Looping var */ int update; /* Update printer attributes? */ char finaluri[HTTP_MAX_URI], /* Final URI for printer */ - method[HTTP_MAX_URI], /* Method portion of URI */ - username[HTTP_MAX_URI], /* Username portion of URI */ - host[HTTP_MAX_URI], /* Host portion of URI */ - resource[HTTP_MAX_URI]; /* Resource portion of URI */ - int port; /* Port portion of URI */ - char name[IPP_MAX_NAME], /* Name of printer */ + name[IPP_MAX_NAME], /* Name of printer */ + newname[IPP_MAX_NAME], /* New name of printer */ *hptr, /* Pointer into hostname */ *sptr; /* Pointer into ServerName */ char local_make_model[IPP_MAX_NAME]; /* Local make and model */ cupsd_printer_t *p; /* Printer information */ - const char *ipp_options; /* ipp-options value */ - - - /* - * Pull the URI apart to see if this is a local or remote printer... - */ + const char *ipp_options, /* ipp-options value */ + *lease_duration; /* lease-duration value */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri, method, sizeof(method), username, - sizeof(username), host, sizeof(host), &port, resource, - sizeof(resource)); /* * Determine if the URI contains any illegal characters in it... @@ -2055,10 +2389,8 @@ process_browse_data( "Class \'%s\' deleted by directory services.", p->name); - cupsArrayRemove(Printers, p); - cupsdSetStringf(&p->name, "%s@%s", p->name, p->hostname); - cupsdSetPrinterAttrs(p); - cupsArrayAdd(Printers, p); + snprintf(newname, sizeof(newname), "%s@%s", p->name, p->hostname); + cupsdRenamePrinter(p, newname); cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, p, NULL, "Class \'%s\' added by directory services.", @@ -2160,10 +2492,8 @@ process_browse_data( "Printer \'%s\' deleted by directory services.", p->name); - cupsArrayRemove(Printers, p); - cupsdSetStringf(&p->name, "%s@%s", p->name, p->hostname); - cupsdSetPrinterAttrs(p); - cupsArrayAdd(Printers, p); + snprintf(newname, sizeof(newname), "%s@%s", p->name, p->hostname); + cupsdRenamePrinter(p, newname); cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, p, NULL, "Printer \'%s\' added by directory services.", @@ -2241,6 +2571,23 @@ process_browse_data( p->state = state; p->browse_time = time(NULL); + if ((lease_duration = cupsGetOption("lease-duration", num_attrs, + attrs)) != NULL) + { + /* + * Grab the lease-duration for the browse data; anything less then 1 + * second or more than 1 week gets the default BrowseTimeout... + */ + + i = atoi(lease_duration); + if (i < 1 || i > 604800) + i = BrowseTimeout; + + p->browse_expire = p->browse_time + i; + } + else + p->browse_expire = p->browse_time + BrowseTimeout; + if (type & CUPS_PRINTER_REJECTING) { type &= ~CUPS_PRINTER_REJECTING; @@ -2294,6 +2641,39 @@ process_browse_data( update = 1; } + if (p->num_options) + { + if (!update && !(type & CUPS_PRINTER_DELETE)) + { + /* + * See if we need to update the attributes... + */ + + if (p->num_options != num_attrs) + update = 1; + else + { + for (i = 0; i < num_attrs; i ++) + if (strcmp(attrs[i].name, p->options[i].name) || + (!attrs[i].value != !p->options[i].value) || + (attrs[i].value && strcmp(attrs[i].value, p->options[i].value))) + { + update = 1; + break; + } + } + } + + /* + * Free the old options... + */ + + cupsFreeOptions(p->num_options, p->options); + } + + p->num_options = num_attrs; + p->options = attrs; + if (type & CUPS_PRINTER_DELETE) { cupsdAddEvent(CUPSD_EVENT_PRINTER_DELETED, p, NULL, @@ -2312,8 +2692,8 @@ process_browse_data( } /* - * See if we have a default printer... If not, make the first printer the - * default. + * See if we have a default printer... If not, make the first network + * default printer the default. */ if (DefaultPrinter == NULL && Printers != NULL && UseNetworkDefault) @@ -2431,6 +2811,9 @@ process_implicit_classes(void) cupsdLogMessage(CUPSD_LOG_INFO, "Added implicit class \"%s\"...", name); + cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, p, NULL, + "Implicit class \'%s\' added by directory services.", + name); } if (first != NULL) @@ -2535,15 +2918,12 @@ slp_attr_callback( SLPError errcode, /* I - Parsing status for this attr */ void *cookie) /* I - Current printer */ { - char *tmp = 0; + char *tmp = 0; /* Temporary string */ cupsd_printer_t *p = (cupsd_printer_t*)cookie; + /* Current printer */ - /* - * Let the compiler know we won't be using these... - */ - - (void)hslp; + (void)hslp; /* anti-compiler-warning-code */ /* * Bail if there was an error @@ -2558,33 +2938,16 @@ slp_attr_callback( memset(p, 0, sizeof(cupsd_printer_t)); - p->type = CUPS_PRINTER_REMOTE; - if (slp_get_attr(attrlist, "(printer-location=", &(p->location))) return (SLP_FALSE); if (slp_get_attr(attrlist, "(printer-info=", &(p->info))) return (SLP_FALSE); if (slp_get_attr(attrlist, "(printer-make-and-model=", &(p->make_model))) return (SLP_FALSE); - - if (slp_get_attr(attrlist, "(color-supported=", &tmp)) - return (SLP_FALSE); - if (!strcasecmp(tmp, "true")) - p->type |= CUPS_PRINTER_COLOR; - - if (slp_get_attr(attrlist, "(finishings-supported=", &tmp)) - return (SLP_FALSE); - if (strstr(tmp, "staple")) - p->type |= CUPS_PRINTER_STAPLE; - if (strstr(tmp, "bind")) - p->type |= CUPS_PRINTER_BIND; - if (strstr(tmp, "punch")) - p->type |= CUPS_PRINTER_PUNCH; - - if (slp_get_attr(attrlist, "(sides-supported=", &tmp)) - return (SLP_FALSE); - if (strstr(tmp,"two-sided")) - p->type |= CUPS_PRINTER_DUPLEX; + if (!slp_get_attr(attrlist, "(printer-type=", &tmp)) + p->type = atoi(tmp); + else + p->type = CUPS_PRINTER_REMOTE; cupsdClearString(&tmp); @@ -2747,5 +3110,5 @@ slp_url_callback( /* - * End of "$Id: dirsvc.c 5117 2006-02-16 14:10:43Z mike $". + * End of "$Id: dirsvc.c 5178 2006-02-26 00:24:23Z mike $". */ diff --git a/scheduler/dirsvc.h b/scheduler/dirsvc.h index 951407efe..ac8eccd66 100644 --- a/scheduler/dirsvc.h +++ b/scheduler/dirsvc.h @@ -1,5 +1,5 @@ /* - * "$Id: dirsvc.h 5031 2006-01-31 03:05:32Z mike $" + * "$Id: dirsvc.h 5198 2006-02-27 21:58:43Z mike $" * * Directory services definitions for the Common UNIX Printing System * (CUPS) scheduler. @@ -31,6 +31,12 @@ # include #endif /* HAVE_LIBSLP */ +#ifdef HAVE_OPENLDAP +# ifdef __sun +# include +# endif /* __sun */ +# include +#endif /* HAVE_OPENLDAP */ /* * Browse protocols... @@ -38,7 +44,7 @@ #define BROWSE_CUPS 1 /* CUPS */ #define BROWSE_SLP 2 /* SLPv2 */ -#define BROWSE_LDAP 4 /* LDAP (not supported yet) */ +#define BROWSE_LDAP 4 /* LDAP */ #define BROWSE_DNSSD 8 /* DNS Service Discovery aka Bonjour */ #define BROWSE_ALL 15 /* All protocols */ @@ -135,6 +141,23 @@ VAR time_t BrowseSLPRefresh VALUE(0); /* Next SLP refresh time */ #endif /* HAVE_LIBSLP */ +#ifdef HAVE_LDAP +# ifdef HAVE_OPENLDAP +VAR LDAP *BrowseLDAPHandle VALUE(NULL); + /* Handle to LDAP server */ +# endif /* HAVE_OPENLDAP */ +VAR time_t BrowseLDAPRefresh VALUE(0); + /* Next LDAP refresh time */ +VAR char *BrowseLDAPBindDN VALUE(NULL), + /* LDAP login DN */ + *BrowseLDAPDN VALUE(NULL), + /* LDAP search DN */ + *BrowseLDAPPassword VALUE(NULL), + /* LDAP login password */ + *BrowseLDAPServer VALUE(NULL); + /* LDAP server to use */ +#endif /* HAVE_LDAP */ + /* * Prototypes... @@ -145,16 +168,22 @@ extern void cupsdSaveRemoteCache(void); extern void cupsdSendBrowseDelete(cupsd_printer_t *p); extern void cupsdSendBrowseList(void); extern void cupsdSendCUPSBrowse(cupsd_printer_t *p); +#ifdef HAVE_LDAP +extern void cupsdSendLDAPBrowse(cupsd_printer_t *p); +#endif /* HAVE_LDAP */ extern void cupsdSendSLPBrowse(cupsd_printer_t *p); extern void cupsdStartBrowsing(void); extern void cupsdStartPolling(void); extern void cupsdStopBrowsing(void); extern void cupsdStopPolling(void); extern void cupsdUpdateCUPSBrowse(void); +#ifdef HAVE_LDAP +extern void cupsdUpdateLDAPBrowse(void); +#endif /* HAVE_LDAP */ extern void cupsdUpdatePolling(void); extern void cupsdUpdateSLPBrowse(void); /* - * End of "$Id: dirsvc.h 5031 2006-01-31 03:05:32Z mike $". + * End of "$Id: dirsvc.h 5198 2006-02-27 21:58:43Z mike $". */ diff --git a/scheduler/filter.c b/scheduler/filter.c index f315910af..92d68f862 100644 --- a/scheduler/filter.c +++ b/scheduler/filter.c @@ -1,5 +1,5 @@ /* - * "$Id: filter.c 5083 2006-02-06 02:57:43Z mike $" + * "$Id: filter.c 5196 2006-02-27 21:23:00Z mike $" * * File type conversion routines for the Common UNIX Printing System (CUPS). * @@ -199,7 +199,7 @@ compare_filters(mime_filter_t *f0, /* I - First filter */ * 'find_filters()' - Find the filters to convert from one type to another. */ -cups_array_t * /* O - Array of filters to run */ +static cups_array_t * /* O - Array of filters to run */ find_filters(mime_t *mime, /* I - MIME database */ mime_type_t *src, /* I - Source file type */ mime_type_t *dst, /* I - Destination file type */ @@ -360,5 +360,5 @@ lookup(mime_t *mime, /* I - MIME database */ /* - * End of "$Id: filter.c 5083 2006-02-06 02:57:43Z mike $". + * End of "$Id: filter.c 5196 2006-02-27 21:23:00Z mike $". */ diff --git a/scheduler/ipp.c b/scheduler/ipp.c index 7053ad0a8..3c50525df 100644 --- a/scheduler/ipp.c +++ b/scheduler/ipp.c @@ -1,5 +1,5 @@ /* - * "$Id: ipp.c 5131 2006-02-18 05:31:36Z mike $" + * "$Id: ipp.c 5164 2006-02-24 20:40:00Z mike $" * * IPP routines for the Common UNIX Printing System (CUPS) scheduler. * @@ -27,6 +27,7 @@ * accept_jobs() - Accept print jobs to a printer. * add_class() - Add a class to the system. * add_file() - Add a file to a job. + * add_job() - Add a job to a print queue. * add_job_state_reasons() - Add the "job-state-reasons" attribute based * upon the job and printer state... * add_job_subscriptions() - Add any subcriptions for a job. @@ -35,6 +36,7 @@ * add_printer_state_reasons() - Add the "printer-state-reasons" attribute * based upon the printer state... * add_queued_job_count() - Add the "queued-job-count" attribute for + * apply_printer_defaults() - Apply printer default options to a job. * authenticate_job() - Set job authentication info. * cancel_all_jobs() - Cancel all print jobs. * cancel_job() - Cancel a print job. @@ -83,6 +85,7 @@ * send_ipp_status() - Send a status back to the IPP client. * set_default() - Set the default destination... * set_job_attrs() - Set job attributes. + * set_printer_defaults() - Set printer default options from a request. * start_printer() - Start a printer. * stop_printer() - Stop a printer. * user_allowed() - See if a user is allowed to print to a queue. @@ -120,14 +123,19 @@ typedef struct static void accept_jobs(cupsd_client_t *con, ipp_attribute_t *uri); static void add_class(cupsd_client_t *con, ipp_attribute_t *uri); -static int add_file(cupsd_client_t *con, cupsd_job_t *job, mime_type_t *filetype, - int compression); +static int add_file(cupsd_client_t *con, cupsd_job_t *job, + mime_type_t *filetype, int compression); +static cupsd_job_t *add_job(cupsd_client_t *con, ipp_attribute_t *uri, + cupsd_printer_t **dprinter); static void add_job_state_reasons(cupsd_client_t *con, cupsd_job_t *job); static void add_job_subscriptions(cupsd_client_t *con, cupsd_job_t *job); static void add_job_uuid(cupsd_client_t *con, cupsd_job_t *job); static void add_printer(cupsd_client_t *con, ipp_attribute_t *uri); -static void add_printer_state_reasons(cupsd_client_t *con, cupsd_printer_t *p); +static void add_printer_state_reasons(cupsd_client_t *con, + cupsd_printer_t *p); static void add_queued_job_count(cupsd_client_t *con, cupsd_printer_t *p); +static void apply_printer_defaults(cupsd_printer_t *printer, + cupsd_job_t *job); static void authenticate_job(cupsd_client_t *con, ipp_attribute_t *uri); static void cancel_all_jobs(cupsd_client_t *con, ipp_attribute_t *uri); static void cancel_job(cupsd_client_t *con, ipp_attribute_t *uri); @@ -137,9 +145,11 @@ static ipp_attribute_t *copy_attribute(ipp_t *to, ipp_attribute_t *attr, int quickcopy); static void copy_attrs(ipp_t *to, ipp_t *from, cups_array_t *ra, ipp_tag_t group, int quickcopy); -static int copy_banner(cupsd_client_t *con, cupsd_job_t *job, const char *name); +static int copy_banner(cupsd_client_t *con, cupsd_job_t *job, + const char *name); static int copy_file(const char *from, const char *to); -static int copy_model(cupsd_client_t *con, const char *from, const char *to); +static int copy_model(cupsd_client_t *con, const char *from, + const char *to); static void copy_job_attrs(cupsd_client_t *con, cupsd_job_t *job, cups_array_t *ra); @@ -187,6 +197,8 @@ __attribute__ ((__format__ (__printf__, 3, 4))) ; static void set_default(cupsd_client_t *con, ipp_attribute_t *uri); static void set_job_attrs(cupsd_client_t *con, ipp_attribute_t *uri); +static void set_printer_defaults(cupsd_client_t *con, + cupsd_printer_t *printer); static void start_printer(cupsd_client_t *con, ipp_attribute_t *uri); static void stop_printer(cupsd_client_t *con, ipp_attribute_t *uri); static int user_allowed(cupsd_printer_t *p, const char *username); @@ -761,6 +773,7 @@ add_class(cupsd_client_t *con, /* I - Client connection */ const char *dest; /* Printer or class name */ ipp_attribute_t *attr; /* Printer attribute */ int modify; /* Non-zero if we just modified */ + char newname[IPP_MAX_NAME]; /* New class name */ int need_restart_job; /* Need to restart job? */ @@ -852,9 +865,8 @@ add_class(cupsd_client_t *con, /* I - Client connection */ if (ImplicitAnyClasses) { - cupsArrayRemove(Printers, pclass); - cupsdSetStringf(&pclass->name, "Any%s", resource + 9); - cupsArrayAdd(Printers, pclass); + snprintf(newname, sizeof(newname), "Any%s", resource + 9); + cupsdRenamePrinter(pclass, newname); } else cupsdDeletePrinter(pclass, 1); @@ -872,11 +884,8 @@ add_class(cupsd_client_t *con, /* I - Client connection */ * Rename the remote class to "Class"... */ - cupsdDeletePrinterFilters(pclass); - cupsArrayRemove(Printers, pclass); - cupsdSetStringf(&pclass->name, "%s@%s", resource + 9, pclass->hostname); - cupsdSetPrinterAttrs(pclass); - cupsArrayAdd(Printers, pclass); + snprintf(newname, sizeof(newname), "%s@%s", resource + 9, pclass->hostname); + cupsdRenamePrinter(pclass, newname); /* * Add the class as a new local class... @@ -955,107 +964,6 @@ add_class(cupsd_client_t *con, /* I - Client connection */ sizeof(pclass->state_message)); cupsdAddPrinterHistory(pclass); } - if ((attr = ippFindAttribute(con->request, "job-sheets-default", - IPP_TAG_ZERO)) != NULL && - !Classification) - { - cupsdSetString(&pclass->job_sheets[0], attr->values[0].string.text); - if (attr->num_values > 1) - cupsdSetString(&pclass->job_sheets[1], attr->values[1].string.text); - else - cupsdSetString(&pclass->job_sheets[1], "none"); - } - if ((attr = ippFindAttribute(con->request, "requesting-user-name-allowed", - IPP_TAG_ZERO)) != NULL) - { - cupsdFreePrinterUsers(pclass); - - pclass->deny_users = 0; - if (attr->value_tag == IPP_TAG_NAME && - (attr->num_values > 1 || - strcmp(attr->values[0].string.text, "all"))) - for (i = 0; i < attr->num_values; i ++) - cupsdAddPrinterUser(pclass, attr->values[i].string.text); - } - else if ((attr = ippFindAttribute(con->request, "requesting-user-name-denied", - IPP_TAG_ZERO)) != NULL) - { - cupsdFreePrinterUsers(pclass); - - pclass->deny_users = 1; - if (attr->value_tag == IPP_TAG_NAME && - (attr->num_values > 1 || - strcmp(attr->values[0].string.text, "none"))) - for (i = 0; i < attr->num_values; i ++) - cupsdAddPrinterUser(pclass, attr->values[i].string.text); - } - if ((attr = ippFindAttribute(con->request, "job-quota-period", - IPP_TAG_INTEGER)) != NULL) - { - cupsdLogMessage(CUPSD_LOG_DEBUG, - "add_class: Setting job-quota-period to %d...", - attr->values[0].integer); - cupsdFreeQuotas(pclass); - pclass->quota_period = attr->values[0].integer; - } - if ((attr = ippFindAttribute(con->request, "job-k-limit", - IPP_TAG_INTEGER)) != NULL) - { - cupsdLogMessage(CUPSD_LOG_DEBUG, - "add_class: Setting job-k-limit to %d...", - attr->values[0].integer); - cupsdFreeQuotas(pclass); - pclass->k_limit = attr->values[0].integer; - } - if ((attr = ippFindAttribute(con->request, "job-page-limit", - IPP_TAG_INTEGER)) != NULL) - { - cupsdLogMessage(CUPSD_LOG_DEBUG, - "add_class: Setting job-page-limit to %d...", - attr->values[0].integer); - cupsdFreeQuotas(pclass); - pclass->page_limit = attr->values[0].integer; - } - if ((attr = ippFindAttribute(con->request, "printer-op-policy", - IPP_TAG_NAME)) != NULL) - { - cupsd_policy_t *p; /* Policy */ - - - if ((p = cupsdFindPolicy(attr->values[0].string.text)) != NULL) - { - cupsdLogMessage(CUPSD_LOG_DEBUG, - "add_class: Setting printer-op-policy to \"%s\"...", - attr->values[0].string.text); - cupsdSetString(&pclass->op_policy, attr->values[0].string.text); - pclass->op_policy_ptr = p; - } - else - { - send_ipp_status(con, IPP_NOT_POSSIBLE, - _("add_class: Unknown printer-op-policy \"%s\"."), - attr->values[0].string.text); - return; - } - } - if ((attr = ippFindAttribute(con->request, "printer-error-policy", - IPP_TAG_NAME)) != NULL) - { - if (strcmp(attr->values[0].string.text, "abort-job") && - strcmp(attr->values[0].string.text, "retry-job") && - strcmp(attr->values[0].string.text, "stop-printer")) - { - send_ipp_status(con, IPP_NOT_POSSIBLE, - _("add_class: Unknown printer-error-policy \"%s\"."), - attr->values[0].string.text); - return; - } - - cupsdLogMessage(CUPSD_LOG_DEBUG, - "add_class: Setting printer-error-policy to \"%s\"...", - attr->values[0].string.text); - cupsdSetString(&pclass->error_policy, attr->values[0].string.text); - } if ((attr = ippFindAttribute(con->request, "member-uris", IPP_TAG_URI)) != NULL) { @@ -1104,6 +1012,8 @@ add_class(cupsd_client_t *con, /* I - Client connection */ } } + set_printer_defaults(con, pclass); + /* * Update the printer class attributes and return... */ @@ -1215,3297 +1125,3301 @@ add_file(cupsd_client_t *con, /* I - Connection to client */ /* - * 'add_job_state_reasons()' - Add the "job-state-reasons" attribute based - * upon the job and printer state... + * 'add_job()' - Add a job to a print queue. */ -static void -add_job_state_reasons( - cupsd_client_t *con, /* I - Client connection */ - cupsd_job_t *job) /* I - Job info */ +static cupsd_job_t * /* O - Job object */ +add_job(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri, /* I - printer-uri */ + cupsd_printer_t **dprinter) /* I - Destination printer */ { - cupsd_printer_t *dest; /* Destination printer */ + http_status_t status; /* Policy status */ + ipp_attribute_t *attr; /* Current attribute */ + const char *dest; /* Destination */ + cups_ptype_t dtype; /* Destination type (printer or class) */ + const char *val; /* Default option value */ + int priority; /* Job priority */ + char *title; /* Job name/title */ + cupsd_job_t *job; /* Current job */ + char job_uri[HTTP_MAX_URI], /* Job URI */ + method[HTTP_MAX_URI], /* Method portion of URI */ + username[HTTP_MAX_URI], /* Username portion of URI */ + host[HTTP_MAX_URI], /* Host portion of URI */ + resource[HTTP_MAX_URI]; /* Resource portion of URI */ + int port; /* Port portion of URI */ + cupsd_printer_t *printer; /* Printer data */ + int kbytes; /* Size of print file */ + int i; /* Looping var */ + int lowerpagerange; /* Page range bound */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job_state_reasons(%p[%d], %d)", - con, con->http.fd, job ? job->id : 0); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); - switch (job ? job->state_value : IPP_JOB_CANCELLED) + /* + * Is the destination valid? + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, + sizeof(method), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) { - case IPP_JOB_PENDING : - if (job->dtype & CUPS_PRINTER_CLASS) - dest = cupsdFindClass(job->dest); - else - dest = cupsdFindPrinter(job->dest); + /* + * Bad URI... + */ - if (dest && dest->state == IPP_PRINTER_STOPPED) - ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, - "job-state-reasons", NULL, "printer-stopped"); - else - ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, - "job-state-reasons", NULL, "none"); - break; + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return (NULL); + } - case IPP_JOB_HELD : - if (ippFindAttribute(job->attrs, "job-hold-until", - IPP_TAG_KEYWORD) != NULL || - ippFindAttribute(job->attrs, "job-hold-until", - IPP_TAG_NAME) != NULL) - ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, - "job-state-reasons", NULL, "job-hold-until-specified"); - else - ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, - "job-state-reasons", NULL, "job-incoming"); - break; + if (dprinter) + *dprinter = printer; - case IPP_JOB_PROCESSING : - ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, - "job-state-reasons", NULL, "job-printing"); - break; + /* + * Check remote printing to non-shared printer... + */ - case IPP_JOB_STOPPED : - ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, - "job-state-reasons", NULL, "job-stopped"); - break; + if (!printer->shared && + strcasecmp(con->http.hostname, "localhost") && + strcasecmp(con->http.hostname, ServerName)) + { + send_ipp_status(con, IPP_NOT_AUTHORIZED, + _("The printer or class is not shared!")); + return (NULL); + } - case IPP_JOB_CANCELLED : - ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, - "job-state-reasons", NULL, "job-canceled-by-user"); - break; + /* + * Check policy... + */ - case IPP_JOB_ABORTED : - ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, - "job-state-reasons", NULL, "aborted-by-system"); - break; + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status); + return (NULL); + } + else if ((printer->type & CUPS_PRINTER_AUTHENTICATED) && !con->username[0]) + { + send_http_error(con, HTTP_UNAUTHORIZED); + return (NULL); + } - case IPP_JOB_COMPLETED : - ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, - "job-state-reasons", NULL, "job-completed-successfully"); - break; + /* + * See if the printer is accepting jobs... + */ + + if (!printer->accepting) + { + send_ipp_status(con, IPP_NOT_ACCEPTING, + _("Destination \"%s\" is not accepting jobs."), + dest); + return (NULL); } -} + /* + * Validate job template attributes; for now just copies and page-ranges... + */ -/* - * 'add_job_subscriptions()' - Add any subcriptions for a job. - */ + if ((attr = ippFindAttribute(con->request, "copies", + IPP_TAG_INTEGER)) != NULL) + { + if (attr->values[0].integer < 1 || attr->values[0].integer > MaxCopies) + { + send_ipp_status(con, IPP_ATTRIBUTES, _("Bad copies value %d."), + attr->values[0].integer); + ippAddInteger(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_INTEGER, + "copies", attr->values[0].integer); + return (NULL); + } + } -static void -add_job_subscriptions( - cupsd_client_t *con, /* I - Client connection */ - cupsd_job_t *job) /* I - Newly created job */ -{ - int i; /* Looping var */ - ipp_attribute_t *prev, /* Previous attribute */ - *next, /* Next attribute */ - *attr; /* Current attribute */ - cupsd_subscription_t *sub; /* Subscription object */ - const char *recipient, /* notify-recipient-uri */ - *pullmethod; /* notify-pull-method */ - ipp_attribute_t *user_data; /* notify-user-data */ - int interval; /* notify-time-interval */ - unsigned mask; /* notify-events */ + if ((attr = ippFindAttribute(con->request, "page-ranges", + IPP_TAG_RANGE)) != NULL) + { + for (i = 0, lowerpagerange = 1; i < attr->num_values; i ++) + { + if (attr->values[i].range.lower < lowerpagerange || + attr->values[i].range.lower > attr->values[i].range.upper) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Bad page-ranges values %d-%d."), + attr->values[i].range.lower, + attr->values[i].range.upper); + return (NULL); + } + lowerpagerange = attr->values[i].range.upper + 1; + } + } /* - * Find the first subscription group attribute; return if we have - * none... + * Make sure we aren't over our limit... */ - for (attr = job->attrs->attrs, prev = NULL; - attr; - prev = attr, attr = attr->next) - if (attr->group_tag == IPP_TAG_SUBSCRIPTION) - break; + if (MaxJobs && cupsArrayCount(Jobs) >= MaxJobs) + cupsdCleanJobs(); - if (!attr) - return; + if (cupsArrayCount(Jobs) >= MaxJobs && MaxJobs) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Too many active jobs.")); + return (NULL); + } + + if (!check_quotas(con, printer)) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, _("Quota limit reached.")); + return (NULL); + } /* - * Process the subscription attributes in the request... + * Create the job and set things up... */ - while (attr) + if ((attr = ippFindAttribute(con->request, "job-priority", + IPP_TAG_INTEGER)) != NULL) + priority = attr->values[0].integer; + else { - recipient = NULL; - pullmethod = NULL; - user_data = NULL; - interval = 0; - mask = CUPSD_EVENT_NONE; - - while (attr && attr->group_tag != IPP_TAG_ZERO) - { - if (!strcmp(attr->name, "notify-recipient") && - attr->value_tag == IPP_TAG_URI) - recipient = attr->values[0].string.text; - else if (!strcmp(attr->name, "notify-pull-method") && - attr->value_tag == IPP_TAG_KEYWORD) - pullmethod = attr->values[0].string.text; - else if (!strcmp(attr->name, "notify-charset") && - attr->value_tag == IPP_TAG_CHARSET && - strcmp(attr->values[0].string.text, "us-ascii") && - strcmp(attr->values[0].string.text, "utf-8")) - { - send_ipp_status(con, IPP_CHARSET, - _("Character set \"%s\" not supported!"), - attr->values[0].string.text); - return; - } - else if (!strcmp(attr->name, "notify-natural-language") && - (attr->value_tag != IPP_TAG_LANGUAGE || - strcmp(attr->values[0].string.text, DefaultLanguage))) - { - send_ipp_status(con, IPP_CHARSET, - _("Language \"%s\" not supported!"), - attr->values[0].string.text); - return; - } - else if (!strcmp(attr->name, "notify-user-data") && - attr->value_tag == IPP_TAG_STRING) - { - if (attr->num_values > 1 || attr->values[0].unknown.length > 63) - { - send_ipp_status(con, IPP_REQUEST_VALUE, - _("The notify-user-data value is too large " - "(%d > 63 octets)!"), - attr->values[0].unknown.length); - return; - } - - user_data = attr; - } - else if (!strcmp(attr->name, "notify-events") && - attr->value_tag == IPP_TAG_KEYWORD) - { - for (i = 0; i < attr->num_values; i ++) - mask |= cupsdEventValue(attr->values[i].string.text); - } - else if (!strcmp(attr->name, "notify-lease-duration")) - { - send_ipp_status(con, IPP_BAD_REQUEST, - _("The notify-lease-duration attribute cannot be " - "used with job subscriptions.")); - return; - } - else if (!strcmp(attr->name, "notify-time-interval") && - attr->value_tag == IPP_TAG_INTEGER) - interval = attr->values[0].integer; - - attr = attr->next; - } + if ((val = cupsGetOption("job-priority", printer->num_options, + printer->options)) != NULL) + priority = atoi(val); + else + priority = 50; - if (!recipient && !pullmethod) - break; + ippAddInteger(con->request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-priority", + priority); + } - if (mask == CUPSD_EVENT_NONE) - mask = CUPSD_EVENT_JOB_COMPLETED; + if ((attr = ippFindAttribute(con->request, "job-name", + IPP_TAG_NAME)) != NULL) + title = attr->values[0].string.text; + else + ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, + title = "Untitled"); - sub = cupsdAddSubscription(mask, cupsdFindDest(job->dest), job, recipient, - 0); + if ((job = cupsdAddJob(priority, printer->name)) == NULL) + { + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("Unable to add job for destination \"%s\"!"), dest); + return (NULL); + } - sub->interval = interval; + job->dtype = dtype; + job->attrs = con->request; + con->request = NULL; - cupsdSetString(&sub->owner, job->username); + add_job_uuid(con, job); + apply_printer_defaults(printer, job); - if (user_data) - { - sub->user_data_len = user_data->values[0].unknown.length; - memcpy(sub->user_data, user_data->values[0].unknown.data, - sub->user_data_len); - } + attr = ippFindAttribute(job->attrs, "requesting-user-name", IPP_TAG_NAME); - ippAddSeparator(con->response); - ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, - "notify-subscription-id", sub->id); + if (con->username[0]) + { + cupsdSetString(&job->username, con->username); if (attr) - attr = attr->next; + cupsdSetString(&attr->values[0].string.text, con->username); + + save_auth_info(con, job); } + else if (attr) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "add_job: requesting-user-name=\"%s\"", + attr->values[0].string.text); - cupsdSaveAllSubscriptions(); + cupsdSetString(&job->username, attr->values[0].string.text); + } + else + cupsdSetString(&job->username, "anonymous"); - /* - * Remove all of the subscription attributes from the job request... - */ + if (!attr) + ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, + "job-originating-user-name", NULL, job->username); + else + { + attr->group_tag = IPP_TAG_JOB; + _cups_sp_free(attr->name); + attr->name = _cups_sp_alloc("job-originating-user-name"); + } - for (attr = job->attrs->attrs, prev = NULL; attr; attr = next) + if ((attr = ippFindAttribute(job->attrs, "job-originating-host-name", + IPP_TAG_ZERO)) != NULL) { - next = attr->next; + /* + * Request contains a job-originating-host-name attribute; validate it... + */ - if (attr->group_tag == IPP_TAG_SUBSCRIPTION || - attr->group_tag == IPP_TAG_ZERO) + if (attr->value_tag != IPP_TAG_NAME || + attr->num_values != 1 || + strcmp(con->http.hostname, "localhost")) { /* - * Free and remove this attribute... + * Can't override the value if we aren't connected via localhost. + * Also, we can only have 1 value and it must be a name value. */ - _ipp_free_attr(attr); - - if (prev) - prev->next = next; - else - job->attrs->attrs = next; - } - else - prev = attr; - } + switch (attr->value_tag) + { + case IPP_TAG_STRING : + case IPP_TAG_TEXTLANG : + case IPP_TAG_NAMELANG : + case IPP_TAG_TEXT : + case IPP_TAG_NAME : + case IPP_TAG_KEYWORD : + case IPP_TAG_URI : + case IPP_TAG_URISCHEME : + case IPP_TAG_CHARSET : + case IPP_TAG_LANGUAGE : + case IPP_TAG_MIMETYPE : + /* + * Free old strings... + */ - job->attrs->last = prev; - job->attrs->current = prev; -} + for (i = 0; i < attr->num_values; i ++) + { + _cups_sp_free(attr->values[i].string.text); + attr->values[i].string.text = NULL; + if (attr->values[i].string.charset) + { + _cups_sp_free(attr->values[i].string.charset); + attr->values[i].string.charset = NULL; + } + } + default : + break; + } -/* - * 'add_job_uuid()' - Add job-uuid attribute to a job. - * - * See RFC 4122 for the definition of UUIDs and the format. - */ + /* + * Use the default connection hostname instead... + */ -static void -add_job_uuid(cupsd_client_t *con, /* I - Client connection */ - cupsd_job_t *job) /* I - Job */ -{ - char uuid[1024]; /* job-uuid string */ - ipp_attribute_t *attr; /* job-uuid attribute */ - _cups_md5_state_t md5state; /* MD5 state */ - unsigned char md5sum[16]; /* MD5 digest/sum */ + attr->value_tag = IPP_TAG_NAME; + attr->num_values = 1; + attr->values[0].string.text = _cups_sp_alloc(con->http.hostname); + } + attr->group_tag = IPP_TAG_JOB; + } + else + { + /* + * No job-originating-host-name attribute, so use the hostname from + * the connection... + */ - /* - * First see if the job already has a job-uuid attribute; if so, return... - */ + ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, + "job-originating-host-name", NULL, con->http.hostname); + } - if ((attr = ippFindAttribute(job->attrs, "job-uuid", IPP_TAG_URI)) != NULL) - return; + ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "time-at-creation", + time(NULL)); + attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, + "time-at-processing", 0); + attr->value_tag = IPP_TAG_NOVALUE; + attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, + "time-at-completed", 0); + attr->value_tag = IPP_TAG_NOVALUE; /* - * No job-uuid attribute, so build a version 3 UUID with the local job - * ID at the end; see RFC 4122 for details. Start with the MD5 sum of - * the ServerName, server name and port that the client connected to, - * and local job ID... + * Add remaining job attributes... */ - snprintf(uuid, sizeof(uuid), "%s:%s:%d:%d", ServerName, con->servername, - con->serverport, job->id); + ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id); + job->state = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_ENUM, + "job-state", IPP_JOB_STOPPED); + job->state_value = job->state->values[0].integer; + job->sheets = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, + "job-media-sheets-completed", 0); + ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri", NULL, + printer->uri); + ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, + title); - _cups_md5_init(&md5state); - _cups_md5_append(&md5state, (unsigned char *)uuid, strlen(uuid)); - _cups_md5_finish(&md5state, md5sum); + if ((attr = ippFindAttribute(job->attrs, "job-k-octets", + IPP_TAG_INTEGER)) != NULL) + attr->values[0].integer = 0; + else + attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, + "job-k-octets", 0); - /* - * Format the UUID URI using the MD5 sum and job ID. - */ - - snprintf(uuid, sizeof(uuid), - "urn:uuid:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x", - md5sum[0], md5sum[1], md5sum[2], md5sum[3], md5sum[4], md5sum[5], - (md5sum[6] & 15) | 0x30, md5sum[7], (md5sum[8] & 0x3f) | 0x40, - md5sum[9], md5sum[10], md5sum[11], md5sum[12], md5sum[13], - md5sum[14], md5sum[15]); - - ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-uuid", NULL, uuid); -} - - -/* - * 'add_printer()' - Add a printer to the system. - */ - -static void -add_printer(cupsd_client_t *con, /* I - Client connection */ - ipp_attribute_t *uri) /* I - URI of printer */ -{ - http_status_t status; /* Policy status */ - int i; /* Looping var */ - char method[HTTP_MAX_URI], /* Method portion of URI */ - username[HTTP_MAX_URI], /* Username portion of URI */ - host[HTTP_MAX_URI], /* Host portion of URI */ - resource[HTTP_MAX_URI]; /* Resource portion of URI */ - int port; /* Port portion of URI */ - cupsd_printer_t *printer; /* Printer/class */ - ipp_attribute_t *attr; /* Printer attribute */ - cups_file_t *fp; /* Script/PPD file */ - char line[1024]; /* Line from file... */ - char srcfile[1024], /* Source Script/PPD file */ - dstfile[1024]; /* Destination Script/PPD file */ - int modify; /* Non-zero if we are modifying */ - int need_restart_job; /* Need to restart job? */ - - - cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_printer(%p[%d], %s)", con, - con->http.fd, uri->values[0].string.text); - - /* - * Do we have a valid URI? - */ - - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if (strncmp(resource, "/printers/", 10) || strlen(resource) == 10) + if ((attr = ippFindAttribute(job->attrs, "job-hold-until", + IPP_TAG_KEYWORD)) == NULL) + attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME); + if (!attr) { - /* - * No, return an error... - */ + if ((val = cupsGetOption("job-hold-until", printer->num_options, + printer->options)) == NULL) + val = "no-hold"; - send_ipp_status(con, IPP_BAD_REQUEST, - _("The printer-uri must be of the form " - "\"ipp://HOSTNAME/printers/PRINTERNAME\".")); - return; + attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD, + "job-hold-until", NULL, val); } - - /* - * Do we have a valid printer name? - */ - - if (!validate_name(resource + 10)) + if (attr && strcmp(attr->values[0].string.text, "no-hold") && + !(printer->type & CUPS_PRINTER_REMOTE)) { /* - * No, return an error... + * Hold job until specified time... */ - send_ipp_status(con, IPP_BAD_REQUEST, - _("The printer-uri \"%s\" contains invalid characters."), - uri->values[0].string.text); - return; + cupsdSetJobHoldUntil(job, attr->values[0].string.text); } - - /* - * Check policy... - */ - - if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + else if (job->attrs->request.op.operation_id == IPP_CREATE_JOB) { - send_http_error(con, status); - return; + job->hold_until = time(NULL) + 60; + job->state->values[0].integer = IPP_JOB_HELD; + job->state_value = IPP_JOB_HELD; + } + else + { + job->state->values[0].integer = IPP_JOB_PENDING; + job->state_value = IPP_JOB_PENDING; } - /* - * See if the printer already exists; if not, create a new printer... - */ - - if ((printer = cupsdFindPrinter(resource + 10)) == NULL) + if (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) || + Classification) { /* - * Printer doesn't exist; see if we have a class of the same name... + * Add job sheets options... */ - if ((printer = cupsdFindClass(resource + 10)) != NULL && - !(printer->type & CUPS_PRINTER_REMOTE)) + if ((attr = ippFindAttribute(job->attrs, "job-sheets", + IPP_TAG_ZERO)) == NULL) { - /* - * Yes, return an error... - */ + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Adding default job-sheets values \"%s,%s\"...", + printer->job_sheets[0], printer->job_sheets[1]); - send_ipp_status(con, IPP_NOT_POSSIBLE, - _("A class named \"%s\" already exists!"), - resource + 10); - return; + attr = ippAddStrings(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-sheets", + 2, NULL, NULL); + attr->values[0].string.text = _cups_sp_alloc(printer->job_sheets[0]); + attr->values[1].string.text = _cups_sp_alloc(printer->job_sheets[1]); } - /* - * No, add the printer... - */ + job->job_sheets = attr; - printer = cupsdAddPrinter(resource + 10); - modify = 0; - } - else if (printer->type & CUPS_PRINTER_IMPLICIT) - { /* - * Rename the implicit printer to "AnyPrinter" or delete it... + * Enforce classification level if set... */ - if (ImplicitAnyClasses) + if (Classification) { - cupsArrayRemove(Printers, printer); - cupsdSetStringf(&printer->name, "Any%s", resource + 10); - cupsArrayAdd(Printers, printer); - } - else - cupsdDeletePrinter(printer, 1); - - /* - * Add the printer as a new local printer... - */ - - printer = cupsdAddPrinter(resource + 10); - modify = 0; - } - else if (printer->type & CUPS_PRINTER_REMOTE) - { - /* - * Rename the remote printer to "Printer@server"... - */ - - cupsdDeletePrinterFilters(printer); - cupsArrayRemove(Printers, printer); - cupsdSetStringf(&printer->name, "%s@%s", resource + 10, printer->hostname); - cupsdSetPrinterAttrs(printer); - cupsArrayAdd(Printers, printer); - - /* - * Add the printer as a new local printer... - */ - - printer = cupsdAddPrinter(resource + 10); - modify = 0; - } - else - modify = 1; - - /* - * Look for attributes and copy them over as needed... - */ - - need_restart_job = 0; - - if ((attr = ippFindAttribute(con->request, "printer-location", - IPP_TAG_TEXT)) != NULL) - cupsdSetString(&printer->location, attr->values[0].string.text); - - if ((attr = ippFindAttribute(con->request, "printer-info", - IPP_TAG_TEXT)) != NULL) - cupsdSetString(&printer->info, attr->values[0].string.text); + cupsdLogMessage(CUPSD_LOG_INFO, + "Classification=\"%s\", ClassifyOverride=%d", + Classification ? Classification : "(null)", + ClassifyOverride); - if ((attr = ippFindAttribute(con->request, "device-uri", - IPP_TAG_URI)) != NULL) - { - /* - * Do we have a valid device URI? - */ + if (ClassifyOverride) + { + if (!strcmp(attr->values[0].string.text, "none") && + (attr->num_values == 1 || + !strcmp(attr->values[1].string.text, "none"))) + { + /* + * Force the leading banner to have the classification on it... + */ - need_restart_job = 1; + cupsdSetString(&attr->values[0].string.text, Classification); - httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); + cupsdLogMessage(CUPSD_LOG_NOTICE, "[Job %d] CLASSIFICATION FORCED " + "job-sheets=\"%s,none\", " + "job-originating-user-name=\"%s\"", + job->id, Classification, job->username); + } + else if (attr->num_values == 2 && + strcmp(attr->values[0].string.text, + attr->values[1].string.text) && + strcmp(attr->values[0].string.text, "none") && + strcmp(attr->values[1].string.text, "none")) + { + /* + * Can't put two different security markings on the same document! + */ - if (!strcmp(method, "file")) - { - /* - * See if the administrator has enabled file devices... - */ + cupsdSetString(&attr->values[1].string.text, attr->values[0].string.text); - if (!FileDevice && strcmp(resource, "/dev/null")) + cupsdLogMessage(CUPSD_LOG_NOTICE, "[Job %d] CLASSIFICATION FORCED " + "job-sheets=\"%s,%s\", " + "job-originating-user-name=\"%s\"", + job->id, attr->values[0].string.text, + attr->values[1].string.text, job->username); + } + else if (strcmp(attr->values[0].string.text, Classification) && + strcmp(attr->values[0].string.text, "none") && + (attr->num_values == 1 || + (strcmp(attr->values[1].string.text, Classification) && + strcmp(attr->values[1].string.text, "none")))) + { + if (attr->num_values == 1) + cupsdLogMessage(CUPSD_LOG_NOTICE, + "[Job %d] CLASSIFICATION OVERRIDDEN " + "job-sheets=\"%s\", " + "job-originating-user-name=\"%s\"", + job->id, attr->values[0].string.text, job->username); + else + cupsdLogMessage(CUPSD_LOG_NOTICE, + "[Job %d] CLASSIFICATION OVERRIDDEN " + "job-sheets=\"%s,%s\",fffff " + "job-originating-user-name=\"%s\"", + job->id, attr->values[0].string.text, + attr->values[1].string.text, job->username); + } + } + else if (strcmp(attr->values[0].string.text, Classification) && + (attr->num_values == 1 || + strcmp(attr->values[1].string.text, Classification))) { /* - * File devices are disabled and the URL is not file:/dev/null... + * Force the banner to have the classification on it... */ - send_ipp_status(con, IPP_NOT_POSSIBLE, - _("File device URIs have been disabled! " - "To enable, see the FileDevice directive in " - "\"%s/cupsd.conf\"."), - ServerRoot); - return; - } - } - else - { - /* - * See if the backend exists and is executable... - */ + if (attr->num_values > 1 && + !strcmp(attr->values[0].string.text, attr->values[1].string.text)) + { + cupsdSetString(&(attr->values[0].string.text), Classification); + cupsdSetString(&(attr->values[1].string.text), Classification); + } + else + { + if (attr->num_values == 1 || + strcmp(attr->values[0].string.text, "none")) + cupsdSetString(&(attr->values[0].string.text), Classification); - snprintf(srcfile, sizeof(srcfile), "%s/backend/%s", ServerBin, method); - if (access(srcfile, X_OK)) - { - /* - * Could not find device in list! - */ + if (attr->num_values > 1 && + strcmp(attr->values[1].string.text, "none")) + cupsdSetString(&(attr->values[1].string.text), Classification); + } - send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad device-uri \"%s\"!"), - attr->values[0].string.text); - return; + if (attr->num_values > 1) + cupsdLogMessage(CUPSD_LOG_NOTICE, + "[Job %d] CLASSIFICATION FORCED " + "job-sheets=\"%s,%s\", " + "job-originating-user-name=\"%s\"", + job->id, attr->values[0].string.text, + attr->values[1].string.text, job->username); + else + cupsdLogMessage(CUPSD_LOG_NOTICE, + "[Job %d] CLASSIFICATION FORCED " + "job-sheets=\"%s\", " + "job-originating-user-name=\"%s\"", + job->id, Classification, job->username); } } - cupsdLogMessage(CUPSD_LOG_INFO, - "Setting %s device-uri to \"%s\" (was \"%s\".)", - printer->name, - cupsdSanitizeURI(attr->values[0].string.text, line, - sizeof(line)), - cupsdSanitizeURI(printer->device_uri, resource, - sizeof(resource))); - - cupsdSetString(&printer->device_uri, attr->values[0].string.text); - } - - if ((attr = ippFindAttribute(con->request, "port-monitor", - IPP_TAG_KEYWORD)) != NULL) - { - ipp_attribute_t *supported; /* port-monitor-supported attribute */ - - - need_restart_job = 1; - - supported = ippFindAttribute(printer->attrs, "port-monitor-supported", - IPP_TAG_KEYWORD); - for (i = 0; i < supported->num_values; i ++) - if (!strcmp(supported->values[i].string.text, - attr->values[0].string.text)) - break; + /* + * See if we need to add the starting sheet... + */ - if (i >= supported->num_values) + if (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT))) { - send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad port-monitor \"%s\"!"), - attr->values[0].string.text); - return; - } - - cupsdLogMessage(CUPSD_LOG_INFO, - "Setting %s port-monitor to \"%s\" (was \"%s\".)", - printer->name, attr->values[0].string.text, - printer->port_monitor); - - if (strcmp(attr->values[0].string.text, "none")) - cupsdSetString(&printer->port_monitor, attr->values[0].string.text); - else - cupsdClearString(&printer->port_monitor); - } + cupsdLogMessage(CUPSD_LOG_INFO, + "Adding start banner page \"%s\" to job %d.", + attr->values[0].string.text, job->id); - if ((attr = ippFindAttribute(con->request, "printer-is-accepting-jobs", - IPP_TAG_BOOLEAN)) != NULL) - { - cupsdLogMessage(CUPSD_LOG_INFO, - "Setting %s printer-is-accepting-jobs to %d (was %d.)", - printer->name, attr->values[0].boolean, printer->accepting); + kbytes = copy_banner(con, job, attr->values[0].string.text); - printer->accepting = attr->values[0].boolean; - cupsdAddPrinterHistory(printer); + cupsdUpdateQuota(printer, job->username, 0, kbytes); + } } + else if ((attr = ippFindAttribute(job->attrs, "job-sheets", + IPP_TAG_ZERO)) != NULL) + job->sheets = attr; - if ((attr = ippFindAttribute(con->request, "printer-is-shared", - IPP_TAG_BOOLEAN)) != NULL) - { - if (printer->shared && !attr->values[0].boolean) - cupsdSendBrowseDelete(printer); - - cupsdLogMessage(CUPSD_LOG_INFO, - "Setting %s printer-is-shared to %d (was %d.)", - printer->name, attr->values[0].boolean, printer->shared); + /* + * Fill in the response info... + */ - printer->shared = attr->values[0].boolean; - } + snprintf(job_uri, sizeof(job_uri), "http://%s:%d/jobs/%d", ServerName, + LocalPort, job->id); - if ((attr = ippFindAttribute(con->request, "printer-state", - IPP_TAG_ENUM)) != NULL) - { - if (attr->values[0].integer != IPP_PRINTER_IDLE && - attr->values[0].integer != IPP_PRINTER_STOPPED) - { - send_ipp_status(con, IPP_BAD_REQUEST, _("Bad printer-state value %d!"), - attr->values[0].integer); - return; - } + ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, "job-uri", NULL, + job_uri); - cupsdLogMessage(CUPSD_LOG_INFO, "Setting %s printer-state to %d (was %d.)", printer->name, - attr->values[0].integer, printer->state); + ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id); - if (attr->values[0].integer == IPP_PRINTER_STOPPED) - cupsdStopPrinter(printer, 0); - else - { - need_restart_job = 1; - cupsdSetPrinterState(printer, (ipp_pstate_t)(attr->values[0].integer), 0); - } - } - if ((attr = ippFindAttribute(con->request, "printer-state-message", - IPP_TAG_TEXT)) != NULL) - { - strlcpy(printer->state_message, attr->values[0].string.text, - sizeof(printer->state_message)); - cupsdAddPrinterHistory(printer); - } - if ((attr = ippFindAttribute(con->request, "job-sheets-default", - IPP_TAG_ZERO)) != NULL && - !Classification) - { - cupsdSetString(&printer->job_sheets[0], attr->values[0].string.text); - if (attr->num_values > 1) - cupsdSetString(&printer->job_sheets[1], attr->values[1].string.text); - else - cupsdSetString(&printer->job_sheets[1], "none"); - } - if ((attr = ippFindAttribute(con->request, "requesting-user-name-allowed", - IPP_TAG_ZERO)) != NULL) - { - cupsdFreePrinterUsers(printer); + ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state", + job->state_value); + add_job_state_reasons(con, job); - printer->deny_users = 0; - if (attr->value_tag == IPP_TAG_NAME && - (attr->num_values > 1 || - strcmp(attr->values[0].string.text, "all"))) - for (i = 0; i < attr->num_values; i ++) - cupsdAddPrinterUser(printer, attr->values[i].string.text); - } - else if ((attr = ippFindAttribute(con->request, "requesting-user-name-denied", - IPP_TAG_ZERO)) != NULL) - { - cupsdFreePrinterUsers(printer); + con->response->request.status.status_code = IPP_OK; - printer->deny_users = 1; - if (attr->value_tag == IPP_TAG_NAME && - (attr->num_values > 1 || - strcmp(attr->values[0].string.text, "none"))) - for (i = 0; i < attr->num_values; i ++) - cupsdAddPrinterUser(printer, attr->values[i].string.text); - } - if ((attr = ippFindAttribute(con->request, "job-quota-period", - IPP_TAG_INTEGER)) != NULL) - { - cupsdLogMessage(CUPSD_LOG_DEBUG, "Setting job-quota-period to %d...", - attr->values[0].integer); - cupsdFreeQuotas(printer); - printer->quota_period = attr->values[0].integer; - } - if ((attr = ippFindAttribute(con->request, "job-k-limit", - IPP_TAG_INTEGER)) != NULL) - { - cupsdLogMessage(CUPSD_LOG_DEBUG, "Setting job-k-limit to %d...", - attr->values[0].integer); - cupsdFreeQuotas(printer); - printer->k_limit = attr->values[0].integer; - } - if ((attr = ippFindAttribute(con->request, "job-page-limit", - IPP_TAG_INTEGER)) != NULL) - { - cupsdLogMessage(CUPSD_LOG_DEBUG, "Setting job-page-limit to %d...", - attr->values[0].integer); - cupsdFreeQuotas(printer); - printer->page_limit = attr->values[0].integer; - } - if ((attr = ippFindAttribute(con->request, "printer-op-policy", - IPP_TAG_NAME)) != NULL) - { - cupsd_policy_t *p; /* Policy */ + /* + * Add any job subscriptions... + */ + add_job_subscriptions(con, job); - if ((p = cupsdFindPolicy(attr->values[0].string.text)) != NULL) - { - cupsdLogMessage(CUPSD_LOG_DEBUG, - "Setting printer-op-policy to \"%s\"...", - attr->values[0].string.text); - cupsdSetString(&printer->op_policy, attr->values[0].string.text); - printer->op_policy_ptr = p; - } - else - { - send_ipp_status(con, IPP_NOT_POSSIBLE, - _("Unknown printer-op-policy \"%s\"."), - attr->values[0].string.text); - return; - } - } - if ((attr = ippFindAttribute(con->request, "printer-error-policy", - IPP_TAG_NAME)) != NULL) - { - if (strcmp(attr->values[0].string.text, "abort-job") && - strcmp(attr->values[0].string.text, "retry-job") && - strcmp(attr->values[0].string.text, "stop-printer")) - { - send_ipp_status(con, IPP_NOT_POSSIBLE, - _("Unknown printer-error-policy \"%s\"."), - attr->values[0].string.text); - return; - } + /* + * Set all but the first two attributes to the job attributes group... + */ - cupsdLogMessage(CUPSD_LOG_DEBUG, - "Setting printer-error-policy to \"%s\"...", - attr->values[0].string.text); - cupsdSetString(&printer->error_policy, attr->values[0].string.text); - } + for (attr = job->attrs->attrs->next->next; attr; attr = attr->next) + attr->group_tag = IPP_TAG_JOB; /* - * See if we have all required attributes... + * Fire the "job created" event... */ - if (!printer->device_uri) - cupsdSetString(&printer->device_uri, "file:///dev/null"); + cupsdAddEvent(CUPSD_EVENT_JOB_CREATED, printer, job, "Job created."); /* - * See if we have an interface script or PPD file attached to the request... + * Return the new job... */ - if (con->filename) - { - need_restart_job = 1; - - strlcpy(srcfile, con->filename, sizeof(srcfile)); + return (job); +} - if ((fp = cupsFileOpen(srcfile, "rb"))) - { - /* - * Yes; get the first line from it... - */ - line[0] = '\0'; - cupsFileGets(fp, line, sizeof(line)); - cupsFileClose(fp); +/* + * 'add_job_state_reasons()' - Add the "job-state-reasons" attribute based + * upon the job and printer state... + */ - /* - * Then see what kind of file it is... - */ +static void +add_job_state_reasons( + cupsd_client_t *con, /* I - Client connection */ + cupsd_job_t *job) /* I - Job info */ +{ + cupsd_printer_t *dest; /* Destination printer */ - snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot, - printer->name); - if (!strncmp(line, "*PPD-Adobe", 10)) - { - /* - * The new file is a PPD file, so remove any old interface script - * that might be lying around... - */ + cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job_state_reasons(%p[%d], %d)", + con, con->http.fd, job ? job->id : 0); - unlink(dstfile); - } - else - { - /* - * This must be an interface script, so move the file over to the - * interfaces directory and make it executable... - */ - - if (copy_file(srcfile, dstfile)) - { - send_ipp_status(con, IPP_INTERNAL_ERROR, - _("Unable to copy interface script - %s!"), - strerror(errno)); - return; - } - else - { - cupsdLogMessage(CUPSD_LOG_DEBUG, - "Copied interface script successfully!"); - chmod(dstfile, 0755); - } - } - - snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot, - printer->name); - - if (!strncmp(line, "*PPD-Adobe", 10)) - { - /* - * The new file is a PPD file, so move the file over to the - * ppd directory and make it readable by all... - */ - - if (copy_file(srcfile, dstfile)) - { - send_ipp_status(con, IPP_INTERNAL_ERROR, - _("Unable to copy PPD file - %s!"), - strerror(errno)); - return; - } - else - { - cupsdLogMessage(CUPSD_LOG_DEBUG, - "Copied PPD file successfully!"); - chmod(dstfile, 0644); - } - } - else - { - /* - * This must be an interface script, so remove any old PPD file that - * may be lying around... - */ - - unlink(dstfile); - } - } - } - else if ((attr = ippFindAttribute(con->request, "ppd-name", - IPP_TAG_NAME)) != NULL) - { - need_restart_job = 1; - - if (!strcmp(attr->values[0].string.text, "raw")) - { - /* - * Raw driver, remove any existing PPD or interface script files. - */ - - snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot, - printer->name); - unlink(dstfile); - - snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot, - printer->name); - unlink(dstfile); - } - else - { - /* - * PPD model file... - */ - - snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot, - printer->name); - unlink(dstfile); - - snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot, - printer->name); - - if (copy_model(con, attr->values[0].string.text, dstfile)) - { - send_ipp_status(con, IPP_INTERNAL_ERROR, _("Unable to copy PPD file!")); - return; - } - else - { - cupsdLogMessage(CUPSD_LOG_DEBUG, - "Copied PPD file successfully!"); - chmod(dstfile, 0644); - } - } - } - - /* - * Update the printer attributes and return... - */ - - cupsdSetPrinterAttrs(printer); - cupsdSaveAllPrinters(); - - if (need_restart_job && printer->job) + switch (job ? job->state_value : IPP_JOB_CANCELLED) { - cupsd_job_t *job; - - /* - * Stop the current job and then restart it below... - */ - - job = (cupsd_job_t *)printer->job; - - cupsdStopJob(job, 1); + case IPP_JOB_PENDING : + if (job->dtype & CUPS_PRINTER_CLASS) + dest = cupsdFindClass(job->dest); + else + dest = cupsdFindPrinter(job->dest); - job->state->values[0].integer = IPP_JOB_PENDING; - job->state_value = IPP_JOB_PENDING; - } + if (dest && dest->state == IPP_PRINTER_STOPPED) + ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, + "job-state-reasons", NULL, "printer-stopped"); + else + ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, + "job-state-reasons", NULL, "none"); + break; - if (need_restart_job) - cupsdCheckJobs(); + case IPP_JOB_HELD : + if (ippFindAttribute(job->attrs, "job-hold-until", + IPP_TAG_KEYWORD) != NULL || + ippFindAttribute(job->attrs, "job-hold-until", + IPP_TAG_NAME) != NULL) + ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, + "job-state-reasons", NULL, "job-hold-until-specified"); + else + ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, + "job-state-reasons", NULL, "job-incoming"); + break; - cupsdWritePrintcap(); + case IPP_JOB_PROCESSING : + ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, + "job-state-reasons", NULL, "job-printing"); + break; - if (modify) - { - cupsdAddEvent(CUPSD_EVENT_PRINTER_MODIFIED, printer, NULL, - "Printer \"%s\" modified by \"%s\".", printer->name, - get_username(con)); + case IPP_JOB_STOPPED : + ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, + "job-state-reasons", NULL, "job-stopped"); + break; - cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" modified by \"%s\".", - printer->name, get_username(con)); - } - else - { - cupsdAddPrinterHistory(printer); + case IPP_JOB_CANCELLED : + ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, + "job-state-reasons", NULL, "job-canceled-by-user"); + break; - cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, printer, NULL, - "New printer \"%s\" added by \"%s\".", printer->name, - get_username(con)); + case IPP_JOB_ABORTED : + ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, + "job-state-reasons", NULL, "aborted-by-system"); + break; - cupsdLogMessage(CUPSD_LOG_INFO, "New printer \"%s\" added by \"%s\".", - printer->name, get_username(con)); + case IPP_JOB_COMPLETED : + ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, + "job-state-reasons", NULL, "job-completed-successfully"); + break; } - - con->response->request.status.status_code = IPP_OK; } /* - * 'add_printer_state_reasons()' - Add the "printer-state-reasons" attribute - * based upon the printer state... + * 'add_job_subscriptions()' - Add any subcriptions for a job. */ static void -add_printer_state_reasons( - cupsd_client_t *con, /* I - Client connection */ - cupsd_printer_t *p) /* I - Printer info */ +add_job_subscriptions( + cupsd_client_t *con, /* I - Client connection */ + cupsd_job_t *job) /* I - Newly created job */ { - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "add_printer_state_reasons(%p[%d], %p[%s])", - con, con->http.fd, p, p->name); - - if (p->num_reasons == 0) - ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, - "printer-state-reasons", NULL, - p->state == IPP_PRINTER_STOPPED ? "paused" : "none"); - else - ippAddStrings(con->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, - "printer-state-reasons", p->num_reasons, NULL, - (const char * const *)p->reasons); -} - - -/* - * 'add_queued_job_count()' - Add the "queued-job-count" attribute for - * the specified printer or class. - */ + int i; /* Looping var */ + ipp_attribute_t *prev, /* Previous attribute */ + *next, /* Next attribute */ + *attr; /* Current attribute */ + cupsd_subscription_t *sub; /* Subscription object */ + const char *recipient, /* notify-recipient-uri */ + *pullmethod; /* notify-pull-method */ + ipp_attribute_t *user_data; /* notify-user-data */ + int interval; /* notify-time-interval */ + unsigned mask; /* notify-events */ -static void -add_queued_job_count( - cupsd_client_t *con, /* I - Client connection */ - cupsd_printer_t *p) /* I - Printer or class */ -{ - int count; /* Number of jobs on destination */ + /* + * Find the first subscription group attribute; return if we have + * none... + */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_queued_job_count(%p[%d], %p[%s])", - con, con->http.fd, p, p->name); + for (attr = job->attrs->attrs, prev = NULL; + attr; + prev = attr, attr = attr->next) + if (attr->group_tag == IPP_TAG_SUBSCRIPTION) + break; - count = cupsdGetPrinterJobCount(p->name); + if (!attr) + return; - ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "queued-job-count", count); -} + /* + * Process the subscription attributes in the request... + */ + while (attr) + { + recipient = NULL; + pullmethod = NULL; + user_data = NULL; + interval = 0; + mask = CUPSD_EVENT_NONE; -/* - * 'authenticate_job()' - Set job authentication info. - */ + while (attr && attr->group_tag != IPP_TAG_ZERO) + { + if (!strcmp(attr->name, "notify-recipient") && + attr->value_tag == IPP_TAG_URI) + recipient = attr->values[0].string.text; + else if (!strcmp(attr->name, "notify-pull-method") && + attr->value_tag == IPP_TAG_KEYWORD) + pullmethod = attr->values[0].string.text; + else if (!strcmp(attr->name, "notify-charset") && + attr->value_tag == IPP_TAG_CHARSET && + strcmp(attr->values[0].string.text, "us-ascii") && + strcmp(attr->values[0].string.text, "utf-8")) + { + send_ipp_status(con, IPP_CHARSET, + _("Character set \"%s\" not supported!"), + attr->values[0].string.text); + return; + } + else if (!strcmp(attr->name, "notify-natural-language") && + (attr->value_tag != IPP_TAG_LANGUAGE || + strcmp(attr->values[0].string.text, DefaultLanguage))) + { + send_ipp_status(con, IPP_CHARSET, + _("Language \"%s\" not supported!"), + attr->values[0].string.text); + return; + } + else if (!strcmp(attr->name, "notify-user-data") && + attr->value_tag == IPP_TAG_STRING) + { + if (attr->num_values > 1 || attr->values[0].unknown.length > 63) + { + send_ipp_status(con, IPP_REQUEST_VALUE, + _("The notify-user-data value is too large " + "(%d > 63 octets)!"), + attr->values[0].unknown.length); + return; + } -static void -authenticate_job(cupsd_client_t *con, /* I - Client connection */ - ipp_attribute_t *uri) /* I - Job URI */ -{ - ipp_attribute_t *attr; /* Job-id attribute */ - int jobid; /* Job ID */ - cupsd_job_t *job; /* Current job */ - char method[HTTP_MAX_URI], - /* Method portion of URI */ - username[HTTP_MAX_URI], - /* Username portion of URI */ - host[HTTP_MAX_URI], - /* Host portion of URI */ - resource[HTTP_MAX_URI]; - /* Resource portion of URI */ - int port; /* Port portion of URI */ + user_data = attr; + } + else if (!strcmp(attr->name, "notify-events") && + attr->value_tag == IPP_TAG_KEYWORD) + { + for (i = 0; i < attr->num_values; i ++) + mask |= cupsdEventValue(attr->values[i].string.text); + } + else if (!strcmp(attr->name, "notify-lease-duration")) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("The notify-lease-duration attribute cannot be " + "used with job subscriptions.")); + return; + } + else if (!strcmp(attr->name, "notify-time-interval") && + attr->value_tag == IPP_TAG_INTEGER) + interval = attr->values[0].integer; + attr = attr->next; + } - cupsdLogMessage(CUPSD_LOG_DEBUG2, "authenticate_job(%p[%d], %s)", - con, con->http.fd, uri->values[0].string.text); + if (!recipient && !pullmethod) + break; - /* - * Start with "everything is OK" status... - */ + if (mask == CUPSD_EVENT_NONE) + mask = CUPSD_EVENT_JOB_COMPLETED; - con->response->request.status.status_code = IPP_OK; + sub = cupsdAddSubscription(mask, cupsdFindDest(job->dest), job, recipient, + 0); - /* - * See if we have a job URI or a printer URI... - */ + sub->interval = interval; - if (!strcmp(uri->name, "printer-uri")) - { - /* - * Got a printer URI; see if we also have a job-id attribute... - */ + cupsdSetString(&sub->owner, job->username); - if ((attr = ippFindAttribute(con->request, "job-id", - IPP_TAG_INTEGER)) == NULL) + if (user_data) { - send_ipp_status(con, IPP_BAD_REQUEST, - _("Got a printer-uri attribute but no job-id!")); - return; + sub->user_data_len = user_data->values[0].unknown.length; + memcpy(sub->user_data, user_data->values[0].unknown.data, + sub->user_data_len); } - jobid = attr->values[0].integer; - } - else - { - /* - * Got a job URI; parse it to get the job ID... - */ - - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if (strncmp(resource, "/jobs/", 6)) - { - /* - * Not a valid URI! - */ - - send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri attribute \"%s\"!"), - uri->values[0].string.text); - return; - } + ippAddSeparator(con->response); + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, + "notify-subscription-id", sub->id); - jobid = atoi(resource + 6); + if (attr) + attr = attr->next; } + cupsdSaveAllSubscriptions(); + /* - * See if the job exists... + * Remove all of the subscription attributes from the job request... */ - if ((job = cupsdFindJob(jobid)) == NULL) + for (attr = job->attrs->attrs, prev = NULL; attr; attr = next) { - /* - * Nope - return a "not found" error... - */ - - send_ipp_status(con, IPP_NOT_FOUND, - _("Job #%d does not exist!"), jobid); - return; - } + next = attr->next; - /* - * See if the job has been completed... - */ + if (attr->group_tag == IPP_TAG_SUBSCRIPTION || + attr->group_tag == IPP_TAG_ZERO) + { + /* + * Free and remove this attribute... + */ - if (job->state_value != IPP_JOB_HELD) - { - /* - * Return a "not-possible" error... - */ + _ipp_free_attr(attr); - send_ipp_status(con, IPP_NOT_POSSIBLE, - _("Job #%d is not held for authentication!"), - jobid); - return; + if (prev) + prev->next = next; + else + job->attrs->attrs = next; + } + else + prev = attr; } - /* - * See if we have already authenticated... - */ + job->attrs->last = prev; + job->attrs->current = prev; +} - if (!con->username[0]) - { - send_ipp_status(con, IPP_NOT_AUTHORIZED, - _("No authentication information provided!")); - return; - } - /* - * See if the job is owned by the requesting user... - */ +/* + * 'add_job_uuid()' - Add job-uuid attribute to a job. + * + * See RFC 4122 for the definition of UUIDs and the format. + */ + +static void +add_job_uuid(cupsd_client_t *con, /* I - Client connection */ + cupsd_job_t *job) /* I - Job */ +{ + char uuid[1024]; /* job-uuid string */ + ipp_attribute_t *attr; /* job-uuid attribute */ + _cups_md5_state_t md5state; /* MD5 state */ + unsigned char md5sum[16]; /* MD5 digest/sum */ - if (!validate_user(job, con, job->username, username, sizeof(username))) - { - send_http_error(con, HTTP_UNAUTHORIZED); - return; - } /* - * Save the authentication information for this job... + * First see if the job already has a job-uuid attribute; if so, return... */ - save_auth_info(con, job); + if ((attr = ippFindAttribute(job->attrs, "job-uuid", IPP_TAG_URI)) != NULL) + return; /* - * Reset the job-hold-until value to "no-hold"... + * No job-uuid attribute, so build a version 3 UUID with the local job + * ID at the end; see RFC 4122 for details. Start with the MD5 sum of + * the ServerName, server name and port that the client connected to, + * and local job ID... */ - if ((attr = ippFindAttribute(job->attrs, "job-hold-until", - IPP_TAG_KEYWORD)) == NULL) - attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME); + snprintf(uuid, sizeof(uuid), "%s:%s:%d:%d", ServerName, con->servername, + con->serverport, job->id); - if (attr) - { - attr->value_tag = IPP_TAG_KEYWORD; - cupsdSetString(&(attr->values[0].string.text), "no-hold"); - } + _cups_md5_init(&md5state); + _cups_md5_append(&md5state, (unsigned char *)uuid, strlen(uuid)); + _cups_md5_finish(&md5state, md5sum); /* - * Release the job and return... + * Format the UUID URI using the MD5 sum and job ID. */ - cupsdReleaseJob(job); + snprintf(uuid, sizeof(uuid), + "urn:uuid:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x%02x%02x%02x%02x", + md5sum[0], md5sum[1], md5sum[2], md5sum[3], md5sum[4], md5sum[5], + (md5sum[6] & 15) | 0x30, md5sum[7], (md5sum[8] & 0x3f) | 0x40, + md5sum[9], md5sum[10], md5sum[11], md5sum[12], md5sum[13], + md5sum[14], md5sum[15]); - cupsdLogMessage(CUPSD_LOG_INFO, "Job %d was authenticated by \"%s\".", jobid, - con->username); + ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-uuid", NULL, uuid); } /* - * 'cancel_all_jobs()' - Cancel all print jobs. + * 'add_printer()' - Add a printer to the system. */ static void -cancel_all_jobs(cupsd_client_t *con, /* I - Client connection */ - ipp_attribute_t *uri) /* I - Job or Printer URI */ +add_printer(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - URI of printer */ { http_status_t status; /* Policy status */ - const char *dest; /* Destination */ - cups_ptype_t dtype; /* Destination type */ + int i; /* Looping var */ char method[HTTP_MAX_URI], /* Method portion of URI */ - userpass[HTTP_MAX_URI], /* Username portion of URI */ + username[HTTP_MAX_URI], /* Username portion of URI */ host[HTTP_MAX_URI], /* Host portion of URI */ resource[HTTP_MAX_URI]; /* Resource portion of URI */ int port; /* Port portion of URI */ - ipp_attribute_t *attr; /* Attribute in request */ - const char *username; /* Username */ - int purge; /* Purge? */ - cupsd_printer_t *printer; /* Printer */ + cupsd_printer_t *printer; /* Printer/class */ + ipp_attribute_t *attr; /* Printer attribute */ + cups_file_t *fp; /* Script/PPD file */ + char line[1024]; /* Line from file... */ + char srcfile[1024], /* Source Script/PPD file */ + dstfile[1024]; /* Destination Script/PPD file */ + int modify; /* Non-zero if we are modifying */ + char newname[IPP_MAX_NAME]; /* New printer name */ + int need_restart_job; /* Need to restart job? */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_all_jobs(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_printer(%p[%d], %s)", con, con->http.fd, uri->values[0].string.text); /* - * See if we have a printer URI... + * Do we have a valid URI? */ - if (strcmp(uri->name, "printer-uri")) + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, + sizeof(method), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (strncmp(resource, "/printers/", 10) || strlen(resource) == 10) { + /* + * No, return an error... + */ + send_ipp_status(con, IPP_BAD_REQUEST, - _("The printer-uri attribute is required!")); + _("The printer-uri must be of the form " + "\"ipp://HOSTNAME/printers/PRINTERNAME\".")); return; } /* - * Get the username (if any) for the jobs we want to cancel (only if - * "my-jobs" is specified... + * Do we have a valid printer name? */ - if ((attr = ippFindAttribute(con->request, "my-jobs", - IPP_TAG_BOOLEAN)) != NULL && - attr->values[0].boolean) + if (!validate_name(resource + 10)) { - if ((attr = ippFindAttribute(con->request, "requesting-user-name", - IPP_TAG_NAME)) != NULL) - username = attr->values[0].string.text; - else - { - send_ipp_status(con, IPP_BAD_REQUEST, - _("Missing requesting-user-name attribute!")); - return; - } + /* + * No, return an error... + */ + + send_ipp_status(con, IPP_BAD_REQUEST, + _("The printer-uri \"%s\" contains invalid characters."), + uri->values[0].string.text); + return; } - else - username = NULL; /* - * Look for the "purge-jobs" attribute... + * Check policy... */ - if ((attr = ippFindAttribute(con->request, "purge-jobs", - IPP_TAG_BOOLEAN)) != NULL) - purge = attr->values[0].boolean; - else - purge = 1; + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status); + return; + } /* - * And if the destination is valid... - */ - - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), userpass, sizeof(userpass), host, - sizeof(host), &port, resource, sizeof(resource)); + * See if the printer already exists; if not, create a new printer... + */ - if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if ((printer = cupsdFindPrinter(resource + 10)) == NULL) { /* - * Bad URI? + * Printer doesn't exist; see if we have a class of the same name... */ - if ((!strncmp(resource, "/printers/", 10) && resource[10]) || - (!strncmp(resource, "/classes/", 9) && resource[9])) - { - send_ipp_status(con, IPP_NOT_FOUND, - _("The printer or class was not found.")); - return; - } - else if (strcmp(resource, "/printers/")) + if ((printer = cupsdFindClass(resource + 10)) != NULL && + !(printer->type & CUPS_PRINTER_REMOTE)) { - send_ipp_status(con, IPP_NOT_FOUND, - _("The printer-uri \"%s\" is not valid."), - uri->values[0].string.text); - return; - } - - /* - * Check policy... - */ + /* + * Yes, return an error... + */ - if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) - { - send_http_error(con, status); + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("A class named \"%s\" already exists!"), + resource + 10); return; } /* - * Cancel all jobs on all printers... + * No, add the printer... */ - cupsdCancelJobs(NULL, username, purge); - - cupsdLogMessage(CUPSD_LOG_INFO, "All jobs were %s by \"%s\".", - purge ? "purged" : "cancelled", get_username(con)); + printer = cupsdAddPrinter(resource + 10); + modify = 0; } - else + else if (printer->type & CUPS_PRINTER_IMPLICIT) { /* - * Check policy... + * Rename the implicit printer to "AnyPrinter" or delete it... */ - if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + if (ImplicitAnyClasses) { - send_http_error(con, status); - return; + snprintf(newname, sizeof(newname), "Any%s", resource + 10); + cupsdRenamePrinter(printer, newname); } + else + cupsdDeletePrinter(printer, 1); /* - * Cancel all of the jobs on the named printer... + * Add the printer as a new local printer... */ - cupsdCancelJobs(dest, username, purge); - - cupsdLogMessage(CUPSD_LOG_INFO, "All jobs on \"%s\" were %s by \"%s\".", - dest, purge ? "purged" : "cancelled", get_username(con)); + printer = cupsdAddPrinter(resource + 10); + modify = 0; } + else if (printer->type & CUPS_PRINTER_REMOTE) + { + /* + * Rename the remote printer to "Printer@server"... + */ - con->response->request.status.status_code = IPP_OK; -} + snprintf(newname, sizeof(newname), "%s@%s", resource + 10, + printer->hostname); + cupsdRenamePrinter(printer, newname); + /* + * Add the printer as a new local printer... + */ -/* - * 'cancel_job()' - Cancel a print job. - */ + printer = cupsdAddPrinter(resource + 10); + modify = 0; + } + else + modify = 1; -static void -cancel_job(cupsd_client_t *con, /* I - Client connection */ - ipp_attribute_t *uri) /* I - Job or Printer URI */ -{ - ipp_attribute_t *attr; /* Current attribute */ - int jobid; /* Job ID */ - char method[HTTP_MAX_URI], /* Method portion of URI */ - username[HTTP_MAX_URI], /* Username portion of URI */ - host[HTTP_MAX_URI], /* Host portion of URI */ - resource[HTTP_MAX_URI]; /* Resource portion of URI */ - int port; /* Port portion of URI */ - cupsd_job_t *job; /* Job information */ - const char *dest; /* Destination */ - cups_ptype_t dtype; /* Destination type (printer or class) */ - cupsd_printer_t *printer; /* Printer data */ + /* + * Look for attributes and copy them over as needed... + */ + need_restart_job = 0; - cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_job(%p[%d], %s)", con, - con->http.fd, uri->values[0].string.text); + if ((attr = ippFindAttribute(con->request, "printer-location", + IPP_TAG_TEXT)) != NULL) + cupsdSetString(&printer->location, attr->values[0].string.text); - /* - * See if we have a job URI or a printer URI... - */ + if ((attr = ippFindAttribute(con->request, "printer-info", + IPP_TAG_TEXT)) != NULL) + cupsdSetString(&printer->info, attr->values[0].string.text); - if (!strcmp(uri->name, "printer-uri")) + if ((attr = ippFindAttribute(con->request, "device-uri", + IPP_TAG_URI)) != NULL) { /* - * Got a printer URI; see if we also have a job-id attribute... + * Do we have a valid device URI? */ - if ((attr = ippFindAttribute(con->request, "job-id", - IPP_TAG_INTEGER)) == NULL) - { - send_ipp_status(con, IPP_BAD_REQUEST, - _("Got a printer-uri attribute but no job-id!")); - return; - } + need_restart_job = 1; - if ((jobid = attr->values[0].integer) == 0) + httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text, method, + sizeof(method), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (!strcmp(method, "file")) { /* - * Find the current job on the specified printer... + * See if the administrator has enabled file devices... */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if (!FileDevice && strcmp(resource, "/dev/null")) { /* - * Bad URI... + * File devices are disabled and the URL is not file:/dev/null... */ - send_ipp_status(con, IPP_NOT_FOUND, - _("The printer or class was not found.")); + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("File device URIs have been disabled! " + "To enable, see the FileDevice directive in " + "\"%s/cupsd.conf\"."), + ServerRoot); return; } - + } + else + { /* - * See if the printer is currently printing a job... + * See if the backend exists and is executable... */ - if (printer->job) - jobid = ((cupsd_job_t *)printer->job)->id; - else + snprintf(srcfile, sizeof(srcfile), "%s/backend/%s", ServerBin, method); + if (access(srcfile, X_OK)) { /* - * No, see if there are any pending jobs... + * Could not find device in list! */ - - for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs); - job; - job = (cupsd_job_t *)cupsArrayNext(ActiveJobs)) - if (job->state_value <= IPP_JOB_PROCESSING && - !strcasecmp(job->dest, dest)) - break; - if (job) - jobid = job->id; - else - { - send_ipp_status(con, IPP_NOT_POSSIBLE, _("No active jobs on %s!"), - dest); - return; - } + send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad device-uri \"%s\"!"), + attr->values[0].string.text); + return; } } - } - else - { - /* - * Got a job URI; parse it to get the job ID... - */ - - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if (strncmp(resource, "/jobs/", 6)) - { - /* - * Not a valid URI! - */ - - send_ipp_status(con, IPP_BAD_REQUEST, - _("Bad job-uri attribute \"%s\"!"), - uri->values[0].string.text); - return; - } - - jobid = atoi(resource + 6); - } - - /* - * See if the job exists... - */ - - if ((job = cupsdFindJob(jobid)) == NULL) - { - /* - * Nope - return a "not found" error... - */ - - send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid); - return; - } - /* - * See if the job is owned by the requesting user... - */ + cupsdLogMessage(CUPSD_LOG_INFO, + "Setting %s device-uri to \"%s\" (was \"%s\".)", + printer->name, + cupsdSanitizeURI(attr->values[0].string.text, line, + sizeof(line)), + cupsdSanitizeURI(printer->device_uri, resource, + sizeof(resource))); - if (!validate_user(job, con, job->username, username, sizeof(username))) - { - send_http_error(con, HTTP_UNAUTHORIZED); - return; + cupsdSetString(&printer->device_uri, attr->values[0].string.text); } - /* - * See if the job is already completed, cancelled, or aborted; if so, - * we can't cancel... - */ - - if (job->state_value >= IPP_JOB_CANCELLED) + if ((attr = ippFindAttribute(con->request, "port-monitor", + IPP_TAG_KEYWORD)) != NULL) { - send_ipp_status(con, IPP_NOT_POSSIBLE, - _("Job #%d is already %s - can\'t cancel."), jobid, - job->state_value == IPP_JOB_CANCELLED ? "cancelled" : - job->state_value == IPP_JOB_ABORTED ? "aborted" : - "completed"); - return; - } + ipp_attribute_t *supported; /* port-monitor-supported attribute */ - /* - * Cancel the job and return... - */ - cupsdAddEvent(CUPSD_EVENT_JOB_COMPLETED, job->printer, job, - "Job cancelled by \"%s\".", username); + need_restart_job = 1; - cupsdCancelJob(job, 0); - cupsdCheckJobs(); + supported = ippFindAttribute(printer->attrs, "port-monitor-supported", + IPP_TAG_KEYWORD); + for (i = 0; i < supported->num_values; i ++) + if (!strcmp(supported->values[i].string.text, + attr->values[0].string.text)) + break; - cupsdLogMessage(CUPSD_LOG_INFO, "Job %d was cancelled by \"%s\".", jobid, - username); + if (i >= supported->num_values) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad port-monitor \"%s\"!"), + attr->values[0].string.text); + return; + } - con->response->request.status.status_code = IPP_OK; -} + cupsdLogMessage(CUPSD_LOG_INFO, + "Setting %s port-monitor to \"%s\" (was \"%s\".)", + printer->name, attr->values[0].string.text, + printer->port_monitor); + if (strcmp(attr->values[0].string.text, "none")) + cupsdSetString(&printer->port_monitor, attr->values[0].string.text); + else + cupsdClearString(&printer->port_monitor); + } -/* - * 'cancel_subscription()' - Cancel a subscription. - */ + if ((attr = ippFindAttribute(con->request, "printer-is-accepting-jobs", + IPP_TAG_BOOLEAN)) != NULL) + { + cupsdLogMessage(CUPSD_LOG_INFO, + "Setting %s printer-is-accepting-jobs to %d (was %d.)", + printer->name, attr->values[0].boolean, printer->accepting); -static void -cancel_subscription( - cupsd_client_t *con, /* I - Client connection */ - int sub_id) /* I - Subscription ID */ -{ - http_status_t status; /* Policy status */ - cupsd_subscription_t *sub; /* Subscription */ + printer->accepting = attr->values[0].boolean; + cupsdAddPrinterHistory(printer); + } + if ((attr = ippFindAttribute(con->request, "printer-is-shared", + IPP_TAG_BOOLEAN)) != NULL) + { + if (printer->shared && !attr->values[0].boolean) + cupsdSendBrowseDelete(printer); - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cancel_subscription(con=%p[%d], sub_id=%d)", - con, con->http.fd, sub_id); + cupsdLogMessage(CUPSD_LOG_INFO, + "Setting %s printer-is-shared to %d (was %d.)", + printer->name, attr->values[0].boolean, printer->shared); - /* - * Is the subscription ID valid? - */ + printer->shared = attr->values[0].boolean; + } - if ((sub = cupsdFindSubscription(sub_id)) == NULL) + if ((attr = ippFindAttribute(con->request, "printer-state", + IPP_TAG_ENUM)) != NULL) { - /* - * Bad subscription ID... - */ + if (attr->values[0].integer != IPP_PRINTER_IDLE && + attr->values[0].integer != IPP_PRINTER_STOPPED) + { + send_ipp_status(con, IPP_BAD_REQUEST, _("Bad printer-state value %d!"), + attr->values[0].integer); + return; + } - send_ipp_status(con, IPP_NOT_FOUND, - _("notify-subscription-id %d no good!"), sub_id); - return; + cupsdLogMessage(CUPSD_LOG_INFO, "Setting %s printer-state to %d (was %d.)", printer->name, + attr->values[0].integer, printer->state); + + if (attr->values[0].integer == IPP_PRINTER_STOPPED) + cupsdStopPrinter(printer, 0); + else + { + need_restart_job = 1; + cupsdSetPrinterState(printer, (ipp_pstate_t)(attr->values[0].integer), 0); + } + } + if ((attr = ippFindAttribute(con->request, "printer-state-message", + IPP_TAG_TEXT)) != NULL) + { + strlcpy(printer->state_message, attr->values[0].string.text, + sizeof(printer->state_message)); + cupsdAddPrinterHistory(printer); } + set_printer_defaults(con, printer); + /* - * Check policy... + * See if we have all required attributes... */ - if ((status = cupsdCheckPolicy(sub->dest ? sub->dest->op_policy_ptr : - DefaultPolicyPtr, - con, sub->owner)) != HTTP_OK) - { - send_http_error(con, status); - return; - } + if (!printer->device_uri) + cupsdSetString(&printer->device_uri, "file:///dev/null"); /* - * Cancel the subscription... + * See if we have an interface script or PPD file attached to the request... */ - cupsdDeleteSubscription(sub, 1); + if (con->filename) + { + need_restart_job = 1; - con->response->request.status.status_code = IPP_OK; -} + strlcpy(srcfile, con->filename, sizeof(srcfile)); + if ((fp = cupsFileOpen(srcfile, "rb"))) + { + /* + * Yes; get the first line from it... + */ -/* - * 'check_quotas()' - Check quotas for a printer and user. - */ + line[0] = '\0'; + cupsFileGets(fp, line, sizeof(line)); + cupsFileClose(fp); -static int /* O - 1 if OK, 0 if not */ -check_quotas(cupsd_client_t *con, /* I - Client connection */ - cupsd_printer_t *p) /* I - Printer or class */ -{ - int i; /* Looping var */ - char username[33]; /* Username */ - cupsd_quota_t *q; /* Quota data */ - struct passwd *pw; /* User password data */ + /* + * Then see what kind of file it is... + */ + snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot, + printer->name); - cupsdLogMessage(CUPSD_LOG_DEBUG2, "check_quotas(%p[%d], %p[%s])", - con, con->http.fd, p, p->name); + if (!strncmp(line, "*PPD-Adobe", 10)) + { + /* + * The new file is a PPD file, so remove any old interface script + * that might be lying around... + */ - /* - * Check input... - */ + unlink(dstfile); + } + else + { + /* + * This must be an interface script, so move the file over to the + * interfaces directory and make it executable... + */ - if (!con || !p) - return (0); + if (copy_file(srcfile, dstfile)) + { + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("Unable to copy interface script - %s!"), + strerror(errno)); + return; + } + else + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Copied interface script successfully!"); + chmod(dstfile, 0755); + } + } - /* - * Figure out who is printing... - */ + snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot, + printer->name); - strlcpy(username, get_username(con), sizeof(username)); + if (!strncmp(line, "*PPD-Adobe", 10)) + { + /* + * The new file is a PPD file, so move the file over to the + * ppd directory and make it readable by all... + */ - /* - * Check global active job limits for printers and users... - */ + if (copy_file(srcfile, dstfile)) + { + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("Unable to copy PPD file - %s!"), + strerror(errno)); + return; + } + else + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Copied PPD file successfully!"); + chmod(dstfile, 0644); + } + } + else + { + /* + * This must be an interface script, so remove any old PPD file that + * may be lying around... + */ - if (MaxJobsPerPrinter) + unlink(dstfile); + } + } + } + else if ((attr = ippFindAttribute(con->request, "ppd-name", + IPP_TAG_NAME)) != NULL) { - /* - * Check if there are too many pending jobs on this printer... - */ + need_restart_job = 1; - if (cupsdGetPrinterJobCount(p->name) >= MaxJobsPerPrinter) + if (!strcmp(attr->values[0].string.text, "raw")) { - cupsdLogMessage(CUPSD_LOG_INFO, "Too many jobs for printer \"%s\"...", - p->name); - return (0); - } - } + /* + * Raw driver, remove any existing PPD or interface script files. + */ - if (MaxJobsPerUser) - { - /* - * Check if there are too many pending jobs for this user... - */ + snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot, + printer->name); + unlink(dstfile); - if (cupsdGetUserJobCount(username) >= MaxJobsPerUser) + snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot, + printer->name); + unlink(dstfile); + } + else { - cupsdLogMessage(CUPSD_LOG_INFO, "Too many jobs for user \"%s\"...", - username); - return (0); + /* + * PPD model file... + */ + + snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot, + printer->name); + unlink(dstfile); + + snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot, + printer->name); + + if (copy_model(con, attr->values[0].string.text, dstfile)) + { + send_ipp_status(con, IPP_INTERNAL_ERROR, _("Unable to copy PPD file!")); + return; + } + else + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Copied PPD file successfully!"); + chmod(dstfile, 0644); + } } } /* - * Check against users... + * Update the printer attributes and return... */ - if (p->num_users == 0 && p->k_limit == 0 && p->page_limit == 0) - return (1); + cupsdSetPrinterAttrs(printer); + cupsdSaveAllPrinters(); - if (p->num_users) + if (need_restart_job && printer->job) { - pw = getpwnam(username); - endpwent(); + cupsd_job_t *job; - for (i = 0; i < p->num_users; i ++) - if (p->users[i][0] == '@') - { - /* - * Check group membership... - */ + /* + * Stop the current job and then restart it below... + */ - if (cupsdCheckGroup(username, pw, p->users[i] + 1)) - break; - } - else if (!strcasecmp(username, p->users[i])) - break; + job = (cupsd_job_t *)printer->job; - if ((i < p->num_users) == p->deny_users) - { - cupsdLogMessage(CUPSD_LOG_INFO, - "Denying user \"%s\" access to printer \"%s\"...", - username, p->name); - return (0); - } + cupsdStopJob(job, 1); + + job->state->values[0].integer = IPP_JOB_PENDING; + job->state_value = IPP_JOB_PENDING; } - /* - * Check quotas... - */ + if (need_restart_job) + cupsdCheckJobs(); - if (p->k_limit || p->page_limit) + cupsdWritePrintcap(); + + if (modify) { - if ((q = cupsdUpdateQuota(p, username, 0, 0)) == NULL) - { - cupsdLogMessage(CUPSD_LOG_ERROR, - "Unable to allocate quota data for user \"%s\"!", - username); - return (0); - } + cupsdAddEvent(CUPSD_EVENT_PRINTER_MODIFIED, printer, NULL, + "Printer \"%s\" modified by \"%s\".", printer->name, + get_username(con)); - if ((q->k_count >= p->k_limit && p->k_limit) || - (q->page_count >= p->page_limit && p->page_limit)) - { - cupsdLogMessage(CUPSD_LOG_INFO, "User \"%s\" is over the quota limit...", - username); - return (0); - } + cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" modified by \"%s\".", + printer->name, get_username(con)); } + else + { + cupsdAddPrinterHistory(printer); - /* - * If we have gotten this far, we're done! - */ + cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, printer, NULL, + "New printer \"%s\" added by \"%s\".", printer->name, + get_username(con)); - return (1); + cupsdLogMessage(CUPSD_LOG_INFO, "New printer \"%s\" added by \"%s\".", + printer->name, get_username(con)); + } + + con->response->request.status.status_code = IPP_OK; } /* - * 'copy_attribute()' - Copy a single attribute. + * 'add_printer_state_reasons()' - Add the "printer-state-reasons" attribute + * based upon the printer state... */ -static ipp_attribute_t * /* O - New attribute */ -copy_attribute( - ipp_t *to, /* O - Destination request/response */ - ipp_attribute_t *attr, /* I - Attribute to copy */ - int quickcopy) /* I - Do a quick copy? */ +static void +add_printer_state_reasons( + cupsd_client_t *con, /* I - Client connection */ + cupsd_printer_t *p) /* I - Printer info */ { - int i; /* Looping var */ - ipp_attribute_t *toattr; /* Destination attribute */ + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "add_printer_state_reasons(%p[%d], %p[%s])", + con, con->http.fd, p, p->name); + if (p->num_reasons == 0) + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "printer-state-reasons", NULL, + p->state == IPP_PRINTER_STOPPED ? "paused" : "none"); + else + ippAddStrings(con->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "printer-state-reasons", p->num_reasons, NULL, + (const char * const *)p->reasons); +} - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "copy_attribute(%p, %p[%s,%x,%x])", to, attr, - attr->name ? attr->name : "(null)", attr->group_tag, - attr->value_tag); - switch (attr->value_tag & ~IPP_TAG_COPY) - { - case IPP_TAG_ZERO : - toattr = ippAddSeparator(to); - break; +/* + * 'add_queued_job_count()' - Add the "queued-job-count" attribute for + * the specified printer or class. + */ - case IPP_TAG_INTEGER : - case IPP_TAG_ENUM : - toattr = ippAddIntegers(to, attr->group_tag, attr->value_tag, - attr->name, attr->num_values, NULL); +static void +add_queued_job_count( + cupsd_client_t *con, /* I - Client connection */ + cupsd_printer_t *p) /* I - Printer or class */ +{ + int count; /* Number of jobs on destination */ - for (i = 0; i < attr->num_values; i ++) - toattr->values[i].integer = attr->values[i].integer; - break; - case IPP_TAG_BOOLEAN : - toattr = ippAddBooleans(to, attr->group_tag, attr->name, - attr->num_values, NULL); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_queued_job_count(%p[%d], %p[%s])", + con, con->http.fd, p, p->name); - for (i = 0; i < attr->num_values; i ++) - toattr->values[i].boolean = attr->values[i].boolean; - break; + count = cupsdGetPrinterJobCount(p->name); - case IPP_TAG_STRING : - case IPP_TAG_TEXT : - case IPP_TAG_NAME : - case IPP_TAG_KEYWORD : - case IPP_TAG_URI : - case IPP_TAG_URISCHEME : - case IPP_TAG_CHARSET : - case IPP_TAG_LANGUAGE : - case IPP_TAG_MIMETYPE : - toattr = ippAddStrings(to, attr->group_tag, - (ipp_tag_t)(attr->value_tag | quickcopy), - attr->name, attr->num_values, NULL, NULL); + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "queued-job-count", count); +} - if (quickcopy) - { - for (i = 0; i < attr->num_values; i ++) - toattr->values[i].string.text = attr->values[i].string.text; - } - else - { - for (i = 0; i < attr->num_values; i ++) - toattr->values[i].string.text = _cups_sp_alloc(attr->values[i].string.text); - } - break; - case IPP_TAG_DATE : - toattr = ippAddDate(to, attr->group_tag, attr->name, - attr->values[0].date); - break; +/* + * 'apply_printer_defaults()' - Apply printer default options to a job. + */ - case IPP_TAG_RESOLUTION : - toattr = ippAddResolutions(to, attr->group_tag, attr->name, - attr->num_values, IPP_RES_PER_INCH, - NULL, NULL); +static void +apply_printer_defaults( + cupsd_printer_t *printer, /* I - Printer */ + cupsd_job_t *job) /* I - Job */ +{ + int i, /* Looping var */ + num_options; /* Number of default options */ + cups_option_t *options, /* Default options */ + *option; /* Current option */ - for (i = 0; i < attr->num_values; i ++) - { - toattr->values[i].resolution.xres = attr->values[i].resolution.xres; - toattr->values[i].resolution.yres = attr->values[i].resolution.yres; - toattr->values[i].resolution.units = attr->values[i].resolution.units; - } - break; - case IPP_TAG_RANGE : - toattr = ippAddRanges(to, attr->group_tag, attr->name, - attr->num_values, NULL, NULL); + /* + * Collect all of the default options and add the missing ones to the + * job object... + */ - for (i = 0; i < attr->num_values; i ++) - { - toattr->values[i].range.lower = attr->values[i].range.lower; - toattr->values[i].range.upper = attr->values[i].range.upper; - } - break; + for (i = printer->num_options, num_options = 0, option = printer->options; + i > 0; + i --, option ++) + if (!ippFindAttribute(job->attrs, option->name, IPP_TAG_ZERO)) + { + num_options = cupsAddOption(option->name, option->value, num_options, + &options); + } - case IPP_TAG_TEXTLANG : - case IPP_TAG_NAMELANG : - toattr = ippAddStrings(to, attr->group_tag, - (ipp_tag_t)(attr->value_tag | quickcopy), - attr->name, attr->num_values, NULL, NULL); + /* + * Encode these options as attributes in the job object... + */ - if (quickcopy) - { - for (i = 0; i < attr->num_values; i ++) - { - toattr->values[i].string.charset = attr->values[i].string.charset; - toattr->values[i].string.text = attr->values[i].string.text; - } - } - else - { - for (i = 0; i < attr->num_values; i ++) - { - if (!i) - toattr->values[i].string.charset = - _cups_sp_alloc(attr->values[i].string.charset); - else - toattr->values[i].string.charset = - toattr->values[0].string.charset; + cupsEncodeOptions2(job->attrs, num_options, options, IPP_TAG_JOB); + cupsFreeOptions(num_options, options); +} + + +/* + * 'authenticate_job()' - Set job authentication info. + */ + +static void +authenticate_job(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Job URI */ +{ + ipp_attribute_t *attr; /* Job-id attribute */ + int jobid; /* Job ID */ + cupsd_job_t *job; /* Current job */ + char method[HTTP_MAX_URI], + /* Method portion of URI */ + username[HTTP_MAX_URI], + /* Username portion of URI */ + host[HTTP_MAX_URI], + /* Host portion of URI */ + resource[HTTP_MAX_URI]; + /* Resource portion of URI */ + int port; /* Port portion of URI */ - toattr->values[i].string.text = _cups_sp_alloc(attr->values[i].string.text); - } - } - break; - case IPP_TAG_BEGIN_COLLECTION : - toattr = ippAddCollections(to, attr->group_tag, attr->name, - attr->num_values, NULL); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "authenticate_job(%p[%d], %s)", + con, con->http.fd, uri->values[0].string.text); - for (i = 0; i < attr->num_values; i ++) - { - toattr->values[i].collection = ippNew(); - copy_attrs(toattr->values[i].collection, attr->values[i].collection, - NULL, IPP_TAG_ZERO, 0); - } - break; + /* + * Start with "everything is OK" status... + */ - default : - toattr = ippAddIntegers(to, attr->group_tag, attr->value_tag, - attr->name, attr->num_values, NULL); + con->response->request.status.status_code = IPP_OK; - for (i = 0; i < attr->num_values; i ++) - { - toattr->values[i].unknown.length = attr->values[i].unknown.length; + /* + * See if we have a job URI or a printer URI... + */ - if (toattr->values[i].unknown.length > 0) - { - if ((toattr->values[i].unknown.data = - malloc(toattr->values[i].unknown.length)) == NULL) - toattr->values[i].unknown.length = 0; - else - memcpy(toattr->values[i].unknown.data, - attr->values[i].unknown.data, - toattr->values[i].unknown.length); - } - } - break; /* anti-compiler-warning-code */ - } + if (!strcmp(uri->name, "printer-uri")) + { + /* + * Got a printer URI; see if we also have a job-id attribute... + */ - return (toattr); -} + if ((attr = ippFindAttribute(con->request, "job-id", + IPP_TAG_INTEGER)) == NULL) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Got a printer-uri attribute but no job-id!")); + return; + } + + jobid = attr->values[0].integer; + } + else + { + /* + * Got a job URI; parse it to get the job ID... + */ + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, + sizeof(method), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (strncmp(resource, "/jobs/", 6)) + { + /* + * Not a valid URI! + */ -/* - * 'copy_attrs()' - Copy attributes from one request to another. - */ + send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri attribute \"%s\"!"), + uri->values[0].string.text); + return; + } -static void -copy_attrs(ipp_t *to, /* I - Destination request */ - ipp_t *from, /* I - Source request */ - cups_array_t *ra, /* I - Requested attributes */ - ipp_tag_t group, /* I - Group to copy */ - int quickcopy) /* I - Do a quick copy? */ -{ - ipp_attribute_t *fromattr; /* Source attribute */ + jobid = atoi(resource + 6); + } + /* + * See if the job exists... + */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "copy_attrs(to=%p, from=%p, ra=%p, group=%x, quickcopy=%d)", - to, from, ra, group, quickcopy); + if ((job = cupsdFindJob(jobid)) == NULL) + { + /* + * Nope - return a "not found" error... + */ - if (!to || !from) + send_ipp_status(con, IPP_NOT_FOUND, + _("Job #%d does not exist!"), jobid); return; + } - for (fromattr = from->attrs; fromattr; fromattr = fromattr->next) + /* + * See if the job has been completed... + */ + + if (job->state_value != IPP_JOB_HELD) { /* - * Filter attributes as needed... + * Return a "not-possible" error... */ - if (group != IPP_TAG_ZERO && fromattr->group_tag != group && - fromattr->group_tag != IPP_TAG_ZERO && !fromattr->name) - continue; + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Job #%d is not held for authentication!"), + jobid); + return; + } - if (!ra || cupsArrayFind(ra, fromattr->name)) - copy_attribute(to, fromattr, quickcopy); + /* + * See if we have already authenticated... + */ + + if (!con->username[0]) + { + send_ipp_status(con, IPP_NOT_AUTHORIZED, + _("No authentication information provided!")); + return; + } + + /* + * See if the job is owned by the requesting user... + */ + + if (!validate_user(job, con, job->username, username, sizeof(username))) + { + send_http_error(con, HTTP_UNAUTHORIZED); + return; + } + + /* + * Save the authentication information for this job... + */ + + save_auth_info(con, job); + + /* + * Reset the job-hold-until value to "no-hold"... + */ + + if ((attr = ippFindAttribute(job->attrs, "job-hold-until", + IPP_TAG_KEYWORD)) == NULL) + attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME); + + if (attr) + { + attr->value_tag = IPP_TAG_KEYWORD; + cupsdSetString(&(attr->values[0].string.text), "no-hold"); } + + /* + * Release the job and return... + */ + + cupsdReleaseJob(job); + + cupsdLogMessage(CUPSD_LOG_INFO, "Job %d was authenticated by \"%s\".", jobid, + con->username); } /* - * 'copy_banner()' - Copy a banner file to the requests directory for the - * specified job. + * 'cancel_all_jobs()' - Cancel all print jobs. */ -static int /* O - Size of banner file in kbytes */ -copy_banner(cupsd_client_t *con, /* I - Client connection */ - cupsd_job_t *job, /* I - Job information */ - const char *name) /* I - Name of banner */ +static void +cancel_all_jobs(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Job or Printer URI */ { - int i; /* Looping var */ - int kbytes; /* Size of banner file in kbytes */ - char filename[1024]; /* Job filename */ - cupsd_banner_t *banner; /* Pointer to banner */ - cups_file_t *in; /* Input file */ - cups_file_t *out; /* Output file */ - int ch; /* Character from file */ - char attrname[255], /* Name of attribute */ - *s; /* Pointer into name */ - ipp_attribute_t *attr; /* Attribute */ + http_status_t status; /* Policy status */ + const char *dest; /* Destination */ + cups_ptype_t dtype; /* Destination type */ + char method[HTTP_MAX_URI], /* Method portion of URI */ + userpass[HTTP_MAX_URI], /* Username portion of URI */ + host[HTTP_MAX_URI], /* Host portion of URI */ + resource[HTTP_MAX_URI]; /* Resource portion of URI */ + int port; /* Port portion of URI */ + ipp_attribute_t *attr; /* Attribute in request */ + const char *username; /* Username */ + int purge; /* Purge? */ + cupsd_printer_t *printer; /* Printer */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_banner(%p[%d], %p[%d], %s)", - con, con->http.fd, job, job->id, name ? name : "(null)"); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_all_jobs(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); /* - * Find the banner; return if not found or "none"... + * See if we have a printer URI... */ - if (!name || !strcmp(name, "none") || - (banner = cupsdFindBanner(name)) == NULL) - return (0); + if (strcmp(uri->name, "printer-uri")) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("The printer-uri attribute is required!")); + return; + } /* - * Open the banner and job files... + * Get the username (if any) for the jobs we want to cancel (only if + * "my-jobs" is specified... */ - if (add_file(con, job, banner->filetype, 0)) - return (0); - - snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, job->id, - job->num_files); - if ((out = cupsFileOpen(filename, "w")) == NULL) + if ((attr = ippFindAttribute(con->request, "my-jobs", + IPP_TAG_BOOLEAN)) != NULL && + attr->values[0].boolean) { - cupsdLogMessage(CUPSD_LOG_ERROR, - "copy_banner: Unable to create banner job file %s - %s", - filename, strerror(errno)); - job->num_files --; - return (0); + if ((attr = ippFindAttribute(con->request, "requesting-user-name", + IPP_TAG_NAME)) != NULL) + username = attr->values[0].string.text; + else + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Missing requesting-user-name attribute!")); + return; + } } + else + username = NULL; - fchmod(cupsFileNumber(out), 0640); - fchown(cupsFileNumber(out), RunUser, Group); + /* + * Look for the "purge-jobs" attribute... + */ + + if ((attr = ippFindAttribute(con->request, "purge-jobs", + IPP_TAG_BOOLEAN)) != NULL) + purge = attr->values[0].boolean; + else + purge = 1; /* - * Try the localized banner file under the subdirectory... + * And if the destination is valid... */ - strlcpy(attrname, con->request->attrs->next->values[0].string.text, - sizeof(attrname)); - if (strlen(attrname) > 2 && attrname[2] == '-') + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, + sizeof(method), userpass, sizeof(userpass), host, + sizeof(host), &port, resource, sizeof(resource)); + + if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) { /* - * Convert ll-cc to ll_CC... + * Bad URI? */ - attrname[2] = '_'; - attrname[3] = toupper(attrname[3] & 255); - attrname[4] = toupper(attrname[4] & 255); - } + if ((!strncmp(resource, "/printers/", 10) && resource[10]) || + (!strncmp(resource, "/classes/", 9) && resource[9])) + { + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + else if (strcmp(resource, "/printers/")) + { + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer-uri \"%s\" is not valid."), + uri->values[0].string.text); + return; + } - snprintf(filename, sizeof(filename), "%s/banners/%s/%s", DataDir, - attrname, name); + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status); + return; + } - if (access(filename, 0) && strlen(attrname) > 2) - { /* - * Wasn't able to find "ll_CC" locale file; try the non-national - * localization banner directory. + * Cancel all jobs on all printers... */ - attrname[2] = '\0'; + cupsdCancelJobs(NULL, username, purge); - snprintf(filename, sizeof(filename), "%s/banners/%s/%s", DataDir, - attrname, name); + cupsdLogMessage(CUPSD_LOG_INFO, "All jobs were %s by \"%s\".", + purge ? "purged" : "cancelled", get_username(con)); } - - if (access(filename, 0)) + else { /* - * Use the non-localized banner file. + * Check policy... */ - snprintf(filename, sizeof(filename), "%s/banners/%s", DataDir, name); - } + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status); + return; + } - if ((in = cupsFileOpen(filename, "r")) == NULL) - { - cupsFileClose(out); - unlink(filename); - cupsdLogMessage(CUPSD_LOG_ERROR, - "copy_banner: Unable to open banner template file %s - %s", - filename, strerror(errno)); - job->num_files --; - return (0); + /* + * Cancel all of the jobs on the named printer... + */ + + cupsdCancelJobs(dest, username, purge); + + cupsdLogMessage(CUPSD_LOG_INFO, "All jobs on \"%s\" were %s by \"%s\".", + dest, purge ? "purged" : "cancelled", get_username(con)); } + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'cancel_job()' - Cancel a print job. + */ + +static void +cancel_job(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Job or Printer URI */ +{ + ipp_attribute_t *attr; /* Current attribute */ + int jobid; /* Job ID */ + char method[HTTP_MAX_URI], /* Method portion of URI */ + username[HTTP_MAX_URI], /* Username portion of URI */ + host[HTTP_MAX_URI], /* Host portion of URI */ + resource[HTTP_MAX_URI]; /* Resource portion of URI */ + int port; /* Port portion of URI */ + cupsd_job_t *job; /* Job information */ + const char *dest; /* Destination */ + cups_ptype_t dtype; /* Destination type (printer or class) */ + cupsd_printer_t *printer; /* Printer data */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_job(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); + /* - * Parse the file to the end... + * See if we have a job URI or a printer URI... */ - while ((ch = cupsFileGetChar(in)) != EOF) - if (ch == '{') + if (!strcmp(uri->name, "printer-uri")) + { + /* + * Got a printer URI; see if we also have a job-id attribute... + */ + + if ((attr = ippFindAttribute(con->request, "job-id", + IPP_TAG_INTEGER)) == NULL) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Got a printer-uri attribute but no job-id!")); + return; + } + + if ((jobid = attr->values[0].integer) == 0) { /* - * Get an attribute name... + * Find the current job on the specified printer... */ - for (s = attrname; (ch = cupsFileGetChar(in)) != EOF;) - if (!isalpha(ch & 255) && ch != '-' && ch != '?') - break; - else if (s < (attrname + sizeof(attrname) - 1)) - *s++ = ch; - else - break; - - *s = '\0'; + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, + sizeof(method), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); - if (ch != '}') + if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) { /* - * Ignore { followed by stuff that is not an attribute name... + * Bad URI... */ - cupsFilePrintf(out, "{%s%c", attrname, ch); - continue; + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; } /* - * See if it is defined... + * See if the printer is currently printing a job... */ - if (attrname[0] == '?') - s = attrname + 1; + if (printer->job) + jobid = ((cupsd_job_t *)printer->job)->id; else - s = attrname; - - if (!strcmp(s, "printer-name")) - { - cupsFilePuts(out, job->dest); - continue; - } - else if ((attr = ippFindAttribute(job->attrs, s, IPP_TAG_ZERO)) == NULL) { /* - * See if we have a leading question mark... + * No, see if there are any pending jobs... */ + + for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs); + job; + job = (cupsd_job_t *)cupsArrayNext(ActiveJobs)) + if (job->state_value <= IPP_JOB_PROCESSING && + !strcasecmp(job->dest, dest)) + break; - if (attrname[0] != '?') + if (job) + jobid = job->id; + else { - /* - * Nope, write to file as-is; probably a PostScript procedure... - */ + send_ipp_status(con, IPP_NOT_POSSIBLE, _("No active jobs on %s!"), + dest); + return; + } + } + } + } + else + { + /* + * Got a job URI; parse it to get the job ID... + */ - cupsFilePrintf(out, "{%s}", attrname); - } + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, + sizeof(method), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (strncmp(resource, "/jobs/", 6)) + { + /* + * Not a valid URI! + */ - continue; - } + send_ipp_status(con, IPP_BAD_REQUEST, + _("Bad job-uri attribute \"%s\"!"), + uri->values[0].string.text); + return; + } + + jobid = atoi(resource + 6); + } + + /* + * See if the job exists... + */ + + if ((job = cupsdFindJob(jobid)) == NULL) + { + /* + * Nope - return a "not found" error... + */ + + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid); + return; + } + + /* + * See if the job is owned by the requesting user... + */ + + if (!validate_user(job, con, job->username, username, sizeof(username))) + { + send_http_error(con, HTTP_UNAUTHORIZED); + return; + } + + /* + * See if the job is already completed, cancelled, or aborted; if so, + * we can't cancel... + */ + + if (job->state_value >= IPP_JOB_CANCELLED) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Job #%d is already %s - can\'t cancel."), jobid, + job->state_value == IPP_JOB_CANCELLED ? "cancelled" : + job->state_value == IPP_JOB_ABORTED ? "aborted" : + "completed"); + return; + } - /* - * Output value(s)... - */ + /* + * Cancel the job and return... + */ - for (i = 0; i < attr->num_values; i ++) - { - if (i) - cupsFilePutChar(out, ','); + cupsdAddEvent(CUPSD_EVENT_JOB_COMPLETED, job->printer, job, + "Job cancelled by \"%s\".", username); - switch (attr->value_tag) - { - case IPP_TAG_INTEGER : - case IPP_TAG_ENUM : - if (!strncmp(s, "time-at-", 8)) - cupsFilePuts(out, cupsdGetDateTime(attr->values[i].integer)); - else - cupsFilePrintf(out, "%d", attr->values[i].integer); - break; + cupsdCancelJob(job, 0); + cupsdCheckJobs(); - case IPP_TAG_BOOLEAN : - cupsFilePrintf(out, "%d", attr->values[i].boolean); - break; + cupsdLogMessage(CUPSD_LOG_INFO, "Job %d was cancelled by \"%s\".", jobid, + username); - case IPP_TAG_NOVALUE : - cupsFilePuts(out, "novalue"); - break; + con->response->request.status.status_code = IPP_OK; +} - case IPP_TAG_RANGE : - cupsFilePrintf(out, "%d-%d", attr->values[i].range.lower, - attr->values[i].range.upper); - break; - case IPP_TAG_RESOLUTION : - cupsFilePrintf(out, "%dx%d%s", attr->values[i].resolution.xres, - attr->values[i].resolution.yres, - attr->values[i].resolution.units == IPP_RES_PER_INCH ? - "dpi" : "dpc"); - break; +/* + * 'cancel_subscription()' - Cancel a subscription. + */ - case IPP_TAG_URI : - case IPP_TAG_STRING : - case IPP_TAG_TEXT : - case IPP_TAG_NAME : - case IPP_TAG_KEYWORD : - case IPP_TAG_CHARSET : - case IPP_TAG_LANGUAGE : - if (!strcasecmp(banner->filetype->type, "postscript")) - { - /* - * Need to quote strings for PS banners... - */ +static void +cancel_subscription( + cupsd_client_t *con, /* I - Client connection */ + int sub_id) /* I - Subscription ID */ +{ + http_status_t status; /* Policy status */ + cupsd_subscription_t *sub; /* Subscription */ - const char *p; - for (p = attr->values[i].string.text; *p; p ++) - { - if (*p == '(' || *p == ')' || *p == '\\') - { - cupsFilePutChar(out, '\\'); - cupsFilePutChar(out, *p); - } - else if (*p < 32 || *p > 126) - cupsFilePrintf(out, "\\%03o", *p & 255); - else - cupsFilePutChar(out, *p); - } - } - else - cupsFilePuts(out, attr->values[i].string.text); - break; + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cancel_subscription(con=%p[%d], sub_id=%d)", + con, con->http.fd, sub_id); - default : - break; /* anti-compiler-warning-code */ - } - } - } - else if (ch == '\\') /* Quoted char */ - { - ch = cupsFileGetChar(in); + /* + * Is the subscription ID valid? + */ - if (ch != '{') /* Only do special handling for \{ */ - cupsFilePutChar(out, '\\'); + if ((sub = cupsdFindSubscription(sub_id)) == NULL) + { + /* + * Bad subscription ID... + */ - cupsFilePutChar(out, ch); - } - else - cupsFilePutChar(out, ch); + send_ipp_status(con, IPP_NOT_FOUND, + _("notify-subscription-id %d no good!"), sub_id); + return; + } - cupsFileClose(in); + /* + * Check policy... + */ - kbytes = (cupsFileTell(out) + 1023) / 1024; + if ((status = cupsdCheckPolicy(sub->dest ? sub->dest->op_policy_ptr : + DefaultPolicyPtr, + con, sub->owner)) != HTTP_OK) + { + send_http_error(con, status); + return; + } - if ((attr = ippFindAttribute(job->attrs, "job-k-octets", - IPP_TAG_INTEGER)) != NULL) - attr->values[0].integer += kbytes; + /* + * Cancel the subscription... + */ - cupsFileClose(out); + cupsdDeleteSubscription(sub, 1); - return (kbytes); + con->response->request.status.status_code = IPP_OK; } /* - * 'copy_file()' - Copy a PPD file or interface script... + * 'check_quotas()' - Check quotas for a printer and user. */ -static int /* O - 0 = success, -1 = error */ -copy_file(const char *from, /* I - Source file */ - const char *to) /* I - Destination file */ +static int /* O - 1 if OK, 0 if not */ +check_quotas(cupsd_client_t *con, /* I - Client connection */ + cupsd_printer_t *p) /* I - Printer or class */ { - cups_file_t *src, /* Source file */ - *dst; /* Destination file */ - int bytes; /* Bytes to read/write */ - char buffer[2048]; /* Copy buffer */ + int i; /* Looping var */ + char username[33]; /* Username */ + cupsd_quota_t *q; /* Quota data */ + struct passwd *pw; /* User password data */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_file(\"%s\", \"%s\")", from, to); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "check_quotas(%p[%d], %p[%s])", + con, con->http.fd, p, p->name); /* - * Open the source and destination file for a copy... + * Check input... */ - if ((src = cupsFileOpen(from, "rb")) == NULL) - return (-1); + if (!con || !p) + return (0); - if ((dst = cupsFileOpen(to, "wb")) == NULL) + /* + * Figure out who is printing... + */ + + strlcpy(username, get_username(con), sizeof(username)); + + /* + * Check global active job limits for printers and users... + */ + + if (MaxJobsPerPrinter) { - cupsFileClose(src); - return (-1); + /* + * Check if there are too many pending jobs on this printer... + */ + + if (cupsdGetPrinterJobCount(p->name) >= MaxJobsPerPrinter) + { + cupsdLogMessage(CUPSD_LOG_INFO, "Too many jobs for printer \"%s\"...", + p->name); + return (0); + } + } + + if (MaxJobsPerUser) + { + /* + * Check if there are too many pending jobs for this user... + */ + + if (cupsdGetUserJobCount(username) >= MaxJobsPerUser) + { + cupsdLogMessage(CUPSD_LOG_INFO, "Too many jobs for user \"%s\"...", + username); + return (0); + } } /* - * Copy the source file to the destination... + * Check against users... */ - while ((bytes = cupsFileRead(src, buffer, sizeof(buffer))) > 0) - if (cupsFileWrite(dst, buffer, bytes) < bytes) + if (p->num_users == 0 && p->k_limit == 0 && p->page_limit == 0) + return (1); + + if (p->num_users) + { + pw = getpwnam(username); + endpwent(); + + for (i = 0; i < p->num_users; i ++) + if (p->users[i][0] == '@') + { + /* + * Check group membership... + */ + + if (cupsdCheckGroup(username, pw, p->users[i] + 1)) + break; + } + else if (!strcasecmp(username, p->users[i])) + break; + + if ((i < p->num_users) == p->deny_users) { - cupsFileClose(src); - cupsFileClose(dst); - return (-1); + cupsdLogMessage(CUPSD_LOG_INFO, + "Denying user \"%s\" access to printer \"%s\"...", + username, p->name); + return (0); } + } /* - * Close both files and return... + * Check quotas... */ - cupsFileClose(src); + if (p->k_limit || p->page_limit) + { + if ((q = cupsdUpdateQuota(p, username, 0, 0)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate quota data for user \"%s\"!", + username); + return (0); + } - return (cupsFileClose(dst)); + if ((q->k_count >= p->k_limit && p->k_limit) || + (q->page_count >= p->page_limit && p->page_limit)) + { + cupsdLogMessage(CUPSD_LOG_INFO, "User \"%s\" is over the quota limit...", + username); + return (0); + } + } + + /* + * If we have gotten this far, we're done! + */ + + return (1); } /* - * 'copy_model()' - Copy a PPD model file, substituting default values - * as needed... + * 'copy_attribute()' - Copy a single attribute. */ -static int /* O - 0 = success, -1 = error */ -copy_model(cupsd_client_t *con, /* I - Client connection */ - const char *from, /* I - Source file */ - const char *to) /* I - Destination file */ +static ipp_attribute_t * /* O - New attribute */ +copy_attribute( + ipp_t *to, /* O - Destination request/response */ + ipp_attribute_t *attr, /* I - Attribute to copy */ + int quickcopy) /* I - Do a quick copy? */ { - fd_set *input; /* select() input set */ - struct timeval timeout; /* select() timeout */ - int maxfd; /* Maximum file descriptor for select() */ - char tempfile[1024]; /* Temporary PPD file */ - int tempfd; /* Temporary PPD file descriptor */ - int temppid; /* Process ID of cups-driverd */ - int temppipe[2]; /* Temporary pipes */ - char *argv[4], /* Command-line arguments */ - *envp[MAX_ENV]; /* Environment */ - cups_file_t *src, /* Source file */ - *dst; /* Destination file */ - int bytes, /* Bytes from pipe */ - total; /* Total bytes from pipe */ - char buffer[2048], /* Copy buffer */ - *ptr; /* Pointer into buffer */ - int i; /* Looping var */ - char option[PPD_MAX_NAME], /* Option name */ - choice[PPD_MAX_NAME]; /* Choice name */ - int num_defaults; /* Number of default options */ - ppd_default_t *defaults; /* Default options */ - char cups_protocol[PPD_MAX_LINE]; - /* cupsProtocol attribute */ - int have_letter, /* Have Letter size */ - have_a4; /* Have A4 size */ -#ifdef HAVE_LIBPAPER - char *paper_result; /* Paper size name from libpaper */ - char system_paper[64]; /* Paper size name buffer */ -#endif /* HAVE_LIBPAPER */ + int i; /* Looping var */ + ipp_attribute_t *toattr; /* Destination attribute */ cupsdLogMessage(CUPSD_LOG_DEBUG2, - "copy_model(con=%p, from=\"%s\", to=\"%s\")", - con, from, to); - - /* - * Run cups-driverd to get the PPD file... - */ + "copy_attribute(%p, %p[%s,%x,%x])", to, attr, + attr->name ? attr->name : "(null)", attr->group_tag, + attr->value_tag); - argv[0] = "cups-driverd"; - argv[1] = "cat"; - argv[2] = (char *)from; - argv[3] = NULL; + switch (attr->value_tag & ~IPP_TAG_COPY) + { + case IPP_TAG_ZERO : + toattr = ippAddSeparator(to); + break; - cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0]))); + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + toattr = ippAddIntegers(to, attr->group_tag, attr->value_tag, + attr->name, attr->num_values, NULL); - snprintf(buffer, sizeof(buffer), "%s/daemon/cups-driverd", ServerBin); - snprintf(tempfile, sizeof(tempfile), "%s/%d.ppd", TempDir, con->http.fd); - tempfd = open(tempfile, O_WRONLY | O_CREAT | O_TRUNC, 0600); - if (tempfd < 0) - return (-1); + for (i = 0; i < attr->num_values; i ++) + toattr->values[i].integer = attr->values[i].integer; + break; - cupsdOpenPipe(temppipe); + case IPP_TAG_BOOLEAN : + toattr = ippAddBooleans(to, attr->group_tag, attr->name, + attr->num_values, NULL); - if ((input = calloc(1, SetSize)) == NULL) - { - close(tempfd); - unlink(tempfile); + for (i = 0; i < attr->num_values; i ++) + toattr->values[i].boolean = attr->values[i].boolean; + break; - cupsdLogMessage(CUPSD_LOG_ERROR, - "copy_model: Unable to allocate %d bytes for select()...", - SetSize); - return (-1); - } + case IPP_TAG_STRING : + case IPP_TAG_TEXT : + case IPP_TAG_NAME : + case IPP_TAG_KEYWORD : + case IPP_TAG_URI : + case IPP_TAG_URISCHEME : + case IPP_TAG_CHARSET : + case IPP_TAG_LANGUAGE : + case IPP_TAG_MIMETYPE : + toattr = ippAddStrings(to, attr->group_tag, + (ipp_tag_t)(attr->value_tag | quickcopy), + attr->name, attr->num_values, NULL, NULL); - cupsdLogMessage(CUPSD_LOG_DEBUG, - "copy_model: Running \"cups-driverd cat %s\"...", from); + if (quickcopy) + { + for (i = 0; i < attr->num_values; i ++) + toattr->values[i].string.text = attr->values[i].string.text; + } + else + { + for (i = 0; i < attr->num_values; i ++) + toattr->values[i].string.text = _cups_sp_alloc(attr->values[i].string.text); + } + break; - if (!cupsdStartProcess(buffer, argv, envp, -1, temppipe[1], CGIPipes[1], - -1, 0, &temppid)) - { - free(input); - close(tempfd); - unlink(tempfile); - return (-1); - } + case IPP_TAG_DATE : + toattr = ippAddDate(to, attr->group_tag, attr->name, + attr->values[0].date); + break; - close(temppipe[1]); + case IPP_TAG_RESOLUTION : + toattr = ippAddResolutions(to, attr->group_tag, attr->name, + attr->num_values, IPP_RES_PER_INCH, + NULL, NULL); - /* - * Wait up to 30 seconds for the PPD file to be copied... - */ + for (i = 0; i < attr->num_values; i ++) + { + toattr->values[i].resolution.xres = attr->values[i].resolution.xres; + toattr->values[i].resolution.yres = attr->values[i].resolution.yres; + toattr->values[i].resolution.units = attr->values[i].resolution.units; + } + break; - total = 0; + case IPP_TAG_RANGE : + toattr = ippAddRanges(to, attr->group_tag, attr->name, + attr->num_values, NULL, NULL); - if (temppipe[0] > CGIPipes[0]) - maxfd = temppipe[0] + 1; - else - maxfd = CGIPipes[0] + 1; + for (i = 0; i < attr->num_values; i ++) + { + toattr->values[i].range.lower = attr->values[i].range.lower; + toattr->values[i].range.upper = attr->values[i].range.upper; + } + break; - for (;;) - { - /* - * See if we have data ready... - */ + case IPP_TAG_TEXTLANG : + case IPP_TAG_NAMELANG : + toattr = ippAddStrings(to, attr->group_tag, + (ipp_tag_t)(attr->value_tag | quickcopy), + attr->name, attr->num_values, NULL, NULL); - bytes = 0; + if (quickcopy) + { + for (i = 0; i < attr->num_values; i ++) + { + toattr->values[i].string.charset = attr->values[i].string.charset; + toattr->values[i].string.text = attr->values[i].string.text; + } + } + else + { + for (i = 0; i < attr->num_values; i ++) + { + if (!i) + toattr->values[i].string.charset = + _cups_sp_alloc(attr->values[i].string.charset); + else + toattr->values[i].string.charset = + toattr->values[0].string.charset; - FD_SET(temppipe[0], input); - FD_SET(CGIPipes[0], input); + toattr->values[i].string.text = _cups_sp_alloc(attr->values[i].string.text); + } + } + break; - timeout.tv_sec = 30; - timeout.tv_usec = 0; + case IPP_TAG_BEGIN_COLLECTION : + toattr = ippAddCollections(to, attr->group_tag, attr->name, + attr->num_values, NULL); - if ((i = select(maxfd, input, NULL, NULL, &timeout)) < 0) - { - if (errno == EINTR) - continue; - else + for (i = 0; i < attr->num_values; i ++) + { + toattr->values[i].collection = ippNew(); + copy_attrs(toattr->values[i].collection, attr->values[i].collection, + NULL, IPP_TAG_ZERO, 0); + } break; - } - else if (i == 0) - { - /* - * We have timed out... - */ - break; - } + default : + toattr = ippAddIntegers(to, attr->group_tag, attr->value_tag, + attr->name, attr->num_values, NULL); - if (FD_ISSET(temppipe[0], input)) - { - /* - * Read the PPD file from the pipe, and write it to the PPD file. - */ + for (i = 0; i < attr->num_values; i ++) + { + toattr->values[i].unknown.length = attr->values[i].unknown.length; - if ((bytes = read(temppipe[0], buffer, sizeof(buffer))) > 0) - { - if (write(tempfd, buffer, bytes) < bytes) - break; + if (toattr->values[i].unknown.length > 0) + { + if ((toattr->values[i].unknown.data = + malloc(toattr->values[i].unknown.length)) == NULL) + toattr->values[i].unknown.length = 0; + else + memcpy(toattr->values[i].unknown.data, + attr->values[i].unknown.data, + toattr->values[i].unknown.length); + } + } + break; /* anti-compiler-warning-code */ + } - total += bytes; - } - else - break; - } + return (toattr); +} + + +/* + * 'copy_attrs()' - Copy attributes from one request to another. + */ + +static void +copy_attrs(ipp_t *to, /* I - Destination request */ + ipp_t *from, /* I - Source request */ + cups_array_t *ra, /* I - Requested attributes */ + ipp_tag_t group, /* I - Group to copy */ + int quickcopy) /* I - Do a quick copy? */ +{ + ipp_attribute_t *fromattr; /* Source attribute */ - if (FD_ISSET(CGIPipes[0], input)) - cupsdUpdateCGI(); - } - close(temppipe[0]); - close(tempfd); + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "copy_attrs(to=%p, from=%p, ra=%p, group=%x, quickcopy=%d)", + to, from, ra, group, quickcopy); - free(input); + if (!to || !from) + return; - if (!total) + for (fromattr = from->attrs; fromattr; fromattr = fromattr->next) { /* - * No data from cups-deviced... + * Filter attributes as needed... */ - cupsdLogMessage(CUPSD_LOG_ERROR, "copy_model: empty PPD file!"); - unlink(tempfile); - return (-1); + if (group != IPP_TAG_ZERO && fromattr->group_tag != group && + fromattr->group_tag != IPP_TAG_ZERO && !fromattr->name) + continue; + + if (!ra || cupsArrayFind(ra, fromattr->name)) + copy_attribute(to, fromattr, quickcopy); } +} - /* - * Read the source file and see what page sizes are supported... - */ - if ((src = cupsFileOpen(tempfile, "rb")) == NULL) - { - unlink(tempfile); - return (-1); - } +/* + * 'copy_banner()' - Copy a banner file to the requests directory for the + * specified job. + */ - have_letter = 0; - have_a4 = 0; +static int /* O - Size of banner file in kbytes */ +copy_banner(cupsd_client_t *con, /* I - Client connection */ + cupsd_job_t *job, /* I - Job information */ + const char *name) /* I - Name of banner */ +{ + int i; /* Looping var */ + int kbytes; /* Size of banner file in kbytes */ + char filename[1024]; /* Job filename */ + cupsd_banner_t *banner; /* Pointer to banner */ + cups_file_t *in; /* Input file */ + cups_file_t *out; /* Output file */ + int ch; /* Character from file */ + char attrname[255], /* Name of attribute */ + *s; /* Pointer into name */ + ipp_attribute_t *attr; /* Attribute */ - while (cupsFileGets(src, buffer, sizeof(buffer))) - if (!strncmp(buffer, "*PageSize ", 10)) - { - /* - * Strip UI text and command data from the end of the line... - */ - if ((ptr = strchr(buffer + 10, '/')) != NULL) - *ptr = '\0'; - if ((ptr = strchr(buffer + 10, ':')) != NULL) - *ptr = '\0'; + cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_banner(%p[%d], %p[%d], %s)", + con, con->http.fd, job, job->id, name ? name : "(null)"); - for (ptr = buffer + 10; isspace(*ptr); ptr ++); + /* + * Find the banner; return if not found or "none"... + */ - /* - * Look for Letter and A4 page sizes... - */ + if (!name || !strcmp(name, "none") || + (banner = cupsdFindBanner(name)) == NULL) + return (0); - if (!strcmp(ptr, "Letter")) - have_letter = 1; + /* + * Open the banner and job files... + */ - if (!strcmp(ptr, "A4")) - have_a4 = 1; - } + if (add_file(con, job, banner->filetype, 0)) + return (0); - cupsFileRewind(src); + snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, job->id, + job->num_files); + if ((out = cupsFileOpen(filename, "w")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "copy_banner: Unable to create banner job file %s - %s", + filename, strerror(errno)); + job->num_files --; + return (0); + } + + fchmod(cupsFileNumber(out), 0640); + fchown(cupsFileNumber(out), RunUser, Group); /* - * Open the destination (if possible) and set the default options... + * Try the localized banner file under the subdirectory... */ - num_defaults = 0; - defaults = NULL; - cups_protocol[0] = '\0'; - - if ((dst = cupsFileOpen(to, "rb")) != NULL) + strlcpy(attrname, con->request->attrs->next->values[0].string.text, + sizeof(attrname)); + if (strlen(attrname) > 2 && attrname[2] == '-') { /* - * Read all of the default lines from the old PPD... + * Convert ll-cc to ll_CC... */ - while (cupsFileGets(dst, buffer, sizeof(buffer))) - if (!strncmp(buffer, "*Default", 8)) - { - /* - * Add the default option... - */ + attrname[2] = '_'; + attrname[3] = toupper(attrname[3] & 255); + attrname[4] = toupper(attrname[4] & 255); + } - if (!ppd_parse_line(buffer, option, sizeof(option), - choice, sizeof(choice))) - num_defaults = ppd_add_default(option, choice, num_defaults, - &defaults); - } - else if (!strncmp(buffer, "*cupsProtocol:", 14)) - strlcpy(cups_protocol, buffer, sizeof(cups_protocol)); + snprintf(filename, sizeof(filename), "%s/banners/%s/%s", DataDir, + attrname, name); - cupsFileClose(dst); - } -#ifdef HAVE_LIBPAPER - else if ((paper_result = systempapername()) != NULL) + if (access(filename, 0) && strlen(attrname) > 2) { /* - * Set the default media sizes from the systemwide default... + * Wasn't able to find "ll_CC" locale file; try the non-national + * localization banner directory. */ - strlcpy(system_paper, paper_result, sizeof(system_paper)); - system_paper[0] = toupper(system_paper[0] & 255); + attrname[2] = '\0'; - if ((!strcmp(system_paper, "Letter") && have_letter) || - (!strcmp(system_paper, "A4") && have_a4)) - { - num_defaults = ppd_add_default("PageSize", system_paper, - num_defaults, &defaults); - num_defaults = ppd_add_default("PageRegion", system_paper, - num_defaults, &defaults); - num_defaults = ppd_add_default("PaperDimension", system_paper, - num_defaults, &defaults); - num_defaults = ppd_add_default("ImageableArea", system_paper, - num_defaults, &defaults); - } + snprintf(filename, sizeof(filename), "%s/banners/%s/%s", DataDir, + attrname, name); } -#endif /* HAVE_LIBPAPER */ - else + + if (access(filename, 0)) { /* - * Add the default media sizes... - * - * Note: These values are generally not valid for large-format devices - * like plotters, however it is probably safe to say that those - * users will configure the media size after initially adding - * the device anyways... + * Use the non-localized banner file. */ - if (!DefaultLanguage || - !strcasecmp(DefaultLanguage, "C") || - !strcasecmp(DefaultLanguage, "POSIX") || - !strcasecmp(DefaultLanguage, "en") || - !strncasecmp(DefaultLanguage, "en_US", 5) || - !strncasecmp(DefaultLanguage, "en_CA", 5) || - !strncasecmp(DefaultLanguage, "fr_CA", 5)) - { - /* - * These are the only locales that will default to "letter" size... - */ - - if (have_letter) - { - num_defaults = ppd_add_default("PageSize", "Letter", num_defaults, - &defaults); - num_defaults = ppd_add_default("PageRegion", "Letter", num_defaults, - &defaults); - num_defaults = ppd_add_default("PaperDimension", "Letter", num_defaults, - &defaults); - num_defaults = ppd_add_default("ImageableArea", "Letter", num_defaults, - &defaults); - } - } - else if (have_a4) - { - /* - * The rest default to "a4" size... - */ + snprintf(filename, sizeof(filename), "%s/banners/%s", DataDir, name); + } - num_defaults = ppd_add_default("PageSize", "A4", num_defaults, - &defaults); - num_defaults = ppd_add_default("PageRegion", "A4", num_defaults, - &defaults); - num_defaults = ppd_add_default("PaperDimension", "A4", num_defaults, - &defaults); - num_defaults = ppd_add_default("ImageableArea", "A4", num_defaults, - &defaults); - } + if ((in = cupsFileOpen(filename, "r")) == NULL) + { + cupsFileClose(out); + unlink(filename); + cupsdLogMessage(CUPSD_LOG_ERROR, + "copy_banner: Unable to open banner template file %s - %s", + filename, strerror(errno)); + job->num_files --; + return (0); } /* - * Open the destination file for a copy... + * Parse the file to the end... */ - if ((dst = cupsFileOpen(to, "wb")) == NULL) - { - if (num_defaults > 0) - free(defaults); + while ((ch = cupsFileGetChar(in)) != EOF) + if (ch == '{') + { + /* + * Get an attribute name... + */ - cupsFileClose(src); - unlink(tempfile); - return (-1); - } + for (s = attrname; (ch = cupsFileGetChar(in)) != EOF;) + if (!isalpha(ch & 255) && ch != '-' && ch != '?') + break; + else if (s < (attrname + sizeof(attrname) - 1)) + *s++ = ch; + else + break; - /* - * Copy the source file to the destination... - */ + *s = '\0'; + + if (ch != '}') + { + /* + * Ignore { followed by stuff that is not an attribute name... + */ + + cupsFilePrintf(out, "{%s%c", attrname, ch); + continue; + } - while (cupsFileGets(src, buffer, sizeof(buffer))) - { - if (!strncmp(buffer, "*Default", 8)) - { /* - * Check for an previous default option choice... + * See if it is defined... */ - if (!ppd_parse_line(buffer, option, sizeof(option), - choice, sizeof(choice))) - { - for (i = 0; i < num_defaults; i ++) - if (!strcmp(option, defaults[i].option)) - { - /* - * Substitute the previous choice... - */ + if (attrname[0] == '?') + s = attrname + 1; + else + s = attrname; - snprintf(buffer, sizeof(buffer), "*Default%s: %s", option, - defaults[i].choice); - break; - } + if (!strcmp(s, "printer-name")) + { + cupsFilePuts(out, job->dest); + continue; } - } + else if ((attr = ippFindAttribute(job->attrs, s, IPP_TAG_ZERO)) == NULL) + { + /* + * See if we have a leading question mark... + */ - cupsFilePrintf(dst, "%s\n", buffer); - } + if (attrname[0] != '?') + { + /* + * Nope, write to file as-is; probably a PostScript procedure... + */ - if (cups_protocol[0]) - cupsFilePrintf(dst, "%s\n", cups_protocol); + cupsFilePrintf(out, "{%s}", attrname); + } - if (num_defaults > 0) - free(defaults); + continue; + } - /* - * Close both files and return... - */ + /* + * Output value(s)... + */ - cupsFileClose(src); + for (i = 0; i < attr->num_values; i ++) + { + if (i) + cupsFilePutChar(out, ','); - unlink(tempfile); + switch (attr->value_tag) + { + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + if (!strncmp(s, "time-at-", 8)) + cupsFilePuts(out, cupsdGetDateTime(attr->values[i].integer)); + else + cupsFilePrintf(out, "%d", attr->values[i].integer); + break; - return (cupsFileClose(dst)); -} + case IPP_TAG_BOOLEAN : + cupsFilePrintf(out, "%d", attr->values[i].boolean); + break; + case IPP_TAG_NOVALUE : + cupsFilePuts(out, "novalue"); + break; -/* - * 'copy_job_attrs()' - Copy job attributes. - */ + case IPP_TAG_RANGE : + cupsFilePrintf(out, "%d-%d", attr->values[i].range.lower, + attr->values[i].range.upper); + break; -static void -copy_job_attrs(cupsd_client_t *con, /* I - Client connection */ - cupsd_job_t *job, /* I - Job */ - cups_array_t *ra) /* I - Requested attributes array */ -{ - char job_uri[HTTP_MAX_URI]; /* Job URI */ + case IPP_TAG_RESOLUTION : + cupsFilePrintf(out, "%dx%d%s", attr->values[i].resolution.xres, + attr->values[i].resolution.yres, + attr->values[i].resolution.units == IPP_RES_PER_INCH ? + "dpi" : "dpc"); + break; + case IPP_TAG_URI : + case IPP_TAG_STRING : + case IPP_TAG_TEXT : + case IPP_TAG_NAME : + case IPP_TAG_KEYWORD : + case IPP_TAG_CHARSET : + case IPP_TAG_LANGUAGE : + if (!strcasecmp(banner->filetype->type, "postscript")) + { + /* + * Need to quote strings for PS banners... + */ - /* - * Send the requested attributes for each job... - */ + const char *p; - httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL, - con->servername, con->serverport, "/jobs/%d", - job->id); + for (p = attr->values[i].string.text; *p; p ++) + { + if (*p == '(' || *p == ')' || *p == '\\') + { + cupsFilePutChar(out, '\\'); + cupsFilePutChar(out, *p); + } + else if (*p < 32 || *p > 126) + cupsFilePrintf(out, "\\%03o", *p & 255); + else + cupsFilePutChar(out, *p); + } + } + else + cupsFilePuts(out, attr->values[i].string.text); + break; - if (!ra || cupsArrayFind(ra, "job-more-info")) - ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, - "job-more-info", NULL, job_uri); + default : + break; /* anti-compiler-warning-code */ + } + } + } + else if (ch == '\\') /* Quoted char */ + { + ch = cupsFileGetChar(in); - if (job->state_value > IPP_JOB_PROCESSING && - (!ra || cupsArrayFind(ra, "job-preserved"))) - ippAddBoolean(con->response, IPP_TAG_JOB, "job-preserved", - job->num_files > 0); + if (ch != '{') /* Only do special handling for \{ */ + cupsFilePutChar(out, '\\'); - if (!ra || cupsArrayFind(ra, "job-printer-up-time")) - ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, - "job-printer-up-time", time(NULL)); + cupsFilePutChar(out, ch); + } + else + cupsFilePutChar(out, ch); - if (!ra || cupsArrayFind(ra, "job-state-reasons")) - add_job_state_reasons(con, job); + cupsFileClose(in); - if (!ra || cupsArrayFind(ra, "job-uri")) - ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, - "job-uri", NULL, job_uri); + kbytes = (cupsFileTell(out) + 1023) / 1024; - copy_attrs(con->response, job->attrs, ra, IPP_TAG_JOB, 0); + if ((attr = ippFindAttribute(job->attrs, "job-k-octets", + IPP_TAG_INTEGER)) != NULL) + attr->values[0].integer += kbytes; + + cupsFileClose(out); + + return (kbytes); } /* - * 'copy_printer_attrs()' - Copy printer attributes. + * 'copy_file()' - Copy a PPD file or interface script... */ -static void -copy_printer_attrs( - cupsd_client_t *con, /* I - Client connection */ - cupsd_printer_t *printer, /* I - Printer */ - cups_array_t *ra) /* I - Requested attributes array */ +static int /* O - 0 = success, -1 = error */ +copy_file(const char *from, /* I - Source file */ + const char *to) /* I - Destination file */ { - char printer_uri[HTTP_MAX_URI]; - /* Printer URI */ - time_t curtime; /* Current time */ - int i; /* Looping var */ - ipp_attribute_t *history; /* History collection */ + cups_file_t *src, /* Source file */ + *dst; /* Destination file */ + int bytes; /* Bytes to read/write */ + char buffer[2048]; /* Copy buffer */ + cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_file(\"%s\", \"%s\")", from, to); + /* - * Copy the printer attributes to the response using requested-attributes - * and document-format attributes that may be provided by the client. + * Open the source and destination file for a copy... */ - curtime = time(NULL); - -#ifdef __APPLE__ - if ((!ra || cupsArrayFind(ra, "com.apple.print.recoverable-message")) && - printer->recoverable) - ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT, - "com.apple.print.recoverable-message", NULL, - printer->recoverable); -#endif /* __APPLE__ */ - - if (!ra || cupsArrayFind(ra, "printer-current-time")) - ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time", - ippTimeToDate(curtime)); - - if (!ra || cupsArrayFind(ra, "printer-error-policy")) - ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME, - "printer-error-policy", NULL, printer->error_policy); - - if (!ra || cupsArrayFind(ra, "printer-is-accepting-jobs")) - ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-accepting-jobs", - printer->accepting); - - if (!ra || cupsArrayFind(ra, "printer-is-shared")) - ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-shared", - printer->shared); + if ((src = cupsFileOpen(from, "rb")) == NULL) + return (-1); - if (!ra || cupsArrayFind(ra, "printer-op-policy")) - ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME, - "printer-op-policy", NULL, printer->op_policy); + if ((dst = cupsFileOpen(to, "wb")) == NULL) + { + cupsFileClose(src); + return (-1); + } - if (!ra || cupsArrayFind(ra, "printer-state")) - ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", - printer->state); + /* + * Copy the source file to the destination... + */ - if (!ra || cupsArrayFind(ra, "printer-state-change-time")) - ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "printer-state-change-time", printer->state_time); - - if (MaxPrinterHistory > 0 && printer->num_history > 0 && - cupsArrayFind(ra, "printer-state-history")) - { - /* - * Printer history is only sent if specifically requested, so that - * older CUPS/IPP clients won't barf on the collection attributes. - */ + while ((bytes = cupsFileRead(src, buffer, sizeof(buffer))) > 0) + if (cupsFileWrite(dst, buffer, bytes) < bytes) + { + cupsFileClose(src); + cupsFileClose(dst); + return (-1); + } - history = ippAddCollections(con->response, IPP_TAG_PRINTER, - "printer-state-history", - printer->num_history, NULL); + /* + * Close both files and return... + */ - for (i = 0; i < printer->num_history; i ++) - copy_attrs(history->values[i].collection = ippNew(), printer->history[i], - NULL, IPP_TAG_ZERO, 0); - } + cupsFileClose(src); - if (!ra || cupsArrayFind(ra, "printer-state-message")) - ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT, - "printer-state-message", NULL, printer->state_message); + return (cupsFileClose(dst)); +} - if (!ra || cupsArrayFind(ra, "printer-state-reasons")) - add_printer_state_reasons(con, printer); - if (!ra || cupsArrayFind(ra, "printer-type")) - { - int type; /* printer-type value */ +/* + * 'copy_model()' - Copy a PPD model file, substituting default values + * as needed... + */ +static int /* O - 0 = success, -1 = error */ +copy_model(cupsd_client_t *con, /* I - Client connection */ + const char *from, /* I - Source file */ + const char *to) /* I - Destination file */ +{ + fd_set *input; /* select() input set */ + struct timeval timeout; /* select() timeout */ + int maxfd; /* Maximum file descriptor for select() */ + char tempfile[1024]; /* Temporary PPD file */ + int tempfd; /* Temporary PPD file descriptor */ + int temppid; /* Process ID of cups-driverd */ + int temppipe[2]; /* Temporary pipes */ + char *argv[4], /* Command-line arguments */ + *envp[MAX_ENV]; /* Environment */ + cups_file_t *src, /* Source file */ + *dst; /* Destination file */ + int bytes, /* Bytes from pipe */ + total; /* Total bytes from pipe */ + char buffer[2048], /* Copy buffer */ + *ptr; /* Pointer into buffer */ + int i; /* Looping var */ + char option[PPD_MAX_NAME], /* Option name */ + choice[PPD_MAX_NAME]; /* Choice name */ + int num_defaults; /* Number of default options */ + ppd_default_t *defaults; /* Default options */ + char cups_protocol[PPD_MAX_LINE]; + /* cupsProtocol attribute */ + int have_letter, /* Have Letter size */ + have_a4; /* Have A4 size */ +#ifdef HAVE_LIBPAPER + char *paper_result; /* Paper size name from libpaper */ + char system_paper[64]; /* Paper size name buffer */ +#endif /* HAVE_LIBPAPER */ - /* - * Add the CUPS-specific printer-type attribute... - */ - type = printer->type; + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "copy_model(con=%p, from=\"%s\", to=\"%s\")", + con, from, to); - if (printer == DefaultPrinter) - type |= CUPS_PRINTER_DEFAULT; + /* + * Run cups-driverd to get the PPD file... + */ - if (!printer->accepting) - type |= CUPS_PRINTER_REJECTING; + argv[0] = "cups-driverd"; + argv[1] = "cat"; + argv[2] = (char *)from; + argv[3] = NULL; - if (!printer->shared) - type |= CUPS_PRINTER_NOT_SHARED; + cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0]))); - ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-type", - type); + snprintf(buffer, sizeof(buffer), "%s/daemon/cups-driverd", ServerBin); + snprintf(tempfile, sizeof(tempfile), "%s/%d.ppd", TempDir, con->http.fd); + tempfd = open(tempfile, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (tempfd < 0) + return (-1); + + cupsdOpenPipe(temppipe); + + if ((input = calloc(1, SetSize)) == NULL) + { + close(tempfd); + unlink(tempfile); + + cupsdLogMessage(CUPSD_LOG_ERROR, + "copy_model: Unable to allocate %d bytes for select()...", + SetSize); + return (-1); } - if (!ra || cupsArrayFind(ra, "printer-up-time")) - ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "printer-up-time", curtime); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "copy_model: Running \"cups-driverd cat %s\"...", from); - if ((!ra || cupsArrayFind(ra, "printer-uri-supported")) && - !ippFindAttribute(printer->attrs, "printer-uri-supported", - IPP_TAG_URI)) + if (!cupsdStartProcess(buffer, argv, envp, -1, temppipe[1], CGIPipes[1], + -1, 0, &temppid)) { - httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), - "ipp", NULL, con->servername, con->serverport, - "/printers/%s", printer->name); - ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, - "printer-uri-supported", NULL, printer_uri); - cupsdLogMessage(CUPSD_LOG_DEBUG2, "printer-uri-supported=\"%s\"", - printer_uri); + free(input); + close(tempfd); + unlink(tempfile); + return (-1); } - if (!ra || cupsArrayFind(ra, "queued-job-count")) - add_queued_job_count(con, printer); + close(temppipe[1]); - copy_attrs(con->response, printer->attrs, ra, IPP_TAG_ZERO, 0); - copy_attrs(con->response, CommonData, ra, IPP_TAG_ZERO, IPP_TAG_COPY); -} + /* + * Wait up to 30 seconds for the PPD file to be copied... + */ + total = 0; -/* - * 'copy_subscription_attrs()' - Copy subscription attributes. - */ + if (temppipe[0] > CGIPipes[0]) + maxfd = temppipe[0] + 1; + else + maxfd = CGIPipes[0] + 1; -static void -copy_subscription_attrs( - cupsd_client_t *con, /* I - Client connection */ - cupsd_subscription_t *sub, /* I - Subscription */ - cups_array_t *ra) /* I - Requested attributes array */ -{ - ipp_attribute_t *attr; /* Current attribute */ - char printer_uri[HTTP_MAX_URI]; - /* Printer URI */ - int count; /* Number of events */ - unsigned mask; /* Current event mask */ - const char *name; /* Current event name */ + for (;;) + { + /* + * See if we have data ready... + */ + bytes = 0; - /* - * Copy the subscription attributes to the response using the - * requested-attributes attribute that may be provided by the client. - */ + FD_SET(temppipe[0], input); + FD_SET(CGIPipes[0], input); - if (!ra || cupsArrayFind(ra, "notify-events")) - { - if ((name = cupsdEventName((cupsd_eventmask_t)sub->mask)) != NULL) + timeout.tv_sec = 30; + timeout.tv_usec = 0; + + if ((i = select(maxfd, input, NULL, NULL, &timeout)) < 0) + { + if (errno == EINTR) + continue; + else + break; + } + else if (i == 0) { /* - * Simple event list... + * We have timed out... */ - ippAddString(con->response, IPP_TAG_SUBSCRIPTION, - IPP_TAG_KEYWORD | IPP_TAG_COPY, - "notify-events", NULL, name); + break; } - else + + if (FD_ISSET(temppipe[0], input)) { /* - * Complex event list... + * Read the PPD file from the pipe, and write it to the PPD file. */ - for (mask = 1, count = 0; mask < CUPSD_EVENT_ALL; mask <<= 1) - if (sub->mask & mask) - count ++; - - attr = ippAddStrings(con->response, IPP_TAG_SUBSCRIPTION, - IPP_TAG_KEYWORD | IPP_TAG_COPY, - "notify-events", count, NULL, NULL); - - for (mask = 1, count = 0; mask < CUPSD_EVENT_ALL; mask <<= 1) - if (sub->mask & mask) - { - attr->values[count].string.text = - (char *)cupsdEventName((cupsd_eventmask_t)mask); + if ((bytes = read(temppipe[0], buffer, sizeof(buffer))) > 0) + { + if (write(tempfd, buffer, bytes) < bytes) + break; - count ++; - } + total += bytes; + } + else + break; } + + if (FD_ISSET(CGIPipes[0], input)) + cupsdUpdateCGI(); } - if (sub->job && (!ra || cupsArrayFind(ra, "notify-job-id"))) - ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, - "notify-job-id", sub->job->id); + close(temppipe[0]); + close(tempfd); - if (!sub->job && (!ra || cupsArrayFind(ra, "notify-lease-duration"))) - ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, - "notify-lease-duration", sub->lease); + free(input); - if (sub->dest && (!ra || cupsArrayFind(ra, "notify-printer-uri"))) + if (!total) { - httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), - "ipp", NULL, con->servername, con->serverport, - "/printers/%s", sub->dest->name); - ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, - "notify-printer-uri", NULL, printer_uri); + /* + * No data from cups-deviced... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, "copy_model: empty PPD file!"); + unlink(tempfile); + return (-1); } - if (sub->recipient && (!ra || cupsArrayFind(ra, "notify-recipient-uri"))) - ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, - "notify-recipient-uri", NULL, sub->recipient); - else if (!ra || cupsArrayFind(ra, "notify-pull-method")) - ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, - "notify-pull-method", NULL, "ippget"); + /* + * Read the source file and see what page sizes are supported... + */ - if (!ra || cupsArrayFind(ra, "notify-subscriber-user-name")) - ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_NAME, - "notify-subscriber-user-name", NULL, sub->owner); + if ((src = cupsFileOpen(tempfile, "rb")) == NULL) + { + unlink(tempfile); + return (-1); + } - if (!ra || cupsArrayFind(ra, "notify-subscription-id")) - ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, - "notify-subscription-id", sub->id); + have_letter = 0; + have_a4 = 0; - if (!ra || cupsArrayFind(ra, "notify-time-interval")) - ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, - "notify-time-interval", sub->interval); + while (cupsFileGets(src, buffer, sizeof(buffer))) + if (!strncmp(buffer, "*PageSize ", 10)) + { + /* + * Strip UI text and command data from the end of the line... + */ - if (sub->user_data_len > 0 && (!ra || cupsArrayFind(ra, "notify-user-data"))) - ippAddOctetString(con->response, IPP_TAG_SUBSCRIPTION, "notify-user-data", - sub->user_data, sub->user_data_len); -} + if ((ptr = strchr(buffer + 10, '/')) != NULL) + *ptr = '\0'; + if ((ptr = strchr(buffer + 10, ':')) != NULL) + *ptr = '\0'; + for (ptr = buffer + 10; isspace(*ptr); ptr ++); -/* - * 'create_job()' - Print a file to a printer or class. - */ + /* + * Look for Letter and A4 page sizes... + */ -static void -create_job(cupsd_client_t *con, /* I - Client connection */ - ipp_attribute_t *uri) /* I - Printer URI */ -{ - http_status_t status; /* Policy status */ - ipp_attribute_t *attr; /* Current attribute */ - const char *dest; /* Destination */ - cups_ptype_t dtype; /* Destination type (printer or class) */ - int priority; /* Job priority */ - char *title; /* Job name/title */ - cupsd_job_t *job; /* Current job */ - char job_uri[HTTP_MAX_URI], /* Job URI */ - method[HTTP_MAX_URI], /* Method portion of URI */ - username[HTTP_MAX_URI], /* Username portion of URI */ - host[HTTP_MAX_URI], /* Host portion of URI */ - resource[HTTP_MAX_URI]; /* Resource portion of URI */ - int port; /* Port portion of URI */ - cupsd_printer_t *printer; /* Printer data */ - int kbytes; /* Size of print file */ - int i; /* Looping var */ - int lowerpagerange; /* Page range bound */ + if (!strcmp(ptr, "Letter")) + have_letter = 1; + if (!strcmp(ptr, "A4")) + have_a4 = 1; + } - cupsdLogMessage(CUPSD_LOG_DEBUG2, "create_job(%p[%d], %s)", con, - con->http.fd, uri->values[0].string.text); + cupsFileRewind(src); /* - * Is the destination valid? + * Open the destination (if possible) and set the default options... */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); + num_defaults = 0; + defaults = NULL; + cups_protocol[0] = '\0'; - if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if ((dst = cupsFileOpen(to, "rb")) != NULL) { /* - * Bad URI... + * Read all of the default lines from the old PPD... */ - send_ipp_status(con, IPP_NOT_FOUND, - _("The printer or class was not found.")); - return; - } + while (cupsFileGets(dst, buffer, sizeof(buffer))) + if (!strncmp(buffer, "*Default", 8)) + { + /* + * Add the default option... + */ - /* - * Check remote printing to non-shared printer... - */ + if (!ppd_parse_line(buffer, option, sizeof(option), + choice, sizeof(choice))) + num_defaults = ppd_add_default(option, choice, num_defaults, + &defaults); + } + else if (!strncmp(buffer, "*cupsProtocol:", 14)) + strlcpy(cups_protocol, buffer, sizeof(cups_protocol)); - if (!printer->shared && - strcasecmp(con->http.hostname, "localhost") && - strcasecmp(con->http.hostname, ServerName)) - { - send_ipp_status(con, IPP_NOT_AUTHORIZED, - _("The printer or class is not shared!")); - return; + cupsFileClose(dst); } +#ifdef HAVE_LIBPAPER + else if ((paper_result = systempapername()) != NULL) + { + /* + * Set the default media sizes from the systemwide default... + */ - /* - * Check policy... - */ + strlcpy(system_paper, paper_result, sizeof(system_paper)); + system_paper[0] = toupper(system_paper[0] & 255); - if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) - { - send_http_error(con, status); - return; + if ((!strcmp(system_paper, "Letter") && have_letter) || + (!strcmp(system_paper, "A4") && have_a4)) + { + num_defaults = ppd_add_default("PageSize", system_paper, + num_defaults, &defaults); + num_defaults = ppd_add_default("PageRegion", system_paper, + num_defaults, &defaults); + num_defaults = ppd_add_default("PaperDimension", system_paper, + num_defaults, &defaults); + num_defaults = ppd_add_default("ImageableArea", system_paper, + num_defaults, &defaults); + } } - else if ((printer->type & CUPS_PRINTER_AUTHENTICATED) && !con->username[0]) +#endif /* HAVE_LIBPAPER */ + else { - send_http_error(con, HTTP_UNAUTHORIZED); - return; + /* + * Add the default media sizes... + * + * Note: These values are generally not valid for large-format devices + * like plotters, however it is probably safe to say that those + * users will configure the media size after initially adding + * the device anyways... + */ + + if (!DefaultLanguage || + !strcasecmp(DefaultLanguage, "C") || + !strcasecmp(DefaultLanguage, "POSIX") || + !strcasecmp(DefaultLanguage, "en") || + !strncasecmp(DefaultLanguage, "en_US", 5) || + !strncasecmp(DefaultLanguage, "en_CA", 5) || + !strncasecmp(DefaultLanguage, "fr_CA", 5)) + { + /* + * These are the only locales that will default to "letter" size... + */ + + if (have_letter) + { + num_defaults = ppd_add_default("PageSize", "Letter", num_defaults, + &defaults); + num_defaults = ppd_add_default("PageRegion", "Letter", num_defaults, + &defaults); + num_defaults = ppd_add_default("PaperDimension", "Letter", num_defaults, + &defaults); + num_defaults = ppd_add_default("ImageableArea", "Letter", num_defaults, + &defaults); + } + } + else if (have_a4) + { + /* + * The rest default to "a4" size... + */ + + num_defaults = ppd_add_default("PageSize", "A4", num_defaults, + &defaults); + num_defaults = ppd_add_default("PageRegion", "A4", num_defaults, + &defaults); + num_defaults = ppd_add_default("PaperDimension", "A4", num_defaults, + &defaults); + num_defaults = ppd_add_default("ImageableArea", "A4", num_defaults, + &defaults); + } } /* - * See if the printer is accepting jobs... + * Open the destination file for a copy... */ - if (!printer->accepting) + if ((dst = cupsFileOpen(to, "wb")) == NULL) { - send_ipp_status(con, IPP_NOT_ACCEPTING, - _("Destination \"%s\" is not accepting jobs."), - dest); - return; + if (num_defaults > 0) + free(defaults); + + cupsFileClose(src); + unlink(tempfile); + return (-1); } /* - * Validate job template attributes; for now just copies and page-ranges... + * Copy the source file to the destination... */ - if ((attr = ippFindAttribute(con->request, "copies", - IPP_TAG_INTEGER)) != NULL) + while (cupsFileGets(src, buffer, sizeof(buffer))) { - if (attr->values[0].integer < 1 || attr->values[0].integer > MaxCopies) + if (!strncmp(buffer, "*Default", 8)) { - send_ipp_status(con, IPP_ATTRIBUTES, _("Bad copies value %d."), - attr->values[0].integer); - ippAddInteger(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_INTEGER, - "copies", attr->values[0].integer); - return; - } - } + /* + * Check for an previous default option choice... + */ - if ((attr = ippFindAttribute(con->request, "page-ranges", - IPP_TAG_RANGE)) != NULL) - { - for (i = 0, lowerpagerange = 1; i < attr->num_values; i ++) - { - if (attr->values[i].range.lower < lowerpagerange || - attr->values[i].range.lower > attr->values[i].range.upper) + if (!ppd_parse_line(buffer, option, sizeof(option), + choice, sizeof(choice))) { - send_ipp_status(con, IPP_BAD_REQUEST, - _("Bad page-ranges values %d-%d."), - attr->values[i].range.lower, - attr->values[i].range.upper); - return; - } + for (i = 0; i < num_defaults; i ++) + if (!strcmp(option, defaults[i].option)) + { + /* + * Substitute the previous choice... + */ - lowerpagerange = attr->values[i].range.upper + 1; + snprintf(buffer, sizeof(buffer), "*Default%s: %s", option, + defaults[i].choice); + break; + } + } } + + cupsFilePrintf(dst, "%s\n", buffer); } + if (cups_protocol[0]) + cupsFilePrintf(dst, "%s\n", cups_protocol); + + if (num_defaults > 0) + free(defaults); + /* - * Make sure we aren't over our limit... + * Close both files and return... */ - if (MaxJobs && cupsArrayCount(Jobs) >= MaxJobs) - cupsdCleanJobs(); + cupsFileClose(src); + + unlink(tempfile); + + return (cupsFileClose(dst)); +} + + +/* + * 'copy_job_attrs()' - Copy job attributes. + */ - if (cupsArrayCount(Jobs) >= MaxJobs && MaxJobs) - { - send_ipp_status(con, IPP_NOT_POSSIBLE, - _("Too many active jobs.")); - return; - } +static void +copy_job_attrs(cupsd_client_t *con, /* I - Client connection */ + cupsd_job_t *job, /* I - Job */ + cups_array_t *ra) /* I - Requested attributes array */ +{ + char job_uri[HTTP_MAX_URI]; /* Job URI */ - if (!check_quotas(con, printer)) - { - send_ipp_status(con, IPP_NOT_POSSIBLE, _("Quota limit reached.")); - return; - } /* - * Create the job and set things up... + * Send the requested attributes for each job... */ - if ((attr = ippFindAttribute(con->request, "job-priority", - IPP_TAG_INTEGER)) != NULL) - priority = attr->values[0].integer; - else - ippAddInteger(con->request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-priority", - priority = 50); + httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL, + con->servername, con->serverport, "/jobs/%d", + job->id); - if ((attr = ippFindAttribute(con->request, "job-name", - IPP_TAG_NAME)) != NULL) - title = attr->values[0].string.text; - else - ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, - title = "Untitled"); + if (!ra || cupsArrayFind(ra, "job-more-info")) + ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, + "job-more-info", NULL, job_uri); - if ((job = cupsdAddJob(priority, printer->name)) == NULL) - { - send_ipp_status(con, IPP_INTERNAL_ERROR, - _("Unable to add job for destination \"%s\"!"), dest); - return; - } + if (job->state_value > IPP_JOB_PROCESSING && + (!ra || cupsArrayFind(ra, "job-preserved"))) + ippAddBoolean(con->response, IPP_TAG_JOB, "job-preserved", + job->num_files > 0); - job->dtype = dtype; - job->attrs = con->request; - con->request = NULL; + if (!ra || cupsArrayFind(ra, "job-printer-up-time")) + ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, + "job-printer-up-time", time(NULL)); - add_job_uuid(con, job); + if (!ra || cupsArrayFind(ra, "job-state-reasons")) + add_job_state_reasons(con, job); - attr = ippFindAttribute(job->attrs, "requesting-user-name", IPP_TAG_NAME); + if (!ra || cupsArrayFind(ra, "job-uri")) + ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, + "job-uri", NULL, job_uri); - if (con->username[0]) - { - cupsdSetString(&job->username, con->username); + copy_attrs(con->response, job->attrs, ra, IPP_TAG_JOB, 0); +} - if (attr) - cupsdSetString(&attr->values[0].string.text, con->username); - save_auth_info(con, job); - } - else if (attr) - { - cupsdLogMessage(CUPSD_LOG_DEBUG, - "create_job: requesting-user-name = \"%s\"", - attr->values[0].string.text); +/* + * 'copy_printer_attrs()' - Copy printer attributes. + */ - cupsdSetString(&job->username, attr->values[0].string.text); - } - else - cupsdSetString(&job->username, "anonymous"); +static void +copy_printer_attrs( + cupsd_client_t *con, /* I - Client connection */ + cupsd_printer_t *printer, /* I - Printer */ + cups_array_t *ra) /* I - Requested attributes array */ +{ + char printer_uri[HTTP_MAX_URI]; + /* Printer URI */ + time_t curtime; /* Current time */ + int i; /* Looping var */ + ipp_attribute_t *history; /* History collection */ - if (!attr) - ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, - "job-originating-user-name", NULL, job->username); - else - { - attr->group_tag = IPP_TAG_JOB; - cupsdSetString(&attr->name, "job-originating-user-name"); - } - if ((attr = ippFindAttribute(job->attrs, "job-originating-host-name", - IPP_TAG_ZERO)) != NULL) - { - /* - * Request contains a job-originating-host-name attribute; validate it... - */ + /* + * Copy the printer attributes to the response using requested-attributes + * and document-format attributes that may be provided by the client. + */ - if (attr->value_tag != IPP_TAG_NAME || - attr->num_values != 1 || - strcmp(con->http.hostname, "localhost")) - { - /* - * Can't override the value if we aren't connected via localhost. - * Also, we can only have 1 value and it must be a name value. - */ + curtime = time(NULL); - switch (attr->value_tag) - { - case IPP_TAG_STRING : - case IPP_TAG_TEXTLANG : - case IPP_TAG_NAMELANG : - case IPP_TAG_TEXT : - case IPP_TAG_NAME : - case IPP_TAG_KEYWORD : - case IPP_TAG_URI : - case IPP_TAG_URISCHEME : - case IPP_TAG_CHARSET : - case IPP_TAG_LANGUAGE : - case IPP_TAG_MIMETYPE : - /* - * Free old strings... - */ +#ifdef __APPLE__ + if ((!ra || cupsArrayFind(ra, "com.apple.print.recoverable-message")) && + printer->recoverable) + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT, + "com.apple.print.recoverable-message", NULL, + printer->recoverable); +#endif /* __APPLE__ */ - for (i = 0; i < attr->num_values; i ++) - { - _cups_sp_free(attr->values[i].string.text); - attr->values[i].string.text = NULL; - if (attr->values[i].string.charset) - { - _cups_sp_free(attr->values[i].string.charset); - attr->values[i].string.charset = NULL; - } - } + if (!ra || cupsArrayFind(ra, "printer-current-time")) + ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time", + ippTimeToDate(curtime)); - default : - break; - } + if (!ra || cupsArrayFind(ra, "printer-error-policy")) + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME, + "printer-error-policy", NULL, printer->error_policy); - /* - * Use the default connection hostname instead... - */ + if (!ra || cupsArrayFind(ra, "printer-is-accepting-jobs")) + ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-accepting-jobs", + printer->accepting); - attr->value_tag = IPP_TAG_NAME; - attr->num_values = 1; - attr->values[0].string.text = _cups_sp_alloc(con->http.hostname); - } + if (!ra || cupsArrayFind(ra, "printer-is-shared")) + ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-shared", + printer->shared); - attr->group_tag = IPP_TAG_JOB; - } - else + if (!ra || cupsArrayFind(ra, "printer-op-policy")) + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME, + "printer-op-policy", NULL, printer->op_policy); + + if (!ra || cupsArrayFind(ra, "printer-state")) + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", + printer->state); + + if (!ra || cupsArrayFind(ra, "printer-state-change-time")) + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "printer-state-change-time", printer->state_time); + + if (MaxPrinterHistory > 0 && printer->num_history > 0 && + cupsArrayFind(ra, "printer-state-history")) { /* - * No job-originating-host-name attribute, so use the hostname from - * the connection... + * Printer history is only sent if specifically requested, so that + * older CUPS/IPP clients won't barf on the collection attributes. */ - ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, - "job-originating-host-name", NULL, con->http.hostname); + history = ippAddCollections(con->response, IPP_TAG_PRINTER, + "printer-state-history", + printer->num_history, NULL); + + for (i = 0; i < printer->num_history; i ++) + copy_attrs(history->values[i].collection = ippNew(), printer->history[i], + NULL, IPP_TAG_ZERO, 0); } - ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "time-at-creation", - time(NULL)); - attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, - "time-at-processing", 0); - attr->value_tag = IPP_TAG_NOVALUE; - attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, - "time-at-completed", 0); - attr->value_tag = IPP_TAG_NOVALUE; + if (!ra || cupsArrayFind(ra, "printer-state-message")) + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT, + "printer-state-message", NULL, printer->state_message); - /* - * Add remaining job attributes... - */ + if (!ra || cupsArrayFind(ra, "printer-state-reasons")) + add_printer_state_reasons(con, printer); - ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id); - job->state = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_ENUM, - "job-state", IPP_JOB_STOPPED); - job->state_value = job->state->values[0].integer; - job->sheets = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, - "job-media-sheets-completed", 0); - ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri", NULL, - printer->uri); - ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, - title); + if (!ra || cupsArrayFind(ra, "printer-type")) + { + int type; /* printer-type value */ - if ((attr = ippFindAttribute(job->attrs, "job-k-octets", - IPP_TAG_INTEGER)) != NULL) - attr->values[0].integer = 0; - else - attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, - "job-k-octets", 0); - if ((attr = ippFindAttribute(job->attrs, "job-hold-until", - IPP_TAG_KEYWORD)) == NULL) - attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME); - if (!attr) - attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD, - "job-hold-until", NULL, "no-hold"); - if (attr && strcmp(attr->values[0].string.text, "no-hold") && - !(printer->type & CUPS_PRINTER_REMOTE)) - { /* - * Hold job until specified time... + * Add the CUPS-specific printer-type attribute... */ - cupsdSetJobHoldUntil(job, attr->values[0].string.text); + type = printer->type; + + if (printer == DefaultPrinter) + type |= CUPS_PRINTER_DEFAULT; + + if (!printer->accepting) + type |= CUPS_PRINTER_REJECTING; + + if (!printer->shared) + type |= CUPS_PRINTER_NOT_SHARED; + + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-type", + type); } - else - job->hold_until = time(NULL) + 60; - job->state->values[0].integer = IPP_JOB_HELD; - job->state_value = IPP_JOB_HELD; + if (!ra || cupsArrayFind(ra, "printer-up-time")) + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "printer-up-time", curtime); - if (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) || - Classification) + if ((!ra || cupsArrayFind(ra, "printer-uri-supported")) && + !ippFindAttribute(printer->attrs, "printer-uri-supported", + IPP_TAG_URI)) { - /* - * Add job sheets options... - */ + httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), + "ipp", NULL, con->servername, con->serverport, + "/printers/%s", printer->name); + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, + "printer-uri-supported", NULL, printer_uri); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "printer-uri-supported=\"%s\"", + printer_uri); + } - if ((attr = ippFindAttribute(job->attrs, "job-sheets", - IPP_TAG_ZERO)) == NULL) - { - cupsdLogMessage(CUPSD_LOG_DEBUG, - "Adding default job-sheets values \"%s,%s\"...", - printer->job_sheets[0], printer->job_sheets[1]); + if (!ra || cupsArrayFind(ra, "queued-job-count")) + add_queued_job_count(con, printer); - attr = ippAddStrings(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-sheets", - 2, NULL, NULL); - attr->values[0].string.text = _cups_sp_alloc(printer->job_sheets[0]); - attr->values[1].string.text = _cups_sp_alloc(printer->job_sheets[1]); - } + copy_attrs(con->response, printer->attrs, ra, IPP_TAG_ZERO, 0); + copy_attrs(con->response, CommonData, ra, IPP_TAG_ZERO, IPP_TAG_COPY); +} - job->job_sheets = attr; - /* - * Enforce classification level if set... - */ +/* + * 'copy_subscription_attrs()' - Copy subscription attributes. + */ - if (Classification) - { - cupsdLogMessage(CUPSD_LOG_INFO, - "Classification=\"%s\", ClassifyOverride=%d", - Classification ? Classification : "(null)", - ClassifyOverride); +static void +copy_subscription_attrs( + cupsd_client_t *con, /* I - Client connection */ + cupsd_subscription_t *sub, /* I - Subscription */ + cups_array_t *ra) /* I - Requested attributes array */ +{ + ipp_attribute_t *attr; /* Current attribute */ + char printer_uri[HTTP_MAX_URI]; + /* Printer URI */ + int count; /* Number of events */ + unsigned mask; /* Current event mask */ + const char *name; /* Current event name */ - if (ClassifyOverride) - { - if (!strcmp(attr->values[0].string.text, "none") && - (attr->num_values == 1 || - !strcmp(attr->values[1].string.text, "none"))) - { - /* - * Force the leading banner to have the classification on it... - */ - cupsdSetString(&attr->values[0].string.text, Classification); + /* + * Copy the subscription attributes to the response using the + * requested-attributes attribute that may be provided by the client. + */ - cupsdLogMessage(CUPSD_LOG_NOTICE, "[Job %d] CLASSIFICATION FORCED " - "job-sheets=\"%s,none\", " - "job-originating-user-name=\"%s\"", - job->id, Classification, job->username); - } - else if (attr->num_values == 2 && - strcmp(attr->values[0].string.text, - attr->values[1].string.text) && - strcmp(attr->values[0].string.text, "none") && - strcmp(attr->values[1].string.text, "none")) - { - /* - * Can't put two different security markings on the same document! - */ + if (!ra || cupsArrayFind(ra, "notify-events")) + { + if ((name = cupsdEventName((cupsd_eventmask_t)sub->mask)) != NULL) + { + /* + * Simple event list... + */ - cupsdSetString(&attr->values[1].string.text, attr->values[0].string.text); + ippAddString(con->response, IPP_TAG_SUBSCRIPTION, + IPP_TAG_KEYWORD | IPP_TAG_COPY, + "notify-events", NULL, name); + } + else + { + /* + * Complex event list... + */ - cupsdLogMessage(CUPSD_LOG_NOTICE, "[Job %d] CLASSIFICATION FORCED " - "job-sheets=\"%s,%s\", " - "job-originating-user-name=\"%s\"", - job->id, attr->values[0].string.text, - attr->values[1].string.text, job->username); - } - else if (strcmp(attr->values[0].string.text, Classification) && - strcmp(attr->values[0].string.text, "none") && - (attr->num_values == 1 || - (strcmp(attr->values[1].string.text, Classification) && - strcmp(attr->values[1].string.text, "none")))) - { - if (attr->num_values == 1) - cupsdLogMessage(CUPSD_LOG_NOTICE, - "[Job %d] CLASSIFICATION OVERRIDDEN " - "job-sheets=\"%s\", " - "job-originating-user-name=\"%s\"", - job->id, attr->values[0].string.text, job->username); - else - cupsdLogMessage(CUPSD_LOG_NOTICE, - "[Job %d] CLASSIFICATION OVERRIDDEN " - "job-sheets=\"%s,%s\",fffff " - "job-originating-user-name=\"%s\"", - job->id, attr->values[0].string.text, - attr->values[1].string.text, job->username); - } - } - else if (strcmp(attr->values[0].string.text, Classification) && - (attr->num_values == 1 || - strcmp(attr->values[1].string.text, Classification))) - { - /* - * Force the banner to have the classification on it... - */ + for (mask = 1, count = 0; mask < CUPSD_EVENT_ALL; mask <<= 1) + if (sub->mask & mask) + count ++; - if (attr->num_values > 1 && - !strcmp(attr->values[0].string.text, attr->values[1].string.text)) - { - cupsdSetString(&(attr->values[0].string.text), Classification); - cupsdSetString(&(attr->values[1].string.text), Classification); - } - else - { - if (attr->num_values == 1 || - strcmp(attr->values[0].string.text, "none")) - cupsdSetString(&(attr->values[0].string.text), Classification); + attr = ippAddStrings(con->response, IPP_TAG_SUBSCRIPTION, + IPP_TAG_KEYWORD | IPP_TAG_COPY, + "notify-events", count, NULL, NULL); - if (attr->num_values > 1 && - strcmp(attr->values[1].string.text, "none")) - cupsdSetString(&(attr->values[1].string.text), Classification); - } + for (mask = 1, count = 0; mask < CUPSD_EVENT_ALL; mask <<= 1) + if (sub->mask & mask) + { + attr->values[count].string.text = + (char *)cupsdEventName((cupsd_eventmask_t)mask); - if (attr->num_values > 1) - cupsdLogMessage(CUPSD_LOG_NOTICE, - "[Job %d] CLASSIFICATION FORCED " - "job-sheets=\"%s,%s\", " - "job-originating-user-name=\"%s\"", - job->id, attr->values[0].string.text, - attr->values[1].string.text, job->username); - else - cupsdLogMessage(CUPSD_LOG_NOTICE, - "[Job %d] CLASSIFICATION FORCED " - "job-sheets=\"%s\", " - "job-originating-user-name=\"%s\"", - job->id, Classification, job->username); - } + count ++; + } } + } - /* - * See if we need to add the starting sheet... - */ - - if (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT))) - { - cupsdLogMessage(CUPSD_LOG_INFO, - "Adding start banner page \"%s\" to job %d.", - attr->values[0].string.text, job->id); + if (sub->job && (!ra || cupsArrayFind(ra, "notify-job-id"))) + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, + "notify-job-id", sub->job->id); - kbytes = copy_banner(con, job, attr->values[0].string.text); + if (!sub->job && (!ra || cupsArrayFind(ra, "notify-lease-duration"))) + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, + "notify-lease-duration", sub->lease); - cupsdUpdateQuota(printer, job->username, 0, kbytes); - } + if (sub->dest && (!ra || cupsArrayFind(ra, "notify-printer-uri"))) + { + httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), + "ipp", NULL, con->servername, con->serverport, + "/printers/%s", sub->dest->name); + ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, + "notify-printer-uri", NULL, printer_uri); } - else if ((attr = ippFindAttribute(job->attrs, "job-sheets", - IPP_TAG_ZERO)) != NULL) - job->sheets = attr; - /* - * Fill in the response info... - */ + if (sub->recipient && (!ra || cupsArrayFind(ra, "notify-recipient-uri"))) + ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, + "notify-recipient-uri", NULL, sub->recipient); + else if (!ra || cupsArrayFind(ra, "notify-pull-method")) + ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, + "notify-pull-method", NULL, "ippget"); - snprintf(job_uri, sizeof(job_uri), "http://%s:%d/jobs/%d", ServerName, - LocalPort, job->id); + if (!ra || cupsArrayFind(ra, "notify-subscriber-user-name")) + ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_NAME, + "notify-subscriber-user-name", NULL, sub->owner); - ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, "job-uri", NULL, job_uri); + if (!ra || cupsArrayFind(ra, "notify-subscription-id")) + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, + "notify-subscription-id", sub->id); - ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id); + if (!ra || cupsArrayFind(ra, "notify-time-interval")) + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, + "notify-time-interval", sub->interval); - ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state", - job->state_value); + if (sub->user_data_len > 0 && (!ra || cupsArrayFind(ra, "notify-user-data"))) + ippAddOctetString(con->response, IPP_TAG_SUBSCRIPTION, "notify-user-data", + sub->user_data, sub->user_data_len); +} - con->response->request.status.status_code = IPP_OK; - /* - * Add any job subscriptions... - */ +/* + * 'create_job()' - Print a file to a printer or class. + */ + +static void +create_job(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer URI */ +{ + cupsd_job_t *job; /* New job */ + - add_job_subscriptions(con, job); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "create_job(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); /* - * Set all but the first two attributes to the job attributes group... + * Create the job object... */ - for (attr = job->attrs->attrs->next->next; attr; attr = attr->next) - attr->group_tag = IPP_TAG_JOB; + if ((job = add_job(con, uri, NULL)) == NULL) + return; /* * Save and log the job... @@ -4515,8 +4429,6 @@ create_job(cupsd_client_t *con, /* I - Client connection */ cupsdLogMessage(CUPSD_LOG_INFO, "Job %d created on \"%s\" by \"%s\".", job->id, job->dest, job->username); - - cupsdAddEvent(CUPSD_EVENT_JOB_CREATED, printer, job, "Job created."); } @@ -5210,7 +5122,7 @@ get_devices(cupsd_client_t *con) /* I - Client connection */ snprintf(command, sizeof(command), "%s/daemon/cups-deviced", ServerBin); snprintf(options, sizeof(options), - "cups-deviced %d+%d+%d+requested-attributes=%s", + "%d+%d+%d+requested-attributes=%s", con->request->request.op.request_id, limit ? limit->values[0].integer : 0, User, attrs); @@ -5662,378 +5574,168 @@ get_notifications(cupsd_client_t *con) /* I - Client connection */ else j = min_seq - sub->first_event_id; - for (; j < sub->num_events; j ++) - { - ippAddSeparator(con->response); - - copy_attrs(con->response, sub->events[j]->attrs, NULL, - IPP_TAG_EVENT_NOTIFICATION, 0); - } - } -} - - -/* - * 'get_ppds()' - Get the list of PPD files on the local system. - */ - -static void -get_ppds(cupsd_client_t *con) /* I - Client connection */ -{ - http_status_t status; /* Policy status */ - int i; /* Looping var */ - ipp_attribute_t *limit, /* Limit attribute */ - *make, /* ppd-make attribute */ - *requested; /* requested-attributes attribute */ - char command[1024], /* cups-deviced command */ - options[1024], /* Options to pass to command */ - attrs[1024], /* String for requested attributes */ - *aptr; /* Pointer into string */ - int alen; /* Length of attribute value */ - - - cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppds(%p[%d])", con, con->http.fd); - - /* - * Check policy... - */ - - if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) - { - send_http_error(con, status); - return; - } - - /* - * Run cups-driverd command with the given options... - */ - - limit = ippFindAttribute(con->request, "limit", IPP_TAG_INTEGER); - make = ippFindAttribute(con->request, "ppd-make", IPP_TAG_TEXT); - requested = ippFindAttribute(con->request, "requested-attributes", - IPP_TAG_KEYWORD); - - if (requested) - { - for (i = 0, aptr = attrs; i < requested->num_values; i ++) - { - /* - * Check that we have enough room... - */ - - alen = strlen(requested->values[i].string.text); - if (alen > (sizeof(attrs) - (aptr - attrs) - 2)) - break; - - /* - * Put commas between values... - */ - - if (i) - *aptr++ = ','; - - /* - * Add the value to the end of the string... - */ - - strcpy(aptr, requested->values[i].string.text); - aptr += alen; - } - - /* - * If we have more attribute names than will fit, default to "all"... - */ - - if (i < requested->num_values) - strcpy(attrs, "all"); - } - else - strcpy(attrs, "all"); - - snprintf(command, sizeof(command), "%s/daemon/cups-driverd", ServerBin); - snprintf(options, sizeof(options), - "cups-driverd list+%d+%d+requested-attributes=%s%s%s", - con->request->request.op.request_id, - limit ? limit->values[0].integer : 0, - attrs, - make ? "%20ppd-make=" : "", - make ? make->values[0].string.text : ""); - - if (cupsdSendCommand(con, command, options, 0)) - { - /* - * Command started successfully, don't send an IPP response here... - */ - - ippDelete(con->response); - con->response = NULL; - } - else - { - /* - * Command failed, return "internal error" so the user knows something - * went wrong... - */ - - send_ipp_status(con, IPP_INTERNAL_ERROR, - _("cups-driverd failed to execute.")); - } -} - - -/* - * 'get_printer_attrs()' - Get printer attributes. - */ - -static void -get_printer_attrs(cupsd_client_t *con, /* I - Client connection */ - ipp_attribute_t *uri) /* I - Printer URI */ -{ - http_status_t status; /* Policy status */ - const char *dest; /* Destination */ - cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], - /* Method portion of URI */ - username[HTTP_MAX_URI], - /* Username portion of URI */ - host[HTTP_MAX_URI], - /* Host portion of URI */ - resource[HTTP_MAX_URI]; - /* Resource portion of URI */ - int port; /* Port portion of URI */ - cupsd_printer_t *printer; /* Printer/class */ - cups_array_t *ra; /* Requested attributes array */ - - - cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printer_attrs(%p[%d], %s)", con, - con->http.fd, uri->values[0].string.text); - - /* - * Is the destination valid? - */ - - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) - { - /* - * Bad URI... - */ - - send_ipp_status(con, IPP_NOT_FOUND, - _("The printer or class was not found.")); - return; - } - - /* - * Check policy... - */ - - if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) - { - send_http_error(con, status); - return; - } - - /* - * Send the attributes... - */ - - ra = create_requested_array(con->request); - - copy_printer_attrs(con, printer, ra); - - cupsArrayDelete(ra); - - con->response->request.status.status_code = IPP_OK; -} - - -/* - * 'get_printers()' - Get a list of printers or classes. - */ - -static void -get_printers(cupsd_client_t *con, /* I - Client connection */ - int type) /* I - 0 or CUPS_PRINTER_CLASS */ -{ - http_status_t status; /* Policy status */ - ipp_attribute_t *attr; /* Current attribute */ - int limit; /* Maximum number of printers to return */ - int count; /* Number of printers that match */ - cupsd_printer_t *printer; /* Current printer pointer */ - int printer_type, /* printer-type attribute */ - printer_mask; /* printer-type-mask attribute */ - char *location; /* Location string */ - const char *username; /* Current user */ - char *first_printer_name; /* first-printer-name attribute */ - cups_array_t *ra; /* Requested attributes array */ - - - cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printers(%p[%d], %x)", con, - con->http.fd, type); - - /* - * Check policy... - */ - - if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) - { - send_http_error(con, status); - return; - } - - /* - * Check for printers... - */ - - if (!Printers || !cupsArrayCount(Printers)) - { - send_ipp_status(con, IPP_NOT_FOUND, _("No destinations added.")); - return; - } - - /* - * See if they want to limit the number of printers reported... - */ - - if ((attr = ippFindAttribute(con->request, "limit", - IPP_TAG_INTEGER)) != NULL) - limit = attr->values[0].integer; - else - limit = 10000000; - - if ((attr = ippFindAttribute(con->request, "first-printer-name", - IPP_TAG_NAME)) != NULL) - first_printer_name = attr->values[0].string.text; - else - first_printer_name = NULL; + for (; j < sub->num_events; j ++) + { + ippAddSeparator(con->response); - /* - * Support filtering... - */ + copy_attrs(con->response, sub->events[j]->attrs, NULL, + IPP_TAG_EVENT_NOTIFICATION, 0); + } + } +} - if ((attr = ippFindAttribute(con->request, "printer-type", - IPP_TAG_ENUM)) != NULL) - printer_type = attr->values[0].integer; - else - printer_type = 0; - if ((attr = ippFindAttribute(con->request, "printer-type-mask", - IPP_TAG_ENUM)) != NULL) - printer_mask = attr->values[0].integer; - else - printer_mask = 0; +/* + * 'get_ppds()' - Get the list of PPD files on the local system. + */ - if ((attr = ippFindAttribute(con->request, "printer-location", - IPP_TAG_TEXT)) != NULL) - location = attr->values[0].string.text; - else - location = NULL; +static void +get_ppds(cupsd_client_t *con) /* I - Client connection */ +{ + http_status_t status; /* Policy status */ + int i; /* Looping var */ + ipp_attribute_t *limit, /* Limit attribute */ + *make, /* ppd-make attribute */ + *requested; /* requested-attributes attribute */ + char command[1024], /* cups-deviced command */ + options[1024], /* Options to pass to command */ + attrs[1024], /* String for requested attributes */ + *aptr; /* Pointer into string */ + int alen; /* Length of attribute value */ - if (con->username[0]) - username = con->username; - else if ((attr = ippFindAttribute(con->request, "requesting-user-name", - IPP_TAG_NAME)) != NULL) - username = attr->values[0].string.text; - else - username = NULL; - ra = create_requested_array(con->request); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppds(%p[%d])", con, con->http.fd); /* - * OK, build a list of printers for this printer... + * Check policy... */ - if (first_printer_name) + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) { - if ((printer = cupsdFindDest(first_printer_name)) == NULL) - printer = (cupsd_printer_t *)cupsArrayFirst(Printers); + send_http_error(con, status); + return; } - else - printer = (cupsd_printer_t *)cupsArrayFirst(Printers); - for (count = 0; - count < limit && printer; - printer = (cupsd_printer_t *)cupsArrayNext(Printers)) + /* + * Run cups-driverd command with the given options... + */ + + limit = ippFindAttribute(con->request, "limit", IPP_TAG_INTEGER); + make = ippFindAttribute(con->request, "ppd-make", IPP_TAG_TEXT); + requested = ippFindAttribute(con->request, "requested-attributes", + IPP_TAG_KEYWORD); + + if (requested) { - if ((!type || (printer->type & CUPS_PRINTER_CLASS) == type) && - (printer->type & printer_mask) == printer_type && - (!location || !printer->location || - !strcasecmp(printer->location, location))) + for (i = 0, aptr = attrs; i < requested->num_values; i ++) { /* - * If HideImplicitMembers is enabled, see if this printer or class - * is a member of an implicit class... + * Check that we have enough room... */ - if (ImplicitClasses && HideImplicitMembers && - printer->in_implicit_class) - continue; + alen = strlen(requested->values[i].string.text); + if (alen > (sizeof(attrs) - (aptr - attrs) - 2)) + break; /* - * If a username is specified, see if it is allowed or denied - * access... + * Put commas between values... */ - if (printer->num_users && username && !user_allowed(printer, username)) - continue; + if (i) + *aptr++ = ','; /* - * Add the group separator as needed... + * Add the value to the end of the string... */ - if (count > 0) - ippAddSeparator(con->response); - - count ++; + strcpy(aptr, requested->values[i].string.text); + aptr += alen; + } - /* - * Send the attributes... - */ + /* + * If we have more attribute names than will fit, default to "all"... + */ - copy_printer_attrs(con, printer, ra); - } + if (i < requested->num_values) + strcpy(attrs, "all"); } + else + strcpy(attrs, "all"); - cupsArrayDelete(ra); + snprintf(command, sizeof(command), "%s/daemon/cups-driverd", ServerBin); + snprintf(options, sizeof(options), + "list+%d+%d+requested-attributes=%s%s%s", + con->request->request.op.request_id, + limit ? limit->values[0].integer : 0, + attrs, + make ? "%20ppd-make=" : "", + make ? make->values[0].string.text : ""); - con->response->request.status.status_code = IPP_OK; + if (cupsdSendCommand(con, command, options, 0)) + { + /* + * Command started successfully, don't send an IPP response here... + */ + + ippDelete(con->response); + con->response = NULL; + } + else + { + /* + * Command failed, return "internal error" so the user knows something + * went wrong... + */ + + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("cups-driverd failed to execute.")); + } } /* - * 'get_subscription_attrs()' - Get subscription attributes. + * 'get_printer_attrs()' - Get printer attributes. */ static void -get_subscription_attrs( - cupsd_client_t *con, /* I - Client connection */ - int sub_id) /* I - Subscription ID */ +get_printer_attrs(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer URI */ { http_status_t status; /* Policy status */ - cupsd_subscription_t *sub; /* Subscription */ + const char *dest; /* Destination */ + cups_ptype_t dtype; /* Destination type (printer or class) */ + char method[HTTP_MAX_URI], + /* Method portion of URI */ + username[HTTP_MAX_URI], + /* Username portion of URI */ + host[HTTP_MAX_URI], + /* Host portion of URI */ + resource[HTTP_MAX_URI]; + /* Resource portion of URI */ + int port; /* Port portion of URI */ + cupsd_printer_t *printer; /* Printer/class */ cups_array_t *ra; /* Requested attributes array */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "get_subscription_attrs(con=%p[%d], sub_id=%d)", - con, con->http.fd, sub_id); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printer_attrs(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); /* - * Is the subscription ID valid? + * Is the destination valid? */ - if ((sub = cupsdFindSubscription(sub_id)) == NULL) + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, + sizeof(method), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) { /* - * Bad subscription ID... + * Bad URI... */ send_ipp_status(con, IPP_NOT_FOUND, - _("notify-subscription-id %d no good!"), sub_id); + _("The printer or class was not found.")); return; } @@ -6041,22 +5743,19 @@ get_subscription_attrs( * Check policy... */ - if ((status = cupsdCheckPolicy(sub->dest ? sub->dest->op_policy_ptr : - DefaultPolicyPtr, - con, sub->owner)) != HTTP_OK) + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) { send_http_error(con, status); return; } /* - * Copy the subscription attributes to the response using the - * requested-attributes attribute that may be provided by the client. + * Send the attributes... */ ra = create_requested_array(con->request); - copy_subscription_attrs(con, sub, ra); + copy_printer_attrs(con, printer, ra); cupsArrayDelete(ra); @@ -6065,364 +5764,188 @@ get_subscription_attrs( /* - * 'get_subscriptions()' - Get subscriptions. + * 'get_printers()' - Get a list of printers or classes. */ static void -get_subscriptions(cupsd_client_t *con, /* I - Client connection */ - ipp_attribute_t *uri) /* I - Printer/job URI */ +get_printers(cupsd_client_t *con, /* I - Client connection */ + int type) /* I - 0 or CUPS_PRINTER_CLASS */ { - http_status_t status; /* Policy status */ - int count; /* Number of subscriptions */ - int limit; /* Limit */ - cupsd_subscription_t *sub; /* Subscription */ - cups_array_t *ra; /* Requested attributes array */ - ipp_attribute_t *attr; /* Attribute */ - cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], - /* Method portion of URI */ - username[HTTP_MAX_URI], - /* Username portion of URI */ - host[HTTP_MAX_URI], - /* Host portion of URI */ - resource[HTTP_MAX_URI]; - /* Resource portion of URI */ - int port; /* Port portion of URI */ - cupsd_job_t *job; /* Job pointer */ - cupsd_printer_t *printer; /* Printer */ - - - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "get_subscriptions(con=%p[%d], uri=%s)", - con, con->http.fd, uri->values[0].string.text); - - /* - * Is the destination valid? - */ - - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if (!strcmp(resource, "/") || - (!strncmp(resource, "/jobs", 5) && strlen(resource) <= 6) || - (!strncmp(resource, "/printers", 9) && strlen(resource) <= 10) || - (!strncmp(resource, "/classes", 8) && strlen(resource) <= 9)) - { - printer = NULL; - job = NULL; - } - else if (!strncmp(resource, "/jobs/", 6) && resource[6]) - { - printer = NULL; - job = cupsdFindJob(atoi(resource + 6)); - - if (!job) - { - send_ipp_status(con, IPP_NOT_FOUND, _("Job #%s does not exist!"), - resource + 6); - return; - } - } - else if (!cupsdValidateDest(host, resource, &dtype, &printer)) - { - /* - * Bad URI... - */ + http_status_t status; /* Policy status */ + ipp_attribute_t *attr; /* Current attribute */ + int limit; /* Maximum number of printers to return */ + int count; /* Number of printers that match */ + cupsd_printer_t *printer; /* Current printer pointer */ + int printer_type, /* printer-type attribute */ + printer_mask; /* printer-type-mask attribute */ + char *location; /* Location string */ + const char *username; /* Current user */ + char *first_printer_name; /* first-printer-name attribute */ + cups_array_t *ra; /* Requested attributes array */ - send_ipp_status(con, IPP_NOT_FOUND, - _("The printer or class was not found.")); - return; - } - else if ((attr = ippFindAttribute(con->request, "notify-job-id", - IPP_TAG_INTEGER)) != NULL) - { - job = cupsdFindJob(attr->values[0].integer); - if (!job) - { - send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), - attr->values[0].integer); - return; - } - } - else - job = NULL; + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printers(%p[%d], %x)", con, + con->http.fd, type); /* * Check policy... */ - if ((status = cupsdCheckPolicy(printer ? printer->op_policy_ptr : - DefaultPolicyPtr, - con, NULL)) != HTTP_OK) + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) { send_http_error(con, status); return; } /* - * Copy the subscription attributes to the response using the - * requested-attributes attribute that may be provided by the client. + * Check for printers... */ - ra = create_requested_array(con->request); + if (!Printers || !cupsArrayCount(Printers)) + { + send_ipp_status(con, IPP_NOT_FOUND, _("No destinations added.")); + return; + } + + /* + * See if they want to limit the number of printers reported... + */ if ((attr = ippFindAttribute(con->request, "limit", IPP_TAG_INTEGER)) != NULL) limit = attr->values[0].integer; else - limit = 0; + limit = 10000000; + + if ((attr = ippFindAttribute(con->request, "first-printer-name", + IPP_TAG_NAME)) != NULL) + first_printer_name = attr->values[0].string.text; + else + first_printer_name = NULL; /* - * See if we only want to see subscriptions for a specific user... + * Support filtering... */ - if ((attr = ippFindAttribute(con->request, "my-subscriptions", - IPP_TAG_BOOLEAN)) != NULL && - attr->values[0].boolean) - strlcpy(username, get_username(con), sizeof(username)); + if ((attr = ippFindAttribute(con->request, "printer-type", + IPP_TAG_ENUM)) != NULL) + printer_type = attr->values[0].integer; else - username[0] = '\0'; - - for (sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions), count = 0; - sub; - sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions)) - if ((!printer || sub->dest == printer) && (!job || sub->job == job) && - (!username[0] || !strcasecmp(username, sub->owner))) - { - ippAddSeparator(con->response); - copy_subscription_attrs(con, sub, ra); - - count ++; - if (limit && count >= limit) - break; - } - - cupsArrayDelete(ra); + printer_type = 0; - if (count) - con->response->request.status.status_code = IPP_OK; + if ((attr = ippFindAttribute(con->request, "printer-type-mask", + IPP_TAG_ENUM)) != NULL) + printer_mask = attr->values[0].integer; else - send_ipp_status(con, IPP_NOT_FOUND, _("No subscriptions found.")); -} - - -/* - * 'get_username()' - Get the username associated with a request. - */ - -static const char * /* O - Username */ -get_username(cupsd_client_t *con) /* I - Connection */ -{ - ipp_attribute_t *attr; /* Attribute */ + printer_mask = 0; + if ((attr = ippFindAttribute(con->request, "printer-location", + IPP_TAG_TEXT)) != NULL) + location = attr->values[0].string.text; + else + location = NULL; if (con->username[0]) - return (con->username); + username = con->username; else if ((attr = ippFindAttribute(con->request, "requesting-user-name", IPP_TAG_NAME)) != NULL) - return (attr->values[0].string.text); + username = attr->values[0].string.text; else - return ("anonymous"); -} - - -/* - * 'hold_job()' - Hold a print job. - */ - -static void -hold_job(cupsd_client_t *con, /* I - Client connection */ - ipp_attribute_t *uri) /* I - Job or Printer URI */ -{ - ipp_attribute_t *attr, /* Current job-hold-until */ - *newattr; /* New job-hold-until */ - int jobid; /* Job ID */ - char method[HTTP_MAX_URI], /* Method portion of URI */ - username[HTTP_MAX_URI], /* Username portion of URI */ - host[HTTP_MAX_URI], /* Host portion of URI */ - resource[HTTP_MAX_URI]; /* Resource portion of URI */ - int port; /* Port portion of URI */ - cupsd_job_t *job; /* Job information */ - + username = NULL; - cupsdLogMessage(CUPSD_LOG_DEBUG2, "hold_job(%p[%d], %s)", con, con->http.fd, - uri->values[0].string.text); + ra = create_requested_array(con->request); /* - * See if we have a job URI or a printer URI... + * OK, build a list of printers for this printer... */ - if (!strcmp(uri->name, "printer-uri")) + if (first_printer_name) { - /* - * Got a printer URI; see if we also have a job-id attribute... - */ - - if ((attr = ippFindAttribute(con->request, "job-id", - IPP_TAG_INTEGER)) == NULL) - { - send_ipp_status(con, IPP_BAD_REQUEST, - _("Got a printer-uri attribute but no job-id!")); - return; - } - - jobid = attr->values[0].integer; + if ((printer = cupsdFindDest(first_printer_name)) == NULL) + printer = (cupsd_printer_t *)cupsArrayFirst(Printers); } else - { - /* - * Got a job URI; parse it to get the job ID... - */ - - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); + printer = (cupsd_printer_t *)cupsArrayFirst(Printers); - if (strncmp(resource, "/jobs/", 6)) + for (count = 0; + count < limit && printer; + printer = (cupsd_printer_t *)cupsArrayNext(Printers)) + { + if ((!type || (printer->type & CUPS_PRINTER_CLASS) == type) && + (printer->type & printer_mask) == printer_type && + (!location || !printer->location || + !strcasecmp(printer->location, location))) { /* - * Not a valid URI! + * If HideImplicitMembers is enabled, see if this printer or class + * is a member of an implicit class... */ - send_ipp_status(con, IPP_BAD_REQUEST, - _("Bad job-uri attribute \"%s\"!"), - uri->values[0].string.text); - return; - } - - jobid = atoi(resource + 6); - } - - /* - * See if the job exists... - */ - - if ((job = cupsdFindJob(jobid)) == NULL) - { - /* - * Nope - return a "not found" error... - */ - - send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid); - return; - } - - /* - * See if the job is owned by the requesting user... - */ - - if (!validate_user(job, con, job->username, username, sizeof(username))) - { - send_http_error(con, HTTP_UNAUTHORIZED); - return; - } - - /* - * Hold the job and return... - */ - - cupsdHoldJob(job); + if (ImplicitClasses && HideImplicitMembers && + printer->in_implicit_class) + continue; - if ((newattr = ippFindAttribute(con->request, "job-hold-until", - IPP_TAG_KEYWORD)) == NULL) - newattr = ippFindAttribute(con->request, "job-hold-until", IPP_TAG_NAME); + /* + * If a username is specified, see if it is allowed or denied + * access... + */ - if ((attr = ippFindAttribute(job->attrs, "job-hold-until", - IPP_TAG_KEYWORD)) == NULL) - attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME); + if (printer->num_users && username && !user_allowed(printer, username)) + continue; - if (attr) - { - /* - * Free the old hold value and copy the new one over... - */ + /* + * Add the group separator as needed... + */ - _cups_sp_free(attr->values[0].string.text); + if (count > 0) + ippAddSeparator(con->response); - if (newattr) - { - attr->value_tag = newattr->value_tag; - attr->values[0].string.text = - _cups_sp_alloc(newattr->values[0].string.text); - } - else - { - attr->value_tag = IPP_TAG_KEYWORD; - attr->values[0].string.text = _cups_sp_alloc("indefinite"); - } + count ++; - /* - * Hold job until specified time... - */ + /* + * Send the attributes... + */ - cupsdSetJobHoldUntil(job, attr->values[0].string.text); + copy_printer_attrs(con, printer, ra); + } } - cupsdLogMessage(CUPSD_LOG_INFO, "Job %d was held by \"%s\".", jobid, - username); + cupsArrayDelete(ra); con->response->request.status.status_code = IPP_OK; } /* - * 'move_job()' - Move a job to a new destination. + * 'get_subscription_attrs()' - Get subscription attributes. */ static void -move_job(cupsd_client_t *con, /* I - Client connection */ - ipp_attribute_t *uri) /* I - Job URI */ +get_subscription_attrs( + cupsd_client_t *con, /* I - Client connection */ + int sub_id) /* I - Subscription ID */ { - http_status_t status; /* Policy status */ - ipp_attribute_t *attr; /* Current attribute */ - int jobid; /* Job ID */ - cupsd_job_t *job; /* Current job */ - const char *src, /* Source printer/class */ - *dest; /* Destination */ - cups_ptype_t stype, /* Source type (printer or class) */ - dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], /* Method portion of URI */ - username[HTTP_MAX_URI], /* Username portion of URI */ - host[HTTP_MAX_URI], /* Host portion of URI */ - resource[HTTP_MAX_URI]; /* Resource portion of URI */ - int port; /* Port portion of URI */ - cupsd_printer_t *sprinter, /* Source printer */ - *dprinter; /* Destination printer */ + http_status_t status; /* Policy status */ + cupsd_subscription_t *sub; /* Subscription */ + cups_array_t *ra; /* Requested attributes array */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "move_job(%p[%d], %s)", con, con->http.fd, - uri->values[0].string.text); + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "get_subscription_attrs(con=%p[%d], sub_id=%d)", + con, con->http.fd, sub_id); /* - * Get the new printer or class... + * Is the subscription ID valid? */ - if ((attr = ippFindAttribute(con->request, "job-printer-uri", - IPP_TAG_URI)) == NULL) - { - /* - * Need job-printer-uri... - */ - - send_ipp_status(con, IPP_BAD_REQUEST, - _("job-printer-uri attribute missing!")); - return; - } - - httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((dest = cupsdValidateDest(host, resource, &dtype, &dprinter)) == NULL) + if ((sub = cupsdFindSubscription(sub_id)) == NULL) { /* - * Bad URI... + * Bad subscription ID... */ send_ipp_status(con, IPP_NOT_FOUND, - _("The printer or class was not found.")); + _("notify-subscription-id %d no good!"), sub_id); return; } @@ -6430,952 +5953,893 @@ move_job(cupsd_client_t *con, /* I - Client connection */ * Check policy... */ - if ((status = cupsdCheckPolicy(dprinter->op_policy_ptr, con, NULL)) != HTTP_OK) + if ((status = cupsdCheckPolicy(sub->dest ? sub->dest->op_policy_ptr : + DefaultPolicyPtr, + con, sub->owner)) != HTTP_OK) { send_http_error(con, status); return; } /* - * See if we have a job URI or a printer URI... + * Copy the subscription attributes to the response using the + * requested-attributes attribute that may be provided by the client. */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); + ra = create_requested_array(con->request); - if (!strcmp(uri->name, "printer-uri")) - { - /* - * Got a printer URI; see if we also have a job-id attribute... - */ + copy_subscription_attrs(con, sub, ra); - if ((attr = ippFindAttribute(con->request, "job-id", - IPP_TAG_INTEGER)) == NULL) - { - /* - * Move all jobs... - */ + cupsArrayDelete(ra); - if ((src = cupsdValidateDest(host, resource, &stype, &sprinter)) == NULL) - { - /* - * Bad URI... - */ + con->response->request.status.status_code = IPP_OK; +} - send_ipp_status(con, IPP_NOT_FOUND, - _("The printer or class was not found.")); - return; - } - job = NULL; - } - else - { - /* - * Otherwise, just move a single job... - */ +/* + * 'get_subscriptions()' - Get subscriptions. + */ - if ((job = cupsdFindJob(attr->values[0].integer)) == NULL) - { - /* - * Nope - return a "not found" error... - */ +static void +get_subscriptions(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer/job URI */ +{ + http_status_t status; /* Policy status */ + int count; /* Number of subscriptions */ + int limit; /* Limit */ + cupsd_subscription_t *sub; /* Subscription */ + cups_array_t *ra; /* Requested attributes array */ + ipp_attribute_t *attr; /* Attribute */ + cups_ptype_t dtype; /* Destination type (printer or class) */ + char method[HTTP_MAX_URI], + /* Method portion of URI */ + username[HTTP_MAX_URI], + /* Username portion of URI */ + host[HTTP_MAX_URI], + /* Host portion of URI */ + resource[HTTP_MAX_URI]; + /* Resource portion of URI */ + int port; /* Port portion of URI */ + cupsd_job_t *job; /* Job pointer */ + cupsd_printer_t *printer; /* Printer */ - send_ipp_status(con, IPP_NOT_FOUND, - _("Job #%d does not exist!"), attr->values[0].integer); - return; - } - else - { - /* - * Job found, initialize source pointers... - */ - src = NULL; - sprinter = NULL; - } - } + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "get_subscriptions(con=%p[%d], uri=%s)", + con, con->http.fd, uri->values[0].string.text); + + /* + * Is the destination valid? + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, + sizeof(method), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (!strcmp(resource, "/") || + (!strncmp(resource, "/jobs", 5) && strlen(resource) <= 6) || + (!strncmp(resource, "/printers", 9) && strlen(resource) <= 10) || + (!strncmp(resource, "/classes", 8) && strlen(resource) <= 9)) + { + printer = NULL; + job = NULL; } - else + else if (!strncmp(resource, "/jobs/", 6) && resource[6]) { - /* - * Got a job URI; parse it to get the job ID... - */ + printer = NULL; + job = cupsdFindJob(atoi(resource + 6)); - if (strncmp(resource, "/jobs/", 6)) + if (!job) { - /* - * Not a valid URI! - */ - - send_ipp_status(con, IPP_BAD_REQUEST, - _("Bad job-uri attribute \"%s\"!"), - uri->values[0].string.text); + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%s does not exist!"), + resource + 6); return; } - + } + else if (!cupsdValidateDest(host, resource, &dtype, &printer)) + { /* - * See if the job exists... + * Bad URI... */ - jobid = atoi(resource + 6); + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + else if ((attr = ippFindAttribute(con->request, "notify-job-id", + IPP_TAG_INTEGER)) != NULL) + { + job = cupsdFindJob(attr->values[0].integer); - if ((job = cupsdFindJob(jobid)) == NULL) + if (!job) { - /* - * Nope - return a "not found" error... - */ - - send_ipp_status(con, IPP_NOT_FOUND, - _("Job #%d does not exist!"), jobid); + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), + attr->values[0].integer); return; } - else - { - /* - * Job found, initialize source pointers... - */ - - src = NULL; - sprinter = NULL; - } } + else + job = NULL; /* - * Now move the job or jobs... + * Check policy... */ - if (job) + if ((status = cupsdCheckPolicy(printer ? printer->op_policy_ptr : + DefaultPolicyPtr, + con, NULL)) != HTTP_OK) { - /* - * See if the job has been completed... - */ - - if (job->state_value > IPP_JOB_STOPPED) - { - /* - * Return a "not-possible" error... - */ + send_http_error(con, status); + return; + } - send_ipp_status(con, IPP_NOT_POSSIBLE, - _("Job #%d is finished and cannot be altered!"), - job->id); - return; - } + /* + * Copy the subscription attributes to the response using the + * requested-attributes attribute that may be provided by the client. + */ - /* - * See if the job is owned by the requesting user... - */ + ra = create_requested_array(con->request); - if (!validate_user(job, con, job->username, username, sizeof(username))) - { - send_http_error(con, HTTP_UNAUTHORIZED); - return; - } + if ((attr = ippFindAttribute(con->request, "limit", + IPP_TAG_INTEGER)) != NULL) + limit = attr->values[0].integer; + else + limit = 0; - /* - * Move the job to a different printer or class... - */ + /* + * See if we only want to see subscriptions for a specific user... + */ - cupsdMoveJob(job, dest); - } + if ((attr = ippFindAttribute(con->request, "my-subscriptions", + IPP_TAG_BOOLEAN)) != NULL && + attr->values[0].boolean) + strlcpy(username, get_username(con), sizeof(username)); else - { - /* - * Got the source printer, now look through the jobs... - */ + username[0] = '\0'; - for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); - job; - job = (cupsd_job_t *)cupsArrayNext(Jobs)) + for (sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions), count = 0; + sub; + sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions)) + if ((!printer || sub->dest == printer) && (!job || sub->job == job) && + (!username[0] || !strcasecmp(username, sub->owner))) { - /* - * See if the job is pointing at the source printer or has not been - * completed... - */ - - if (strcasecmp(job->dest, src) || - job->state_value > IPP_JOB_STOPPED) - continue; + ippAddSeparator(con->response); + copy_subscription_attrs(con, sub, ra); - /* - * See if the job can be moved by the requesting user... - */ + count ++; + if (limit && count >= limit) + break; + } - if (!validate_user(job, con, job->username, username, sizeof(username))) - continue; + cupsArrayDelete(ra); - /* - * Move the job to a different printer or class... - */ + if (count) + con->response->request.status.status_code = IPP_OK; + else + send_ipp_status(con, IPP_NOT_FOUND, _("No subscriptions found.")); +} - cupsdMoveJob(job, dest); - } - } - /* - * Start jobs if possible... - */ +/* + * 'get_username()' - Get the username associated with a request. + */ - cupsdCheckJobs(); +static const char * /* O - Username */ +get_username(cupsd_client_t *con) /* I - Connection */ +{ + ipp_attribute_t *attr; /* Attribute */ - /* - * Return with "everything is OK" status... - */ - con->response->request.status.status_code = IPP_OK; + if (con->username[0]) + return (con->username); + else if ((attr = ippFindAttribute(con->request, "requesting-user-name", + IPP_TAG_NAME)) != NULL) + return (attr->values[0].string.text); + else + return ("anonymous"); } /* - * 'ppd_add_default()' - Add a PPD default choice. + * 'hold_job()' - Hold a print job. */ -static int /* O - Number of defaults */ -ppd_add_default( - const char *option, /* I - Option name */ - const char *choice, /* I - Choice name */ - int num_defaults, /* I - Number of defaults */ - ppd_default_t **defaults) /* IO - Defaults */ +static void +hold_job(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Job or Printer URI */ { - int i; /* Looping var */ - ppd_default_t *temp; /* Temporary defaults array */ + ipp_attribute_t *attr, /* Current job-hold-until */ + *newattr; /* New job-hold-until */ + int jobid; /* Job ID */ + char method[HTTP_MAX_URI], /* Method portion of URI */ + username[HTTP_MAX_URI], /* Username portion of URI */ + host[HTTP_MAX_URI], /* Host portion of URI */ + resource[HTTP_MAX_URI]; /* Resource portion of URI */ + int port; /* Port portion of URI */ + cupsd_job_t *job; /* Job information */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "hold_job(%p[%d], %s)", con, con->http.fd, + uri->values[0].string.text); /* - * First check if the option already has a default value; the PPD spec - * says that the first one is used... + * See if we have a job URI or a printer URI... */ - for (i = 0, temp = *defaults; i < num_defaults; i ++) - if (!strcmp(option, temp[i].option)) - return (num_defaults); + if (!strcmp(uri->name, "printer-uri")) + { + /* + * Got a printer URI; see if we also have a job-id attribute... + */ - /* - * Now add the option... - */ + if ((attr = ippFindAttribute(con->request, "job-id", + IPP_TAG_INTEGER)) == NULL) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Got a printer-uri attribute but no job-id!")); + return; + } - if (num_defaults == 0) - temp = malloc(sizeof(ppd_default_t)); + jobid = attr->values[0].integer; + } else - temp = realloc(*defaults, (num_defaults + 1) * sizeof(ppd_default_t)); - - if (!temp) { - cupsdLogMessage(CUPSD_LOG_ERROR, "ppd_add_default: Unable to add default value for \"%s\" - %s", - option, strerror(errno)); - return (num_defaults); - } - - *defaults = temp; - temp += num_defaults; + /* + * Got a job URI; parse it to get the job ID... + */ - strlcpy(temp->option, option, sizeof(temp->option)); - strlcpy(temp->choice, choice, sizeof(temp->choice)); + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, + sizeof(method), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); - return (num_defaults + 1); -} + if (strncmp(resource, "/jobs/", 6)) + { + /* + * Not a valid URI! + */ + send_ipp_status(con, IPP_BAD_REQUEST, + _("Bad job-uri attribute \"%s\"!"), + uri->values[0].string.text); + return; + } -/* - * 'ppd_parse_line()' - Parse a PPD default line. - */ + jobid = atoi(resource + 6); + } -static int /* O - 0 on success, -1 on failure */ -ppd_parse_line(const char *line, /* I - Line */ - char *option, /* O - Option name */ - int olen, /* I - Size of option name */ - char *choice, /* O - Choice name */ - int clen) /* I - Size of choice name */ -{ /* - * Verify this is a default option line... + * See if the job exists... */ - if (strncmp(line, "*Default", 8)) - return (-1); + if ((job = cupsdFindJob(jobid)) == NULL) + { + /* + * Nope - return a "not found" error... + */ + + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid); + return; + } /* - * Read the option name... + * See if the job is owned by the requesting user... */ - for (line += 8, olen --; isalnum(*line & 255); line ++) - if (olen > 0) - { - *option++ = *line; - olen --; - } - - *option = '\0'; + if (!validate_user(job, con, job->username, username, sizeof(username))) + { + send_http_error(con, HTTP_UNAUTHORIZED); + return; + } /* - * Skip everything else up to the colon (:)... + * Hold the job and return... */ - while (*line && *line != ':') - line ++; + cupsdHoldJob(job); - if (!*line) - return (-1); + if ((newattr = ippFindAttribute(con->request, "job-hold-until", + IPP_TAG_KEYWORD)) == NULL) + newattr = ippFindAttribute(con->request, "job-hold-until", IPP_TAG_NAME); - line ++; + if ((attr = ippFindAttribute(job->attrs, "job-hold-until", + IPP_TAG_KEYWORD)) == NULL) + attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME); - /* - * Now grab the option choice, skipping leading whitespace... - */ + if (attr) + { + /* + * Free the old hold value and copy the new one over... + */ - while (isspace(*line & 255)) - line ++; + _cups_sp_free(attr->values[0].string.text); - for (clen --; isalnum(*line & 255); line ++) - if (clen > 0) + if (newattr) { - *choice++ = *line; - clen --; + attr->value_tag = newattr->value_tag; + attr->values[0].string.text = + _cups_sp_alloc(newattr->values[0].string.text); + } + else + { + attr->value_tag = IPP_TAG_KEYWORD; + attr->values[0].string.text = _cups_sp_alloc("indefinite"); } - *choice = '\0'; + /* + * Hold job until specified time... + */ - /* - * Return with no errors... - */ + cupsdSetJobHoldUntil(job, attr->values[0].string.text); + } - return (0); + cupsdLogMessage(CUPSD_LOG_INFO, "Job %d was held by \"%s\".", jobid, + username); + + con->response->request.status.status_code = IPP_OK; } /* - * 'print_job()' - Print a file to a printer or class. + * 'move_job()' - Move a job to a new destination. */ static void -print_job(cupsd_client_t *con, /* I - Client connection */ - ipp_attribute_t *uri) /* I - Printer URI */ +move_job(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Job URI */ { http_status_t status; /* Policy status */ ipp_attribute_t *attr; /* Current attribute */ - ipp_attribute_t *format; /* Document-format attribute */ - const char *dest; /* Destination */ - cups_ptype_t dtype; /* Destination type (printer or class) */ - int priority; /* Job priority */ - char *title; /* Job name/title */ + int jobid; /* Job ID */ cupsd_job_t *job; /* Current job */ - char job_uri[HTTP_MAX_URI], /* Job URI */ - method[HTTP_MAX_URI], /* Method portion of URI */ + const char *src, /* Source printer/class */ + *dest; /* Destination */ + cups_ptype_t stype, /* Source type (printer or class) */ + dtype; /* Destination type (printer or class) */ + char method[HTTP_MAX_URI], /* Method portion of URI */ username[HTTP_MAX_URI], /* Username portion of URI */ host[HTTP_MAX_URI], /* Host portion of URI */ - resource[HTTP_MAX_URI], /* Resource portion of URI */ - filename[1024]; /* Job filename */ + resource[HTTP_MAX_URI]; /* Resource portion of URI */ int port; /* Port portion of URI */ - mime_type_t *filetype; /* Type of file */ - char super[MIME_MAX_SUPER], /* Supertype of file */ - type[MIME_MAX_TYPE], /* Subtype of file */ - mimetype[MIME_MAX_SUPER + MIME_MAX_TYPE + 2]; - /* Textual name of mime type */ - cupsd_printer_t *printer; /* Printer data */ - struct stat fileinfo; /* File information */ - int kbytes; /* Size of file */ - int i; /* Looping var */ - int lowerpagerange; /* Page range bound */ - int compression; /* Document compression */ + cupsd_printer_t *sprinter, /* Source printer */ + *dprinter; /* Destination printer */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "print_job(%p[%d], %s)", con, con->http.fd, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "move_job(%p[%d], %s)", con, con->http.fd, uri->values[0].string.text); /* - * Validate job template attributes; for now just copies and page-ranges... + * Get the new printer or class... */ - if ((attr = ippFindAttribute(con->request, "copies", - IPP_TAG_INTEGER)) != NULL) - { - if (attr->values[0].integer < 1 || attr->values[0].integer > MaxCopies) - { - send_ipp_status(con, IPP_ATTRIBUTES, _("Bad copies value %d."), - attr->values[0].integer); - ippAddInteger(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_INTEGER, - "copies", attr->values[0].integer); - return; - } - } - - if ((attr = ippFindAttribute(con->request, "page-ranges", - IPP_TAG_RANGE)) != NULL) + if ((attr = ippFindAttribute(con->request, "job-printer-uri", + IPP_TAG_URI)) == NULL) { - for (i = 0, lowerpagerange = 1; i < attr->num_values; i ++) - { - if (attr->values[i].range.lower < lowerpagerange || - attr->values[i].range.lower > attr->values[i].range.upper) - { - send_ipp_status(con, IPP_BAD_REQUEST, - _("Bad page-ranges values %d-%d."), - attr->values[i].range.lower, - attr->values[i].range.upper); - return; - } + /* + * Need job-printer-uri... + */ - lowerpagerange = attr->values[i].range.upper + 1; - } + send_ipp_status(con, IPP_BAD_REQUEST, + _("job-printer-uri attribute missing!")); + return; } + + httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text, method, + sizeof(method), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); - /* - * OK, see if the client is sending the document compressed - CUPS - * only supports "none" and "gzip". - */ - - compression = CUPS_FILE_NONE; - - if ((attr = ippFindAttribute(con->request, "compression", - IPP_TAG_KEYWORD)) != NULL) + if ((dest = cupsdValidateDest(host, resource, &dtype, &dprinter)) == NULL) { - if (strcmp(attr->values[0].string.text, "none") -#ifdef HAVE_LIBZ - && strcmp(attr->values[0].string.text, "gzip") -#endif /* HAVE_LIBZ */ - ) - { - send_ipp_status(con, IPP_ATTRIBUTES, - _("Unsupported compression \"%s\"!"), - attr->values[0].string.text); - ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD, - "compression", NULL, attr->values[0].string.text); - return; - } + /* + * Bad URI... + */ -#ifdef HAVE_LIBZ - if (!strcmp(attr->values[0].string.text, "gzip")) - compression = CUPS_FILE_GZIP; -#endif /* HAVE_LIBZ */ + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; } /* - * Do we have a file to print? + * Check policy... */ - if (!con->filename) + if ((status = cupsdCheckPolicy(dprinter->op_policy_ptr, con, NULL)) != HTTP_OK) { - send_ipp_status(con, IPP_BAD_REQUEST, _("No file!?!")); + send_http_error(con, status); return; } /* - * Is it a format we support? + * See if we have a job URI or a printer URI... */ - if ((format = ippFindAttribute(con->request, "document-format", - IPP_TAG_MIMETYPE)) != NULL) + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, + sizeof(method), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (!strcmp(uri->name, "printer-uri")) { /* - * Grab format from client... + * Got a printer URI; see if we also have a job-id attribute... */ - if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]", super, type) != 2) + if ((attr = ippFindAttribute(con->request, "job-id", + IPP_TAG_INTEGER)) == NULL) { - send_ipp_status(con, IPP_BAD_REQUEST, - _("Could not scan type \"%s\"!"), - format->values[0].string.text); - return; + /* + * Move all jobs... + */ + + if ((src = cupsdValidateDest(host, resource, &stype, &sprinter)) == NULL) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + job = NULL; + } + else + { + /* + * Otherwise, just move a single job... + */ + + if ((job = cupsdFindJob(attr->values[0].integer)) == NULL) + { + /* + * Nope - return a "not found" error... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("Job #%d does not exist!"), attr->values[0].integer); + return; + } + else + { + /* + * Job found, initialize source pointers... + */ + + src = NULL; + sprinter = NULL; + } } } else { /* - * No document format attribute? Auto-type it! + * Got a job URI; parse it to get the job ID... */ - strcpy(super, "application"); - strcpy(type, "octet-stream"); - } + if (strncmp(resource, "/jobs/", 6)) + { + /* + * Not a valid URI! + */ + + send_ipp_status(con, IPP_BAD_REQUEST, + _("Bad job-uri attribute \"%s\"!"), + uri->values[0].string.text); + return; + } - if (!strcmp(super, "application") && !strcmp(type, "octet-stream")) - { /* - * Auto-type the file... + * See if the job exists... */ - ipp_attribute_t *doc_name; /* document-name attribute */ - - - cupsdLogMessage(CUPSD_LOG_DEBUG, "print_job: auto-typing file..."); - - doc_name = ippFindAttribute(con->request, "document-name", IPP_TAG_NAME); - filetype = mimeFileType(MimeDatabase, con->filename, - doc_name ? doc_name->values[0].string.text : NULL, - &compression); + jobid = atoi(resource + 6); - if (filetype) + if ((job = cupsdFindJob(jobid)) == NULL) { /* - * Replace the document-format attribute value with the auto-typed one. + * Nope - return a "not found" error... */ - snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super, - filetype->type); - - if (format) - { - _cups_sp_free(format->values[0].string.text); - - format->values[0].string.text = _cups_sp_alloc(mimetype); - } - else - ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, - "document-format", NULL, mimetype); + send_ipp_status(con, IPP_NOT_FOUND, + _("Job #%d does not exist!"), jobid); + return; } else - filetype = mimeType(MimeDatabase, super, type); - } - else - filetype = mimeType(MimeDatabase, super, type); - - if (!filetype) - { - send_ipp_status(con, IPP_DOCUMENT_FORMAT, - _("Unsupported format \'%s/%s\'!"), super, type); - cupsdLogMessage(CUPSD_LOG_INFO, - "Hint: Do you have the raw file printing rules enabled?"); - - if (format) - ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE, - "document-format", NULL, format->values[0].string.text); + { + /* + * Job found, initialize source pointers... + */ - return; + src = NULL; + sprinter = NULL; + } } - cupsdLogMessage(CUPSD_LOG_DEBUG, "print_job: request file type is %s/%s.", - filetype->super, filetype->type); - /* - * Read any embedded job ticket info from PS files... + * Now move the job or jobs... */ - if (!strcasecmp(filetype->super, "application") && - !strcasecmp(filetype->type, "postscript")) - read_ps_job_ticket(con); + if (job) + { + /* + * See if the job has been completed... + */ + + if (job->state_value > IPP_JOB_STOPPED) + { + /* + * Return a "not-possible" error... + */ + + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Job #%d is finished and cannot be altered!"), + job->id); + return; + } - /* - * Is the destination valid? - */ + /* + * See if the job is owned by the requesting user... + */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); + if (!validate_user(job, con, job->username, username, sizeof(username))) + { + send_http_error(con, HTTP_UNAUTHORIZED); + return; + } - if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) - { /* - * Bad URI... + * Move the job to a different printer or class... */ - send_ipp_status(con, IPP_NOT_FOUND, - _("The printer or class was not found.")); - return; + cupsdMoveJob(job, dest); } + else + { + /* + * Got the source printer, now look through the jobs... + */ - /* - * Check remote printing to non-shared printer... - */ + for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); + job; + job = (cupsd_job_t *)cupsArrayNext(Jobs)) + { + /* + * See if the job is pointing at the source printer or has not been + * completed... + */ - if (!printer->shared && - strcasecmp(con->http.hostname, "localhost") && - strcasecmp(con->http.hostname, ServerName)) - { - send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Printer not shared!")); - return; - } + if (strcasecmp(job->dest, src) || + job->state_value > IPP_JOB_STOPPED) + continue; - /* - * Check policy... - */ + /* + * See if the job can be moved by the requesting user... + */ - if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) - { - send_http_error(con, status); - return; - } - else if ((printer->type & CUPS_PRINTER_AUTHENTICATED) && !con->username[0]) - { - send_http_error(con, status); - return; - } + if (!validate_user(job, con, job->username, username, sizeof(username))) + continue; - /* - * See if the printer is accepting jobs... - */ + /* + * Move the job to a different printer or class... + */ - if (!printer->accepting) - { - send_ipp_status(con, IPP_NOT_ACCEPTING, - _("Destination \"%s\" is not accepting jobs."), dest); - return; + cupsdMoveJob(job, dest); + } } /* - * Make sure we aren't over our limit... + * Start jobs if possible... */ - if (MaxJobs && cupsArrayCount(Jobs) >= MaxJobs) - cupsdCleanJobs(); - - if (cupsArrayCount(Jobs) >= MaxJobs && MaxJobs) - { - send_ipp_status(con, IPP_NOT_POSSIBLE, - _("Too many jobs - %d jobs, max jobs is %d."), - cupsArrayCount(Jobs), MaxJobs); - return; - } - - if (!check_quotas(con, printer)) - { - send_ipp_status(con, IPP_NOT_POSSIBLE, _("Quota limit reached.")); - return; - } + cupsdCheckJobs(); /* - * Create the job and set things up... + * Return with "everything is OK" status... */ - if ((attr = ippFindAttribute(con->request, "job-priority", - IPP_TAG_INTEGER)) != NULL) - priority = attr->values[0].integer; - else - ippAddInteger(con->request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-priority", - priority = 50); + con->response->request.status.status_code = IPP_OK; +} - if ((attr = ippFindAttribute(con->request, "job-name", - IPP_TAG_NAME)) != NULL) - title = attr->values[0].string.text; - else - ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, - title = "Untitled"); - if ((job = cupsdAddJob(priority, printer->name)) == NULL) - { - send_ipp_status(con, IPP_INTERNAL_ERROR, - _("Unable to add job for destination \"%s\"!"), dest); - return; - } +/* + * 'ppd_add_default()' - Add a PPD default choice. + */ - job->dtype = dtype; - job->attrs = con->request; - con->request = NULL; +static int /* O - Number of defaults */ +ppd_add_default( + const char *option, /* I - Option name */ + const char *choice, /* I - Choice name */ + int num_defaults, /* I - Number of defaults */ + ppd_default_t **defaults) /* IO - Defaults */ +{ + int i; /* Looping var */ + ppd_default_t *temp; /* Temporary defaults array */ - add_job_uuid(con, job); /* - * Copy the rest of the job info... + * First check if the option already has a default value; the PPD spec + * says that the first one is used... */ - attr = ippFindAttribute(job->attrs, "requesting-user-name", IPP_TAG_NAME); - - if (con->username[0]) - { - cupsdSetString(&job->username, con->username); - - if (attr) - cupsdSetString(&attr->values[0].string.text, con->username); + for (i = 0, temp = *defaults; i < num_defaults; i ++) + if (!strcmp(option, temp[i].option)) + return (num_defaults); - save_auth_info(con, job); - } - else if (attr) - { - cupsdLogMessage(CUPSD_LOG_DEBUG, "print_job: requesting-user-name = \"%s\"", - attr->values[0].string.text); + /* + * Now add the option... + */ - cupsdSetString(&job->username, attr->values[0].string.text); - } + if (num_defaults == 0) + temp = malloc(sizeof(ppd_default_t)); else - cupsdSetString(&job->username, "anonymous"); + temp = realloc(*defaults, (num_defaults + 1) * sizeof(ppd_default_t)); - if (!attr) - ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, - "job-originating-user-name", NULL, job->username); - else + if (!temp) { - attr->group_tag = IPP_TAG_JOB; - cupsdSetString(&attr->name, "job-originating-user-name"); + cupsdLogMessage(CUPSD_LOG_ERROR, "ppd_add_default: Unable to add default value for \"%s\" - %s", + option, strerror(errno)); + return (num_defaults); } - /* - * Add remaining job attributes... - */ + *defaults = temp; + temp += num_defaults; - if ((attr = ippFindAttribute(job->attrs, "job-originating-host-name", - IPP_TAG_ZERO)) != NULL) - { - /* - * Request contains a job-originating-host-name attribute; validate it... - */ + strlcpy(temp->option, option, sizeof(temp->option)); + strlcpy(temp->choice, choice, sizeof(temp->choice)); - if (attr->value_tag != IPP_TAG_NAME || - attr->num_values != 1 || - strcmp(con->http.hostname, "localhost")) - { - /* - * Can't override the value if we aren't connected via localhost. - * Also, we can only have 1 value and it must be a name value. - */ + return (num_defaults + 1); +} - switch (attr->value_tag) - { - case IPP_TAG_STRING : - case IPP_TAG_TEXTLANG : - case IPP_TAG_NAMELANG : - case IPP_TAG_TEXT : - case IPP_TAG_NAME : - case IPP_TAG_KEYWORD : - case IPP_TAG_URI : - case IPP_TAG_URISCHEME : - case IPP_TAG_CHARSET : - case IPP_TAG_LANGUAGE : - case IPP_TAG_MIMETYPE : - /* - * Free old strings... - */ - for (i = 0; i < attr->num_values; i ++) - { - _cups_sp_free(attr->values[i].string.text); - attr->values[i].string.text = NULL; - if (attr->values[i].string.charset) - { - _cups_sp_free(attr->values[i].string.charset); - attr->values[i].string.charset = NULL; - } - } +/* + * 'ppd_parse_line()' - Parse a PPD default line. + */ - default : - break; - } +static int /* O - 0 on success, -1 on failure */ +ppd_parse_line(const char *line, /* I - Line */ + char *option, /* O - Option name */ + int olen, /* I - Size of option name */ + char *choice, /* O - Choice name */ + int clen) /* I - Size of choice name */ +{ + /* + * Verify this is a default option line... + */ - /* - * Use the default connection hostname instead... - */ + if (strncmp(line, "*Default", 8)) + return (-1); - attr->value_tag = IPP_TAG_NAME; - attr->num_values = 1; - attr->values[0].string.text = _cups_sp_alloc(con->http.hostname); + /* + * Read the option name... + */ + + for (line += 8, olen --; isalnum(*line & 255); line ++) + if (olen > 0) + { + *option++ = *line; + olen --; } - attr->group_tag = IPP_TAG_JOB; - } - else - { - /* - * No job-originating-host-name attribute, so use the hostname from - * the connection... - */ + *option = '\0'; - ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, - "job-originating-host-name", NULL, con->http.hostname); - } + /* + * Skip everything else up to the colon (:)... + */ - ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id); - job->state = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_ENUM, - "job-state", IPP_JOB_PENDING); - job->state_value = job->state->values[0].integer; - job->sheets = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, - "job-media-sheets-completed", 0); - ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri", NULL, - printer->uri); - ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, - title); + while (*line && *line != ':') + line ++; - if ((attr = ippFindAttribute(job->attrs, "job-k-octets", - IPP_TAG_INTEGER)) == NULL) - attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, - "job-k-octets", 0); + if (!*line) + return (-1); - if (stat(con->filename, &fileinfo)) - kbytes = 0; - else - kbytes = (fileinfo.st_size + 1023) / 1024; + line ++; - cupsdUpdateQuota(printer, job->username, 0, kbytes); - attr->values[0].integer += kbytes; + /* + * Now grab the option choice, skipping leading whitespace... + */ - ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "time-at-creation", - time(NULL)); - attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, - "time-at-processing", 0); - attr->value_tag = IPP_TAG_NOVALUE; - attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, - "time-at-completed", 0); - attr->value_tag = IPP_TAG_NOVALUE; + while (isspace(*line & 255)) + line ++; - if ((attr = ippFindAttribute(job->attrs, "job-hold-until", - IPP_TAG_KEYWORD)) == NULL) - attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME); - if (!attr) - attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD, - "job-hold-until", NULL, "no-hold"); + for (clen --; isalnum(*line & 255); line ++) + if (clen > 0) + { + *choice++ = *line; + clen --; + } - if (attr && strcmp(attr->values[0].string.text, "no-hold") && - !(printer->type & CUPS_PRINTER_REMOTE)) - { - /* - * Hold job until specified time... - */ + *choice = '\0'; - job->state->values[0].integer = IPP_JOB_HELD; - job->state_value = IPP_JOB_HELD; - cupsdSetJobHoldUntil(job, attr->values[0].string.text); - } + /* + * Return with no errors... + */ - if (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) || - Classification) - { - /* - * Add job sheets options... - */ + return (0); +} - if ((attr = ippFindAttribute(job->attrs, "job-sheets", - IPP_TAG_ZERO)) == NULL) - { - cupsdLogMessage(CUPSD_LOG_DEBUG, - "Adding default job-sheets values \"%s,%s\"...", - printer->job_sheets[0], printer->job_sheets[1]); - attr = ippAddStrings(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-sheets", - 2, NULL, NULL); - attr->values[0].string.text = _cups_sp_alloc(printer->job_sheets[0]); - attr->values[1].string.text = _cups_sp_alloc(printer->job_sheets[1]); - } +/* + * 'print_job()' - Print a file to a printer or class. + */ - job->job_sheets = attr; +static void +print_job(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer URI */ +{ + ipp_attribute_t *attr; /* Current attribute */ + ipp_attribute_t *format; /* Document-format attribute */ + cupsd_job_t *job; /* New job */ + char filename[1024]; /* Job filename */ + mime_type_t *filetype; /* Type of file */ + char super[MIME_MAX_SUPER], /* Supertype of file */ + type[MIME_MAX_TYPE], /* Subtype of file */ + mimetype[MIME_MAX_SUPER + MIME_MAX_TYPE + 2]; + /* Textual name of mime type */ + cupsd_printer_t *printer; /* Printer data */ + struct stat fileinfo; /* File information */ + int kbytes; /* Size of file */ + int compression; /* Document compression */ - /* - * Enforce classification level if set... - */ - if (Classification) - { - cupsdLogMessage(CUPSD_LOG_INFO, - "Classification=\"%s\", ClassifyOverride=%d", - Classification ? Classification : "(null)", - ClassifyOverride); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "print_job(%p[%d], %s)", con, con->http.fd, + uri->values[0].string.text); - if (ClassifyOverride) - { - if (!strcmp(attr->values[0].string.text, "none") && - (attr->num_values == 1 || - !strcmp(attr->values[1].string.text, "none"))) - { - /* - * Force the leading banner to have the classification on it... - */ + /* + * Validate print file attributes, for now just document-format and + * compression (CUPS only supports "none" and "gzip")... + */ - cupsdSetString(&attr->values[0].string.text, Classification); + compression = CUPS_FILE_NONE; - cupsdLogMessage(CUPSD_LOG_NOTICE, - "[Job %d] CLASSIFICATION FORCED " - "job-sheets=\"%s,none\", " - "job-originating-user-name=\"%s\"", - job->id, Classification, job->username); - } - else if (attr->num_values == 2 && - strcmp(attr->values[0].string.text, - attr->values[1].string.text) && - strcmp(attr->values[0].string.text, "none") && - strcmp(attr->values[1].string.text, "none")) - { - /* - * Can't put two different security markings on the same document! - */ + if ((attr = ippFindAttribute(con->request, "compression", + IPP_TAG_KEYWORD)) != NULL) + { + if (strcmp(attr->values[0].string.text, "none") +#ifdef HAVE_LIBZ + && strcmp(attr->values[0].string.text, "gzip") +#endif /* HAVE_LIBZ */ + ) + { + send_ipp_status(con, IPP_ATTRIBUTES, + _("Unsupported compression \"%s\"!"), + attr->values[0].string.text); + ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD, + "compression", NULL, attr->values[0].string.text); + return; + } - cupsdSetString(&attr->values[1].string.text, attr->values[0].string.text); +#ifdef HAVE_LIBZ + if (!strcmp(attr->values[0].string.text, "gzip")) + compression = CUPS_FILE_GZIP; +#endif /* HAVE_LIBZ */ + } - cupsdLogMessage(CUPSD_LOG_NOTICE, - "[Job %d] CLASSIFICATION FORCED " - "job-sheets=\"%s,%s\", " - "job-originating-user-name=\"%s\"", - job->id, attr->values[0].string.text, - attr->values[1].string.text, job->username); - } - else if (strcmp(attr->values[0].string.text, Classification) && - strcmp(attr->values[0].string.text, "none") && - (attr->num_values == 1 || - (strcmp(attr->values[1].string.text, Classification) && - strcmp(attr->values[1].string.text, "none")))) - { - if (attr->num_values == 1) - cupsdLogMessage(CUPSD_LOG_NOTICE, - "[Job %d] CLASSIFICATION OVERRIDDEN " - "job-sheets=\"%s\", " - "job-originating-user-name=\"%s\"", - job->id, attr->values[0].string.text, - job->username); - else - cupsdLogMessage(CUPSD_LOG_NOTICE, - "[Job %d] CLASSIFICATION OVERRIDDEN " - "job-sheets=\"%s,%s\", " - "job-originating-user-name=\"%s\"", - job->id, attr->values[0].string.text, - attr->values[1].string.text, job->username); - } - } - else if (strcmp(attr->values[0].string.text, Classification) && - (attr->num_values == 1 || - strcmp(attr->values[1].string.text, Classification))) - { - /* - * Force the banner to have the classification on it... - */ + /* + * Do we have a file to print? + */ - if (attr->num_values > 1 && - !strcmp(attr->values[0].string.text, attr->values[1].string.text)) - { - cupsdSetString(&(attr->values[0].string.text), Classification); - cupsdSetString(&(attr->values[1].string.text), Classification); - } - else - { - if (attr->num_values == 1 || - strcmp(attr->values[0].string.text, "none")) - cupsdSetString(&(attr->values[0].string.text), Classification); + if (!con->filename) + { + send_ipp_status(con, IPP_BAD_REQUEST, _("No file!?!")); + return; + } - if (attr->num_values > 1 && - strcmp(attr->values[1].string.text, "none")) - cupsdSetString(&(attr->values[1].string.text), Classification); - } + /* + * Is it a format we support? + */ - if (attr->num_values > 1) - cupsdLogMessage(CUPSD_LOG_NOTICE, - "[Job %d] CLASSIFICATION FORCED " - "job-sheets=\"%s,%s\", " - "job-originating-user-name=\"%s\"", - job->id, attr->values[0].string.text, - attr->values[1].string.text, job->username); - else - cupsdLogMessage(CUPSD_LOG_NOTICE, - "[Job %d] CLASSIFICATION FORCED " - "job-sheets=\"%s\", " - "job-originating-user-name=\"%s\"", - job->id, Classification, job->username); - } + if ((format = ippFindAttribute(con->request, "document-format", + IPP_TAG_MIMETYPE)) != NULL) + { + /* + * Grab format from client... + */ + + if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]", super, type) != 2) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Could not scan type \"%s\"!"), + format->values[0].string.text); + return; } + } + else + { + /* + * No document format attribute? Auto-type it! + */ + + strcpy(super, "application"); + strcpy(type, "octet-stream"); + } + if (!strcmp(super, "application") && !strcmp(type, "octet-stream")) + { /* - * Add the starting sheet... + * Auto-type the file... */ - if (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT))) + ipp_attribute_t *doc_name; /* document-name attribute */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG, "print_job: auto-typing file..."); + + doc_name = ippFindAttribute(con->request, "document-name", IPP_TAG_NAME); + filetype = mimeFileType(MimeDatabase, con->filename, + doc_name ? doc_name->values[0].string.text : NULL, + &compression); + + if (filetype) { - cupsdLogMessage(CUPSD_LOG_INFO, - "Adding start banner page \"%s\" to job %d.", - attr->values[0].string.text, job->id); + /* + * Replace the document-format attribute value with the auto-typed one. + */ - kbytes = copy_banner(con, job, attr->values[0].string.text); + snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super, + filetype->type); - cupsdUpdateQuota(printer, job->username, 0, kbytes); + if (format) + { + _cups_sp_free(format->values[0].string.text); + + format->values[0].string.text = _cups_sp_alloc(mimetype); + } + else + ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, + "document-format", NULL, mimetype); } + else + filetype = mimeType(MimeDatabase, super, type); } - else if ((attr = ippFindAttribute(job->attrs, "job-sheets", - IPP_TAG_ZERO)) != NULL) - job->sheets = attr; - + else + filetype = mimeType(MimeDatabase, super, type); + + if (!filetype) + { + send_ipp_status(con, IPP_DOCUMENT_FORMAT, + _("Unsupported format \'%s/%s\'!"), super, type); + cupsdLogMessage(CUPSD_LOG_INFO, + "Hint: Do you have the raw file printing rules enabled?"); + + if (format) + ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE, + "document-format", NULL, format->values[0].string.text); + + return; + } + + cupsdLogMessage(CUPSD_LOG_DEBUG, "print_job: request file type is %s/%s.", + filetype->super, filetype->type); + + /* + * Read any embedded job ticket info from PS files... + */ + + if (!strcasecmp(filetype->super, "application") && + !strcasecmp(filetype->type, "postscript")) + read_ps_job_ticket(con); + + /* + * Create the job object... + */ + + if ((job = add_job(con, uri, &printer)) == NULL) + return; + + /* + * Update quota data... + */ + + if (stat(con->filename, &fileinfo)) + kbytes = 0; + else + kbytes = (fileinfo.st_size + 1023) / 1024; + + cupsdUpdateQuota(printer, job->username, 0, kbytes); + + if ((attr = ippFindAttribute(job->attrs, "job-k-octets", + IPP_TAG_INTEGER)) != NULL) + attr->values[0].integer += kbytes; + /* * Add the job file... */ @@ -7407,37 +6871,6 @@ print_job(cupsd_client_t *con, /* I - Client connection */ cupsdUpdateQuota(printer, job->username, 0, kbytes); } - /* - * Fill in the response info... - */ - - snprintf(job_uri, sizeof(job_uri), "http://%s:%d/jobs/%d", ServerName, - LocalPort, job->id); - - ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, "job-uri", NULL, - job_uri); - - ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id); - - ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state", - job->state_value); - add_job_state_reasons(con, job); - - con->response->request.status.status_code = IPP_OK; - - /* - * Add any job subscriptions... - */ - - add_job_subscriptions(con, job); - - /* - * Set all but the first two attributes to the job attributes group... - */ - - for (attr = job->attrs->attrs->next->next; attr; attr = attr->next) - attr->group_tag = IPP_TAG_JOB; - /* * Log and save the job... */ @@ -7449,8 +6882,6 @@ print_job(cupsd_client_t *con, /* I - Client connection */ cupsdSaveJob(job); - cupsdAddEvent(CUPSD_EVENT_JOB_CREATED, printer, job, "Job created."); - /* * Start the job if possible... */ @@ -9020,6 +8451,256 @@ set_job_attrs(cupsd_client_t *con, /* I - Client connection */ } +/* + * 'set_printer_defaults()' - Set printer default options from a request. + */ + +static void +set_printer_defaults( + cupsd_client_t *con, /* I - Client connection */ + cupsd_printer_t *printer) /* I - Printer */ +{ + int i; /* Looping var */ + ipp_attribute_t *attr; /* Current attribute */ + int namelen; /* Length of attribute name */ + char name[256], /* New attribute name */ + value[256]; /* String version of integer attrs */ + + + for (attr = con->request->attrs; attr; attr = attr->next) + { + /* + * Skip non-printer attributes... + */ + + if (attr->group_tag != IPP_TAG_PRINTER || !attr->name) + continue; + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_printer_defaults: %s", attr->name); + + if (!strcmp(attr->name, "job-sheets-default")) + { + /* + * Only allow keywords and names... + */ + + if (attr->value_tag != IPP_TAG_NAME && attr->value_tag != IPP_TAG_KEYWORD) + continue; + + /* + * Only allow job-sheets-default to be set when running without a + * system high classification level... + */ + + if (Classification) + continue; + + cupsdSetString(&printer->job_sheets[0], attr->values[0].string.text); + + if (attr->num_values > 1) + cupsdSetString(&printer->job_sheets[1], attr->values[1].string.text); + else + cupsdSetString(&printer->job_sheets[1], "none"); + } + else if (!strcmp(attr->name, "requesting-user-name-allowed")) + { + cupsdFreePrinterUsers(printer); + + printer->deny_users = 0; + + if (attr->value_tag == IPP_TAG_NAME && + (attr->num_values > 1 || + strcmp(attr->values[0].string.text, "all"))) + { + for (i = 0; i < attr->num_values; i ++) + cupsdAddPrinterUser(printer, attr->values[i].string.text); + } + } + else if (!strcmp(attr->name, "requesting-user-name-denied")) + { + cupsdFreePrinterUsers(printer); + + printer->deny_users = 1; + + if (attr->value_tag == IPP_TAG_NAME && + (attr->num_values > 1 || + strcmp(attr->values[0].string.text, "none"))) + { + for (i = 0; i < attr->num_values; i ++) + cupsdAddPrinterUser(printer, attr->values[i].string.text); + } + } + else if (!strcmp(attr->name, "job-quota-period")) + { + if (attr->value_tag != IPP_TAG_INTEGER) + continue; + + cupsdLogMessage(CUPSD_LOG_DEBUG, "Setting job-quota-period to %d...", + attr->values[0].integer); + cupsdFreeQuotas(printer); + + printer->quota_period = attr->values[0].integer; + } + else if (!strcmp(attr->name, "job-k-limit")) + { + if (attr->value_tag != IPP_TAG_INTEGER) + continue; + + cupsdLogMessage(CUPSD_LOG_DEBUG, "Setting job-k-limit to %d...", + attr->values[0].integer); + cupsdFreeQuotas(printer); + + printer->k_limit = attr->values[0].integer; + } + else if (!strcmp(attr->name, "job-page-limit")) + { + if (attr->value_tag != IPP_TAG_INTEGER) + continue; + + cupsdLogMessage(CUPSD_LOG_DEBUG, "Setting job-page-limit to %d...", + attr->values[0].integer); + cupsdFreeQuotas(printer); + + printer->page_limit = attr->values[0].integer; + } + else if (!strcmp(attr->name, "printer-op-policy")) + { + cupsd_policy_t *p; /* Policy */ + + + if (attr->value_tag != IPP_TAG_NAME) + continue; + + if ((p = cupsdFindPolicy(attr->values[0].string.text)) != NULL) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Setting printer-op-policy to \"%s\"...", + attr->values[0].string.text); + cupsdSetString(&printer->op_policy, attr->values[0].string.text); + printer->op_policy_ptr = p; + } + else + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Unknown printer-op-policy \"%s\"."), + attr->values[0].string.text); + return; + } + } + else if (!strcmp(attr->name, "printer-error-policy")) + { + if (attr->value_tag != IPP_TAG_NAME && attr->value_tag != IPP_TAG_KEYWORD) + continue; + + if (strcmp(attr->values[0].string.text, "abort-job") && + strcmp(attr->values[0].string.text, "retry-job") && + strcmp(attr->values[0].string.text, "stop-printer")) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Unknown printer-error-policy \"%s\"."), + attr->values[0].string.text); + return; + } + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Setting printer-error-policy to \"%s\"...", + attr->values[0].string.text); + cupsdSetString(&printer->error_policy, attr->values[0].string.text); + } + else if (!strcmp(attr->name, "document-format-default") || + !strcmp(attr->name, "notify-lease-duration-default") || + !strcmp(attr->name, "notify-notify-events-default")) + continue; + + /* + * Skip any other non-default attributes... + */ + + namelen = strlen(attr->name); + if (namelen < 9 || strcmp(attr->name + namelen - 8, "-default") || + namelen > (sizeof(name) - 1) || attr->num_values != 1) + continue; + + /* + * OK, anything else must be a user-defined default... + */ + + strlcpy(name, attr->name, sizeof(name)); + name[namelen - 8] = '\0'; /* Strip "-default" */ + + switch (attr->value_tag) + { + case IPP_TAG_DELETEATTR : + printer->num_options = cupsRemoveOption(name, + printer->num_options, + &(printer->options)); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Deleting %s", attr->name); + break; + + case IPP_TAG_NAME : + case IPP_TAG_KEYWORD : + case IPP_TAG_URI : + printer->num_options = cupsAddOption(name, + attr->values[0].string.text, + printer->num_options, + &(printer->options)); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Setting %s to \"%s\"...", attr->name, + attr->values[0].string.text); + break; + + case IPP_TAG_BOOLEAN : + printer->num_options = cupsAddOption(name, + attr->values[0].boolean ? + "true" : "false", + printer->num_options, + &(printer->options)); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Setting %s to %s...", attr->name, + attr->values[0].boolean ? "true" : "false"); + break; + + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + sprintf(value, "%d", attr->values[0].integer); + printer->num_options = cupsAddOption(name, value, + printer->num_options, + &(printer->options)); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Setting %s to %s...", attr->name, value); + break; + + case IPP_TAG_RANGE : + sprintf(value, "%d-%d", attr->values[0].range.lower, + attr->values[0].range.upper); + printer->num_options = cupsAddOption(name, value, + printer->num_options, + &(printer->options)); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Setting %s to %s...", attr->name, value); + break; + + case IPP_TAG_RESOLUTION : + sprintf(value, "%dx%d%s", attr->values[0].resolution.xres, + attr->values[0].resolution.yres, + attr->values[0].resolution.units == IPP_RES_PER_INCH ? + "dpi" : "dpc"); + printer->num_options = cupsAddOption(name, value, + printer->num_options, + &(printer->options)); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Setting %s to %s...", attr->name, value); + break; + + default : + /* Do nothing for other values */ + break; + } + } +} + + /* * 'start_printer()' - Start a printer. */ @@ -9413,5 +9094,5 @@ validate_user(cupsd_job_t *job, /* I - Job */ /* - * End of "$Id: ipp.c 5131 2006-02-18 05:31:36Z mike $". + * End of "$Id: ipp.c 5164 2006-02-24 20:40:00Z mike $". */ diff --git a/scheduler/job.c b/scheduler/job.c index 0c65f3e34..3fbc59f92 100644 --- a/scheduler/job.c +++ b/scheduler/job.c @@ -1,5 +1,5 @@ /* - * "$Id: job.c 5131 2006-02-18 05:31:36Z mike $" + * "$Id: job.c 5196 2006-02-27 21:23:00Z mike $" * * Job management routines for the Common UNIX Printing System (CUPS). * @@ -2868,7 +2868,7 @@ free_job(cupsd_job_t *job) /* I - Job */ * the textual IPP attributes. */ -int /* O - Size of attribute buffer */ +static int /* O - Size of attribute buffer */ ipp_length(ipp_t *ipp) /* I - IPP request */ { int bytes; /* Number of bytes */ @@ -3424,5 +3424,5 @@ set_hold_until(cupsd_job_t *job, /* I - Job to update */ /* - * End of "$Id: job.c 5131 2006-02-18 05:31:36Z mike $". + * End of "$Id: job.c 5196 2006-02-27 21:23:00Z mike $". */ diff --git a/scheduler/log.c b/scheduler/log.c index 1aa41a704..52a61132b 100644 --- a/scheduler/log.c +++ b/scheduler/log.c @@ -1,5 +1,5 @@ /* - * "$Id: log.c 4860 2005-12-01 22:07:26Z mike $" + * "$Id: log.c 5194 2006-02-27 20:57:07Z mike $" * * Log file routines for the Common UNIX Printing System (CUPS). * @@ -36,10 +36,7 @@ #include "cupsd.h" #include - -#ifdef HAVE_VSYSLOG -# include -#endif /* HAVE_VSYSLOG */ +#include /* @@ -549,5 +546,5 @@ check_log_file(cups_file_t **lf, /* IO - Log file */ /* - * End of "$Id: log.c 4860 2005-12-01 22:07:26Z mike $". + * End of "$Id: log.c 5194 2006-02-27 20:57:07Z mike $". */ diff --git a/scheduler/main.c b/scheduler/main.c index d0371248b..018fba69a 100644 --- a/scheduler/main.c +++ b/scheduler/main.c @@ -1,5 +1,5 @@ /* - * "$Id: main.c 5108 2006-02-15 19:33:09Z mike $" + * "$Id: main.c 5157 2006-02-23 20:58:57Z mike $" * * Scheduler main loop for the Common UNIX Printing System (CUPS). * @@ -865,10 +865,16 @@ main(int argc, /* I - Number of command-line args */ cupsdUpdatePolling(); #ifdef HAVE_LIBSLP - if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_SLP) && + if ((BrowseRemoteProtocols & BROWSE_SLP) && BrowseSLPRefresh <= current_time) cupsdUpdateSLPBrowse(); #endif /* HAVE_LIBSLP */ + +#ifdef HAVE_LDAP + if ((BrowseRemoteProtocols & BROWSE_LDAP) && + BrowseLDAPRefresh <= current_time) + cupsdUpdateLDAPBrowse(); +#endif /* HAVE_LDAP */ } if (Browsing && BrowseLocalProtocols && current_time > browse_time) @@ -2209,6 +2215,14 @@ select_timeout(int fds) /* I - Number of descriptors returned */ } #endif /* HAVE_LIBSLP */ +#ifdef HAVE_LDAP + if ((BrowseLocalProtocols & BROWSE_LDAP) && (BrowseLDAPRefresh < timeout)) + { + timeout = BrowseLDAPRefresh; + why = "update LDAP browsing"; + } +#endif /* HAVE_LDAP */ + if (BrowseLocalProtocols & BROWSE_CUPS) { for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); @@ -2324,5 +2338,5 @@ usage(int status) /* O - Exit status */ /* - * End of "$Id: main.c 5108 2006-02-15 19:33:09Z mike $". + * End of "$Id: main.c 5157 2006-02-23 20:58:57Z mike $". */ diff --git a/scheduler/printers.c b/scheduler/printers.c index 9423e1b37..96ccbcaa8 100644 --- a/scheduler/printers.c +++ b/scheduler/printers.c @@ -1,5 +1,5 @@ /* - * "$Id: printers.c 5143 2006-02-21 19:13:01Z mike $" + * "$Id: printers.c 5178 2006-02-26 00:24:23Z mike $" * * Printer routines for the Common UNIX Printing System (CUPS). * @@ -32,6 +32,7 @@ * cupsdFindPrinter() - Find a printer in the list. * cupsdFreePrinterUsers() - Free allow/deny users. * cupsdLoadAllPrinters() - Load printers from the printers.conf file. + * cupsdRenamePrinter() - Rename a printer. * cupsdSaveAllPrinters() - Save all printer definitions to the * printers.conf file. * cupsdSetPrinterAttrs() - Set printer attributes based upon the PPD @@ -44,6 +45,8 @@ * cupsdWritePrintcap() - Write a pseudo-printcap file for older * applications that need it... * cupsdSanitizeURI() - Sanitize a device URI... + * add_printer_defaults() - Add name-default attributes to the printer + * attributes. * add_printer_filter() - Add a MIME filter for a printer. * add_printer_formats() - Add document-format-supported values for * a printer. @@ -67,6 +70,7 @@ * Local functions... */ +static void add_printer_defaults(cupsd_printer_t *p); static void add_printer_filter(cupsd_printer_t *p, const char *filter); static void add_printer_formats(cupsd_printer_t *p); static int compare_printers(void *first, void *second, void *data); @@ -401,15 +405,9 @@ cupsdCreateCommonData(void) sizeof(compressions) / sizeof(compressions[0]), NULL, compressions); - /* TODO: move to printer-specific section! */ - /* copies-default */ - ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "copies-default", 1); - /* copies-supported */ ippAddRange(CommonData, IPP_TAG_PRINTER, "copies-supported", 1, MaxCopies); - /* TODO: move to printer-specific section! */ /* document-format-default */ ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE, "document-format-default", NULL, "application/octet-stream"); @@ -423,21 +421,11 @@ cupsdCreateCommonData(void) "ipp-versions-supported", sizeof(versions) / sizeof(versions[0]), NULL, versions); - /* TODO: move to printer-specific section! */ - /* job-hold-until-default */ - ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, - "job-hold-until-default", NULL, "no-hold"); - /* job-hold-until-supported */ ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "job-hold-until-supported", sizeof(holds) / sizeof(holds[0]), NULL, holds); - /* TODO: move to printer-specific section! */ - /* job-priority-default */ - ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "job-priority-default", 50); - /* job-priority-supported */ ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "job-priority-supported", 100); @@ -503,7 +491,6 @@ cupsdCreateCommonData(void) (int)(sizeof(notify_attrs) / sizeof(notify_attrs[0])), NULL, notify_attrs); - /* TODO: move to printer-specific section! */ /* notify-lease-duration-default */ ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "notify-lease-duration-default", DefaultLeaseDuration); @@ -536,11 +523,6 @@ cupsdCreateCommonData(void) ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "notify-schemes-supported", NULL, "mailto"); - /* TODO: move to printer-specific section! */ - /* number-up-default */ - ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "number-up-default", 1); - /* number-up-supported */ ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "number-up-supported", sizeof(nups) / sizeof(nups[0]), nups); @@ -550,11 +532,6 @@ cupsdCreateCommonData(void) "operations-supported", sizeof(ops) / sizeof(ops[0]) + JobFiles - 1, (int *)ops); - /* TODO: move to printer-specific section! */ - /* orientation-requested-default */ - ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM, - "orientation-requested-default", IPP_PORTRAIT); - /* orientation-requested-supported */ ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM, "orientation-requested-supported", 4, (int *)orients); @@ -746,10 +723,15 @@ cupsdDeletePrinter( cupsdClearString(&p->op_policy); cupsdClearString(&p->error_policy); + if (p->browse_attrs) + free(p->browse_attrs); + #ifdef __APPLE__ cupsdClearString(&p->recoverable); #endif /* __APPLE__ */ + cupsFreeOptions(p->num_options, p->options); + free(p); /* @@ -999,6 +981,25 @@ cupsdLoadAllPrinters(void) return; } } + else if (!strcasecmp(line, "Option") && value) + { + /* + * Option name value + */ + + for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++); + + if (!*valueptr) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + else + { + for (; *valueptr && isspace(*valueptr & 255); *valueptr++ = '\0'); + + p->num_options = cupsAddOption(value, valueptr, p->num_options, + &(p->options)); + } + } else if (!strcasecmp(line, "PortMonitor")) { if (value && strcmp(value, "none")) @@ -1227,6 +1228,53 @@ cupsdLoadAllPrinters(void) } +/* + * 'cupsdRenamePrinter()' - Rename a printer. + */ + +void +cupsdRenamePrinter( + cupsd_printer_t *p, /* I - Printer */ + const char *name) /* I - New name */ +{ + /* + * Remove the printer from the array(s) first... + */ + + cupsArrayRemove(Printers, p); + + if (p->type & CUPS_PRINTER_IMPLICIT) + cupsArrayRemove(ImplicitPrinters, p); + + /* + * Rename the printer type... + */ + + mimeDeleteType(MimeDatabase, p->filetype); + p->filetype = mimeAddType(MimeDatabase, "printer", name); + + /* + * Rename the printer... + */ + + cupsdSetStringf(&p->name, name); + + /* + * Reset printer attributes... + */ + + cupsdSetPrinterAttrs(p); + + /* + * Add the printer back to the printer array(s)... + */ + + cupsArrayAdd(Printers, p); + if (p->type & CUPS_PRINTER_IMPLICIT) + cupsArrayAdd(ImplicitPrinters, p); +} + + /* * 'cupsdSaveAllPrinters()' - Save all printer definitions to the printers.conf * file. @@ -1242,6 +1290,7 @@ cupsdSaveAllPrinters(void) cupsd_printer_t *printer; /* Current printer class */ time_t curtime; /* Current time */ struct tm *curdate; /* Current date */ + cups_option_t *option; /* Current option */ /* @@ -1363,6 +1412,11 @@ cupsdSaveAllPrinters(void) if (printer->error_policy) cupsFilePrintf(fp, "ErrorPolicy %s\n", printer->error_policy); + for (i = printer->num_options, option = printer->options; + i > 0; + i --, option ++) + cupsFilePrintf(fp, "Option %s %s\n", option->name, option->value); + cupsFilePuts(fp, "\n"); #ifdef __sgi @@ -1385,32 +1439,33 @@ cupsdSaveAllPrinters(void) void cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ { - char uri[HTTP_MAX_URI]; - /* URI for printer */ - char resource[HTTP_MAX_URI]; - /* Resource portion of URI */ - int i; /* Looping var */ - char filename[1024]; /* Name of PPD file */ - int num_media; /* Number of media options */ - cupsd_location_t *auth; /* Pointer to authentication element */ - const char *auth_supported;/* Authentication supported */ - cups_ptype_t printer_type; /* Printer type data */ - ppd_file_t *ppd; /* PPD file data */ - ppd_option_t *input_slot, /* InputSlot options */ - *media_type, /* MediaType options */ - *page_size, /* PageSize options */ - *output_bin, /* OutputBin options */ - *media_quality; /* EFMediaQualityMode options */ - ppd_attr_t *ppdattr; /* PPD attribute */ - ipp_attribute_t *attr; /* Attribute data */ - ipp_value_t *val; /* Attribute value */ - int num_finishings; /* Number of finishings */ - ipp_finish_t finishings[5]; /* finishings-supported values */ + int i, /* Looping var */ + length; /* Length of browse attributes */ + char uri[HTTP_MAX_URI]; /* URI for printer */ + char resource[HTTP_MAX_URI]; /* Resource portion of URI */ + char filename[1024]; /* Name of PPD file */ + int num_media; /* Number of media options */ + cupsd_location_t *auth; /* Pointer to authentication element */ + const char *auth_supported; /* Authentication supported */ + cups_ptype_t printer_type; /* Printer type data */ + ppd_file_t *ppd; /* PPD file data */ + ppd_option_t *input_slot, /* InputSlot options */ + *media_type, /* MediaType options */ + *page_size, /* PageSize options */ + *output_bin, /* OutputBin options */ + *media_quality, /* EFMediaQualityMode options */ + *duplex; /* Duplex options */ + ppd_attr_t *ppdattr; /* PPD attribute */ + ipp_attribute_t *attr; /* Attribute data */ + ipp_value_t *val; /* Attribute value */ + int num_finishings; /* Number of finishings */ + ipp_finish_t finishings[5]; /* finishings-supported values */ + cups_option_t *option; /* Current printer option */ static const char * const sides[3] = /* sides-supported values */ { - "one", - "two-long-edge", - "two-short-edge" + "one-sided", + "two-sided-long-edge", + "two-sided-short-edge" }; @@ -1699,9 +1754,8 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ if (num_media == 0) { cupsdLogMessage(CUPSD_LOG_CRIT, - "The PPD file for printer %s " - "contains no media options and is therefore " - "invalid!", p->name); + "The PPD file for printer %s contains no media " + "options and is therefore invalid!", p->name); } else { @@ -1728,21 +1782,21 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ for (i = 0; i < page_size->num_choices; i ++, val ++) val->string.text = _cups_sp_alloc(page_size->choices[i].choice); - ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default", - NULL, page_size->defchoice); + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "media-default", NULL, page_size->defchoice); } else if (input_slot != NULL) - ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default", - NULL, input_slot->defchoice); + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "media-default", NULL, input_slot->defchoice); else if (media_type != NULL) - ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default", - NULL, media_type->defchoice); + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "media-default", NULL, media_type->defchoice); else if (media_quality != NULL) - ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default", - NULL, media_quality->defchoice); + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "media-default", NULL, media_quality->defchoice); else - ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default", - NULL, "none"); + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "media-default", NULL, "none"); } } @@ -1769,14 +1823,28 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ * Duplexing, etc... */ - if (ppdFindOption(ppd, "Duplex") != NULL) + if ((duplex = ppdFindOption(ppd, "Duplex")) == NULL) + if ((duplex = ppdFindOption(ppd, "EFDuplex")) == NULL) + if ((duplex = ppdFindOption(ppd, "EFDuplexing")) == NULL) + if ((duplex = ppdFindOption(ppd, "KD03Duplex")) == NULL) + duplex = ppdFindOption(ppd, "JCLDuplex"); + + if (duplex && duplex->num_choices > 1) { p->type |= CUPS_PRINTER_DUPLEX; - ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "sides-supported", - 3, NULL, sides); - ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "sides-default", - NULL, "one"); + ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "sides-supported", 3, NULL, sides); + + if (!strcasecmp(duplex->defchoice, "DuplexTumble")) + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "sides-default", NULL, "two-sided-short-edge"); + else if (!strcasecmp(duplex->defchoice, "DuplexNoTumble")) + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "sides-default", NULL, "two-sided-long-edge"); + else + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "sides-default", NULL, "one-sided"); } if (ppdFindOption(ppd, "Collate") != NULL) @@ -1883,16 +1951,18 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ pstatus = ppdLastError(&pline); - cupsdLogMessage(CUPSD_LOG_ERROR, "PPD file for %s cannot be loaded!", p->name); + cupsdLogMessage(CUPSD_LOG_ERROR, "PPD file for %s cannot be loaded!", + p->name); if (pstatus <= PPD_ALLOC_ERROR) cupsdLogMessage(CUPSD_LOG_ERROR, "%s", strerror(errno)); else - cupsdLogMessage(CUPSD_LOG_ERROR, "%s on line %d.", ppdErrorString(pstatus), - pline); + cupsdLogMessage(CUPSD_LOG_ERROR, "%s on line %d.", + ppdErrorString(pstatus), pline); - cupsdLogMessage(CUPSD_LOG_INFO, "Hint: Run \"cupstestppd %s\" and fix any errors.", - filename); + cupsdLogMessage(CUPSD_LOG_INFO, + "Hint: Run \"cupstestppd %s\" and fix any errors.", + filename); /* * Add a filter from application/vnd.cups-raw to printer/name to @@ -1915,7 +1985,7 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ snprintf(filename, sizeof(filename), "%s/interfaces/%s", ServerRoot, p->name); - if (access(filename, X_OK) == 0) + if (!access(filename, X_OK)) { /* * Yes, we have a System V style interface script; use it! @@ -1981,6 +2051,99 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ } } + /* + * Copy the printer options into a browse attributes string we can re-use. + */ + + if (!(p->type & CUPS_PRINTER_REMOTE)) + { + const char *valptr; /* Pointer into value */ + char *attrptr; /* Pointer into attribute string */ + + + /* + * Free the old browse attributes as needed... + */ + + if (p->browse_attrs) + free(p->browse_attrs); + + /* + * Compute the length of all attributes + job-sheets, lease-duration, + * and BrowseLocalOptions. + */ + + for (length = 1, i = p->num_options, option = p->options; + i > 0; + i --, option ++) + { + length += strlen(option->name) + 2; + + if (option->value) + { + for (valptr = option->value; *valptr; valptr ++) + if (strchr(" \"\'\\", *valptr)) + length += 2; + else + length ++; + } + } + + length += 13 + strlen(p->job_sheets[0]) + strlen(p->job_sheets[1]); + length += 32; + if (BrowseLocalOptions) + length += 12 + strlen(BrowseLocalOptions); + + /* + * Allocate the new string... + */ + + if ((p->browse_attrs = calloc(1, length)) == NULL) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate %d bytes for browse data!", + length); + else + { + /* + * Got the allocated string, now copy the options and attributes over... + */ + + sprintf(p->browse_attrs, "job-sheets=%s,%s lease-duration=%d", + p->job_sheets[0], p->job_sheets[1], BrowseTimeout); + attrptr = p->browse_attrs + strlen(p->browse_attrs); + + if (BrowseLocalOptions) + { + sprintf(attrptr, " ipp-options=%s", BrowseLocalOptions); + attrptr += strlen(attrptr); + } + + for (i = p->num_options, option = p->options; + i > 0; + i --, option ++) + { + *attrptr++ = ' '; + strcpy(attrptr, option->name); + attrptr += strlen(attrptr); + + if (option->value) + { + *attrptr++ = '='; + + for (valptr = option->value; *valptr; valptr ++) + { + if (strchr(" \"\'\\", *valptr)) + *attrptr++ = '\\'; + + *attrptr++ = *valptr; + } + } + } + + *attrptr = '\0'; + } + } + /* * Populate the document-format-supported attribute... */ @@ -1990,6 +2153,12 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ DEBUG_printf(("cupsdSetPrinterAttrs: leaving name = %s, type = %x\n", p->name, p->type)); + /* + * Add name-default attributes... + */ + + add_printer_defaults(p); + #ifdef __sgi /* * Write the IRIX printer config and status files... @@ -2586,6 +2755,70 @@ cupsdSanitizeURI(const char *uri, /* I - Original device URI */ } +/* + * 'add_printer_defaults()' - Add name-default attributes to the printer attributes. + */ + +static void +add_printer_defaults(cupsd_printer_t *p)/* I - Printer */ +{ + int i; /* Looping var */ + int num_options; /* Number of default options */ + cups_option_t *options, /* Default options */ + *option; /* Current option */ + char name[256]; /* name-default */ + + + /* + * Add all of the default options from the .conf files... + */ + + for (num_options = 0, i = p->num_options, option = p->options; + i > 0; + i --, option ++) + { + if (strcmp(option->name, "ipp-options") && + strcmp(option->name, "job-sheets") && + strcmp(option->name, "lease-duration")) + { + snprintf(name, sizeof(name), "%s-default", option->name); + num_options = cupsAddOption(name, option->value, num_options, &options); + } + } + + /* + * Convert options to IPP attributes... + */ + + cupsEncodeOptions2(p->attrs, num_options, options, IPP_TAG_PRINTER); + cupsFreeOptions(num_options, options); + + /* + * Add standard -default attributes as needed... + */ + + if (!cupsGetOption("copies", p->num_options, p->options)) + ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "copies-default", + 1); + + if (!cupsGetOption("job-hold-until", p->num_options, p->options)) + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "job-hold-until-default", NULL, "no-hold"); + + if (!cupsGetOption("job-priority", p->num_options, p->options)) + ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "job-priority-default", 50); + + if (!cupsGetOption("number-up", p->num_options, p->options)) + ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "number-up-default", 1); + + if (!cupsGetOption("orientation-requested", p->num_options, p->options)) + ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, + "orientation-requested-default", IPP_PORTRAIT); +} + + /* * 'add_printer_filter()' - Add a MIME filter for a printer. */ @@ -2641,6 +2874,15 @@ add_printer_filter( } } + /* + * Mark the CUPS_PRINTER_COMMANDS bit if we have a filter for + * application/vnd.cups-command... + */ + + if (!strcasecmp(super, "application") && + !strcasecmp(type, "vnd.cups-command")) + p->type |= CUPS_PRINTER_COMMANDS; + /* * Add the filter to the MIME database, supporting wildcards as needed... */ @@ -3109,5 +3351,5 @@ write_irix_state(cupsd_printer_t *p) /* I - Printer to update */ /* - * End of "$Id: printers.c 5143 2006-02-21 19:13:01Z mike $". + * End of "$Id: printers.c 5178 2006-02-26 00:24:23Z mike $". */ diff --git a/scheduler/printers.h b/scheduler/printers.h index 79872ecdd..cdc5756d2 100644 --- a/scheduler/printers.h +++ b/scheduler/printers.h @@ -1,5 +1,5 @@ /* - * "$Id: printers.h 5083 2006-02-06 02:57:43Z mike $" + * "$Id: printers.h 5178 2006-02-26 00:24:23Z mike $" * * Printer definitions for the Common UNIX Printing System (CUPS) scheduler. * @@ -60,6 +60,8 @@ typedef struct cupsd_printer_s time_t state_time; /* Time at this state */ char *job_sheets[2]; /* Banners/job sheets */ cups_ptype_t type; /* Printer type (color, small, etc.) */ + char *browse_attrs; /* Attributes sent with browse data */ + time_t browse_expire; /* Expiration time for printer */ time_t browse_time; /* Last time update was sent/received */ char *device_uri; /* Device URI */ char *port_monitor; /* Port monitor */ @@ -80,6 +82,8 @@ typedef struct cupsd_printer_s int num_history; /* Number of history collections */ ipp_t **history; /* History data */ int sequence_number; /* Increasing sequence number */ + int num_options; /* Number of default options */ + cups_option_t *options; /* Default options */ #ifdef __APPLE__ char *recoverable; /* com.apple.print.recoverable-message */ #endif /* __APPLE__ */ @@ -123,6 +127,7 @@ extern cupsd_quota_t *cupsdFindQuota(cupsd_printer_t *p, const char *username); extern void cupsdFreePrinterUsers(cupsd_printer_t *p); extern void cupsdFreeQuotas(cupsd_printer_t *p); extern void cupsdLoadAllPrinters(void); +extern void cupsdRenamePrinter(cupsd_printer_t *p, const char *name); extern void cupsdSaveAllPrinters(void); extern void cupsdSetPrinterAttrs(cupsd_printer_t *p); extern void cupsdSetPrinterReasons(cupsd_printer_t *p, const char *s); @@ -143,5 +148,5 @@ extern char *cupsdSanitizeURI(const char *uri, char *buffer, /* - * End of "$Id: printers.h 5083 2006-02-06 02:57:43Z mike $". + * End of "$Id: printers.h 5178 2006-02-26 00:24:23Z mike $". */ diff --git a/scheduler/server.c b/scheduler/server.c index 74c2fc071..79a393a82 100644 --- a/scheduler/server.c +++ b/scheduler/server.c @@ -1,5 +1,5 @@ /* - * "$Id: server.c 5095 2006-02-09 16:22:48Z mike $" + * "$Id: server.c 5200 2006-02-28 00:10:32Z mike $" * * Server start/stop routines for the Common UNIX Printing System (CUPS). * @@ -152,18 +152,6 @@ cupsdStopServer(void) Clients = NULL; } -#if defined(HAVE_SSL) && defined(HAVE_CDSASSL) - /* - * Free all of the certificates... - */ - - if (ServerCertificatesArray) - { - CFRelease(ServerCertificatesArray); - ServerCertificatesArray = NULL; - } -#endif /* HAVE_SSL && HAVE_CDSASSL */ - /* * Close the pipe for CGI processes... */ @@ -223,5 +211,5 @@ cupsdStopServer(void) /* - * End of "$Id: server.c 5095 2006-02-09 16:22:48Z mike $". + * End of "$Id: server.c 5200 2006-02-28 00:10:32Z mike $". */ diff --git a/scheduler/testdirsvc.c b/scheduler/testdirsvc.c index 51c2cc523..c38d0c21e 100644 --- a/scheduler/testdirsvc.c +++ b/scheduler/testdirsvc.c @@ -1,5 +1,5 @@ /* - * "$Id: testdirsvc.c 4821 2005-11-04 19:36:39Z mike $" + * "$Id: testdirsvc.c 5178 2006-02-26 00:24:23Z mike $" * * Browsing test program for the Common UNIX Printing System (CUPS). * @@ -55,10 +55,13 @@ main(int argc, /* I - Number of command-line arguments */ int i, /* Looping var */ printer, /* Current printer */ num_printers, /* Number of printers */ + pclass, /* Current printer class */ + num_pclasses, /* Number of printer classes */ server, /* Current server */ num_servers, /* Number of servers */ count, /* Number of printers sent this cycle */ interval, /* Browse Interval */ + lease, /* Browse lease-duration */ continuous, /* Run continuously? */ port, /* Browse port */ sock, /* Browse socket */ @@ -106,8 +109,10 @@ main(int argc, /* I - Number of command-line arguments */ */ num_printers = 10; + num_pclasses = 5; num_servers = 1; interval = 30; + lease = 60; port = 0; verbose = 0; continuous = 0; @@ -117,8 +122,6 @@ main(int argc, /* I - Number of command-line arguments */ { if (!strcmp(argv[i], "-c")) continuous = 1; - if (!strcmp(argv[i], "-v")) - verbose = 1; else if (!strcmp(argv[i], "-i")) { i ++; @@ -127,6 +130,14 @@ main(int argc, /* I - Number of command-line arguments */ else usage(); } + else if (!strcmp(argv[i], "-l")) + { + i ++; + if (i < argc) + lease = atoi(argv[i]); + else + usage(); + } else if (!strcmp(argv[i], "-o")) { i ++; @@ -135,6 +146,14 @@ main(int argc, /* I - Number of command-line arguments */ else usage(); } + else if (!strcmp(argv[i], "-C")) + { + i ++; + if (i < argc) + num_pclasses = atoi(argv[i]); + else + usage(); + } else if (!strcmp(argv[i], "-p")) { i ++; @@ -151,6 +170,8 @@ main(int argc, /* I - Number of command-line arguments */ else usage(); } + else if (!strcmp(argv[i], "-v")) + verbose = 1; else if (isdigit(argv[i][0] & 255)) { port = atoi(argv[i]); @@ -159,7 +180,8 @@ main(int argc, /* I - Number of command-line arguments */ usage(); } - if (num_printers <= 0 || num_servers <= 0 || interval <= 0 || port <= 0) + if ((num_printers <= 0 && num_pclasses <= 0) || num_servers <= 0 || + interval <= 0 || lease < 1 || port <= 0) usage(); /* @@ -207,7 +229,7 @@ main(int argc, /* I - Number of command-line arguments */ printf("Sending %d printers from %d servers...\n", num_printers, num_servers); - count = num_servers * num_printers / interval + 1; + count = num_servers * (num_printers + num_pclasses) / interval + 1; curtime = time(NULL); curdate = localtime(&curtime); seconds = interval; @@ -227,11 +249,45 @@ main(int argc, /* I - Number of command-line arguments */ snprintf(packet, sizeof(packet), "%x %x ipp://testserver-%d/printers/%s-%d \"Server Room %d\" " - "\"Test Printer %d\" \"Acme Blazer 2000\"%s%s\n", + "\"Test Printer %d\" \"Acme Blazer 2000\"%s%s " + "lease-duration=%d\n", CUPS_PRINTER_REMOTE, IPP_PRINTER_IDLE, server + 1, names[printer % 26], printer / 26 + 1, server + 1, printer + 1, options ? " ipp-options=" : "", - options ? options : ""); + options ? options : "", lease); + + if (verbose) + printf("[%02d:%02d:%02d] %s", curdate->tm_hour, curdate->tm_min, + curdate->tm_sec, packet); + + if (sendto(sock, packet, strlen(packet), 0, + (struct sockaddr *)&addr, sizeof(addr)) < 0) + perror("Unabled to send packet"); + } + } + + + for (i = 0, pclass = 0; pclass < num_pclasses; pclass ++) + { + for (server = 0; server < num_servers; server ++, i ++) + { + if (i == count) + { + seconds --; + i = 0; + sleep(1); + curtime = time(NULL); + curdate = localtime(&curtime); + } + + snprintf(packet, sizeof(packet), + "%x %x ipp://testserver-%d/classes/class-%s-%d \"Server Room %d\" " + "\"Test Class %d\" \"Acme Blazer 2000\"%s%s " + "lease-duration=%d\n", + CUPS_PRINTER_REMOTE | CUPS_PRINTER_CLASS, IPP_PRINTER_IDLE, + server + 1, names[pclass % 26], pclass / 26 + 1, server + 1, + pclass + 1, options ? " ipp-options=" : "", + options ? options : "", lease); if (verbose) printf("[%02d:%02d:%02d] %s", curdate->tm_hour, curdate->tm_min, @@ -265,11 +321,13 @@ main(int argc, /* I - Number of command-line arguments */ void usage(void) { - puts("Usage: testdirsvc [-i interval] [-o ipp-options] [-p printers] [-s servers] [-v] port"); + puts("Usage: testdirsvc [-c] [-i interval] [-l lease-duration] " + "[-o ipp-options] [-p printers] " + "[-C classes] [-s servers] [-v] port"); exit(0); } /* - * End of "$Id: testdirsvc.c 4821 2005-11-04 19:36:39Z mike $". + * End of "$Id: testdirsvc.c 5178 2006-02-26 00:24:23Z mike $". */ diff --git a/scheduler/type.c b/scheduler/type.c index 50d49d26a..79f7a229b 100644 --- a/scheduler/type.c +++ b/scheduler/type.c @@ -1,5 +1,5 @@ /* - * "$Id: type.c 5052 2006-02-02 16:21:13Z mike $" + * "$Id: type.c 5180 2006-02-26 01:31:45Z mike $" * * MIME typing routines for the Common UNIX Printing System (CUPS). * @@ -544,11 +544,11 @@ mimeFileType(mime_t *mime, /* I - MIME database */ mime_type_t *type; /* File type */ - DEBUG_printf(("mimeFileType(mime=%p, pathname=\"%s\", basename=\"%s\", " + DEBUG_printf(("mimeFileType(mime=%p, pathname=\"%s\", filename=\"%s\", " "compression=%p)\n", mime, pathname ? pathname : "(nil)", filename ? filename : "(nil)", - basenamecompression)); + compression)); /* * Range check input parameters... @@ -690,8 +690,8 @@ checkrules(const char *filename, /* I - Filename */ #endif /* DEBUG */ - DEBUG_printf(("checkrules(filename=\"%s\", fp=%p, rules=%p)\n", filename, - fp, rules)); + DEBUG_printf(("checkrules(filename=\"%s\", fb=%p, rules=%p)\n", filename, + fb, rules)); if (rules == NULL) return (0); @@ -1161,5 +1161,5 @@ patmatch(const char *s, /* I - String to match against */ /* - * End of "$Id: type.c 5052 2006-02-02 16:21:13Z mike $". + * End of "$Id: type.c 5180 2006-02-26 01:31:45Z mike $". */ diff --git a/scripting/java/src/com/easysw/cups/Cups.java b/scripting/java/src/com/easysw/cups/Cups.java index a2cbd92b9..84fdf459d 100644 --- a/scripting/java/src/com/easysw/cups/Cups.java +++ b/scripting/java/src/com/easysw/cups/Cups.java @@ -1,13 +1,13 @@ package com.easysw.cups; /** - * @version 1.00 06-NOV-2002 + * @version 1.2 26-FEB-2006 * @author Easy Software Products * * Internet Printing Protocol definitions for the Common UNIX Printing * System (CUPS). * - * Copyright 1997-2002 by Easy Software Products. + * Copyright 1997-2006 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -19,11 +19,11 @@ package com.easysw.cups; * Attn: CUPS Licensing Information * Easy Software Products * 44141 Airport View Drive, Suite 204 - * Hollywood, Maryland 20636-3111 USA + * Hollywood, Maryland 20636 USA * - * Voice: (301) 373-9603 + * Voice: (301) 373-9600 * EMail: cups-info@cups.org - * WWW: http://www.cups.org + * WWW: http://www.cups.org/ */ /** @@ -31,7 +31,7 @@ package com.easysw.cups; * reading and writing data, and performing common CUPS operations. * * @author TDB - * @version 1.0.1 + * @version 1.2 * @since JDK1.3 */ @@ -1175,7 +1175,9 @@ public class Cups a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_URI, "printer-uri" ); - a.addString( "", site + "/printers/" + printer_name ); + String p_uri = "ipp://" + address + ":" + + port + "/printers/" + printer_name; + a.addString( "", p_uri ); ipp.addAttribute(a); if (doRequest("cupsGetPrinterAttributes")) diff --git a/scripting/php/Dependencies b/scripting/php/Dependencies index c5e45a09c..f674ca767 100644 --- a/scripting/php/Dependencies +++ b/scripting/php/Dependencies @@ -1,6 +1,6 @@ # DO NOT DELETE -phpcups.o: php_phpcups.h ../../cups/cups.h ../../cups/ipp.h ../../cups/http.h -phpcups.o: ../../cups/md5.h ../../cups/ppd.h ../../cups/ipp.h -phpcups.o: ../../cups/language.h ../../cups/string.h ../../config.h -phpcups.o: ../../cups/debug.h +phpcups.o: phpcups.h ../../cups/cups.h ../../cups/ipp.h ../../cups/http.h +phpcups.o: ../../cups/md5.h ../../cups/ppd.h ../../cups/array.h +phpcups.o: ../../cups/file.h ../../cups/language.h ../../cups/language.h +phpcups.o: ../../cups/string.h ../../config.h ../../cups/debug.h diff --git a/scripting/php/Example/phpcups.inc.php4 b/scripting/php/Example/phpcups.inc.php4 deleted file mode 100644 index dfb11fb09..000000000 --- a/scripting/php/Example/phpcups.inc.php4 +++ /dev/null @@ -1,310 +0,0 @@ -printer_name = ""; - $this->printer_destination = ""; - $this->is_default = 0; - $this->options = Array(); - $this->printer_state = -1; - $this->printer_state_message = ""; - $this->accepting_jobs = FALSE; - $this->queued_job_count = 0; - $this->description = ""; - $this->location = ""; - $this->printer_info = ""; - $this->printer_more_info = ""; - $this->make_and_model = ""; - $this->printer_uri_supported = Array(); - $this->device_uri = ""; - $this->job_quota_period = 0; - $this->job_k_limit = 0; - $this->job_page_limit = 0; - $this->color_supported = FALSE; - $this->pages_per_minute = 0; - $this->finishings_supported = Array(); - $this->finishings_default = 0; - $this->printer_type = 0; - $this->operations_supported = Array(); - $this->multiple_document_jobs_supported = FALSE; - $this->multiple_operation_time_out = 0; - $this->job_priority_supported_lower = 0; - $this->job_priority_supported_upper = 100; - $this->job_priority_default = 50; - $this->copies_supported_lower = 1; - $this->copies_supported_upper = 1; - $this->copies_default = 1; - $this->page_range_supported = FALSE; - $this->number_up_supported = Array(); - $this->number_up_default = 0; - $this->orientation_requested_supported = Array(); - $this->orientation_requested_default = 3; - $this->media_supported = Array(); - $this->media_default = ""; - - } // End of constructor - - - // - // Get the attributes - // - function getAttributes() - { - $o_arr = cups_get_dest_options($this->printer_server, - $this->printer_name, - $this->printer_instance); - $this->printer_options = $o_arr; - - $attrs = cups_get_printer_attributes( "localhost", $this->printer_name ); - while ($obj = current($attrs)) - { - next($attrs); - - if ($obj->name == "printer-state") - { - $this->printer_state = $obj->value; - } - else if ($obj->name == "printer-state-message") - { - $this->printer_state_message = $obj->value; - } - else if ($obj->name == "printer-location") - { - $this->location = $obj->value; - } - else if ($obj->name == "printer-make-and-model") - { - $this->description = $obj->value; - } - else if ($obj->name == "printer-uri-supported") - { - $this->printer_uri_supported[$obj->value] = $obj->value; - } - else if ($obj->name == "device-uri") - { - $this->device_uri = $obj->value; - } - else if ($obj->name == "queued-job-count") - { - $this->queued_job_count = $obj->value; - } - else if ($obj->name == "printer-is-accepting-jobs") - { - $this->accepting_jobs = $obj->value ? TRUE : FALSE; - } - else if ($obj->name == "color-supported") - { - $this->color_supported = $obj->value ? TRUE : FALSE; - } - else if ($obj->name == "pages-per-minute") - { - $this->pages_per_minute = $obj->value; - } - else if ($obj->name == "operations-supported") - { - $this->operations_supported["O$obj->value"] = $obj->value; - } - else if ($obj->name == "orientation-requested-supported") - { - $this->orientation_requested_supported["O$obj->value"] = $obj->value; - } - else if ($obj->name == "orientation-requested-default") - { - $this->orientation_requested_default = $obj->value; - } - else if ($obj->name == "finishings-supported") - { - $this->finishings_supported["F$obj->value"] = $obj->value; - } - else if ($obj->name == "finishings-default") - { - $this->finishings_default = $obj->value; - } - else if ($obj->name == "number-up-supported") - { - $this->number_up_supported["N$obj->value"] = $obj->value; - } - else if ($obj->name == "number-up-default") - { - $this->number_up_default = $obj->value; - } - else if ($obj->name == "printer-type") - { - $this->printer_type = $obj->value; - } - else if ($obj->name == "multiple-document-jobs-suppoted") - { - $this->multiple_document_jobs_supported = $obj->value ? TRUE : FALSE; - } - else if ($obj->name == "multiple-operation-time-out") - { - $this->multiple_operation_time_out = $obj->value; - } - else if ($obj->name == "job-priority-supported") - { - $this->job_priority_supported_upper = $obj->value; - } - else if ($obj->name == "job-priority-default") - { - $this->job_priority_default = $obj->value; - } - else if ($obj->name == "copies-supported") - { - $tmpa = explode("-",$obj->value); - if (count($tmpa) > 1) - { - $this->copies_supported_lower = $tmpa[0]; - $this->copies_supported_upper = $tmpa[1]; - } - else if (count($tmpa) == 1) - { - $this->copies_supported_lower = $tmpa[0]; - $this->copies_supported_upper = $tmpa[0]; - } - } - else if ($obj->name == "copies-default") - { - $this->copies_supported_default = $obj->value; - } - else if ($obj->name == "page-ranges-supported") - { - $this->page_ranges_supported = $obj->value ? TRUE : FALSE; - } - else if ($obj->name == "media-default") - { - $this->media_default = $obj->value; - } - else if ($obj->name == "media-supported") - { - $this->media_supported[$obj->value] = $obj->value; - } - - } // while - - } // End of getAttributes - - - } // End of CupsPrinter class - - - - - // - // Get the printer / destination list. - // - function phpcups_getDestList() - { - $return_value = Array(); - - // - // Get the destination objects array. - // - $p_arr = cups_get_dest_list(); - - if (!IS_ARRAY($p_arr)) - { - return(NULL); - } - - reset($p_arr); - - while ($p_obj = current($p_arr)) - { - next($p_arr); - - // - // Get the options for the current destination. - // - $o_arr = cups_get_dest_options("localhost",$p_obj->name,$p_obj->instance); - - $p = new CupsPrinter(); - $p->printer_name = $p_obj->name; - $p->printer_instance = $p_obj->instance; - $p->is_default = $p_obj->is_default; - $p->printer_options = $o_arr; - $p->getAttributes(); - - $return_value[$p->printer_name] = $p; - } - return($return_value); - - } // End of phpcups_getDestList() - - - - -} // if included. -?> diff --git a/scripting/php/Makefile b/scripting/php/Makefile index c93559e4b..398c2714e 100644 --- a/scripting/php/Makefile +++ b/scripting/php/Makefile @@ -3,7 +3,7 @@ # # PHP Makefile for the Common UNIX Printing System (CUPS). # -# Copyright 1997-2005 by Easy Software Products, all rights reserved. +# Copyright 1997-2006 by Easy Software Products, all rights reserved. # # These coded instructions, statements, and computer programs are the # property of Easy Software Products and are protected by Federal @@ -15,23 +15,24 @@ # Attn: CUPS Licensing Information # Easy Software Products # 44141 Airport View Drive, Suite 204 -# Hollywood, Maryland 20636-3111 USA +# Hollywood, Maryland 20636 USA # # Voice: (301) 373-9603 # EMail: cups-info@cups.org -# WWW: http://www.cups.org +# WWW: http://www.cups.org/ # include ../../Makedefs # -# Where to install the PHP module... +# Where to install and how to compile the PHP module... # -PHPDIR = `php-config --extension-dir` -OPTIONS = `php-config --includes` -I../.. -DCOMPILE_DL_PHPCUPS -PHPLIBS = `php-config --ldflags` `php-config --libs` +PHPDIR = $(BUILDROOT)`$(PHPCONFIG) --extension-dir` +OPTIONS = -I../.. `$(PHPCONFIG) --includes` +PHPLIBS = `$(PHPCONFIG) --ldflags` `$(PHPCONFIG) --libs` + # # Object files... diff --git a/scripting/php/README b/scripting/php/README index 0cb23f1d5..e4ab27d84 100644 --- a/scripting/php/README +++ b/scripting/php/README @@ -1,21 +1,157 @@ -README - 04/08/2003 +README - 02/25/2006 ------------------- -This directory contains a dynamically loadable CUPS extension -module for PHP 4. To compile it type: +INTRODUCTION - make + This directory contains a dynamically loadable CUPS extension + module for PHP 4 and 5. The CUPS 1.2 module has been + substantially updated to provide an API more consistent with + the C API and is NOT compatible with the CUPS 1.1 module. -To install it, type: - make install +COMPILING AND INSTALLING -Questions should be reported to the CUPS newsgroups/mailing -lists at: + Run "make" to compile the PHP CUPS extension: - http://www.cups.org/newsgroups.php + make -Bug reports and enhancement requests can be submitted via the -form at: + To install it, type: + + make install + + +RESOURCES AND SUPPORT + + Questions should be reported to the CUPS newsgroups/mailing + lists at: + + http://www.cups.org/newsgroups.php + + Bug reports and enhancement requests can be submitted via the + form at: + + http://www.cups.org/str.php + + +QUICK REFERENCE DOCUMENTATION + + In lieu of actual documentation, the following definitions + can be used as a quick reference to the supported functions: + + + CUPS_CANCEL_JOB + + Cancels a job on the named destination: + + bool cups_cancel_job(string dest, int id) + + The return value is TRUE on success and FALSE on failure. + + Example: + + if (!cups_cancel_job("myprinter", 123)) + print("Unable to cancel job: " . cups_last_error_string() . "\n"); + + + CUPS_GET_DESTS + + Gets a list of available destinations: + + array cups_get_dests() + + The return value is an array of objects with the following + properties: + + name The name of the printer or class + instance The instance of the printer or class + is_default TRUE if the printer or class is the default destination + options Associative array of options and their values + + Example: + + $dest = cups_get_dests(); + + + CUPS_GET_JOBS + + Gets a list of jobs: + + array cups_get_jobs(string dest, bool myjobs, int completed) + + The "dest" string can be blank for jobs on all destinations. + Pass TRUE for "myjobs" to only get jobs for the current user. + The "completed" argument can be 0 for pending jobs, 1 for + completed jobs, and -1 for all jobs. + + The return value is an array of objects with the following + properties: + + id The job ID + dest Printer or class name + title Title/job name + user User the submitted the job + format Document format + state Job state + size Size in kilobytes + priority Priority (1-100) + completed_time Time the job was completed + creation_time Time the job was created + processing_time Time the job was processed + + Example: + + $jobs = cups_get_jobs("", FALSE, -1); + + + CUPS_LAST_ERROR + + Returns the IPP status code for the most recent request: + + int cups_last_error() + + Example: + + $error = cups_last_error(); + + + CUPS_LAST_ERROR_STRING + + Returns the IPP status-message string for the most recent request: + + string cups_last_error_string() + + Example: + + $message = cups_last_error_string(); + + + CUPS_PRINT_FILE + + Prints a single file to a printer or class: + + int cups_print_file(string dest, string filename, string title, + array options) + + The return value is the job ID or 0 if there was an error. + + Example: + + $options = array("name" => "value", "name2" => "value2"); + $id = cups_print_file("dest", "filename", "title", $options); + + + CUPS_PRINT_FILES + + Prints one or more files to a printer or class: + + int cups_print_files(string dest, array files, string title, + array options); + + The return value is the job ID or 0 if there was an error. + + Example: + + $files = array("file1", "file2", "file3"); + $options = array("name" => "value", "name2" => "value2"); + $id = cups_print_file("dest", $files, "title", $options); - http://www.cups.org/str.php diff --git a/scripting/php/config.m4 b/scripting/php/config.m4 deleted file mode 100644 index 562e9e27b..000000000 --- a/scripting/php/config.m4 +++ /dev/null @@ -1,60 +0,0 @@ -dnl $Id: config.m4 3867 2003-08-14 22:29:23Z ted $ -dnl config.m4 for extension phpcups - -dnl Comments in this file start with the string 'dnl'. -dnl Remove where necessary. This file will not work -dnl without editing. - -dnl If your extension references something external, use with: - -PHP_ARG_WITH(phpcups, for phpcups support, -dnl Make sure that the comment is aligned: -[ --with-phpcups Include phpcups support]) - -dnl Otherwise use enable: - -dnl PHP_ARG_ENABLE(phpcups, whether to enable phpcups support, -dnl Make sure that the comment is aligned: -dnl [ --enable-phpcups Enable phpcups support]) - -if test "$PHP_PHPCUPS" != "no"; then - dnl Write more examples of tests here... - - dnl # --with-phpcups -> check with-path - dnl SEARCH_PATH="/usr/local /usr" # you might want to change this - dnl SEARCH_FOR="/include/phpcups.h" # you most likely want to change this - dnl if test -r $PHP_PHPCUPS/; then # path given as parameter - dnl PHPCUPS_DIR=$PHP_PHPCUPS - dnl else # search default path list - dnl AC_MSG_CHECKING(for phpcups files in default path) - dnl for i in $SEARCH_PATH ; do - dnl if test -r $i/$SEARCH_FOR; then - dnl PHPCUPS_DIR=$i - dnl AC_MSG_RESULT(found in $i) - dnl fi - dnl done - dnl fi - dnl - dnl if test -z "$PHPCUPS_DIR"; then - dnl AC_MSG_RESULT(not found) - dnl AC_MSG_ERROR(Please reinstall the phpcups distribution) - dnl fi - - dnl # --with-phpcups -> add include path - PHP_ADD_INCLUDE(/var/httpd2/web2/cups) - PHP_ADD_INCLUDE(/var/httpd2/web2/cups/cups) - - dnl # --with-phpcups -> chech for lib and symbol presence - dnl LIBNAME=phpcups # you may want to change this - dnl LIBSYMBOL=phpcups # you most likely want to change this - dnl old_LIBS=$LIBS - dnl LIBS="$LIBS -L$PHPCUPS_DIR/lib -lm -ldl" - dnl AC_CHECK_LIB($LIBNAME, $LIBSYMBOL, [AC_DEFINE(HAVE_PHPCUPSLIB,1,[ ])], - dnl [AC_MSG_ERROR(wrong phpcups lib version or lib not found)]) - dnl LIBS=$old_LIBS - dnl - dnl PHP_SUBST(PHPCUPS_SHARED_LIBADD) - PHP_ADD_LIBRARY_WITH_PATH("cups", "/var/httpd2/web2/cups/cups", PHPCUPS_SHARED_LIBADD) - - PHP_EXTENSION(phpcups, $ext_shared) -fi diff --git a/scripting/php/php_phpcups.h b/scripting/php/php_phpcups.h deleted file mode 100644 index 8b3fdeede..000000000 --- a/scripting/php/php_phpcups.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * "$Id: php_phpcups.h 4523 2005-05-23 20:14:19Z mike $" - * - * PHP module include file for the Common UNIX Printing System (CUPS). - * - * Copyright 1997-2003 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Easy Software Products and are protected by Federal - * copyright law. Distribution and use rights are outlined in the file - * "LICENSE.txt" which should have been included with this file. If this - * file is missing or damaged please contact Easy Software Products - * at: - * - * Attn: CUPS Licensing Information - * Easy Software Products - * 44141 Airport View Drive, Suite 204 - * Hollywood, Maryland 20636-3111 USA - * - * Voice: (301) 373-9603 - * EMail: cups-info@cups.org - * WWW: http://www.cups.org - */ - -#ifndef PHP_PHPCUPS_H -# define PHP_PHPCUPS_H - -extern zend_module_entry phpcups_module_entry; -# define phpext_phpcups_ptr &phpcups_module_entry - -# ifdef PHP_WIN32 -# define PHP_PHPCUPS_API __declspec(dllexport) -# else -# define PHP_PHPCUPS_API -# endif - -# ifdef ZTS -# include "TSRM.h" -# endif - -PHP_MINIT_FUNCTION(phpcups); -PHP_MSHUTDOWN_FUNCTION(phpcups); -PHP_RINIT_FUNCTION(phpcups); -PHP_RSHUTDOWN_FUNCTION(phpcups); -PHP_MINFO_FUNCTION(phpcups); - -PHP_FUNCTION(confirm_phpcups_compiled); -PHP_FUNCTION(cups_get_dest_options); -PHP_FUNCTION(cups_get_dest_list); -PHP_FUNCTION(cups_get_jobs); -PHP_FUNCTION(cups_cancel_job); -PHP_FUNCTION(cups_print_file); -PHP_FUNCTION(cups_last_error); -PHP_FUNCTION(cups_get_printer_attributes); - -/* - Declare any global variables you may need between the BEGIN - and END macros here: - -ZEND_BEGIN_MODULE_GLOBALS(phpcups) - int global_value; - char *global_string; -ZEND_END_MODULE_GLOBALS(phpcups) -*/ - -/* In every utility function you add that needs to use variables - in php_phpcups_globals, call TSRM_FETCH(); after declaring other - variables used by that function, or better yet, pass in TSRMG_CC - after the last function argument and declare your utility function - with TSRMG_DC after the last declared argument. Always refer to - the globals in your function as PHPCUPS_G(variable). You are - encouraged to rename these macros something shorter, see - examples in any other php module directory. -*/ - -# ifdef ZTS -# define PHPCUPS_G(v) TSRMG(phpcups_globals_id, zend_phpcups_globals *, v) -# else -# define PHPCUPS_G(v) (phpcups_globals.v) -# endif - -#endif /* !PHP_PHPCUPS_H */ - - -/* - * End of "$Id: php_phpcups.h 4523 2005-05-23 20:14:19Z mike $". - */ diff --git a/scripting/php/phpcups.c b/scripting/php/phpcups.c index 5d34314c5..845177345 100644 --- a/scripting/php/phpcups.c +++ b/scripting/php/phpcups.c @@ -1,28 +1,9 @@ /* - +----------------------------------------------------------------------+ - | PHP version 4.0 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 2.02 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at | - | http://www.php.net/license/2_02.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: | - | | - +----------------------------------------------------------------------+ - */ - -/* - * "$Id: phpcups.c 4530 2005-06-01 20:15:51Z mike $" + * "$Id: phpcups.c 5171 2006-02-25 08:44:43Z mike $" * * Printing utilities for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2002 by Easy Software Products. + * Copyright 1997-2006 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -34,1324 +15,444 @@ * Attn: CUPS Licensing Information * Easy Software Products * 44141 Airport View Drive, Suite 204 - * Hollywood, Maryland 20636-3111 USA + * Hollywood, Maryland 20636 USA * * Voice: (301) 373-9603 * EMail: cups-info@cups.org - * WWW: http://www.cups.org + * WWW: http://www.cups.org/ + * + * Contents: + * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "php_phpcups.h" - /* * Include necessary headers... */ -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#if defined(WIN32) || defined(__EMX__) -# include -#else -# include -#endif /* WIN32 || __EMX__ */ - - -static int le_result, le_link, le_plink; - - +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +#include "phpcups.h" -/* - * Local globals... +/* + * PHP function list... */ -static http_t *cups_server = NULL; /* Current server connection */ -static ipp_status_t last_error = IPP_OK; /* Last IPP error */ -static char authstring[HTTP_MAX_VALUE] = ""; - /* Authorization string */ -static char pwdstring[33] = ""; /* Last password string */ - - - +function_entry phpcups_functions[] = +{ + PHP_FE(cups_cancel_job, NULL) + PHP_FE(cups_get_dests, NULL) + PHP_FE(cups_get_jobs, NULL) + PHP_FE(cups_last_error, NULL) + PHP_FE(cups_last_error_string, NULL) + PHP_FE(cups_print_file, NULL) + PHP_FE(cups_print_files, NULL) + {NULL, NULL, NULL} +}; /* - * ********************************************************************* + * PHP module info... */ - - - -/* If you declare any globals in php_phpcups.h uncomment this: -ZEND_DECLARE_MODULE_GLOBALS(phpcups) -*/ - -/* True global resources - no need for thread safety here */ -static int le_phpcups; - -/* - * Every user visible function must have an entry in phpcups_functions[]. - */ -function_entry phpcups_functions[] = { - PHP_FE(confirm_phpcups_compiled,NULL) - PHP_FE(cups_get_dest_list, NULL) - PHP_FE(cups_get_dest_options, NULL) - PHP_FE(cups_get_jobs, NULL) - PHP_FE(cups_cancel_job, NULL) - PHP_FE(cups_last_error, NULL) - PHP_FE(cups_print_file, NULL) - PHP_FE(cups_get_printer_attributes, NULL) - {NULL, NULL, NULL} +zend_module_entry phpcups_module_entry = +{ + STANDARD_MODULE_HEADER, + "phpcups", + phpcups_functions, + PHP_MINIT(phpcups), + NULL, + NULL, + NULL, + NULL, + CUPS_SVERSION, + STANDARD_MODULE_PROPERTIES }; - - -zend_module_entry phpcups_module_entry = { - STANDARD_MODULE_HEADER, - "phpcups", - phpcups_functions, - PHP_MINIT(phpcups), - PHP_MSHUTDOWN(phpcups), - PHP_RINIT(phpcups), /* Replace with NULL if there's nothing to do at request start */ - PHP_RSHUTDOWN(phpcups), /* Replace with NULL if there's nothing to do at request end */ - PHP_MINFO(phpcups), - "0.1", /* Replace with version number for your extension */ - STANDARD_MODULE_PROPERTIES -}; - -#ifdef COMPILE_DL_PHPCUPS ZEND_GET_MODULE(phpcups) -#endif - - - - -/* Remove comments and fill if you need to have entries in php.ini -PHP_INI_BEGIN() - STD_PHP_INI_ENTRY("phpcups.value", "42", PHP_INI_ALL, OnUpdateInt, global_value, zend_phpcups_globals, phpcups_globals) - STD_PHP_INI_ENTRY("phpcups.string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_phpcups_globals, phpcups_globals) -PHP_INI_END() -*/ - +/* + * 'cups_convert_options()' - Convert a PHP options array to a CUPS options array. + */ -/* Uncomment this function if you have INI entries -static void php_phpcups_init_globals(zend_phpcups_globals *phpcups_globals) +static int /* O - Number of options */ +cups_convert_options( + zval *optionsobj, /* I - Options array object */ + cups_option_t **options) /* O - Options */ { - phpcups_globals->value = 0; - phpcups_globals->string = NULL; -} -*/ + int num_options; /* Number of options */ + HashTable *ht; /* Option array hash table */ + Bucket *current; /* Current element in array */ + ht = Z_ARRVAL_P(optionsobj); + num_options = 0; + for (current = ht->pListHead; current; current = current->pListNext) + num_options = cupsAddOption(current->arKey, + Z_STRVAL_P(((zval *)current->pDataPtr)), + num_options, options); -PHP_MINIT_FUNCTION(phpcups) -{ - /* If you have INI entries, uncomment these lines - ZEND_INIT_MODULE_GLOBALS(phpcups, php_phpcups_init_globals, NULL); - REGISTER_INI_ENTRIES(); - */ - return SUCCESS; + return (num_options); } -PHP_MSHUTDOWN_FUNCTION(phpcups) -{ - /* uncomment this line if you have INI entries - UNREGISTER_INI_ENTRIES(); - */ - return SUCCESS; -} -/* Remove if there's nothing to do at request start */ -PHP_RINIT_FUNCTION(phpcups) -{ - return SUCCESS; -} +/* + * 'zm_startup_phpcups()' - Initialize the CUPS module. + */ -/* Remove if there's nothing to do at request end */ -PHP_RSHUTDOWN_FUNCTION(phpcups) +PHP_MINIT_FUNCTION(phpcups) { - return SUCCESS; + REGISTER_LONG_CONSTANT("CUPS_PRINTER_LOCAL", CUPS_PRINTER_LOCAL, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_CLASS", CUPS_PRINTER_CLASS, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_REMOTE", CUPS_PRINTER_REMOTE, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_BW", CUPS_PRINTER_BW, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_COLOR", CUPS_PRINTER_COLOR, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_DUPLEX", CUPS_PRINTER_DUPLEX, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_STAPLE", CUPS_PRINTER_STAPLE, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_COPIES", CUPS_PRINTER_COPIES, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_COLLATE", CUPS_PRINTER_COLLATE, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_PUNCH", CUPS_PRINTER_PUNCH, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_COVER", CUPS_PRINTER_COVER, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_BIND", CUPS_PRINTER_BIND, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_SORT", CUPS_PRINTER_SORT, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_SMALL", CUPS_PRINTER_SMALL, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_MEDIUM", CUPS_PRINTER_MEDIUM, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_LARGE", CUPS_PRINTER_LARGE, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_VARIABLE", CUPS_PRINTER_VARIABLE, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_IMPLICIT", CUPS_PRINTER_IMPLICIT, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_DEFAULT", CUPS_PRINTER_DEFAULT, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_FAX", CUPS_PRINTER_FAX, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_REJECTING", CUPS_PRINTER_REJECTING, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_DELETE", CUPS_PRINTER_DELETE, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_NOT_SHARED", CUPS_PRINTER_NOT_SHARED, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_AUTHENTICATED", CUPS_PRINTER_AUTHENTICATED, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_COMMANDS", CUPS_PRINTER_COMMANDS, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_OPTIONS", CUPS_PRINTER_OPTIONS, CONST_CS); + + REGISTER_LONG_CONSTANT("IPP_OK", IPP_OK, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_OK_SUBST", IPP_OK_SUBST, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_OK_CONFLICT", IPP_OK_CONFLICT, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_OK_IGNORED_SUBSCRIPTIONS", IPP_OK_IGNORED_SUBSCRIPTIONS, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_OK_IGNORED_NOTIFICATIONS", IPP_OK_IGNORED_NOTIFICATIONS, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_OK_TOO_MANY_EVENTS", IPP_OK_TOO_MANY_EVENTS, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_OK_BUT_CANCEL_SUBSCRIPTION", IPP_OK_BUT_CANCEL_SUBSCRIPTION, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_OK_EVENTS_COMPLETE", IPP_OK_EVENTS_COMPLETE, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_REDIRECTION_OTHER_SITE", IPP_REDIRECTION_OTHER_SITE, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_BAD_REQUEST", IPP_BAD_REQUEST, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_FORBIDDEN", IPP_FORBIDDEN, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_NOT_AUTHENTICATED", IPP_NOT_AUTHENTICATED, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_NOT_AUTHORIZED", IPP_NOT_AUTHORIZED, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_NOT_POSSIBLE", IPP_NOT_POSSIBLE, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_TIMEOUT", IPP_TIMEOUT, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_NOT_FOUND", IPP_NOT_FOUND, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_GONE", IPP_GONE, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_REQUEST_ENTITY", IPP_REQUEST_ENTITY, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_REQUEST_VALUE", IPP_REQUEST_VALUE, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_DOCUMENT_FORMAT", IPP_DOCUMENT_FORMAT, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_ATTRIBUTES", IPP_ATTRIBUTES, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_URI_SCHEME", IPP_URI_SCHEME, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_CHARSET", IPP_CHARSET, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_CONFLICT", IPP_CONFLICT, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_COMPRESSION_NOT_SUPPORTED", IPP_COMPRESSION_NOT_SUPPORTED, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_COMPRESSION_ERROR", IPP_COMPRESSION_ERROR, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_DOCUMENT_FORMAT_ERROR", IPP_DOCUMENT_FORMAT_ERROR, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_DOCUMENT_ACCESS_ERROR", IPP_DOCUMENT_ACCESS_ERROR, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_ATTRIBUTES_NOT_SETTABLE", IPP_ATTRIBUTES_NOT_SETTABLE, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_IGNORED_ALL_SUBSCRIPTIONS", IPP_IGNORED_ALL_SUBSCRIPTIONS, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_TOO_MANY_SUBSCRIPTIONS", IPP_TOO_MANY_SUBSCRIPTIONS, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_IGNORED_ALL_NOTIFICATIONS", IPP_IGNORED_ALL_NOTIFICATIONS, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_PRINT_SUPPORT_FILE_NOT_FOUND", IPP_PRINT_SUPPORT_FILE_NOT_FOUND, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_INTERNAL_ERROR", IPP_INTERNAL_ERROR, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_OPERATION_NOT_SUPPORTED", IPP_OPERATION_NOT_SUPPORTED, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_SERVICE_UNAVAILABLE", IPP_SERVICE_UNAVAILABLE, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_VERSION_NOT_SUPPORTED", IPP_VERSION_NOT_SUPPORTED, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_DEVICE_ERROR", IPP_DEVICE_ERROR, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_TEMPORARY_ERROR", IPP_TEMPORARY_ERROR, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_NOT_ACCEPTING", IPP_NOT_ACCEPTING, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_PRINTER_BUSY", IPP_PRINTER_BUSY, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_ERROR_JOB_CANCELLED", IPP_ERROR_JOB_CANCELLED, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_MULTIPLE_JOBS_NOT_SUPPORTED", IPP_MULTIPLE_JOBS_NOT_SUPPORTED, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_PRINTER_IS_DEACTIVATED", IPP_PRINTER_IS_DEACTIVATED, CONST_CS); + + return (SUCCESS); } +/* + * 'zif_cups_cancel_job()' - Cancel a job. + */ - -PHP_MINFO_FUNCTION(phpcups) +PHP_FUNCTION(cups_cancel_job) { - php_info_print_table_start(); - php_info_print_table_header(2, "phpcups support", "enabled"); - php_info_print_table_end(); + char *dest; /* Destination */ + int dest_len, /* Length of destination */ + id; /* Job ID */ - /* Remove comments if you have entries in php.ini - DISPLAY_INI_ENTRIES(); - */ -} - - - - - - - -/* Remove the following function when you have succesfully modified config.m4 - so that your module can be compiled into PHP, it exists only for testing - purposes. */ - -/* Every user-visible function in PHP should document itself in the source */ -PHP_FUNCTION(confirm_phpcups_compiled) -{ - char *arg = NULL; - int arg_len, len; - char string[256]; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) { - return; - } + if (ZEND_NUM_ARGS() != 2 || + zend_parse_parameters(2, "sl", &dest, &dest_len, &id)) + { + WRONG_PARAM_COUNT; + } - len = sprintf(string, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "phpcups", arg); - RETURN_STRINGL(string, len, 1); + RETURN_LONG(cupsCancelJob(dest, id)); } -/* The previous line is meant for vim and emacs, so it can correctly fold and - unfold functions in source code. See the corresponding marks just before - function definition, where the functions purpose is also documented. Please - follow this convention for the convenience of others editing your code. -*/ - - - - - - - - - /* - * Function: cups_get_dest_options - * - * Date: 8 April 2002 - TDB - * - * Parameters: d_name - String - Name of destination. - * d_instance - String - Name of instance on destination. - * - * Returns: Array of option "objects", with each object - * containing the members: - * - * name - String - Option name - * value - String - Option value - * - * Comments: - * + * 'zif_cups_get_dests()' - . */ -PHP_FUNCTION(cups_get_dest_options) -{ - char *arg = NULL; - int arg_len, len; - zval *new_object; - - zval **d_server, - **d_name, - **d_instance; - - char c_server[256], - c_name[256], - c_instance[256]; - - char l_server[256], - l_name[256], - l_instance[256]; +PHP_FUNCTION(cups_get_dests) +{ + int i, j, /* Looping vars */ + num_dests; /* Number of destinations */ + cups_dest_t *dests, /* Destinations */ + *dest; /* Current destination */ + cups_option_t *option; /* Current option */ + zval *destobj, /* Destination object */ + *optionsobj; /* Options object */ - cups_dest_t *dests, *dptr; - int num_dests; - int i, j; - array_init(return_value); + if (ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } - if ((ZEND_NUM_ARGS() != 3) || - (zend_get_parameters_ex(3,&d_server,&d_name,&d_instance) != SUCCESS)) - { - WRONG_PARAM_COUNT; - } + if ((num_dests = cupsGetDests(&dests)) <= 0) + { + RETURN_NULL(); + } - convert_to_string_ex( d_server ); - convert_to_string_ex( d_name ); - convert_to_string_ex( d_instance ); - - /* - * Find the dest/instance we want options for. - */ - bzero( c_server, 256 ); - bzero( c_name, 256 ); - bzero( c_instance, 256 ); - - if ( (char *)(*d_server)->value.str.val != NULL ) - strcpy( c_server,(char *)(*d_server)->value.str.val ); - if ( (char *)(*d_name)->value.str.val != NULL ) - strcpy( c_name,(char *)(*d_name)->value.str.val ); - if ( (char *)(*d_instance)->value.str.val != NULL ) - strcpy( c_instance,(char *)(*d_instance)->value.str.val ); - - - if (strlen(c_server)) - cupsSetServer(c_server); - - num_dests = cupsGetDests(&dests); - for (i=0, j = -1; (i < num_dests) && (j < 0); i++) + if (array_init(return_value) == SUCCESS) + { + for (i = 0, dest = dests; i < num_dests; i ++, dest ++) { - dptr = &dests[i]; - - if (dptr->name == NULL) - strcpy( l_name, "" ); - else - strcpy( l_name, dptr->name ); - - if (dptr->instance == NULL) - strcpy( l_instance, "" ); - else - strcpy( l_instance, dptr->instance ); + MAKE_STD_ZVAL(destobj); - if ((!strcmp( l_name, c_name )) && - (!strcmp( l_instance, c_instance ))) + if (object_init(destobj) == SUCCESS) { + /* + * Add properties to the destination for each of the cups_dest_t + * members... + */ - for (j=0; j < dptr->num_options; j++ ) - { - if ((dptr->options[j].name != NULL) && - (dptr->options[j].value != NULL)) - { - MAKE_STD_ZVAL(new_object); - if (object_init(new_object) == SUCCESS) - { - add_property_string(new_object,"name",dptr->options[j].name, 1 ); - add_property_string(new_object,"value",dptr->options[j].value,1); - add_next_index_zval( return_value, new_object ); - } - } - } - } - } - cupsFreeDests(num_dests,dests); -} - - - - -/* - * Function: cups_get_dest_list - * - * Date: 8 April 2002 - TDB - * - * Parameters: cups server (optional) - * - * Returns: Array of destination "objects", with each object - * containing the members: - * - * name - String - Name of destination. - * instance - String - Name of instance on destination. - * is_default - Long - 1 if default printer. - * num_options - Long - Number of options for destination. - * - * Comments: - * - */ -PHP_FUNCTION(cups_get_dest_list) -{ - char *arg = NULL; - int arg_len, len; - - zval **z_server; - zval *new_object; - - char c_server[256]; - - char string[2560]; - char temp[256]; - - cups_dest_t *dests, *dptr; - int num_dests; - int i; - - /* - * Initialize the return array. - */ - array_init(return_value); + add_property_string(destobj, "name", dest->name, 1); + add_property_string(destobj, "instance", + dest->instance ? dest->instance : "", 1); + add_property_long(destobj, "is_default", dest->is_default); - switch (ZEND_NUM_ARGS()) - { - /* - * Change servers if passed. - */ - case 1: if (zend_get_parameters_ex(1,&z_server) != SUCCESS) - { - WRONG_PARAM_COUNT; - } - convert_to_string_ex( z_server ); - if ( (char *)(*z_server)->value.str.val != NULL ) - { - strcpy( c_server,(char *)(*z_server)->value.str.val ); - cupsSetServer( c_server ); - } - break; - } + /* + * Create an associative array for the options... + */ + MAKE_STD_ZVAL(optionsobj); - /* - * First get the destination list from the cups server. - */ - num_dests = cupsGetDests(&dests); + if (array_init(optionsobj) == SUCCESS) + { + for (j = 0, option = dest->options; + j < dest->num_options; + j ++, option ++) + add_assoc_string(optionsobj, option->name, option->value, 1); - /* - * Loop through the list, create and fill in the objects, and - * add them to the array. - */ - string[0] = '\0'; - for (i=0; i < num_dests; i++) - { - dptr = &dests[i]; + add_property_zval(destobj, "options", optionsobj); + } - MAKE_STD_ZVAL(new_object); - if (object_init(new_object) == SUCCESS) - { - if (strlen(c_server)) - add_property_string( new_object, "server", c_server, 1 ); - else - add_property_string( new_object, "server", "", 1 ); - - if (dptr->name != NULL) - add_property_string( new_object, "name", dptr->name, 1 ); - else - add_property_string( new_object, "name", "", 1 ); - - if (dptr->instance != NULL) - add_property_string( new_object, "instance", dptr->instance, 1 ); - else - add_property_string( new_object, "instance", "", 1 ); - - add_property_long( new_object, "is_default", dptr->is_default ); - add_property_long( new_object, "num_options", dptr->num_options ); - add_next_index_zval( return_value, new_object ); + add_index_zval(return_value, i, destobj); } } + } - /* - * free the list ..... - */ - cupsFreeDests(num_dests,dests); + cupsFreeDests(num_dests, dests); } - /* - * Function: cups_get_jobs - * - * Date: 8 April 2002 - TDB - * - * Parameters: server - String - Name or IP of cups server. Blank - * for localhost. - * - * name - String - Name of destination to query. - * - * user - String - Username to get job list for. - * * Optional, default all users - * - * my_jobs - Long - Show only my jobs - * * Optional, default FALSE - * - * completed - Long - Show completed jobs - * * Optional, default FALSE - * - * Returns: Array of print job "objects", with each object - * containing the members: - * - * id - Long - Job id - * dest - String - Name of destination. - * title - String - Title of document. - * user - String - User who submitted job. - * format - String - Document format (MIME type) - * state - Long - Current state of the job. - * size - Long - Size in bytes of the job. - * priority - Long - Job priority. - * completed_time - Long - Time job completed (UNIX time). - * creation_time - Long - Time job created (UNIX time). - * processing_time- Long - Processing time in seconds? - * - * Comments: - * + * 'zif_cups_get_jobs()' - Get a list of jobs. */ -PHP_FUNCTION( cups_get_jobs ) -{ - char *arg = NULL; - int arg_len, - len; - - zval *new_object; - - zval **z_server, - **z_name, - **z_user, - **z_myjobs, - **z_completed; - - char p_server[256], - p_name[256], - p_user[256]; +PHP_FUNCTION(cups_get_jobs) +{ + char *dest; /* Destination */ + int dest_len, /* Length of destination */ + myjobs, /* Only show my jobs? */ + completed; /* Show completed jobs? */ + int i, /* Looping var */ + num_jobs; /* Number of jobs */ + cups_job_t *jobs, /* Jobs */ + *job; /* Current job */ + zval *jobobj; /* Job object */ - int p_myjobs, - p_completed; - cups_job_t *jobs, - *jptr; - int num_jobs; - int i; - bzero( p_server, 256 ); - bzero( p_name, 256 ); - bzero( p_user, 256 ); - p_myjobs = 0; - p_completed = 0; + if (ZEND_NUM_ARGS() != 3 || + zend_parse_parameters(3, "sll", &dest, &dest_len, &myjobs, &completed)) + { + WRONG_PARAM_COUNT; + } - /* - * Initialize return value. - */ - array_init(return_value); + if (!*dest) + dest = NULL; - /* - * Parse params. - */ - switch(ZEND_NUM_ARGS()) - { - /* - * server, destination only provided. - */ - case 2: - if (zend_get_parameters_ex( 2, &z_server,&z_name ) == SUCCESS) - { - convert_to_string_ex( z_server); - if ( (char *)(*z_server)->value.str.val != NULL ) - strcpy( p_server,(char *)(*z_server)->value.str.val ); - convert_to_string_ex( z_name ); - if ( (char *)(*z_name)->value.str.val != NULL ) - strcpy( p_name,(char *)(*z_name)->value.str.val ); - } - break; - - /* - * server, destination and user - */ - case 3: - if (zend_get_parameters_ex( 3, &z_server, &z_name, - &z_user ) == SUCCESS) - { - convert_to_string_ex( z_name ); - convert_to_string_ex( z_user ); - convert_to_string_ex( z_server); - if ( (char *)(*z_server)->value.str.val != NULL ) - strcpy( p_server,(char *)(*z_server)->value.str.val ); - if ( (char *)(*z_name)->value.str.val != NULL ) - strcpy( p_name,(char *)(*z_name)->value.str.val ); - if ( (char *)(*z_user)->value.str.val != NULL ) - strcpy( p_user,(char *)(*z_user)->value.str.val ); - } - break; - - /* - * server, destination, user, and myjobs - */ - case 4: - if (zend_get_parameters_ex( 4, &z_server, &z_name, &z_user, - &z_myjobs ) == SUCCESS) - { - convert_to_string_ex( z_name ); - convert_to_string_ex( z_user ); - convert_to_string_ex( z_server); - if ( (char *)(*z_server)->value.str.val != NULL ) - strcpy( p_server,(char *)(*z_server)->value.str.val ); - if ( (char *)(*z_name)->value.str.val != NULL ) - strcpy( p_name,(char *)(*z_name)->value.str.val ); - if ( (char *)(*z_user)->value.str.val != NULL ) - strcpy( p_user,(char *)(*z_user)->value.str.val ); - - convert_to_string_ex( z_myjobs ); - p_myjobs = strtoul((char *)(*z_myjobs)->value.str.val,NULL,10); - } - break; - - /* - * server, destination, user, myjobs, and completed - */ - case 5: - if (zend_get_parameters_ex( 5, &z_server, &z_name, &z_user, - &z_myjobs, &z_completed ) == SUCCESS) - { - convert_to_string_ex( z_name ); - convert_to_string_ex( z_user ); - convert_to_string_ex( z_server); - if ( (char *)(*z_server)->value.str.val != NULL ) - strcpy( p_server,(char *)(*z_server)->value.str.val ); - if ( (char *)(*z_name)->value.str.val != NULL ) - strcpy( p_name,(char *)(*z_name)->value.str.val ); - if ( (char *)(*z_user)->value.str.val != NULL ) - strcpy( p_user,(char *)(*z_user)->value.str.val ); - - convert_to_string_ex( z_myjobs ); - p_myjobs = strtoul((char *)(*z_myjobs)->value.str.val,NULL,10); - - convert_to_string_ex( z_completed); - p_completed = strtoul((char *)(*z_completed)->value.str.val,NULL,10); - } - break; - } + if ((num_jobs = cupsGetJobs(&jobs, dest, myjobs, completed)) <= 0) + { + RETURN_NULL(); + } - /* - * Set the cups server if given. - */ - if (strlen(p_server)) - cupsSetServer(p_server); - - /* - * Set the cups user if given, otherwise get all jobs. - */ - if (strlen(p_user)) - cupsSetUser(p_user); - else - cupsSetUser("root"); - - /* - * Get the jobs list from the CUPS server. - */ - num_jobs = cupsGetJobs(&jobs,p_name,p_myjobs,p_completed); - - /* - * Build the array of objects to return. - */ - for (i=0; i < num_jobs; i++) + if (array_init(return_value) == SUCCESS) + { + for (i = 0, job = jobs; i < num_jobs; i ++, job ++) { - jptr = &jobs[i]; + MAKE_STD_ZVAL(jobobj); - MAKE_STD_ZVAL(new_object); - if (object_init(new_object) == SUCCESS) - { - add_property_long(new_object,"id",jptr->id ); - add_property_string(new_object,"dest",jptr->dest, 1 ); - add_property_string(new_object,"title",jptr->title, 1 ); - add_property_string(new_object,"user",jptr->user, 1 ); - add_property_string(new_object,"format",jptr->format, 1 ); - add_property_long(new_object,"state",jptr->state ); - add_property_long(new_object,"size",jptr->size ); - add_property_long(new_object,"priority",jptr->priority ); - add_property_long(new_object,"completed_time",jptr->completed_time); - add_property_long(new_object,"creation_time",jptr->creation_time); - add_property_long(new_object,"processing_time",jptr->processing_time); - add_next_index_zval( return_value, new_object ); - } - else + if (object_init(jobobj) == SUCCESS) { - printf("\nError creating new object\n"); + /* + * Add properties to the job for each of the cups_job_t + * members... + */ + + add_property_long(jobobj, "id", job->id); + add_property_string(jobobj, "dest", job->dest, 1); + add_property_string(jobobj, "title", job->title, 1); + add_property_string(jobobj, "user", job->user, 1); + add_property_string(jobobj, "format", job->format, 1); + add_property_long(jobobj, "state", job->state); + add_property_long(jobobj, "size", job->size); + add_property_long(jobobj, "priority", job->priority); + add_property_long(jobobj, "completed_time", job->completed_time); + add_property_long(jobobj, "creation_time", job->creation_time); + add_property_long(jobobj, "processing_time", job->processing_time); + + add_index_zval(return_value, i, jobobj); } } - cupsFreeJobs(num_jobs,jobs); -} - + } + cupsFreeJobs(num_jobs, jobs); +} /* - * Function: cups_last_error - * - * Date: 8 April 2002 - TDB - * - * Parameters: none. - * - * Returns: error number - Long - * - * Comments: - * + * 'zif_cups_last_error()' - Return the last IPP status code. */ + PHP_FUNCTION(cups_last_error) { - static char error[1024]; - - zval **z_server; - char c_server[256]; - - bzero( c_server, 256 ); - - switch (ZEND_NUM_ARGS()) + if (ZEND_NUM_ARGS() != 0) { - /* - * Change servers if passed. - */ - case 1: if (zend_get_parameters_ex(1,&z_server) != SUCCESS) - { - WRONG_PARAM_COUNT; - } - convert_to_string_ex( z_server ); - if ( (char *)(*z_server)->value.str.val != NULL ) - { - strcpy( c_server,(char *)(*z_server)->value.str.val ); - cupsSetServer( c_server ); - } - break; + WRONG_PARAM_COUNT; } - sprintf( error,"%d", cupsLastError()); - RETURN_STRINGL(error, strlen(error)+1, 1); + RETURN_LONG(cupsLastError()); } - - - - /* - * Function: cups_cancel_job - * - * Date: 8 April 2002 - TDB - * - * Parameters: server - String - Name or IP of cups server. - * name - String - Name of destination. - * job - Long - Job ID to cancel. - * - * Returns: error number - Long????????? - * - * Comments: - * + * 'zif_cups_last_error_string()' - Return the last IPP status-message. */ -PHP_FUNCTION(cups_cancel_job) -{ - zval **z_server, **z_name, **z_job; - - char p_server[256], p_name[256]; - int p_job; - - int ret_val = -1; - - /* - * Get parameters ..... - */ - if ((ZEND_NUM_ARGS() != 3) || - (zend_get_parameters_ex( 3, &z_server, &z_name, &z_job ) != SUCCESS)) - { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex( z_server); - if ( (char *)(*z_name)->value.str.val != NULL ) - { - strcpy( p_server,(char *)(*z_server)->value.str.val ); - cupsSetServer(p_server); - } - - convert_to_string_ex( z_name ); - if ( (char *)(*z_name)->value.str.val != NULL ) - strcpy( p_name,(char *)(*z_name)->value.str.val ); - - convert_to_string_ex( z_job ); - p_job = strtoul((char *)(*z_job)->value.str.val,NULL,10); - - if (strlen(p_server)) - cupsSetServer(p_server); - cupsSetUser("root"); - - /* - * Errrr .... Cancel the job ...... - */ - ret_val = cupsCancelJob(p_name,p_job); - - RETURN_LONG(ret_val); -} - - -cups_option_t *_phpcups_parse_options( cups_option_t *options, - int *num_options, char *param ) +PHP_FUNCTION(cups_last_error_string) { - char name[1024], value[1024]; - - sscanf(param,"%1023[^=]=%1023s", name, value ); - - if (strlen(name) && strlen(value)) + if (ZEND_NUM_ARGS() != 0) { - if (options == NULL) - { - options = (cups_option_t *)emalloc(sizeof(cups_option_t)); - options->name = (char *)emalloc(strlen(name)+1); - options->value = (char *)emalloc(strlen(value)+1); - strcpy( options->name, name ); - strcpy( options->value, value ); - *num_options++; - } - else - { - options = (cups_option_t *)erealloc(options, - (*num_options+1) * sizeof(cups_option_t)); - options[*num_options].name = (char *)emalloc(strlen(name)+1); - options[*num_options].value = (char *)emalloc(strlen(value)+1); - strcpy( options[*num_options].name, name ); - strcpy( options[*num_options].value, value ); - *num_options++; - } + WRONG_PARAM_COUNT; } - return(options); -} - - -/* - * Function: cups_print_file - * - * Date: 8 April 2002 - TDB - * - * Parameters: printer - String - Name of destination. - * filename - String - Name of file to print (full path). - * title - String - Title of document. - * - * Returns: Job ID - Long - * - * Comments: - * - */ -PHP_FUNCTION(cups_print_file) -{ - zval **z_server, **z_printer, **z_filename, **z_title, - **z_options, **keydata; - - HashTable *param_ht; - char p_server[256]; - char p_printer[256]; - char p_filename[256]; - char p_title[256]; - - char temp[4096]; - cups_option_t *options = NULL; - - int count, current; - int ret_val = -1; - - bzero( p_server, 256 ); - bzero( p_printer, 256 ); - bzero( p_filename, 256 ); - bzero( p_title, 256 ); - bzero( temp, 4096); - current = 0; - - int zend_num_args = ZEND_NUM_ARGS(); - switch (zend_num_args) - { - /* - * Server / Destination / filename only. - */ - case 3: - if (zend_get_parameters_ex( 3, &z_server, &z_printer, - &z_filename) != SUCCESS) - { - WRONG_PARAM_COUNT; - } - convert_to_string_ex( z_server); - if ( (char *)(*z_server)->value.str.val != NULL ) - { - strcpy( p_server,(char *)(*z_server)->value.str.val ); - cupsSetServer(p_server); - } - convert_to_string_ex( z_printer); - if ( (char *)(*z_printer)->value.str.val != NULL ) - strcpy( p_printer,(char *)(*z_printer)->value.str.val ); - convert_to_string_ex( z_filename ); - if ( (char *)(*z_filename)->value.str.val != NULL ) - strcpy( p_filename,(char *)(*z_filename)->value.str.val ); - strcpy( p_title,"untitled"); - break; - - /* - * Server, destination, filename and title. - */ - case 4: - if (zend_get_parameters_ex( 4, &z_server, - &z_printer, - &z_filename, - &z_title) != SUCCESS) - { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex( z_server); - if ( (char *)(*z_server)->value.str.val != NULL ) - { - strcpy( p_server,(char *)(*z_server)->value.str.val ); - cupsSetServer(p_server); - } - - convert_to_string_ex( z_printer); - if ( (char *)(*z_printer)->value.str.val != NULL ) - strcpy( p_printer,(char *)(*z_printer)->value.str.val ); - - convert_to_string_ex( z_filename ); - if ( (char *)(*z_filename)->value.str.val != NULL ) - strcpy( p_filename,(char *)(*z_filename)->value.str.val ); - - convert_to_string_ex( z_title ); - if ( (char *)(*z_title)->value.str.val != NULL ) - strcpy( p_title,(char *)(*z_title)->value.str.val ); - - _zz_internal_log( "cups_print_file", p_server ); - _zz_internal_log( "cups_print_file", p_printer ); - _zz_internal_log( "cups_print_file", p_filename ); - _zz_internal_log( "cups_print_file", p_title ); - break; - - /* - * Server, destination, filename and title plus printer options. - */ - case 5: - if (zend_get_parameters_ex( 5, &z_server, - &z_printer, - &z_filename, - &z_title, - &z_options) != SUCCESS) - { - WRONG_PARAM_COUNT; - } - convert_to_string_ex( z_server); - if ( (char *)(*z_server)->value.str.val != NULL ) - { - strcpy( p_server,(char *)(*z_server)->value.str.val ); - cupsSetServer(p_server); - } - convert_to_string_ex( z_printer); - if ( (char *)(*z_printer)->value.str.val != NULL ) - strcpy( p_printer,(char *)(*z_printer)->value.str.val ); - convert_to_string_ex( z_filename ); - if ( (char *)(*z_filename)->value.str.val != NULL ) - strcpy( p_filename,(char *)(*z_filename)->value.str.val ); - convert_to_string_ex( z_title ); - if ( (char *)(*z_title)->value.str.val != NULL ) - strcpy( p_title,(char *)(*z_title)->value.str.val ); - - _zz_internal_log( "cups_print_file(server)", p_server ); - _zz_internal_log( "cups_print_file(printer)", p_printer ); - _zz_internal_log( "cups_print_file(filename)", p_filename ); - _zz_internal_log( "cups_print_file(title)", p_title ); - - /* - * Convert options array. - */ - convert_to_array_ex( z_options ); - param_ht = Z_ARRVAL_PP( z_options ); - count = zend_hash_num_elements( param_ht ); - options = emalloc(sizeof(zval **) * count); - - current = 0; - zend_hash_internal_pointer_reset(param_ht); - for (current=0; current < count; current++) - { - zend_hash_get_current_data(param_ht,(void **)&keydata); - switch(Z_TYPE_PP(keydata)) - { - case IS_STRING: - convert_to_string_ex(keydata); - strcpy(temp,(char *)(*keydata)->value.str.val ); - _zz_internal_log( "cups_print_file(option)", temp ); - options = _phpcups_parse_options( options, ¤t, - temp ); - break; - } - zend_hash_move_forward(param_ht); - } - break; - - default: WRONG_PARAM_COUNT; - } - - if (current > 0) - { - - bzero(temp,4096); - sprintf(temp,"(2) - P: %s F: %s T: %s C: %d", p_printer, p_filename, - p_title, current ); - _zz_internal_log( "cups_print_file", temp ); - ret_val = cupsPrintFile( p_printer,p_filename,p_title,current,options); - for (current=0; current < count; current++) - { - efree( options[current].name ); - efree( options[current].value ); - } - efree(options); - } - else - { - _zz_internal_log( "cups_print_file", "going to print"); - ret_val = cupsPrintFile( p_printer,p_filename,p_title,0,NULL ); - } - - RETURN_LONG(ret_val); + RETURN_STRING((char *)cupsLastErrorString(), 1); } -int _phpcups_get_printer_status(char *server, int port, char *name ); - -typedef struct printer_attrs_type -{ - char *name; - char *value; -} printer_attrs_t; - - - -int num_attrs = 0; -printer_attrs_t *printer_attrs = NULL; - -void free_attrs_list(void); -void _phpcups_free_attrs_list(void); - /* - * Function: cups_get_printer_attributes - * - * Date: 8 April 2002 - TDB - * - * Parameters: name - String - Name of destination. - * - * Returns: state - String - * - * Comments: - * + * 'zif_cups_print_file()' - Print a single file. */ -PHP_FUNCTION(cups_get_printer_attributes) -{ - zval **z_server, **z_port, **z_name; - - zval *new_object; - - char p_server[256], p_name[256]; - int p_port = 631; - int i, count; - - - /* - * Initialize return value. - */ - array_init(return_value); - - /* - * Get parameters ..... - */ - switch(ZEND_NUM_ARGS()) - { - // - // Destination name only, assume localhost - // - case 1: - if (zend_get_parameters_ex( 1, &z_name ) != SUCCESS) - { - WRONG_PARAM_COUNT; - } - strcpy( p_server,"localhost" ); - convert_to_string_ex( z_name ); - if ( (char *)(*z_name)->value.str.val != NULL ) - strcpy( p_name,(char *)(*z_name)->value.str.val ); - break; - - // - // Server and estination name only, assume port 631 - // - case 2: - if (zend_get_parameters_ex( 2, &z_server, &z_name ) != SUCCESS) - { - WRONG_PARAM_COUNT; - } - convert_to_string_ex( z_server); - if ((char *)(*z_server)->value.str.val != NULL) - strcpy( p_server,(char *)(*z_server)->value.str.val ); - convert_to_string_ex( z_name ); - if ( (char *)(*z_name)->value.str.val != NULL ) - strcpy( p_name,(char *)(*z_name)->value.str.val ); - break; - - // - // Server, destination name and port. - // - case 3: - if(zend_get_parameters_ex(3,&z_server,&z_port,&z_name) != SUCCESS) - { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(z_server); - if ((char *)(*z_server)->value.str.val != NULL) - strcpy( p_server,(char *)(*z_server)->value.str.val ); - convert_to_string_ex(z_name); - if ( (char *)(*z_name)->value.str.val != NULL ) - strcpy( p_name,(char *)(*z_name)->value.str.val ); - convert_to_string_ex(z_port); - if ( (char *)(*z_port)->value.str.val != NULL ) - p_port = atoi( (char *)(*z_name)->value.str.val ); - break; - - default: WRONG_PARAM_COUNT; - } - - printer_attrs = NULL; - count = _phpcups_get_printer_status( p_server, p_port, p_name ); - - /* - * Create an array of objects containing name / value pairs. - */ - for (i=0; i < count; i++) - { - if ((printer_attrs[i].name != NULL) && (printer_attrs[i].value != NULL)) - { - MAKE_STD_ZVAL(new_object); - if (object_init(new_object) == SUCCESS) - { - add_property_string(new_object,"name",printer_attrs[i].name, 1 ); - add_property_string(new_object,"value",printer_attrs[i].value, 1 ); - add_next_index_zval( return_value, new_object ); - } - } - } - _phpcups_free_attrs_list(); -} - - - - -void _phpcups_free_attrs_list(void) +PHP_FUNCTION(cups_print_file) { - int i; - - if (num_attrs < 1) - return; - - for ( i=0; i < num_attrs; i++ ) + char *dest; /* Destination */ + int dest_len; /* Length of destination */ + char *filename; /* Filename */ + int filename_len; /* Length of filename */ + char *title; /* Title */ + int title_len; /* Length of title */ + zval *optionsobj; /* Array of options */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + int id; /* Job ID */ + + + if (ZEND_NUM_ARGS() != 4 || + zend_parse_parameters(4, "sssa", &dest, &dest_len, + &filename, &filename_len, + &title, &title_len, &optionsobj)) { - if (printer_attrs[i].name != NULL) - efree(printer_attrs[i].name); - if (printer_attrs[i].value != NULL) - efree(printer_attrs[i].value ); + WRONG_PARAM_COUNT; } - efree(printer_attrs); - num_attrs = 0; -} + num_options = cups_convert_options(optionsobj, &options); + id = cupsPrintFile(dest, filename, title, num_options, options); + cupsFreeOptions(num_options, options); - - - -int _phpcups_update_attrs_list( char *name, char *value ) -{ - if (num_attrs < 1) - { - printer_attrs = (printer_attrs_t *)emalloc(sizeof(printer_attrs_t)); - printer_attrs->name = (char *)emalloc(strlen(name)+1); - printer_attrs->value = (char *)emalloc(strlen(value)+1); - strcpy( printer_attrs->name, name ); - strcpy( printer_attrs->value, value ); - num_attrs = 1; - } - else - { - printer_attrs = (printer_attrs_t *)erealloc(printer_attrs, - (num_attrs + 1) * sizeof(printer_attrs_t)); - - printer_attrs[num_attrs].name = (char *)emalloc(strlen(name)+1); - printer_attrs[num_attrs].value = (char *)emalloc(strlen(value)+1); - strcpy( printer_attrs[num_attrs].name, name ); - strcpy( printer_attrs[num_attrs].value, value ); - num_attrs++; - } - return(num_attrs); + RETURN_LONG(id); } +/* + * 'zif_cups_print_files()' - Print multiple files. + */ -int _phpcups_get_printer_status( char *server, int port, char *name ) +PHP_FUNCTION(cups_print_files) { - http_encryption_t encrypt = HTTP_ENCRYPT_IF_REQUESTED; - - ipp_t *request, /* IPP Request */ - *response; /* IPP Response */ - ipp_attribute_t *attr; /* Current attribute */ - cups_lang_t *language; /* Default language */ - - char printer_uri[1024]; - char temp[1024]; - static char *req_attrs[] = {"printer-state", "printer-state-reason" }; - int i; - FILE *fp; - - if (name == NULL) - { - last_error = IPP_INTERNAL_ERROR; - return (0); - } - - /* - * Try to connect to the server... - */ - - if ((cups_server = httpConnectEncrypt(server, port, encrypt)) == NULL) + char *dest; /* Destination */ + int dest_len; /* Length of destination */ + zval *filesobj; /* Files array */ + int num_files; /* Number of files */ + const char *files[1000]; /* Files */ + char *title; /* Title */ + int title_len; /* Length of title */ + zval *optionsobj; /* Array of options */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + HashTable *ht2; /* Option array hash table */ + Bucket *current; /* Current element in array */ + int id; /* Job ID */ + + + if (ZEND_NUM_ARGS() != 4 || + zend_parse_parameters(4, "sasa", &dest, &dest_len, &filesobj, + &title, &title_len, &optionsobj)) { - last_error = IPP_SERVICE_UNAVAILABLE; - return (0); + WRONG_PARAM_COUNT; } - /* - * Build a CUPS_GET_PRINTERS request, which requires the following - * attributes: - * - * attributes-charset - * attributes-natural-language - * requested-attributes - */ - - request = ippNew(); - - request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES; - request->request.op.request_id = 1; + ht2 = Z_ARRVAL_P(filesobj); + num_files = 0; - language = cupsLangDefault(); - - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, - "attributes-charset", NULL, cupsLangEncoding(language)); - - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, - "attributes-natural-language", NULL, language->language); - - sprintf(printer_uri, "ipp://localhost/printers/%-s", name ); - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, - "printer-uri", NULL, printer_uri ); - - /* - * Do the request and get back a response... - */ - - num_attrs = 0; - printer_attrs = NULL; - - if ((response = cupsDoRequest(cups_server, request, "/")) != NULL) + for (current = ht2->pListHead; current; current = current->pListNext) { - last_error = response->request.status.status_code; - - for (attr = response->attrs; attr != NULL; attr = attr->next) - { + files[num_files ++] = Z_STRVAL_P(((zval *)current->pDataPtr)); - if (attr->num_values < 1) - continue; - - if (attr->name != NULL && - strcasecmp(attr->name, "printer-state") == 0 && - attr->value_tag == IPP_TAG_ENUM) - { - strcpy( temp, "unknown" ); - switch( attr->values[0].integer ) - { - case 3: strcpy( temp, "idle" ); - break; - case 4: strcpy( temp, "processing" ); - break; - case 5: strcpy( temp, "stopped" ); - break; - default: continue; - } - _phpcups_update_attrs_list( attr->name, temp ); - } - else if (attr->name != NULL && - (attr->value_tag == IPP_TAG_TEXT || - attr->value_tag == IPP_TAG_URI || - attr->value_tag == IPP_TAG_KEYWORD || - attr->value_tag == IPP_TAG_STRING)) - { - for (i=0; i < attr->num_values; i++) - _phpcups_update_attrs_list(attr->name, attr->values[i].string.text ); - } - else if (attr->name != NULL && - (attr->value_tag == IPP_TAG_ENUM || - attr->value_tag == IPP_TAG_BOOLEAN || - attr->value_tag == IPP_TAG_INTEGER)) - { - for (i=0; i < attr->num_values; i++) - { - sprintf(temp,"%-d", attr->values[i].integer ); - _phpcups_update_attrs_list(attr->name, temp ); - } - } - else if (attr->name != NULL && - attr->value_tag == IPP_TAG_RESOLUTION) - { - for (i=0; i < attr->num_values; i++) - { - sprintf(temp,"%-dx%-dx%-d", - attr->values[i].resolution.xres, - attr->values[i].resolution.yres, - attr->values[i].resolution.units ); - _phpcups_update_attrs_list(attr->name, temp ); - } - } - else if (attr->name != NULL && - attr->value_tag == IPP_TAG_RANGE) - { - for (i=0; i < attr->num_values; i++) - { - sprintf(temp,"%d-%d", - attr->values[i].range.lower, - attr->values[i].range.upper ); - _phpcups_update_attrs_list(attr->name, temp ); - } - } - } - ippDelete(response); + if (num_files >= (int)(sizeof(files) / sizeof(files[0]))) + break; } - else - { - last_error = IPP_BAD_REQUEST; - return(0); - } - return (num_attrs); -} + num_options = cups_convert_options(optionsobj, &options); -void _zz_internal_log( char *func, char *line ) -{ - FILE *fp; + id = cupsPrintFiles(dest, num_files, files, title, num_options, options); - if ((fp = fopen("/var/log/cups/project.log","a")) == NULL) - return; + cupsFreeOptions(num_options, options); - fprintf(fp,"phpcups: %s - %s\n", func, line ); - fflush(fp); - fclose(fp); + RETURN_LONG(id); } - -/* - * End of "$Id: phpcups.c 4530 2005-06-01 20:15:51Z mike $". - */ - - /* + * End of "$Id: phpcups.c 5171 2006-02-25 08:44:43Z mike $". */ diff --git a/scripting/php/phpcups.h b/scripting/php/phpcups.h new file mode 100644 index 000000000..a318dad6f --- /dev/null +++ b/scripting/php/phpcups.h @@ -0,0 +1,79 @@ +/* + * "$Id: phpcups.h 5171 2006-02-25 08:44:43Z mike $" + * + * PHP module include file for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org/ + */ + +#ifndef PHPCUPS_H +# define PHPCUPS_H + +/* + * Include necessary headers... + */ + +# include +# include +# include +# include +# include +# include +# include +# include +# if defined(WIN32) || defined(__EMX__) +# include +# else +# include +# endif /* WIN32 || __EMX__ */ + + +/* + * Zend definitions... + */ + +extern zend_module_entry phpcups_module_entry; +# define phpext_phpcups_ptr &phpcups_module_entry + +# ifdef PHP_WIN32 +# define PHP_PHPCUPS_API __declspec(dllexport) +# else +# define PHP_PHPCUPS_API +# endif + +# ifdef ZTS +# include "TSRM.h" +# endif + +PHP_MINIT_FUNCTION(phpcups); + +PHP_FUNCTION(cups_cancel_job); +PHP_FUNCTION(cups_get_dests); +PHP_FUNCTION(cups_get_jobs); +PHP_FUNCTION(cups_last_error); +PHP_FUNCTION(cups_last_error_string); +PHP_FUNCTION(cups_print_file); +PHP_FUNCTION(cups_print_files); + +#endif /* !PHPCUPS_H */ + + +/* + * End of "$Id: phpcups.h 5171 2006-02-25 08:44:43Z mike $". + */ diff --git a/scripting/php/phpcups.php b/scripting/php/phpcups.php old mode 100644 new mode 100755 index 01ce6a8fc..0b5669327 --- a/scripting/php/phpcups.php +++ b/scripting/php/phpcups.php @@ -1,10 +1,11 @@ +#!/usr/bin/php -f \n"; +print("Functions available in the $module extension:\n"); -foreach($functions as $func) { - echo $func."
\n"; +foreach ($functions as $func) +{ + print("$func\n"); } -echo "
\n"; -$function = 'confirm_' . $module . '_compiled'; -if (extension_loaded($module)) { - $str = $function($module); -} else { - $str = "Module $module is not compiled into PHP"; -} -echo "$str\n"; +print("\n"); + +print("cups_get_dests:\n"); +print_r(cups_get_dests()); + +print("cups_get_jobs(\"\", 0, -1):\n"); +print_r(cups_get_jobs("", 0, -1)); + +print("cups_print_file(\"test\", \"../../test/testfile.jpg\", " + ."\"testfile.jpg\", ...):\n"); +print_r(cups_print_file("test", "../../test/testfile.jpg", "testfile.jpg", + array("scaling" => "100", + "page-label" => "testfile.jpg"))); + +print("cups_print_files(\"test\", array(\"../../test/testfile.jpg\", " + ."\"../../test/testfile.ps\"), \"testfiles\", ...):\n"); +print_r(cups_print_files("test", array("../../test/testfile.jpg", + "../../test/testfile.ps"), + "testfiles", + array("scaling" => "100", + "page-label" => "testfile.jpg"))); // // End of "$Id: phpcups.php 3603 2003-04-11 18:42:52Z mike $". diff --git a/systemv/cupsaddsmb.c b/systemv/cupsaddsmb.c index b1cad6572..4d0bdc15e 100644 --- a/systemv/cupsaddsmb.c +++ b/systemv/cupsaddsmb.c @@ -1,5 +1,5 @@ /* - * "$Id: cupsaddsmb.c 5023 2006-01-29 14:39:44Z mike $" + * "$Id: cupsaddsmb.c 5187 2006-02-26 20:36:03Z mike $" * * "cupsaddsmb" command for the Common UNIX Printing System (CUPS). * @@ -564,8 +564,8 @@ export_dest(const char *dest) /* I - Destination to export */ { _cupsLangPrintf(stderr, _("cupsaddsmb: No PPD file for printer \"%s\" - " - "skipping!\n"), - dest); + "%s\n"), + dest, cupsLastErrorString()); httpClose(http); return (0); } @@ -1026,5 +1026,5 @@ write_option(FILE *dstfp, /* I - PPD file */ /* - * End of "$Id: cupsaddsmb.c 5023 2006-01-29 14:39:44Z mike $". + * End of "$Id: cupsaddsmb.c 5187 2006-02-26 20:36:03Z mike $". */ diff --git a/systemv/cupstestppd.c b/systemv/cupstestppd.c index 09f45d5ae..96ad93d92 100644 --- a/systemv/cupstestppd.c +++ b/systemv/cupstestppd.c @@ -1,5 +1,5 @@ /* - * "$Id: cupstestppd.c 4990 2006-01-26 02:21:45Z mike $" + * "$Id: cupstestppd.c 5189 2006-02-27 01:45:57Z mike $" * * PPD test program for the Common UNIX Printing System (CUPS). * @@ -302,31 +302,55 @@ main(int argc, /* I - Number of command-line arguments */ attr->value) ppdversion = (int)(10 * atof(attr->value) + 0.5); - if (verbose > 0) + /* + * Look for default keywords with no matching option... + */ + + for (i = 0; i < ppd->num_attrs; i ++) { - /* - * Look for default keywords with no matching option... - */ + attr = ppd->attrs[i]; - for (i = 0; i < ppd->num_attrs; i ++) + if (!strcmp(attr->name, "DefaultColorSpace") || + !strcmp(attr->name, "DefaultFont") || + !strcmp(attr->name, "DefaultImageableArea") || + !strcmp(attr->name, "DefaultOutputOrder") || + !strcmp(attr->name, "DefaultPaperDimension") || + !strcmp(attr->name, "DefaultTransfer")) + continue; + + if (!strncmp(attr->name, "Default", 7)) { - attr = ppd->attrs[i]; - - if (!strcmp(attr->name, "DefaultColorSpace") || - !strcmp(attr->name, "DefaultFont") || - !strcmp(attr->name, "DefaultImageableArea") || - !strcmp(attr->name, "DefaultOutputOrder") || - !strcmp(attr->name, "DefaultPaperDimension") || - !strcmp(attr->name, "DefaultTransfer")) - continue; - - if (!strncmp(attr->name, "Default", 7) && - !ppdFindOption(ppd, attr->name + 7)) + if ((option = ppdFindOption(ppd, attr->name + 7)) == NULL) _cupsLangPrintf(stdout, _(" WARN %s has no corresponding " "options!\n"), attr->name); - } + else if (strcmp(attr->value, "Unknown")) + { + /* + * Check that the default option value matches a choice... + */ + + for (j = 0; j < option->num_choices; j ++) + if (!strcmp(option->choices[j].choice, attr->value)) + break; + + if (j >= option->num_choices) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** %s %s does not exist!\n"), + attr->name, attr->value); + } + + errors ++; + } + } + } } if ((attr = ppdFindAttr(ppd, "DefaultImageableArea", NULL)) == NULL) @@ -980,6 +1004,182 @@ main(int argc, /* I - Number of command-line arguments */ } } + if ((attr = ppdFindAttr(ppd, "cupsLanguages", NULL)) != NULL && + attr->value) + { + /* + * This file contains localizations, check them... + */ + + char *languages, /* Copy of attribute value */ + *langstart, /* Start of current language */ + *langptr, /* Pointer into languages */ + keyword[PPD_MAX_NAME]; /* Localization keyword */ + + + languages = strdup(attr->value); + for (langptr = languages; *langptr;) + { + /* + * Skip leading whitespace... + */ + + while (isspace(*langptr & 255)) + langptr ++; + + if (!*langptr) + break; + + /* + * Find the end of this language name... + */ + + for (langstart = langptr; + *langptr && !isspace(*langptr & 255); + langptr ++); + + if (*langptr) + *langptr++ = '\0'; + + j = strlen(langstart); + if (j != 2 && j != 5) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** Bad language \"%s\"!\n"), + langstart); + } + + errors ++; + continue; + } + + /* + * Loop through all options and choices... + */ + + for (option = ppdFirstOption(ppd); + option; + option = ppdNextOption(ppd)) + { + snprintf(keyword, sizeof(keyword), "%s.Translation", langstart); + if (!ppdFindAttr(ppd, keyword, option->keyword)) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** Missing \"%s\" translation " + "string for option %s!\n"), + langstart, option->keyword); + } + + errors ++; + } + + for (ptr = option->text; *ptr; ptr ++) + if (*ptr & 128) + break; + + if (*ptr) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** Default translation " + "string for option %s contains 8-bit " + "characters!\n"), + option->keyword); + } + + errors ++; + } + + snprintf(keyword, sizeof(keyword), "%s.%s", langstart, + option->keyword); + for (j = 0; j < option->num_choices; j ++) + { + if (!ppdFindAttr(ppd, keyword, option->choices[j].choice)) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** Missing \"%s\" " + "translation string for option %s, " + "choice %s!\n"), + langstart, option->keyword, + option->choices[j].choice); + } + + errors ++; + } + + for (ptr = option->choices[j].text; *ptr; ptr ++) + if (*ptr & 128) + break; + + if (*ptr) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** Default translation " + "string for option %s choice %s contains " + "8-bit characters!\n"), + option->keyword, + option->choices[j].choice); + } + + errors ++; + } + } + } + } + } + + for (attr = ppdFindAttr(ppd, "cupsFilter", NULL); + attr; + attr = ppdFindNextAttr(ppd, "cupsFilter", NULL)) + { + char super[16], /* Filter super type */ + type[256], /* Filter type */ + program[256]; /* Filter program */ + int cost; /* Filter cost */ + + + if (!attr->value || + sscanf(attr->value, "%15[^/]/%255s%d%255s", super, type, &cost, + program) != 4) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** Bad cupsFilter value \"%s\"!\n"), + attr->value ? attr->value : ""); + } + + errors ++; + } + } + if (errors) status = ERROR_CONFORMANCE; else if (!verbose) @@ -1487,5 +1687,5 @@ usage(void) /* - * End of "$Id: cupstestppd.c 4990 2006-01-26 02:21:45Z mike $". + * End of "$Id: cupstestppd.c 5189 2006-02-27 01:45:57Z mike $". */ diff --git a/systemv/lpadmin.c b/systemv/lpadmin.c index 2cfe32819..35498d904 100644 --- a/systemv/lpadmin.c +++ b/systemv/lpadmin.c @@ -1,5 +1,5 @@ /* - * "$Id: lpadmin.c 5023 2006-01-29 14:39:44Z mike $" + * "$Id: lpadmin.c 5154 2006-02-23 01:36:15Z mike $" * * "lpadmin" command for the Common UNIX Printing System (CUPS). * @@ -1714,8 +1714,10 @@ set_printer_options( *response; /* IPP Response */ ipp_attribute_t *attr; /* IPP attribute */ ipp_op_t op; /* Operation to perform */ - const char *val, /* Option value */ - *ppdfile; /* PPD filename */ + const char *ppdfile; /* PPD filename */ + int ppdchanged; /* PPD changed? */ + ppd_file_t *ppd; /* PPD file */ + ppd_choice_t *choice; /* Marked choice */ char uri[HTTP_MAX_URI], /* URI for printer/class */ line[1024], /* Line from PPD file */ keyword[1024], /* Keyword from Default line */ @@ -1724,7 +1726,7 @@ set_printer_options( FILE *in, /* PPD file */ *out; /* Temporary file */ int outfd; /* Temporary file descriptor */ - const char *protocol; /* Protocol */ + const char *protocol; /* Old protocol option */ DEBUG_printf(("set_printer_options(%p, \"%s\", %d, %p)\n", http, printer, @@ -1763,7 +1765,8 @@ set_printer_options( * See what kind of printer or class it is... */ - if ((attr = ippFindAttribute(response, "printer-type", IPP_TAG_ENUM)) != NULL) + if ((attr = ippFindAttribute(response, "printer-type", + IPP_TAG_ENUM)) != NULL) { if (attr->values[0].integer & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)) { @@ -1795,7 +1798,17 @@ set_printer_options( * Add the options... */ - cupsEncodeOptions(request, num_options, options); + cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER); + + if ((protocol = cupsGetOption("protocol", num_options, options)) != NULL) + { + if (!strcasecmp(protocol, "bcp")) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "port-monitor", + NULL, "bcp"); + else if (!strcasecmp(protocol, "tbcp")) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "port-monitor", + NULL, "tbcp"); + } if (op == CUPS_ADD_PRINTER) ppdfile = cupsGetPPD(printer); @@ -1808,6 +1821,10 @@ set_printer_options( * Set default options in the PPD file... */ + ppd = ppdOpenFile(ppdfile); + ppdMarkDefaults(ppd); + cupsMarkOptions(ppd, num_options, options); + if ((outfd = cupsTempFd(tempfile, sizeof(tempfile))) < 0) { _cupsLangPrintf(stderr, @@ -1830,20 +1847,12 @@ set_printer_options( return (1); } - out = fdopen(outfd, "wb"); - protocol = cupsGetOption("protocol", num_options, options); + out = fdopen(outfd, "wb"); + ppdchanged = 0; while (get_line(line, sizeof(line), in) != NULL) { - if (!strncmp(line, "*cupsProtocol:", 14) && protocol) - { - /* - * Set a new output protocol (BCP or TBCP) below... - */ - - continue; - } - else if (strncmp(line, "*Default", 8)) + if (strncmp(line, "*Default", 8)) fprintf(out, "%s\n", line); else { @@ -1857,32 +1866,42 @@ set_printer_options( if (*keyptr == ':' || isspace(*keyptr & 255)) break; - *keyptr = '\0'; - - if (!strcmp(keyword, "PageRegion")) - val = cupsGetOption("PageSize", num_options, options); + *keyptr++ = '\0'; + while (isspace(*keyptr & 255)) + keyptr ++; + + if (!strcmp(keyword, "PageRegion") || + !strcmp(keyword, "PageSize") || + !strcmp(keyword, "PaperDimension") || + !strcmp(keyword, "ImageableArea")) + { + if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) == NULL) + choice = ppdFindMarkedChoice(ppd, "PageRegion"); + } else - val = cupsGetOption(keyword, num_options, options); + choice = ppdFindMarkedChoice(ppd, keyword); - if (val != NULL) - fprintf(out, "*Default%s: %s\n", keyword, val); + if (choice && strcmp(choice->choice, keyptr)) + { + fprintf(out, "*Default%s: %s\n", keyword, choice->choice); + ppdchanged = 1; + } else fprintf(out, "%s\n", line); } } - if (protocol) - fprintf(out, "*cupsProtocol: \"%s\"\n", protocol); - fclose(in); fclose(out); close(outfd); + ppdClose(ppd); /* * Do the request... */ - response = cupsDoFileRequest(http, request, "/admin/", tempfile); + ippDelete(cupsDoFileRequest(http, request, "/admin/", + ppdchanged ? tempfile : NULL)); /* * Clean up temp files... (TODO: catch signals in case we CTRL-C during @@ -1898,14 +1917,13 @@ set_printer_options( * No PPD file - just set the options... */ - response = cupsDoRequest(http, request, "/admin/"); + ippDelete(cupsDoRequest(http, request, "/admin/")); } /* * Check the response... */ - ippDelete(response); if (cupsLastError() > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); @@ -1947,5 +1965,5 @@ validate_name(const char *name) /* I - Name to check */ /* - * End of "$Id: lpadmin.c 5023 2006-01-29 14:39:44Z mike $". + * End of "$Id: lpadmin.c 5154 2006-02-23 01:36:15Z mike $". */ diff --git a/systemv/lpstat.c b/systemv/lpstat.c index b0aaa43f3..fd58f2774 100644 --- a/systemv/lpstat.c +++ b/systemv/lpstat.c @@ -1,5 +1,5 @@ /* - * "$Id: lpstat.c 5023 2006-01-29 14:39:44Z mike $" + * "$Id: lpstat.c 5199 2006-02-27 22:01:02Z mike $" * * "lpstat" command for the Common UNIX Printing System (CUPS). * @@ -2070,7 +2070,7 @@ show_printers(http_t *http, /* I - HTTP connection to server */ } _cupsLangPuts(stdout, _("\tOn fault: no alert\n")); _cupsLangPuts(stdout, _("\tAfter fault: continue\n")); - // TODO update to use printer-error-policy + /* TODO update to use printer-error-policy */ if (allowed) { _cupsLangPuts(stdout, _("\tUsers allowed:\n")); @@ -2183,7 +2183,7 @@ show_printers(http_t *http, /* I - HTTP connection to server */ } _cupsLangPuts(stdout, _("\tOn fault: no alert\n")); _cupsLangPuts(stdout, _("\tAfter fault: continue\n")); - // TODO update to use printer-error-policy + /* TODO update to use printer-error-policy */ if (allowed) { _cupsLangPuts(stdout, _("\tUsers allowed:\n")); @@ -2246,5 +2246,5 @@ show_scheduler(http_t *http) /* I - HTTP connection to server */ /* - * End of "$Id: lpstat.c 5023 2006-01-29 14:39:44Z mike $". + * End of "$Id: lpstat.c 5199 2006-02-27 22:01:02Z mike $". */ diff --git a/templates/Makefile b/templates/Makefile index 182023329..1dcfcb2bf 100644 --- a/templates/Makefile +++ b/templates/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile 5110 2006-02-15 21:42:46Z mike $" +# "$Id: Makefile 5156 2006-02-23 04:24:32Z mike $" # # Template makefile for the Common UNIX Printing System (CUPS). # @@ -58,6 +58,7 @@ FILES = \ job-restart.tmpl \ jobs.tmpl \ jobs-header.tmpl \ + maintenance.tmpl \ modify-class.tmpl \ modify-printer.tmpl \ option-boolean.tmpl \ @@ -126,5 +127,5 @@ install: all # -# End of "$Id: Makefile 5110 2006-02-15 21:42:46Z mike $". +# End of "$Id: Makefile 5156 2006-02-23 04:24:32Z mike $". # diff --git a/templates/maintenance.tmpl b/templates/maintenance.tmpl new file mode 100644 index 000000000..ab57fb108 --- /dev/null +++ b/templates/maintenance.tmpl @@ -0,0 +1,2 @@ +

Maintenance commands sent; job ID is +{printer_name}-{job_id}.

diff --git a/templates/printers.tmpl b/templates/printers.tmpl index e3ee1aa87..da2824457 100644 --- a/templates/printers.tmpl +++ b/templates/printers.tmpl @@ -1,4 +1,4 @@ -{#printer_name=0?: +{printer_type?:}{#printer_name=0?: {[printer_name]

{printer_name}{default_name={printer_name}? (Default Printer):} {?printer_state_message=?:"{printer_state_message}"}

@@ -18,6 +18,10 @@

Print Test Page +{?cupscommand=1? +Clean Print Heads + +Print Self Test Page:} {printer_state=5? Start Printer diff --git a/templates/test-page.tmpl b/templates/test-page.tmpl index bbca2dcc9..bf49994af 100644 --- a/templates/test-page.tmpl +++ b/templates/test-page.tmpl @@ -1,2 +1,2 @@

Test page sent; job ID is -{printer_name}-{job_id}. +{printer_name}-{job_id}.

diff --git a/tools/makesrcdist b/tools/makesrcdist index fdd0516ef..ff961efd7 100755 --- a/tools/makesrcdist +++ b/tools/makesrcdist @@ -43,7 +43,7 @@ svn export $url /tmp/cups-$version echo Updating version information... cd /tmp/cups-$version/config-scripts -sed -e '1,$s/^CUPS_VERSION=.*/CUPS_VERSION='$fileversion'/' \ +sed -e '1,$s/^CUPS_VERSION=.*/CUPS_VERSION='$version'/' \ -e '1,$s/^CUPS_REVISION=.*/CUPS_REVISION='$revision'/' \ cups-common.m4.new mv cups-common.m4.new cups-common.m4 -- 2.39.2