From 7594b2247beeb33717701f1c58d243995d7ab81a Mon Sep 17 00:00:00 2001 From: jlovell Date: Tue, 20 Mar 2007 18:25:41 +0000 Subject: [PATCH] Load cups into easysw/current. git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@289 a1ca3aef-8c08-0410-bb20-df032aa958be --- CHANGES-1.2.txt | 55 ++++++ CHANGES.txt | 6 +- CREDITS.txt | 2 +- backend/ipp.c | 20 ++- backend/usb-darwin.c | 114 ++++++------ berkeley/lpr.c | 8 +- cgi-bin/admin.c | 46 +++-- cgi-bin/cgi-private.h | 6 +- config-scripts/cups-common.m4 | 10 +- config-scripts/cups-directories.m4 | 6 +- config-scripts/cups-network.m4 | 7 +- config.h.in | 12 +- cups/adminutil.c | 61 +++++-- cups/encode.c | 6 +- cups/localize.c | 19 +- cups/request.c | 17 +- cups/string.c | 8 +- cups/testlang.c | 42 ++++- doc/help/translation.html | 34 ++-- fonts/Vera.ttf | Bin 0 -> 65932 bytes init/cups.sh.in | 6 +- init/org.cups.cupsd.plist | 10 +- pdftops/Catalog.cxx | 20 ++- pdftops/Catalog.h | 2 +- scheduler/auth.c | 10 +- scheduler/auth.h | 6 +- scheduler/client.c | 8 +- scheduler/conf.c | 22 ++- scheduler/conf.h | 11 +- scheduler/cups-driverd.c | 6 +- scheduler/cupsd.h | 14 +- scheduler/dirsvc.c | 33 +++- scheduler/ipp.c | 226 ++++++++++++++++++++++-- scheduler/job.c | 27 ++- scheduler/main.c | 27 ++- scheduler/printers.c | 27 ++- scheduler/quotas.c | 19 +- systemv/lp.c | 8 +- systemv/lpoptions.c | 16 +- templates/admin.tmpl | 1 + templates/de/admin.tmpl | 1 + templates/es/admin.tmpl | 1 + templates/et/admin.tmpl | 1 + templates/fr/admin.tmpl | 1 + templates/it/admin.tmpl | 1 + templates/ja/admin.tmpl | 1 + templates/pl/admin.tmpl | 1 + templates/sv/admin.tmpl | 1 + tools/buttons.gif | Bin 0 -> 35 bytes tools/buttons.txt | 54 ++++++ tools/makebuttons | 268 +++++++++++++++++++++++++++++ 51 files changed, 1110 insertions(+), 198 deletions(-) create mode 100644 fonts/Vera.ttf create mode 100644 tools/buttons.gif create mode 100644 tools/buttons.txt create mode 100755 tools/makebuttons diff --git a/CHANGES-1.2.txt b/CHANGES-1.2.txt index 8c0c5f145..d1fe1e763 100644 --- a/CHANGES-1.2.txt +++ b/CHANGES-1.2.txt @@ -1,6 +1,61 @@ CHANGES-1.2.txt --------------- +CHANGES IN CUPS V1.2.10 + + - ppdLocalize() now supports localizing for Japanese + using the "jp" locale name used by the ppdmerge + program from the CUPS DDK 1.1.0 (STR #2301) + - _cupsAdminSetServerSettings() did not support changing + of top-level directives as designed. + - The init script path check was broken. + - CUPS incorrectly used the attribute "notify-recipient" + instead of "notify-recicpient-uri" in several places + (STR #2297) + - Fixed a configure script bug on MirBSD (STR #2294) + - The pdftops filter did not limit the amount of recursion + of page sets (STR #2293) + - Custom page sizes with fractional point sizes did not + work (STR #2296) + - The lpoptions command would crash when adding or removing + options on a system with no printers (STR #2295) + + +CHANGES IN CUPS V1.2.9 + + - The scheduler did not use the default job-sheets + (banners) for implicit classes (STR #2284) + - The scheduler could crash when listing complete jobs + that had been unloaded from memory (STR #2288) + - The French localization was doubled up (STR #2287) + - Build system fixes for several platforms (STR #2260, + STR #2275) + - The scheduler's openssl certificate generation code was + broken on some platforms (STR #2282) + - The scheduler's log rotation check for devices was + broken (STR #2278) + - The LPD mini-daemon did not handle the document-format + option correctly (STR #2266) + - The pdftops filter ignored the "match" size option in the + pdftops.conf file (STR #2285) + - cupstestppd now validates UTF-8 text strings in + globalized PPD files (STR #2283) + - The outputorder=reverse option did not work with all + printers (STR #2279) + - Classes containing other classes did not always work + (STR #2255) + - Printer location and description information was lost + if the corresponding string contained the "#" character + (STR #2254) + - cupsRemoveOption() did not work properly (STR #2264) + - The USB backend did not work with some USB to parallel + cables on Mac OS X. + - The test page did not print the rulers properly on + large media sizes (STR #2252) + - The text filter could crash when pretty printing certain + types of files (STR #2158) + + CHANGES IN CUPS V1.2.8 - Documentation fixes (STR #2141, STR #2157) diff --git a/CHANGES.txt b/CHANGES.txt index f5e4af6d3..852ce9c4b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,9 +1,13 @@ -CHANGES.txt - 2007-02-19 +CHANGES.txt - 2007-03-19 ------------------------ CHANGES IN CUPS V1.3 - Documentation updates (STR #2130, STR #2131) + - Added new public cupsAdminGetServerSettings() and + cupsAdminSetServerSettings() APIs. + - Added new "makebuttons" script in the "tools" directory + for creating web interface buttons (STR #2231) - Added support for DNS-SD (aka "Bonjour") printer sharing (STR #1171) - Job operations (cancel, hold, release, etc.) from the diff --git a/CREDITS.txt b/CREDITS.txt index c839ba1e4..221ebb6ac 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -6,7 +6,7 @@ like to thank the following individuals for their contributions: Nathaniel Barbour - Lots of testing and feedback. N. Becker - setsid(). - Philippe Combes - French localization. + Philippe Combes - French localization and buttons script. Jean-Eric Cuendet - GhostScript filters for CUPS. Van Dang - HTTP and IPP policeman. L. Peter Deutsch - MD5 code. diff --git a/backend/ipp.c b/backend/ipp.c index c7d647d14..3cc342f2c 100644 --- a/backend/ipp.c +++ b/backend/ipp.c @@ -1,9 +1,9 @@ /* - * "$Id: ipp.c 6318 2007-03-06 04:36:55Z mike $" + * "$Id: ipp.c 6365 2007-03-19 20:56:57Z mike $" * * IPP backend for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 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 @@ -521,6 +521,9 @@ main(int argc, /* I - Number of command-line args */ if ((http = httpConnectEncrypt(hostname, port, cupsEncryption())) == NULL) { + if (job_cancelled) + break; + if (getenv("CLASS") != NULL) { /* @@ -567,10 +570,21 @@ main(int argc, /* I - Number of command-line args */ perror("ERROR: Unable to connect to IPP host"); sleep(30); } + + if (job_cancelled) + break; } } while (http == NULL); + if (job_cancelled) + { + if (argc == 6 || strcmp(filename, argv[6])) + unlink(filename); + + return (CUPS_BACKEND_FAILED); + } + fputs("STATE: -connecting-to-device\n", stderr); fprintf(stderr, "INFO: Connected to %s...\n", hostname); @@ -1667,5 +1681,5 @@ sigterm_handler(int sig) /* I - Signal */ /* - * End of "$Id: ipp.c 6318 2007-03-06 04:36:55Z mike $". + * End of "$Id: ipp.c 6365 2007-03-19 20:56:57Z mike $". */ diff --git a/backend/usb-darwin.c b/backend/usb-darwin.c index 4e0697752..aefbc95cd 100644 --- a/backend/usb-darwin.c +++ b/backend/usb-darwin.c @@ -1,7 +1,7 @@ /* - * "$Id: usb-darwin.c 6302 2007-02-22 19:36:36Z mike $" + * "$Id: usb-darwin.c 6365 2007-03-19 20:56:57Z mike $" * - * © Copyright 2005-2006 Apple Computer, Inc. All rights reserved. + * Copyright © 2005-2007 Apple Inc. All rights reserved. * * IMPORTANT: This Apple software is supplied to you by Apple Computer, * Inc. ("Apple") in consideration of your agreement to the following @@ -185,6 +185,8 @@ typedef struct printer_data_s { /**** Printer context data ****/ UInt32 location; Boolean waitEOF; + + CFRunLoopTimerRef statusTimer; pthread_cond_t reqWaitCompCond; pthread_mutex_t reqWaitMutex; @@ -206,6 +208,7 @@ typedef struct printer_data_s { /**** Printer context data ****/ static Boolean list_device_callback(void *refcon, io_service_t obj); static Boolean find_device_callback(void *refcon, io_service_t obj); +static void statusTimerCallback(CFRunLoopTimerRef timer, void *info); static void iterate_printers(iterator_callback_t callBack, void *userdata); static void device_added(void *userdata, io_iterator_t iterator); static void copy_deviceinfo(CFStringRef deviceIDString, CFStringRef *make, CFStringRef *model, CFStringRef *serial); @@ -637,11 +640,11 @@ static Boolean list_device_callback(void *refcon, io_service_t obj) static Boolean find_device_callback(void *refcon, io_service_t obj) { Boolean keepLooking = true; + printer_data_t *userData = (printer_data_t *)refcon; - if (obj != 0x0 && refcon != NULL) { + if (obj != 0x0) { CFStringRef idString = NULL; UInt32 location = -1; - printer_data_t *userData = (printer_data_t *)refcon; copy_devicestring(obj, &idString, &location); if (idString != NULL) { @@ -676,12 +679,33 @@ static Boolean find_device_callback(void *refcon, io_service_t obj) } } else { - keepLooking = (refcon != NULL && ((printer_data_t *)refcon)->printerObj == 0); + keepLooking = (userData->printerObj == 0); + if (obj == 0x0 && keepLooking) { + CFRunLoopTimerContext context = { 0, userData, NULL, NULL, NULL }; + CFRunLoopTimerRef timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() + 1.0, 10, 0x0, 0x0, statusTimerCallback, &context); + if (timer != NULL) { + CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode); + userData->statusTimer = timer; + } + } + } + + if (!keepLooking && userData->statusTimer != NULL) { + fputs("STATE: -offline-error\n", stderr); + fputs("INFO: Printer is now on-line.\n", stderr); + CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), userData->statusTimer, kCFRunLoopDefaultMode); + CFRelease(userData->statusTimer); + userData->statusTimer = NULL; } return keepLooking; } +static void statusTimerCallback (CFRunLoopTimerRef timer, void *info) +{ + fputs("STATE: +offline-error\n", stderr); + fputs("INFO: Printer is currently off-line.\n", stderr); +} #pragma mark - /* @@ -877,23 +901,20 @@ static kern_return_t unload_classdriver(classdriver_context_t ***classDriver) static kern_return_t load_printerdriver(printer_data_t *printer, CFStringRef *driverBundlePath) { - IOCFPlugInInterface **iodev = NULL; - SInt32 score; + IOCFPlugInInterface **iodev = NULL; + SInt32 score; + kern_return_t kr; + printer_interface_t intf; + HRESULT res; + + kr = IOCreatePlugInInterfaceForService(printer->printerObj, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score); + if (kr == kIOReturnSuccess) + { + if ((res = (*iodev)->QueryInterface(iodev, USB_INTERFACE_KIND, (LPVOID *) &intf)) == noErr) + { + *driverBundlePath = IORegistryEntryCreateCFProperty(printer->printerObj, kUSBClassDriverProperty, NULL, kNilOptions); - kern_return_t kr = IOCreatePlugInInterfaceForService(printer->printerObj, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score); - if (kr == kIOReturnSuccess) { - printer_interface_t intf; - HRESULT res = (*iodev)->QueryInterface(iodev, USB_INTERFACE_KIND, (LPVOID *) &intf); - if (res == noErr) { - CFMutableDictionaryRef properties = NULL; - - kr = IORegistryEntryCreateCFProperties(printer->printerObj, &properties, NULL, kNilOptions); - if (kr == kIOReturnSuccess) { - if (properties != NULL) { - *driverBundlePath = (CFStringRef) CFDictionaryGetValue(properties, kUSBClassDriverProperty); - } - kr = load_classdriver(*driverBundlePath, intf, &printer->printerDriver); - } + kr = load_classdriver(*driverBundlePath, intf, &printer->printerDriver); if (kr != kIOReturnSuccess) (*intf)->Release(intf); @@ -1034,40 +1055,37 @@ static OSStatus copy_deviceid(classdriver_context_t **printer, CFStringRef *devi static void copy_devicestring(io_service_t usbInterface, CFStringRef *deviceID, UInt32 *deviceLocation) { - IOCFPlugInInterface **iodev = NULL; - SInt32 score; - - kern_return_t kr = IOCreatePlugInInterfaceForService(usbInterface, kIOUSBInterfaceUserClientTypeID, + IOCFPlugInInterface **iodev = NULL; + SInt32 score; + kern_return_t kr; + printer_interface_t intf; + HRESULT res; + classdriver_context_t **klassDriver = NULL; + CFStringRef driverBundlePath; + + kr = IOCreatePlugInInterfaceForService(usbInterface, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score); - if (kr == kIOReturnSuccess) { - printer_interface_t intf; - - HRESULT res = (*iodev)->QueryInterface(iodev, USB_INTERFACE_KIND, (LPVOID *) &intf); - if (res == noErr) { + if (kr == kIOReturnSuccess) + { + if ((res = (*iodev)->QueryInterface(iodev, USB_INTERFACE_KIND, (LPVOID *) &intf)) == noErr) + { /* ignore the result for location id... */ (void)(*intf)->GetLocationID(intf, deviceLocation); - CFMutableDictionaryRef properties = NULL; - kr = IORegistryEntryCreateCFProperties(usbInterface, &properties, NULL, kNilOptions); - if (kIOReturnSuccess == kr) { - classdriver_context_t **klassDriver = NULL; - CFStringRef driverBundlePath = NULL; + driverBundlePath = IORegistryEntryCreateCFProperty( usbInterface, kUSBClassDriverProperty, NULL, kNilOptions ); - if (properties != NULL) { - driverBundlePath = (CFStringRef) CFDictionaryGetValue(properties, kUSBClassDriverProperty); - } + kr = load_classdriver(driverBundlePath, intf, &klassDriver); - kr = load_classdriver(driverBundlePath, intf, &klassDriver); - if (kr != kIOReturnSuccess && driverBundlePath != NULL) - kr = load_classdriver(NULL, intf, &klassDriver); - if (kr == kIOReturnSuccess && klassDriver != NULL) { + if (kr != kIOReturnSuccess && driverBundlePath != NULL) + kr = load_classdriver(NULL, intf, &klassDriver); + + if (kr == kIOReturnSuccess && klassDriver != NULL) kr = copy_deviceid(klassDriver, deviceID); - } - unload_classdriver(&klassDriver); - if (properties != NULL) - CFRelease(properties); - } + unload_classdriver(&klassDriver); + + if (driverBundlePath != NULL) + CFRelease(driverBundlePath); /* (*intf)->Release(intf); */ } @@ -1710,5 +1728,5 @@ static void usbGetDevState(printer_data_t *userData, cups_sc_status_t *status, c } /* - * End of "$Id: usb-darwin.c 6302 2007-02-22 19:36:36Z mike $". + * End of "$Id: usb-darwin.c 6365 2007-03-19 20:56:57Z mike $". */ diff --git a/berkeley/lpr.c b/berkeley/lpr.c index 893c62bf3..c4bf045b9 100644 --- a/berkeley/lpr.c +++ b/berkeley/lpr.c @@ -1,9 +1,9 @@ /* - * "$Id: lpr.c 5925 2006-09-05 19:43:11Z mike $" + * "$Id: lpr.c 6356 2007-03-19 13:54:48Z mike $" * * "lpr" command for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products. + * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -232,7 +232,7 @@ main(int argc, /* I - Number of command-line arguments */ snprintf(email, sizeof(email), "mailto:%s@%s", cupsUser(), httpGetHostname(NULL, buffer, sizeof(buffer))); - num_options = cupsAddOption("notify-recipient", email, + num_options = cupsAddOption("notify-recipient-uri", email, num_options, &options); } break; @@ -529,5 +529,5 @@ sighandler(int s) /* I - Signal number */ /* - * End of "$Id: lpr.c 5925 2006-09-05 19:43:11Z mike $". + * End of "$Id: lpr.c 6356 2007-03-19 13:54:48Z mike $". */ diff --git a/cgi-bin/admin.c b/cgi-bin/admin.c index de4bcd112..dd8e25f98 100644 --- a/cgi-bin/admin.c +++ b/cgi-bin/admin.c @@ -1,5 +1,5 @@ /* - * "$Id: admin.c 6304 2007-02-22 22:06:23Z mike $" + * "$Id: admin.c 6361 2007-03-19 16:01:28Z mike $" * * Administration CGI for the Common UNIX Printing System (CUPS). * @@ -360,8 +360,8 @@ do_add_rss_subscription(http_t *http) /* I - HTTP connection */ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); - ippAddString(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, "notify-recipient", - NULL, rss_uri); + ippAddString(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, + "notify-recipient-uri", NULL, rss_uri); ippAddStrings(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, "notify-events", num_events, NULL, events); ippAddInteger(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, @@ -1834,6 +1834,10 @@ do_config_server(http_t *http) /* I - HTTP connection */ *remote_printers, /* REMOTE_PRINTERS value */ *share_printers,/* SHARE_PRINTERS value */ +#ifdef HAVE_GSSAPI + *default_auth_type, + /* DefaultAuthType value */ +#endif /* HAVE_GSSAPI */ *user_cancel_any; /* USER_CANCEL_ANY value */ @@ -1842,12 +1846,17 @@ do_config_server(http_t *http) /* I - HTTP connection */ * Get the checkbox values from the form... */ - debug_logging = cgiGetVariable("DEBUG_LOGGING") ? "1" : "0"; - remote_admin = cgiGetVariable("REMOTE_ADMIN") ? "1" : "0"; - remote_any = cgiGetVariable("REMOTE_ANY") ? "1" : "0"; - remote_printers = cgiGetVariable("REMOTE_PRINTERS") ? "1" : "0"; - share_printers = cgiGetVariable("SHARE_PRINTERS") ? "1" : "0"; - user_cancel_any = cgiGetVariable("USER_CANCEL_ANY") ? "1" : "0"; + debug_logging = cgiGetVariable("DEBUG_LOGGING") ? "1" : "0"; + remote_admin = cgiGetVariable("REMOTE_ADMIN") ? "1" : "0"; + remote_any = cgiGetVariable("REMOTE_ANY") ? "1" : "0"; + remote_printers = cgiGetVariable("REMOTE_PRINTERS") ? "1" : "0"; + share_printers = cgiGetVariable("SHARE_PRINTERS") ? "1" : "0"; + user_cancel_any = cgiGetVariable("USER_CANCEL_ANY") ? "1" : "0"; +#ifdef HAVE_GSSAPI + default_auth_type = cgiGetVariable("KERBEROS") ? "Negotiate" : "Basic"; + + fprintf(stderr, "DEBUG: DefaultAuthType %s\n", default_auth_type); +#endif /* HAVE_GSSAPI */ /* * Get the current server settings... @@ -1878,6 +1887,11 @@ do_config_server(http_t *http) /* I - HTTP connection */ num_settings, settings)) || strcmp(share_printers, cupsGetOption(CUPS_SERVER_SHARE_PRINTERS, num_settings, settings)) || +#ifdef HAVE_GSSAPI + !cupsGetOption("DefaultAuthType", num_settings, settings) || + strcmp(default_auth_type, cupsGetOption("DefaultAuthType", + num_settings, settings)) || +#endif /* HAVE_GSSAPI */ strcmp(user_cancel_any, cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY, num_settings, settings))) { @@ -1900,6 +1914,10 @@ do_config_server(http_t *http) /* I - HTTP connection */ share_printers, num_settings, &settings); num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY, user_cancel_any, num_settings, &settings); +#ifdef HAVE_GSSAPI + num_settings = cupsAddOption("DefaultAuthType", default_auth_type, + num_settings, &settings); +#endif /* HAVE_GSSAPI */ if (!_cupsAdminSetServerSettings(http, num_settings, settings)) { @@ -2473,6 +2491,14 @@ do_menu(http_t *http) /* I - HTTP connection */ settings)) != NULL && atoi(val)) cgiSetVariable("USER_CANCEL_ANY", "CHECKED"); +#ifdef HAVE_GSSAPI + cgiSetVariable("HAVE_GSSAPI", "1"); + + if ((val = cupsGetOption("DefaultAuthType", num_settings, + settings)) != NULL && !strcasecmp(val, "Negotiate")) + cgiSetVariable("KERBEROS", "CHECKED"); +#endif /* HAVE_GSSAPI */ + cupsFreeOptions(num_settings, settings); /* @@ -3225,5 +3251,5 @@ match_string(const char *a, /* I - First string */ /* - * End of "$Id: admin.c 6304 2007-02-22 22:06:23Z mike $". + * End of "$Id: admin.c 6361 2007-03-19 16:01:28Z mike $". */ diff --git a/cgi-bin/cgi-private.h b/cgi-bin/cgi-private.h index b2af6d715..f50a7aabe 100644 --- a/cgi-bin/cgi-private.h +++ b/cgi-bin/cgi-private.h @@ -1,9 +1,9 @@ /* - * "$Id: cgi-private.h 4921 2006-01-12 21:26:26Z mike $" + * "$Id: cgi-private.h 6361 2007-03-19 16:01:28Z mike $" * * Private CGI definitions 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 @@ -40,5 +40,5 @@ /* - * End of "$Id: cgi-private.h 4921 2006-01-12 21:26:26Z mike $". + * End of "$Id: cgi-private.h 6361 2007-03-19 16:01:28Z mike $". */ diff --git a/config-scripts/cups-common.m4 b/config-scripts/cups-common.m4 index 03a348031..765c5109d 100644 --- a/config-scripts/cups-common.m4 +++ b/config-scripts/cups-common.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-common.m4 6304 2007-02-22 22:06:23Z mike $" +dnl "$Id: cups-common.m4 6370 2007-03-20 14:36:12Z mike $" dnl dnl Common configuration stuff for the Common UNIX Printing System (CUPS). dnl @@ -216,10 +216,14 @@ case $uname in AC_CHECK_HEADER(CoreFoundation/CFPriv.h,AC_DEFINE(HAVE_CFPRIV_H)) AC_CHECK_HEADER(CoreFoundation/CFBundlePriv.h,AC_DEFINE(HAVE_CFBUNDLEPRIV_H)) - dnl Check for the new membership functions in MacOSX 10.4 (Tiger)... + dnl Check for the new membership functions in MacOSX 10.4... AC_CHECK_HEADER(membership.h,AC_DEFINE(HAVE_MEMBERSHIP_H)) + AC_CHECK_HEADER(membershipPriv.h,AC_DEFINE(HAVE_MEMBERSHIPPRIV_H)) AC_CHECK_FUNCS(mbr_uid_to_uuid) + dnl Need header... + AC_CHECK_HEADER(dlfcn.h,AC_DEFINE(HAVE_DLFCN_H)) + dnl Check for notify_post support AC_CHECK_HEADER(notify.h,AC_DEFINE(HAVE_NOTIFY_H)) AC_CHECK_FUNCS(notify_post) @@ -277,5 +281,5 @@ AC_SUBST(DEFAULT_IPP_PORT) AC_DEFINE_UNQUOTED(CUPS_DEFAULT_IPP_PORT,$DEFAULT_IPP_PORT) dnl -dnl End of "$Id: cups-common.m4 6304 2007-02-22 22:06:23Z mike $". +dnl End of "$Id: cups-common.m4 6370 2007-03-20 14:36:12Z mike $". dnl diff --git a/config-scripts/cups-directories.m4 b/config-scripts/cups-directories.m4 index 09f3d9697..7728746c9 100644 --- a/config-scripts/cups-directories.m4 +++ b/config-scripts/cups-directories.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-directories.m4 6332 2007-03-12 16:08:51Z mike $" +dnl "$Id: cups-directories.m4 6351 2007-03-19 04:53:49Z mike $" dnl dnl Directory stuff for the Common UNIX Printing System (CUPS). dnl @@ -148,7 +148,7 @@ if test x$rcdir = x; then fi ;; - FreeBSD* | OpenBSD* | MirBsD* | ekkoBSD*) + FreeBSD* | OpenBSD* | MirBSD* | ekkoBSD*) # FreeBSD and OpenBSD ;; @@ -365,5 +365,5 @@ AC_DEFINE_UNQUOTED(CUPS_STATEDIR, "$localstatedir/run/cups") AC_SUBST(CUPS_STATEDIR) dnl -dnl End of "$Id: cups-directories.m4 6332 2007-03-12 16:08:51Z mike $". +dnl End of "$Id: cups-directories.m4 6351 2007-03-19 04:53:49Z mike $". dnl diff --git a/config-scripts/cups-network.m4 b/config-scripts/cups-network.m4 index 10cf68281..8da5f6266 100644 --- a/config-scripts/cups-network.m4 +++ b/config-scripts/cups-network.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-network.m4 6046 2006-10-20 14:43:30Z mike $" +dnl "$Id: cups-network.m4 6365 2007-03-19 20:56:57Z mike $" dnl dnl Networking stuff for the Common UNIX Printing System (CUPS). dnl @@ -89,6 +89,9 @@ fi AC_SUBST(CUPS_DEFAULT_DOMAINSOCKET) AC_SUBST(CUPS_LISTEN_DOMAINSOCKET) +AC_CHECK_HEADERS(AppleTalk/at_proto.h,AC_DEFINE(HAVE_APPLETALK_AT_PROTO_H),, + [#include ]) + dnl -dnl End of "$Id: cups-network.m4 6046 2006-10-20 14:43:30Z mike $". +dnl End of "$Id: cups-network.m4 6365 2007-03-19 20:56:57Z mike $". dnl diff --git a/config.h.in b/config.h.in index e2a76addd..20fe8ce70 100644 --- a/config.h.in +++ b/config.h.in @@ -1,5 +1,5 @@ /* - * "$Id: config.h.in 6304 2007-02-22 22:06:23Z mike $" + * "$Id: config.h.in 6370 2007-03-20 14:36:12Z mike $" * * Configuration file for the Common UNIX Printing System (CUPS). * @@ -465,6 +465,7 @@ */ #undef HAVE_MEMBERSHIP_H +#undef HAVE_MEMBERSHIPPRIV_H #undef HAVE_MBR_UID_TO_UUID @@ -522,8 +523,15 @@ #undef HAVE_KQUEUE +/* + * Do we have the header? + */ + +#undef HAVE_DLFCN_H + + #endif /* !_CUPS_CONFIG_H_ */ /* - * End of "$Id: config.h.in 6304 2007-02-22 22:06:23Z mike $". + * End of "$Id: config.h.in 6370 2007-03-20 14:36:12Z mike $". */ diff --git a/cups/adminutil.c b/cups/adminutil.c index 8b96fcb6c..5ef1a590f 100644 --- a/cups/adminutil.c +++ b/cups/adminutil.c @@ -1,12 +1,9 @@ /* - * "$Id: adminutil.c 6270 2007-02-12 14:27:47Z mike $" + * "$Id: adminutil.c 6361 2007-03-19 16:01:28Z mike $" * * Administration utility API definitions for the Common UNIX Printing * System (CUPS). * - * MANY OF THE FUNCTIONS IN THIS HEADER ARE PRIVATE AND SUBJECT TO - * CHANGE AT ANY TIME. USE AT YOUR OWN RISK. - * * Copyright 2001-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -31,8 +28,10 @@ * * cupsAdminCreateWindowsPPD() - Create the Windows PPD file for a printer. * cupsAdminExportSamba() - Export a printer to Samba. - * _cupsAdminGetServerSettings() - Get settings from the server. - * _cupsAdminSetServerSettings() - Set settings on the server. + * cupsAdminGetServerSettings() - Get settings from the server. + * _cupsAdminGetServerSettings() - Get settings from the server (private). + * cupsAdminSetServerSettings() - Set settings on the server. + * _cupsAdminSetServerSettings() - Set settings on the server (private). * do_samba_command() - Do a SAMBA command. * get_cupsd_conf() - Get the current cupsd.conf file. * invalidate_cupsd_cache() - Invalidate the cached cupsd.conf settings. @@ -693,6 +692,25 @@ cupsAdminExportSamba( } +/* + * 'cupsAdminGetServerSettings()' - Get settings from the server. + * + * The returned settings should be freed with cupsFreeOptions() when + * you are done with them. + * + * @since CUPS 1.3@ + */ + +int /* O - 1 on success, 0 on failure */ +cupsAdminGetServerSettings( + http_t *http, /* I - Connection to server */ + int *num_settings, /* O - Number of settings */ + cups_option_t **settings) /* O - Settings */ +{ + return (_cupsAdminGetServerSettings(http, num_settings, settings)); +} + + /* * '_cupsAdminGetServerSettings()' - Get settings from the server. * @@ -966,6 +984,22 @@ _cupsAdminGetServerSettings( } +/* + * 'cupsAdminSetServerSettings()' - Set settings on the server. + * + * @since CUPS 1.3@ + */ + +int /* O - 1 on success, 0 on failure */ +cupsAdminSetServerSettings( + http_t *http, /* I - Connection to server */ + int num_settings, /* I - Number of settings */ + cups_option_t *settings) /* I - Settings */ +{ + return (_cupsAdminSetServerSettings(http, num_settings, settings)); +} + + /* * '_cupsAdminSetServerSettings()' - Set settings on the server. * @@ -1531,14 +1565,13 @@ _cupsAdminSetServerSettings( } } else if (!in_policy && !in_location && - (val = cupsGetOption(line, num_settings, settings)) != NULL && - !cupsGetOption(line, cupsd_num_settings, cupsd_settings)) + (val = cupsGetOption(line, num_settings, settings)) != NULL) { /* - * Add this directive to the list of directives we have written... + * Replace this directive's value with the new one... */ - cupsd_num_settings = cupsAddOption(line, value, cupsd_num_settings, + cupsd_num_settings = cupsAddOption(line, val, cupsd_num_settings, &cupsd_settings); /* @@ -1546,7 +1579,7 @@ _cupsAdminSetServerSettings( * only support setting root directives, not in sections... */ - cupsFilePrintf(temp, "%s %s\n", line, value); + cupsFilePrintf(temp, "%s %s\n", line, val); } else if (value) { @@ -1752,8 +1785,8 @@ _cupsAdminSetServerSettings( cupsd_num_settings, &cupsd_settings); /* - * Write the new value in its place, without indentation since we - * only support setting root directives, not in sections... + * Write the new value, without indentation since we only support + * setting root directives, not in sections... */ cupsFilePrintf(temp, "%s %s\n", setting->name, setting->value); @@ -2155,5 +2188,5 @@ write_option(cups_file_t *dstfp, /* I - PPD file */ /* - * End of "$Id: adminutil.c 6270 2007-02-12 14:27:47Z mike $". + * End of "$Id: adminutil.c 6361 2007-03-19 16:01:28Z mike $". */ diff --git a/cups/encode.c b/cups/encode.c index 530800d5e..ed91a4ffc 100644 --- a/cups/encode.c +++ b/cups/encode.c @@ -1,5 +1,5 @@ /* - * "$Id: encode.c 6267 2007-02-11 23:24:22Z mike $" + * "$Id: encode.c 6356 2007-03-19 13:54:48Z mike $" * * Option encoding routines for the Common UNIX Printing System (CUPS). * @@ -88,7 +88,7 @@ static const _ipp_option_t ipp_options[] = { "notify-lease-duration-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { "notify-natural-language", IPP_TAG_LANGUAGE, IPP_TAG_SUBSCRIPTION }, { "notify-pull-method", IPP_TAG_KEYWORD, IPP_TAG_SUBSCRIPTION }, - { "notify-recipient", IPP_TAG_URI, IPP_TAG_SUBSCRIPTION }, + { "notify-recipient-uri", IPP_TAG_URI, IPP_TAG_SUBSCRIPTION }, { "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 }, @@ -570,5 +570,5 @@ compare_ipp_options(_ipp_option_t *a, /* I - First option */ /* - * End of "$Id: encode.c 6267 2007-02-11 23:24:22Z mike $". + * End of "$Id: encode.c 6356 2007-03-19 13:54:48Z mike $". */ diff --git a/cups/localize.c b/cups/localize.c index bb9024f9c..d38fdc384 100644 --- a/cups/localize.c +++ b/cups/localize.c @@ -1,9 +1,9 @@ /* - * "$Id: localize.c 5824 2006-08-15 18:19:45Z mike $" + * "$Id: localize.c 6367 2007-03-20 01:34:29Z mike $" * * PPD custom option routines for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 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 @@ -183,6 +183,19 @@ ppd_text(ppd_file_t *ppd, /* I - PPD file */ { snprintf(lkeyword, sizeof(lkeyword), "%s.%s", ll, keyword); attr = ppdFindAttr(ppd, lkeyword, spec); + + if (!attr && !strcmp(ll, "ja")) + { + /* + * Due to a bug in the CUPS DDK 1.1.0 ppdmerge program, Japanese + * PPD files were incorrectly assigned "jp" as the locale name + * instead of "ja". Support both the old (incorrect) and new + * locale names for Japanese... + */ + + snprintf(lkeyword, sizeof(lkeyword), "jp.%s", keyword); + attr = ppdFindAttr(ppd, lkeyword, spec); + } } #ifdef DEBUG @@ -202,5 +215,5 @@ ppd_text(ppd_file_t *ppd, /* I - PPD file */ /* - * End of "$Id: localize.c 5824 2006-08-15 18:19:45Z mike $". + * End of "$Id: localize.c 6367 2007-03-20 01:34:29Z mike $". */ diff --git a/cups/request.c b/cups/request.c index 0e89634ba..53a0f915c 100644 --- a/cups/request.c +++ b/cups/request.c @@ -1,5 +1,5 @@ /* - * "$Id: request.c 6253 2007-02-10 18:48:40Z mike $" + * "$Id: request.c 6355 2007-03-19 06:33:04Z mike $" * * IPP utilities for the Common UNIX Printing System (CUPS). * @@ -144,6 +144,19 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */ else file = NULL; +#ifdef HAVE_SSL + /* + * See if we have an auth-info attribute and are communicating over + * a non-local link. If so, encrypt the link so that we can pass + * the authentication information securely... + */ + + if (ippFindAttribute(request, "auth-info", IPP_TAG_TEXT) && + !httpAddrLocalhost(http->hostaddr) && !http->tls && + httpEncryption(http, HTTP_ENCRYPT_REQUIRED)) + return (NULL); +#endif /* HAVE_SSL */ + /* * Loop until we can send the request without authorization problems. */ @@ -494,5 +507,5 @@ _cupsSetError(ipp_status_t status, /* I - IPP status code */ /* - * End of "$Id: request.c 6253 2007-02-10 18:48:40Z mike $". + * End of "$Id: request.c 6355 2007-03-19 06:33:04Z mike $". */ diff --git a/cups/string.c b/cups/string.c index 5b2cea2a5..c44b7a061 100644 --- a/cups/string.c +++ b/cups/string.c @@ -1,5 +1,5 @@ /* - * "$Id: string.c 6187 2007-01-10 16:20:42Z mike $" + * "$Id: string.c 6345 2007-03-17 18:00:04Z mike $" * * String functions for the Common UNIX Printing System (CUPS). * @@ -266,9 +266,9 @@ _cupsStrFormatd(char *buf, /* I - String */ tempptr < tempdec && bufptr < bufend; *bufptr++ = *tempptr++); - tempdec += declen; + tempptr += declen; - if (*tempdec && bufptr < bufend) + if (*tempptr && bufptr < bufend) { *bufptr++ = '.'; @@ -743,5 +743,5 @@ compare_sp_items(_cups_sp_item_t *a, /* I - First item */ /* - * End of "$Id: string.c 6187 2007-01-10 16:20:42Z mike $". + * End of "$Id: string.c 6345 2007-03-17 18:00:04Z mike $". */ diff --git a/cups/testlang.c b/cups/testlang.c index f41408b03..2c3ebe805 100644 --- a/cups/testlang.c +++ b/cups/testlang.c @@ -1,5 +1,5 @@ /* - * "$Id: testlang.c 4903 2006-01-10 20:02:46Z mike $" + * "$Id: testlang.c 6345 2007-03-17 18:00:04Z mike $" * * Localization test program for the Common UNIX Printing System (CUPS). * @@ -34,6 +34,7 @@ #include #include "i18n.h" +#include "string.h" /* @@ -44,9 +45,23 @@ int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { + int i; /* Looping var */ + int errors = 0; /* Number of errors */ cups_lang_t *language; /* Message catalog */ cups_lang_t *language2; /* Message catalog */ + struct lconv *loc; /* Locale data */ + char buffer[1024]; /* String buffer */ + double number; /* Number */ + static const char * const tests[] = /* Test strings */ + { + "1", + "-1", + "3", + "5.125" + }; + + _cupsSetLocale(argv); if (argc == 1) { @@ -61,6 +76,8 @@ main(int argc, /* I - Number of command-line arguments */ if (language != language2) { + errors ++; + puts("**** ERROR: Language cache did not work! ****"); puts("First result from cupsLangGet:"); } @@ -80,10 +97,29 @@ main(int argc, /* I - Number of command-line arguments */ printf("Yes = \"%s\"\n", _cupsLangString(language2, "Yes")); } - return (0); + loc = localeconv(); + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i ++) + { + number = _cupsStrScand(tests[i], NULL, loc); + + printf("_cupsStrScand(\"%s\") number=%f\n", tests[i], number); + + _cupsStrFormatd(buffer, buffer + sizeof(buffer), number, loc); + + printf("_cupsStrFormatd(%f) buffer=\"%s\"\n", number, buffer); + + if (strcmp(buffer, tests[i])) + { + errors ++; + puts("**** ERROR: Bad formatted number! ****"); + } + } + + return (errors > 0); } /* - * End of "$Id: testlang.c 4903 2006-01-10 20:02:46Z mike $". + * End of "$Id: testlang.c 6345 2007-03-17 18:00:04Z mike $". */ diff --git a/doc/help/translation.html b/doc/help/translation.html index 52efe31a2..320573495 100644 --- a/doc/help/translation.html +++ b/doc/help/translation.html @@ -26,8 +26,11 @@ files and directories:

  • doc/images/button-*.gif - the web interface button images
  • -
  • doc/images/button-*.scm - the Gimp scripts - we use to generate the web interface button images
  • +
  • tools/buttons.txt - the English text for the + web interface buttons
  • + +
  • tools/makebuttons - the shell script we use + to generate the web interface button images
  • doc/index.html - the web interface home page
  • @@ -44,7 +47,7 @@ localization files are placed in subdirectories under the doc and templates using the locale name. Locale names are either ll or ll_CC, where "ll" is the 2-letter language code and "CC" is the 2-letter -country code.

    +country code. CUPS does not currently use or support the newer ll-region syntax for locale names.

    All non-image files must be encoded using the UTF-8 character set.

    @@ -86,22 +89,23 @@ Comment[ll_CC]=Translation of "CUPS Web Interface"

    Button Images

    -

    The web interface button images are used to activate functions -on the CUPS web pages. Table 1 lists the button images and the -English text labels for those buttons. Use the supplied Gimp -scripts to create button images that match the CUPS web interface -and save them in the doc/ll_CC/images subdirectory. -The Gimp button scripts can be installed using the following -command:

    +

    The web interface button images are used to activate functions on +the CUPS web pages. Table 1 lists the button images and the English +text labels for those buttons. Copy the file +tools/buttons.txt to buttons-ll_CC.txt, +translate the text in that file (use UTF-8 as the text encoding!), +and then use the supplied tools/makebuttons script to +create button images that match the CUPS web interface:

    -cp doc/images/button*.scm ~/.gimp-2.2/scripts
    +cp tools/buttons.txt buttons-ll_CC.txt
    +vi buttons-ll_CC.txt
    +tools/makebuttons ll_CC buttons-ll_CC.txt
     
    -

    If you have already started the Gimp application, choose -Refresh Scripts from the Xtns->Script-Fu -sub-menu. The button scripts will be available under a new -Btns +

    Note: The tools/makebuttons script +requires at least version 6.2.4 of the ImageMagick software to +work.

    When you have created all of the button images, edit the Makedefs file and add the locale name to the diff --git a/fonts/Vera.ttf b/fonts/Vera.ttf new file mode 100644 index 0000000000000000000000000000000000000000..58cd6b5e61eff273e920942e28041f8ddcf1e1b5 GIT binary patch literal 65932 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 PathState - /private/var/run/cups/cupsd + /private/var/spool/cups/cache/org.cups.cupsd @@ -29,7 +29,13 @@ SockNodeName - localhost + ::1 + SockServiceName + ipp + + + SockNodeName + 127.0.0.1 SockServiceName ipp diff --git a/pdftops/Catalog.cxx b/pdftops/Catalog.cxx index d1ff4cb8e..4fa6e8e91 100644 --- a/pdftops/Catalog.cxx +++ b/pdftops/Catalog.cxx @@ -23,6 +23,12 @@ #include "Link.h" #include "Catalog.h" +// This define is used to limit the depth of recursive readPageTree calls +// This is needed because the page tree nodes can reference their parents +// leaving us in an infinite loop +// Most sane pdf documents don't have a call depth higher than 10 +#define MAX_CALL_DEPTH 1000 + //------------------------------------------------------------------------ // Catalog //------------------------------------------------------------------------ @@ -71,7 +77,7 @@ Catalog::Catalog(XRef *xrefA) { pageRefs[i].num = -1; pageRefs[i].gen = -1; } - numPages = readPageTree(pagesDict.getDict(), NULL, 0); + numPages = readPageTree(pagesDict.getDict(), NULL, 0, 0); if (numPages != numPages0) { error(-1, "Page count in top-level pages object is incorrect"); } @@ -169,7 +175,7 @@ GString *Catalog::readMetadata() { return s; } -int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start) { +int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start, int callDepth) { Object kids; Object kid; Object kidRef; @@ -214,9 +220,13 @@ int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start) { // This should really be isDict("Pages"), but I've seen at least one // PDF file where the /Type entry is missing. } else if (kid.isDict()) { - if ((start = readPageTree(kid.getDict(), attrs1, start)) - < 0) - goto err2; + if (callDepth > MAX_CALL_DEPTH) { + error(-1, "Limit of %d recursive calls reached while reading the page tree. If your document is correct and not a test to try to force a crash, please report a bug.", MAX_CALL_DEPTH); + } else { + if ((start = readPageTree(kid.getDict(), attrs1, start, callDepth + 1)) + < 0) + goto err2; + } } else { error(-1, "Kid object (page %d) is wrong type (%s)", start+1, kid.getTypeName()); diff --git a/pdftops/Catalog.h b/pdftops/Catalog.h index 08e50cae0..8cef94818 100644 --- a/pdftops/Catalog.h +++ b/pdftops/Catalog.h @@ -85,7 +85,7 @@ private: Object acroForm; // AcroForm dictionary GBool ok; // true if catalog is valid - int readPageTree(Dict *pages, PageAttrs *attrs, int start); + int readPageTree(Dict *pages, PageAttrs *attrs, int start, int callDepth); Object *findDestInTree(Object *tree, GString *name, Object *obj); }; diff --git a/scheduler/auth.c b/scheduler/auth.c index 8baf94511..ddc31ce6d 100644 --- a/scheduler/auth.c +++ b/scheduler/auth.c @@ -1,5 +1,5 @@ /* - * "$Id: auth.c 6314 2007-03-01 19:11:54Z mike $" + * "$Id: auth.c 6361 2007-03-19 16:01:28Z mike $" * * Authorization routines for the Common UNIX Printing System (CUPS). * @@ -835,7 +835,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ } } #ifdef HAVE_GSSAPI - else if (!strncmp(authorization, "Negotiate", 9) && type == AUTH_KERBEROS) + else if (!strncmp(authorization, "Negotiate", 9) && type == AUTH_NEGOTIATE) { int len; /* Length of authorization string */ gss_cred_id_t server_creds; /* Server credentials */ @@ -1819,8 +1819,8 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */ if ((best->encryption >= HTTP_ENCRYPT_REQUIRED && !con->http.tls && strcasecmp(con->http.hostname, "localhost") && best->satisfy == AUTH_SATISFY_ALL) && - !(best->type == AUTH_KERBEROS || - (best->type == AUTH_NONE && DefaultAuthType == AUTH_KERBEROS))) + !(best->type == AUTH_NEGOTIATE || + (best->type == AUTH_NONE && DefaultAuthType == AUTH_NEGOTIATE))) { cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: Need upgrade to TLS..."); @@ -2522,5 +2522,5 @@ to64(char *s, /* O - Output string */ /* - * End of "$Id: auth.c 6314 2007-03-01 19:11:54Z mike $". + * End of "$Id: auth.c 6361 2007-03-19 16:01:28Z mike $". */ diff --git a/scheduler/auth.h b/scheduler/auth.h index 61c7ae993..de62893ac 100644 --- a/scheduler/auth.h +++ b/scheduler/auth.h @@ -1,5 +1,5 @@ /* - * "$Id: auth.h 5919 2006-08-31 04:20:45Z mike $" + * "$Id: auth.h 6361 2007-03-19 16:01:28Z mike $" * * Authorization definitions for the Common UNIX Printing System (CUPS) * scheduler. @@ -38,7 +38,7 @@ #define AUTH_BASIC 1 /* Basic authentication */ #define AUTH_DIGEST 2 /* Digest authentication */ #define AUTH_BASICDIGEST 3 /* Basic authentication w/passwd.md5 */ -#define AUTH_KERBEROS 4 /* Kerberos authentication */ +#define AUTH_NEGOTIATE 4 /* Kerberos authentication */ #define AUTH_ANON 0 /* Anonymous access */ #define AUTH_USER 1 /* Must have a valid username/password */ @@ -159,5 +159,5 @@ extern http_status_t cupsdIsAuthorized(cupsd_client_t *con, const char *owner); /* - * End of "$Id: auth.h 5919 2006-08-31 04:20:45Z mike $". + * End of "$Id: auth.h 6361 2007-03-19 16:01:28Z mike $". */ diff --git a/scheduler/client.c b/scheduler/client.c index 9c0a17dc6..1ba04e969 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -1,5 +1,5 @@ /* - * "$Id: client.c 6329 2007-03-12 14:48:28Z mike $" + * "$Id: client.c 6361 2007-03-19 16:01:28Z mike $" * * Client routines for the Common UNIX Printing System (CUPS) scheduler. * @@ -2221,7 +2221,7 @@ cupsdSendError(cupsd_client_t *con, /* I - Connection */ * never disable it in that case. */ - if (code >= HTTP_BAD_REQUEST && con->http.auth_type != AUTH_KERBEROS) + if (code >= HTTP_BAD_REQUEST && con->http.auth_type != AUTH_NEGOTIATE) con->http.keep_alive = HTTP_KEEPALIVE_OFF; /* @@ -2397,7 +2397,7 @@ cupsdSendHeader(cupsd_client_t *con, /* I - Client to send to */ snprintf(auth_str, sizeof(auth_str), "Digest realm=\"CUPS\", nonce=\"%s\"", con->http.hostname); #ifdef HAVE_GSSAPI - else if (auth_type == AUTH_KERBEROS && !con->no_negotiate && + else if (auth_type == AUTH_NEGOTIATE && !con->no_negotiate && con->gss_output_token.length == 0) strlcpy(auth_str, "Negotiate", sizeof(auth_str)); #endif /* HAVE_GSSAPI */ @@ -4533,5 +4533,5 @@ write_file(cupsd_client_t *con, /* I - Client connection */ /* - * End of "$Id: client.c 6329 2007-03-12 14:48:28Z mike $". + * End of "$Id: client.c 6361 2007-03-19 16:01:28Z mike $". */ diff --git a/scheduler/conf.c b/scheduler/conf.c index d033627ad..04a58bd4d 100644 --- a/scheduler/conf.c +++ b/scheduler/conf.c @@ -1,9 +1,9 @@ /* - * "$Id: conf.c 6253 2007-02-10 18:48:40Z mike $" + * "$Id: conf.c 6365 2007-03-19 20:56:57Z mike $" * * Configuration routines for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 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 @@ -87,6 +87,9 @@ typedef struct static cupsd_var_t variables[] = { { "AccessLog", &AccessLog, CUPSD_VARTYPE_STRING }, +#ifdef __APPLE__ + { "AppleQuotas", &AppleQuotas, CUPSD_VARTYPE_BOOLEAN }, +#endif /* __APPLE__ */ { "AutoPurgeJobs", &JobAutoPurge, CUPSD_VARTYPE_BOOLEAN }, { "BrowseInterval", &BrowseInterval, CUPSD_VARTYPE_INTEGER }, #ifdef HAVE_LDAP @@ -463,6 +466,10 @@ cupsdReadConfiguration(void) cupsdSetString(&LaunchdConf, CUPS_DEFAULT_LAUNCHD_CONF); #endif /* HAVE_LAUNCHD */ +#ifdef __APPLE__ + AppleQuotas = TRUE; +#endif /* __APPLE__ */ + /* * Read the configuration file... */ @@ -1718,10 +1725,9 @@ parse_aaa(cupsd_location_t *loc, /* I - Location */ loc->level = AUTH_USER; } #ifdef HAVE_GSSAPI - else if (!strcasecmp(value, "kerberos") || - !strcasecmp(value, "gssapi")) + else if (!strcasecmp(value, "negotiate")) { - loc->type = AUTH_KERBEROS; + loc->type = AUTH_NEGOTIATE; if (loc->level == AUTH_ANON) loc->level = AUTH_USER; @@ -2737,8 +2743,8 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ else if (!strcasecmp(value, "basicdigest")) DefaultAuthType = AUTH_BASICDIGEST; #ifdef HAVE_GSSAPI - else if (!strcasecmp(value, "kerberos")) - DefaultAuthType = AUTH_KERBEROS; + else if (!strcasecmp(value, "negotiate")) + DefaultAuthType = AUTH_NEGOTIATE; #endif /* HAVE_GSSAPI */ else { @@ -3342,5 +3348,5 @@ read_policy(cups_file_t *fp, /* I - Configuration file */ /* - * End of "$Id: conf.c 6253 2007-02-10 18:48:40Z mike $". + * End of "$Id: conf.c 6365 2007-03-19 20:56:57Z mike $". */ diff --git a/scheduler/conf.h b/scheduler/conf.h index cfb71fc4e..0a5e073d6 100644 --- a/scheduler/conf.h +++ b/scheduler/conf.h @@ -1,10 +1,10 @@ /* - * "$Id: conf.h 6291 2007-02-19 21:54:27Z mike $" + * "$Id: conf.h 6365 2007-03-19 20:56:57Z mike $" * * Configuration file definitions for the Common UNIX Printing System (CUPS) * scheduler. * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 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 @@ -201,6 +201,11 @@ VAR char *LaunchdConf VALUE(NULL); /* launchd(8) configuration file */ #endif /* HAVE_LAUNCHD */ +#ifdef __APPLE__ +VAR int AppleQuotas VALUE(TRUE); + /* Use Apple PrintService Quotas instead of CUPS quotas */ +#endif /* __APPLE__ */ + #ifdef HAVE_AUTHORIZATION_H VAR char *SystemGroupAuthKey VALUE(NULL); /* System group auth key */ @@ -228,5 +233,5 @@ extern int cupsdLogRequest(cupsd_client_t *con, http_status_t code); /* - * End of "$Id: conf.h 6291 2007-02-19 21:54:27Z mike $". + * End of "$Id: conf.h 6365 2007-03-19 20:56:57Z mike $". */ diff --git a/scheduler/cups-driverd.c b/scheduler/cups-driverd.c index 39892bc71..d5ed5a33a 100644 --- a/scheduler/cups-driverd.c +++ b/scheduler/cups-driverd.c @@ -1,5 +1,5 @@ /* - * "$Id: cups-driverd.c 6211 2007-01-23 15:44:34Z mike $" + * "$Id: cups-driverd.c 6363 2007-03-19 20:48:49Z mike $" * * PPD/driver support for the Common UNIX Printing System (CUPS). * @@ -684,7 +684,7 @@ load_ppds(const char *d, /* I - Actual directory */ { "german", "de" }, { "greek", "el" }, { "italian", "it" }, - { "japanese", "jp" }, + { "japanese", "ja" }, { "norwegian", "no" }, { "polish", "pl" }, { "portuguese", "pt" }, @@ -1122,5 +1122,5 @@ load_drivers(void) /* - * End of "$Id: cups-driverd.c 6211 2007-01-23 15:44:34Z mike $". + * End of "$Id: cups-driverd.c 6363 2007-03-19 20:48:49Z mike $". */ diff --git a/scheduler/cupsd.h b/scheduler/cupsd.h index 81b5b3588..93b29b09b 100644 --- a/scheduler/cupsd.h +++ b/scheduler/cupsd.h @@ -1,5 +1,5 @@ /* - * "$Id: cupsd.h 6170 2007-01-02 17:26:41Z mike $" + * "$Id: cupsd.h 6365 2007-03-19 20:56:57Z mike $" * * Main header file for the Common UNIX Printing System (CUPS) scheduler. * @@ -172,6 +172,16 @@ VAR int Launchd VALUE(0); /* Running from launchd */ #endif /* HAVE_LAUNCH_H */ +#if defined(__APPLE__) && defined(HAVE_DLFCN_H) +typedef int (*PSQUpdateQuotaProcPtr)(const char *printer, const char *info, + const char *user, int nPages, int options); +VAR PSQUpdateQuotaProcPtr PSQUpdateQuotaProc + VALUE(0); + /* Apple PrintService quota function */ +#endif /* __APPLE__ && HAVE_DLFCN_H */ + + + /* * Prototypes... @@ -217,5 +227,5 @@ extern void cupsdStopSelect(void); /* - * End of "$Id: cupsd.h 6170 2007-01-02 17:26:41Z mike $". + * End of "$Id: cupsd.h 6365 2007-03-19 20:56:57Z mike $". */ diff --git a/scheduler/dirsvc.c b/scheduler/dirsvc.c index 73abd7bfc..7953ad5d7 100644 --- a/scheduler/dirsvc.c +++ b/scheduler/dirsvc.c @@ -1,5 +1,5 @@ /* - * "$Id: dirsvc.c 6309 2007-02-24 03:11:56Z mike $" + * "$Id: dirsvc.c 6354 2007-03-19 06:16:32Z mike $" * * Directory services routines for the Common UNIX Printing System (CUPS). * @@ -2448,10 +2448,11 @@ dnssdBuildTxtRecord( int *txt_len, /* O - TXT record length */ cupsd_printer_t *p) /* I - Printer information */ { - int i; /* Looping var */ + int i, j; /* Looping vars */ char type_str[32], /* Type to string buffer */ state_str[32], /* State to string buffer */ rp_str[1024], /* Queue name string buffer */ + air_str[1024], /* auth-info-required string buffer */ *keyvalue[32][2]; /* Table of key/value pairs */ @@ -2556,6 +2557,27 @@ dnssdBuildTxtRecord( keyvalue[i ][0] = "pdl"; keyvalue[i++][1] = p->pdl ? p->pdl : "application/postscript"; + if (p->num_auth_info_required) + { + char *air = air_str; /* Pointer into string */ + + + for (j = 0; j < p->num_auth_info_required; j ++) + { + if (air >= (air_str + sizeof(air_str) - 2)) + break; + + if (j) + *air++ = ','; + + strlcpy(air, p->auth_info_required[j], sizeof(air_str) - (air - air_str)); + air += strlen(air); + } + + keyvalue[i ][0] = "air"; + keyvalue[i++][1] = air; + } + /* * Then pack them into a proper txt record... */ @@ -2978,6 +3000,9 @@ process_implicit_classes(void) cupsdSetString(&pclass->location, p->location); cupsdSetString(&pclass->info, p->info); + cupsdSetString(&pclass->job_sheets[0], p->job_sheets[0]); + cupsdSetString(&pclass->job_sheets[1], p->job_sheets[1]); + update = 1; cupsdLogMessage(CUPSD_LOG_DEBUG, "Added implicit class \"%s\"...", @@ -3079,7 +3104,7 @@ process_implicit_classes(void) /* * 'send_cups_browse()' - Send new browsing information using the CUPS - * protocol. + * protocol. */ static void @@ -3774,5 +3799,5 @@ slp_url_callback( /* - * End of "$Id: dirsvc.c 6309 2007-02-24 03:11:56Z mike $". + * End of "$Id: dirsvc.c 6354 2007-03-19 06:16:32Z mike $". */ diff --git a/scheduler/ipp.c b/scheduler/ipp.c index 78edc3cc8..956028484 100644 --- a/scheduler/ipp.c +++ b/scheduler/ipp.c @@ -1,5 +1,5 @@ /* - * "$Id: ipp.c 6318 2007-03-06 04:36:55Z mike $" + * "$Id: ipp.c 6370 2007-03-20 14:36:12Z mike $" * * IPP routines for the Common UNIX Printing System (CUPS) scheduler. * @@ -113,6 +113,17 @@ # include #endif /* HAVE_LIBPAPER */ +#ifdef HAVE_MEMBERSHIP_H +# include +#endif /* HAVE_MEMBERSHIP_H */ +#ifdef HAVE_MEMBERSHIPPRIV_H +# include +#else +extern int mbr_user_name_to_uuid(const char* name, uuid_t uu); +extern int mbr_group_name_to_uuid(const char* name, uuid_t uu); +extern int mbr_check_membership_by_id(uuid_t user, gid_t group, int* ismember); +#endif /* HAVE_MEMBERSHIPPRIV_H */ + /* * Local functions... @@ -1175,16 +1186,31 @@ add_job(cupsd_client_t *con, /* I - Client connection */ * Check policy... */ + auth_info = ippFindAttribute(job->attrs, "auth-info", IPP_TAG_TEXT); + 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]) + else if ((printer->type & CUPS_PRINTER_AUTHENTICATED) && + !con->username[0] && !auth_info) { send_http_error(con, HTTP_UNAUTHORIZED); return (NULL); } +#ifdef HAVE_SSL + else if (auth_info && !con->http.tls && + !httpAddrLocalhost(con->http.hostaddr)) + { + /* + * Require encryption of auth-info over non-local connections... + */ + + send_http_error(con, HTTP_UPGRADE_REQUIRED); + return (NULL); + } +#endif /* HAVE_SSL */ /* * See if the printer is accepting jobs... @@ -1364,8 +1390,6 @@ add_job(cupsd_client_t *con, /* I - Client connection */ attr->name = _cupsStrAlloc("job-originating-user-name"); } - auth_info = ippFindAttribute(job->attrs, "auth-info", IPP_TAG_TEXT); - if (con->username[0] || auth_info) { save_auth_info(con, job, auth_info); @@ -3151,7 +3175,24 @@ check_quotas(cupsd_client_t *con, /* I - Client connection */ int i; /* Looping var */ char username[33]; /* Username */ cupsd_quota_t *q; /* Quota data */ +#ifdef HAVE_MBR_UID_TO_UUID + /* + * Use Apple membership APIs which require that all names represent + * valid user account or group records accessible by the server. + */ + + uuid_t usr_uuid; /* UUID for job requesting user */ + uuid_t usr2_uuid; /* UUID for ACL user name entry */ + uuid_t grp_uuid; /* UUID for ACL group name entry */ + int mbr_err; /* Error from membership function */ + int is_member; /* Is this user a member? */ +#else + /* + * Use standard POSIX APIs for checking users and groups... + */ + struct passwd *pw; /* User password data */ +#endif /* HAVE_MBR_UID_TO_UUID */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "check_quotas(%p[%d], %p[%s])", @@ -3211,8 +3252,34 @@ check_quotas(cupsd_client_t *con, /* I - Client connection */ if (p->num_users) { +#ifdef HAVE_MBR_UID_TO_UUID + /* + * Get UUID for job requesting user... + */ + + if (mbr_user_name_to_uuid((char *)username, usr_uuid)) + { + /* + * Unknown user... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "check_quotas: UUID lookup failed for user \"%s\"", + username); + cupsdLogMessage(CUPSD_LOG_INFO, + "Denying user \"%s\" access to printer \"%s\" " + "(unknown user)...", + username, p->name); + return (0); + } +#else + /* + * Get UID and GID of requesting user... + */ + pw = getpwnam(username); endpwent(); +#endif /* HAVE_MBR_UID_TO_UUID */ for (i = 0; i < p->num_users; i ++) if (p->users[i][0] == '@') @@ -3221,11 +3288,86 @@ check_quotas(cupsd_client_t *con, /* I - Client connection */ * Check group membership... */ +#ifdef HAVE_MBR_UID_TO_UUID + if ((mbr_err = mbr_group_name_to_uuid((char *)p->users[i] + 1, + grp_uuid)) != 0) + { + /* + * Invalid ACL entries are ignored for matching; just record a + * warning in the log... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "check_quotas: UUID lookup failed for ACL entry " + "\"%s\" (err=%d)", p->users[i], mbr_err); + cupsdLogMessage(CUPSD_LOG_WARN, + "Access control entry \"%s\" not a valid group name; " + "entry ignored", p->users[i]); + } + else + { + if ((mbr_err = mbr_check_membership(usr_uuid, grp_uuid, + &is_member)) != 0) + { + /* + * At this point, there should be no errors, but check anyways... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "check_quotas: group \"%s\" membership check " + "failed (err=%d)", p->users[i] + 1, mbr_err); + is_member = 0; + } + + /* + * Stop if we found a match... + */ + + if (is_member) + break; + } +#else if (cupsdCheckGroup(username, pw, p->users[i] + 1)) break; +#endif /* HAVE_MBR_UID_TO_UUID */ + } +#ifdef HAVE_MBR_UID_TO_UUID + else + { + if ((mbr_err = mbr_user_name_to_uuid((char *)p->users[i], + usr2_uuid)) != 0) + { + /* + * Invalid ACL entries are ignored for matching; just record a + * warning in the log... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "check_quotas: UUID lookup failed for ACL entry " + "\"%s\" (err=%d)", p->users[i], mbr_err); + cupsdLogMessage(CUPSD_LOG_WARN, + "Access control entry \"%s\" not a valid user name; " + "entry ignored", p->users[i]); + } + else + { + if ((mbr_err = mbr_check_membership(usr_uuid, usr2_uuid, + &is_member)) != 0) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "check_quotas: User \"%s\" identity check failed " + "(err=%d)", p->users[i], mbr_err); + is_member = 0; + } + + if (is_member) + break; + } } +#else else if (!strcasecmp(username, p->users[i])) break; +#endif /* HAVE_MBR_UID_TO_UUID */ if ((i < p->num_users) == p->deny_users) { @@ -3240,6 +3382,66 @@ check_quotas(cupsd_client_t *con, /* I - Client connection */ * Check quotas... */ +#ifdef __APPLE__ + if (AppleQuotas) + { + /* + * TODO: Define these special page count values as constants! + */ + + if (q->page_count == -4) /* special case: unlimited user */ + { + cupsdLogMessage(CUPSD_LOG_INFO, + "User \"%s\" request approved for printer %s (%s): " + "unlimited quota.", + username, p->name, p->info); + q->page_count = 0; /* allow user to print */ + return (1); + } + else if (q->page_count == -3) /* quota exceeded */ + { + cupsdLogMessage(CUPSD_LOG_INFO, + "User \"%s\" request denied for printer %s (%s): " + "quota limit exceeded.", + username, p->name, p->info); + q->page_count = 2; /* force quota exceeded failure */ + return (0); + } + else if (q->page_count == -2) /* quota disabled for user */ + { + cupsdLogMessage(CUPSD_LOG_INFO, + "User \"%s\" request denied for printer %s (%s): " + "printing disabled for user.", + username, p->name, p->info); + q->page_count = 2; /* force quota exceeded failure */ + return (0); + } + else if (q->page_count == -1) /* quota access error */ + { + cupsdLogMessage(CUPSD_LOG_INFO, + "User \"%s\" request denied for printer %s (%s): " + "unable to determine quota limit.", + username, p->name, p->info); + q->page_count = 2; /* force quota exceeded failure */ + return (0); + } + else if (q->page_count < 0) /* user not found or other error */ + { + cupsdLogMessage(CUPSD_LOG_INFO, + "User \"%s\" request denied for printer %s (%s): " + "user disabled / missing quota.", + username, p->name, p->info); + q->page_count = 2; /* force quota exceeded failure */ + return (0); + } + else /* page within user limits */ + { + q->page_count = 0; /* allow user to print */ + return (1); + } + } + else +#endif /* __APPLE__ */ if (p->k_limit || p->page_limit) { if ((q = cupsdUpdateQuota(p, username, 0, 0)) == NULL) @@ -4832,7 +5034,7 @@ create_subscription( while (attr && attr->group_tag != IPP_TAG_ZERO) { - if (!strcmp(attr->name, "notify-recipient") && + if (!strcmp(attr->name, "notify-recipient-uri") && attr->value_tag == IPP_TAG_URI) { /* @@ -4851,7 +5053,7 @@ create_subscription( resource, sizeof(resource)) < HTTP_URI_OK) { send_ipp_status(con, IPP_NOT_POSSIBLE, - _("Bad notify-recipient URI \"%s\"!"), recipient); + _("Bad notify-recipient-uri URI \"%s\"!"), recipient); ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM, "notify-status-code", IPP_URI_SCHEME); return; @@ -4862,7 +5064,7 @@ create_subscription( if (access(notifier, X_OK)) { send_ipp_status(con, IPP_NOT_POSSIBLE, - _("notify-recipient URI \"%s\" uses unknown scheme!"), + _("notify-recipient-uri URI \"%s\" uses unknown scheme!"), recipient); ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM, "notify-status-code", IPP_URI_SCHEME); @@ -5503,9 +5705,6 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */ if ((job->dtype & dmask) != dtype && (!job->printer || (job->printer->type & dmask) != dtype)) continue; - if (username[0] && strcasecmp(username, job->username)) - continue; - if (completed && job->state_value <= IPP_JOB_STOPPED) continue; @@ -5517,6 +5716,9 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */ if (!job->attrs) continue; + if (username[0] && strcasecmp(username, job->username)) + continue; + if (count > 0) ippAddSeparator(con->response); @@ -7658,7 +7860,6 @@ static void save_krb5_creds(cupsd_client_t *con, /* I - Client connection */ cupsd_job_t *job) /* I - Job */ { -# ifndef __APPLE__ krb5_context krb_context; /* Kerberos context */ krb5_ccache ccache; /* Credentials cache */ OM_uint32 major_status, /* Major status code */ @@ -7699,7 +7900,6 @@ save_krb5_creds(cupsd_client_t *con, /* I - Client connection */ cupsdSetStringf(&(job->ccname), "KRB5CCNAME=FILE:%s", krb5_cc_get_name(krb_context, ccache)); krb5_cc_close(krb_context, ccache); -# endif /* !__APPLE__ */ } #endif /* HAVE_GSSAPI && HAVE_KRB5_H */ @@ -9248,5 +9448,5 @@ validate_user(cupsd_job_t *job, /* I - Job */ /* - * End of "$Id: ipp.c 6318 2007-03-06 04:36:55Z mike $". + * End of "$Id: ipp.c 6370 2007-03-20 14:36:12Z mike $". */ diff --git a/scheduler/job.c b/scheduler/job.c index 3c876a649..aded57757 100644 --- a/scheduler/job.c +++ b/scheduler/job.c @@ -1,5 +1,5 @@ /* - * "$Id: job.c 6318 2007-03-06 04:36:55Z mike $" + * "$Id: job.c 6365 2007-03-19 20:56:57Z mike $" * * Job management routines for the Common UNIX Printing System (CUPS). * @@ -1700,7 +1700,28 @@ cupsdUpdateJob(cupsd_job_t *job) /* I - Job to check */ job->sheets->values[0].integer += copies; if (job->printer->page_limit) - cupsdUpdateQuota(job->printer, job->username, copies, 0); + { + cupsd_quota_t *q = cupsdUpdateQuota(job->printer, job->username, + copies, 0); + +#ifdef __APPLE__ + if (AppleQuotas && q->page_count == -3) + { + /* + * Quota limit exceeded, cancel job in progress immediately... + */ + + cupsdLogMessage(CUPSD_LOG_INFO, + "Job %d canceled: pages exceed user %s quota " + "limit on printer %s (%s).", + job->id, job->username, job->printer->name, + job->printer->info); + + cupsdCancelJob(job, 1, IPP_JOB_CANCELED); + return; + } +#endif /* __APPLE__ */ + } } cupsdLogPage(job, message); @@ -3521,5 +3542,5 @@ unload_job(cupsd_job_t *job) /* I - Job */ /* - * End of "$Id: job.c 6318 2007-03-06 04:36:55Z mike $". + * End of "$Id: job.c 6365 2007-03-19 20:56:57Z mike $". */ diff --git a/scheduler/main.c b/scheduler/main.c index 8591cc0f3..f17969eea 100644 --- a/scheduler/main.c +++ b/scheduler/main.c @@ -1,5 +1,5 @@ /* - * "$Id: main.c 6326 2007-03-11 17:50:18Z mike $" + * "$Id: main.c 6365 2007-03-19 20:56:57Z mike $" * * Scheduler main loop for the Common UNIX Printing System (CUPS). * @@ -61,7 +61,7 @@ #ifdef HAVE_LAUNCH_H # include # include -# define CUPS_KEEPALIVE CUPS_STATEDIR "/org.cups.cupsd" +# define CUPS_KEEPALIVE CUPS_CACHEDIR "/org.cups.cupsd" /* Name of the launchd KeepAlive file */ # ifndef LAUNCH_JOBKEY_KEEPALIVE # define LAUNCH_JOBKEY_KEEPALIVE "KeepAlive" @@ -81,6 +81,10 @@ # include #endif /* HAVE_NOTIFY_H */ +#if defined(__APPLE__) && defined(HAVE_DLFCN_H) +# include +#endif /* __APPLE__ && HAVE_DLFCN_H */ + /* * Local functions... @@ -123,6 +127,12 @@ static CFDictionaryRef launchd_conf_dict = NULL; /* org.cups.cupsd.plist dict */ #endif /* HAVE_LAUNCHD */ +#if defined(__APPLE__) && defined(HAVE_DLFCN_H) +static const char *PSQLibPath = "/usr/lib/libPrintServiceQuota.dylib"; +static const char *PSQLibFuncName = "PSQUpdateQuota"; +static void *PSQLibRef; /* libPrintServiceQuota.dylib */ +#endif /* HAVE_DLFCN_H */ + /* * 'main()' - Main entry for the CUPS scheduler. @@ -424,6 +434,17 @@ main(int argc, /* I - Number of command-line args */ } #endif /* HAVE_LAUNCHD */ +#if defined(__APPLE__) && defined(HAVE_DLFCN_H) + /* + * Load Print Service quota enforcement library (X Server only) + */ + + PSQLibRef = dlopen(PSQLibPath, RTLD_LAZY); + + if (PSQLibRef) + PSQUpdateQuotaProc = dlsym(PSQLibRef, PSQLibFuncName); +#endif /* __APPLE__ && HAVE_DLFCN_H */ + /* * Startup the server... */ @@ -2134,5 +2155,5 @@ usage(int status) /* O - Exit status */ /* - * End of "$Id: main.c 6326 2007-03-11 17:50:18Z mike $". + * End of "$Id: main.c 6365 2007-03-19 20:56:57Z mike $". */ diff --git a/scheduler/printers.c b/scheduler/printers.c index 9a33a2221..c76a97780 100644 --- a/scheduler/printers.c +++ b/scheduler/printers.c @@ -1,5 +1,5 @@ /* - * "$Id: printers.c 6318 2007-03-06 04:36:55Z mike $" + * "$Id: printers.c 6354 2007-03-19 06:16:32Z mike $" * * Printer routines for the Common UNIX Printing System (CUPS). * @@ -2288,6 +2288,14 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ if (BrowseLocalOptions) length += 12 + strlen(BrowseLocalOptions); + if (p->num_auth_info_required > 0) + { + length += 18; /* auth-info-required */ + + for (i = 0; i < p->num_auth_info_required; i ++) + length += strlen(p->auth_info_required[i]) + 1; + } + /* * Allocate the new string... */ @@ -2334,7 +2342,20 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ } } - *attrptr = '\0'; + if (p->num_auth_info_required > 0) + { + strcpy(attrptr, "auth-info-required"); + attrptr += 18; + + for (i = 0; i < p->num_auth_info_required; i ++) + { + *attrptr++ = i ? ',' : '='; + strcpy(attrptr, p->auth_info_required[i]); + attrptr += strlen(attrptr); + } + } + else + *attrptr = '\0'; } } @@ -3632,5 +3653,5 @@ write_irix_state(cupsd_printer_t *p) /* I - Printer to update */ /* - * End of "$Id: printers.c 6318 2007-03-06 04:36:55Z mike $". + * End of "$Id: printers.c 6354 2007-03-19 06:16:32Z mike $". */ diff --git a/scheduler/quotas.c b/scheduler/quotas.c index a51f7f08d..e224ebe3a 100644 --- a/scheduler/quotas.c +++ b/scheduler/quotas.c @@ -1,9 +1,9 @@ /* - * "$Id: quotas.c 5969 2006-09-19 20:09:24Z mike $" + * "$Id: quotas.c 6365 2007-03-19 20:56:57Z mike $" * * Quota routines for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products. + * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -101,6 +101,19 @@ cupsdUpdateQuota( "cupsdUpdateQuota: p=%s username=%s pages=%d k=%d", p->name, username, pages, k); +#if defined(__APPLE__) && defined(HAVE_DLFCN_H) + /* + * Use Apple PrintService quota enforcement if installed (X Server only) + */ + + if (AppleQuotas && PSQUpdateQuotaProc) + { + q->page_count = (*PSQUpdateQuotaProc)(p->name, p->info, username, pages, 0); + + return (q); + } +#endif /* __APPLE__ && HAVE_DLFCN_H */ + curtime = time(NULL); if (curtime < q->next_update) @@ -230,5 +243,5 @@ find_quota(cupsd_printer_t *p, /* I - Printer */ /* - * End of "$Id: quotas.c 5969 2006-09-19 20:09:24Z mike $". + * End of "$Id: quotas.c 6365 2007-03-19 20:56:57Z mike $". */ diff --git a/systemv/lp.c b/systemv/lp.c index 526930cd7..8500f802e 100644 --- a/systemv/lp.c +++ b/systemv/lp.c @@ -1,9 +1,9 @@ /* - * "$Id: lp.c 5925 2006-09-05 19:43:11Z mike $" + * "$Id: lp.c 6356 2007-03-19 13:54:48Z mike $" * * "lp" command for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products. + * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -290,7 +290,7 @@ main(int argc, /* I - Number of command-line arguments */ snprintf(email, sizeof(email), "mailto:%s@%s", cupsUser(), httpGetHostname(NULL, buffer, sizeof(buffer))); - num_options = cupsAddOption("notify-recipient", email, + num_options = cupsAddOption("notify-recipient-uri", email, num_options, &options); } @@ -840,5 +840,5 @@ sighandler(int s) /* I - Signal number */ /* - * End of "$Id: lp.c 5925 2006-09-05 19:43:11Z mike $". + * End of "$Id: lp.c 6356 2007-03-19 13:54:48Z mike $". */ diff --git a/systemv/lpoptions.c b/systemv/lpoptions.c index e6778acc9..582213204 100644 --- a/systemv/lpoptions.c +++ b/systemv/lpoptions.c @@ -1,5 +1,5 @@ /* - * "$Id: lpoptions.c 6202 2007-01-22 21:37:45Z mike $" + * "$Id: lpoptions.c 6347 2007-03-18 03:21:36Z mike $" * * Printer option program for the Common UNIX Printing System (CUPS). * @@ -174,6 +174,12 @@ main(int argc, /* I - Number of command-line arguments */ if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL) dest = dests; + if (dest == NULL) + { + _cupsLangPuts(stderr, _("lpoptions: No printers!?!\n")); + return (1); + } + for (j = 0; j < dest->num_options; j ++) if (cupsGetOption(dest->options[j].name, num_options, options) == NULL) num_options = cupsAddOption(dest->options[j].name, @@ -244,6 +250,12 @@ main(int argc, /* I - Number of command-line arguments */ if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL) dest = dests; + if (dest == NULL) + { + _cupsLangPuts(stderr, _("lpoptions: No printers!?!\n")); + return (1); + } + for (j = 0; j < dest->num_options; j ++) if (cupsGetOption(dest->options[j].name, num_options, options) == NULL) num_options = cupsAddOption(dest->options[j].name, @@ -484,5 +496,5 @@ usage(void) /* - * End of "$Id: lpoptions.c 6202 2007-01-22 21:37:45Z mike $". + * End of "$Id: lpoptions.c 6347 2007-03-18 03:21:36Z mike $". */ diff --git a/templates/admin.tmpl b/templates/admin.tmpl index 056790dfd..137e26475 100644 --- a/templates/admin.tmpl +++ b/templates/admin.tmpl @@ -67,6 +67,7 @@ CLASS="button"> Share published printers connected to this system
             Allow printing from the Internet
    Allow remote administration
    +{have_gssapi? Use Kerberos authentication
    :} Allow users to cancel any job (not just their own)
    Save debugging information for troubleshooting

    diff --git a/templates/de/admin.tmpl b/templates/de/admin.tmpl index 170c42c36..da45641b4 100644 --- a/templates/de/admin.tmpl +++ b/templates/de/admin.tmpl @@ -67,6 +67,7 @@ CLASS="button"> Verteile publizierte Drucker welche mit diesem System verbunden sind
             Allow printing from the Internet
    Erlaube entfernte Verwaltung
    +{have_gssapi? Use Kerberos authentication
    :} Erlaube Benutzern jeden Auftrag abzubrechen (nicht nur die Eigenen)
    Speichere Fehlerinformationen für Fehlersuche

    diff --git a/templates/es/admin.tmpl b/templates/es/admin.tmpl index 3cd99e0dc..2f03f48d4 100644 --- a/templates/es/admin.tmpl +++ b/templates/es/admin.tmpl @@ -67,6 +67,7 @@ CLASS="button"> Compartir impresoras públicas conectadas a este sistema
             Allow printing from the Internet
    Permitir administración remota
    +{have_gssapi? Use Kerberos authentication
    :} Permitir a los usuarios cancelar cualquier trabajo (no sólo los suyos propios)
    Guardar información de depuración para búsqueda de problemas

    diff --git a/templates/et/admin.tmpl b/templates/et/admin.tmpl index e7d38428a..fd47b90c4 100644 --- a/templates/et/admin.tmpl +++ b/templates/et/admin.tmpl @@ -67,6 +67,7 @@ CLASS="button"> Aktiivse süsteemiga ühendatud avaldatud printerite jagamine
             Allow printing from the Internet
    Võrguhalduse lubamine
    +{have_gssapi? Use Kerberos authentication
    :} Kasutajatel lubatakse katkestada kõiki töid (mitte ainult enda omi)
    Silumisinfo salvestamine probleemide tuvastamiseks

    diff --git a/templates/fr/admin.tmpl b/templates/fr/admin.tmpl index e0486ef67..78c7f170d 100644 --- a/templates/fr/admin.tmpl +++ b/templates/fr/admin.tmpl @@ -70,6 +70,7 @@ imprimantes publiques connectées à ce système
             Allow printing from the Internet
    Autoriser l'administration à distance
    +{have_gssapi? Use Kerberos authentication
    :} Autoriser les utilisateurs à annuler n'importe quelle tâche ( pas seulement les leurs )
    Enregistrer les diff --git a/templates/it/admin.tmpl b/templates/it/admin.tmpl index b7526b3cf..f74ffdedd 100644 --- a/templates/it/admin.tmpl +++ b/templates/it/admin.tmpl @@ -67,6 +67,7 @@ CLASS="button"> Condividi le stampanti pubblicate connesse a questo sistema
             Allow printing from the Internet
    Consenti amministrazione remota
    +{have_gssapi? Use Kerberos authentication
    :} Consenti agli utenti di annullare qualunque operazione (non solo le proprie)
    Salva le informazioni di debug per la risoluzione di problemi

    diff --git a/templates/ja/admin.tmpl b/templates/ja/admin.tmpl index ad8a5b7d1..03512ac8c 100644 --- a/templates/ja/admin.tmpl +++ b/templates/ja/admin.tmpl @@ -65,6 +65,7 @@ CLASS="button"> このシステムに接続されている公開済みプリンタを共有
             Allow printing from the Internet
    リモート管理を許可
    +{have_gssapi? Use Kerberos authentication
    :} どのジョブであってもキャンセルすることを (たとえ所有者でなくても) ユーザに許可
    トラブルシューティングのためにデバッグ情報を保存

    diff --git a/templates/pl/admin.tmpl b/templates/pl/admin.tmpl index 12e40cd1c..1302a78d5 100644 --- a/templates/pl/admin.tmpl +++ b/templates/pl/admin.tmpl @@ -65,6 +65,7 @@ CLASS="button"> Udostępnij opublikowane drukarki połączone do tego systemu
             Allow printing from the Internet
    Pozwól na zdalną administrację
    +{have_gssapi? Use Kerberos authentication
    :} Pozwól użytkownikom na anulowanie każdego zadania (nie tylko ich)
    Zapisz informacje o debugowaniu do rozwiązywania problemów

    diff --git a/templates/sv/admin.tmpl b/templates/sv/admin.tmpl index ff80be8b8..690ec5811 100644 --- a/templates/sv/admin.tmpl +++ b/templates/sv/admin.tmpl @@ -67,6 +67,7 @@ CLASS="button"> Dela ut publicerade skrivare anslutna till detta system
             Allow printing from the Internet
    Tillåt fjärradministration
    +{have_gssapi? Use Kerberos authentication
    :} Tillåt användare att avbryta alla jobb (inte bara sina egna)
    Spara felsökningsinformation för problemlösning

    diff --git a/tools/buttons.gif b/tools/buttons.gif new file mode 100644 index 0000000000000000000000000000000000000000..080dc861445e22864699cad9f8e92781456ac69f GIT binary patch literal 35 mc-nLKbh9u|WMp7uXkcWxa%Bkv1A`6_Gk`=Gn3!A`8LR /dev/null 2>&1; then + add_arrows=1 + txt="`echo $txt | sed 's|@UP||g'`" + elif echo $txt | grep '@DOWN' > /dev/null 2>&1; then + add_arrows=2 + txt="`echo $txt | sed 's|@DOWN||g'`" + fi + + tmp_btn=/tmp/cups-btn-$$.bmp + + # First step: generate an image trimmed to the text. + # -> annotate a 40x400 rectangle with the provided text + # -> trim to the text + convert $base -extent 400x40 -fill "$fgclr" \ + -draw "rectangle 0,0 399,39" \ + -fill "#ffffff" -encoding Unicode -pointsize 13 -font "$font" \ + -gravity Center -annotate 0x0+0+0 "$txt" -trim $tmp_btn + + # From the 1st step, we get text width and height + txt_h=`identify -format "%h" $tmp_btn` + txt_w=`identify -format "%w" $tmp_btn` + + if test $txt_h -gt 32; then + echo "ERROR: 2 lines maximum for the button text" + exit 1 + fi + + # With the default font, one line is less than 16 pixels high, and a + # two lines of text is at least 20 pixels high. So, from the text + # height we guess if we need a one- or two-line button. + if test $txt_h -ge 18; then + btn_h=40 + else + btn_h=20 + fi + + if test $add_arrows -gt 0; then + if test $btn_h -eq 20; then + txt_w=`expr $txt_w + 36` + elif test $btn_h -eq 40; then + txt_w=`expr $txt_w + 58` + fi + fi + + # Second step: generate the button. + # + # Procedure: + # + # - Draw a rectangle with the background color (for correct + # button borders) + # - Draw a roundRectangle (args are coordinates, not lengths!) + # - Make the background transparent (with correct fuzz feature) + # - Annotate centered text (in height, it is necessary to have + # -1 in y parameter so that the text is not too low) + rad=`expr $btn_h / 2` + btn_w=`expr $txt_w + $rad + $rad` + btn_top=`expr $btn_h - 1` + + convert $base \ + -extent $btn_w'x'$btn_h -fill "$bgclr" \ + -draw "rectangle 0,0 $btn_w,$btn_h" -fill "$fgclr" \ + -draw "roundRectangle 0,0 `expr $btn_w - 1`,$btn_top `expr $rad - 1`,$rad" \ + -fuzz $fuzz -transparent "$bgclr" -write $filename \ + -fill "#ffffff" -encoding Unicode -pointsize 13 \ + -font "$font" -gravity Center -annotate 0x0+0-1 "$txt" \ + $filename + + if test $add_arrows -gt 0; then + if test $add_arrows -eq 1; then + # UP arrows + if test $btn_h -eq 20; then + # 1-line buttons + pts1="9,15 21,15 15,4" + pts2="`expr $btn_w - 10`,15 `expr $btn_w - 22`,15 `expr $btn_w - 16`,4" + else + # 2-line buttons + pts1="16,30 34,30 25,10" + pts2="`expr $btn_w - 17`,30 `expr $btn_w - 35`,30 `expr $btn_w - 26`,10" + fi + else + # DOWN arrows + if [ $btn_h -eq 20 ]; then + # 1-line buttons + pts1="9,4 21,4 15,15" + pts2="`expr $btn_w - 10`,4 `expr $btn_w - 22`,4 `expr $btn_w - 16`,15" + else + # 2-line buttons + pts1="16,10 34,10 25,30" + pts2="`expr $btn_w - 17`,10 `expr $btn_w - 35`,10 `expr $btn_w - 26`,30" + fi + fi + + convert $filename -fill "#ffffff" -draw "polygon $pts1" \ + -draw "polygon $pts2" $filename + fi + + rm -f $tmp_btn +} + +# Make sure the locale-specific destination directory exists... +if test ! -d doc/$locale/images; then + echo Creating doc/$locale/images... + mkdir -p doc/$locale/images +fi + +# Process each line in the file... +cat $list | while read line; do + if test "x`echo $line | cut -c1`" = "x#"; then + continue + fi + + generate_button doc/$locale/images/$line +done + +# +# End of "$Id$". +# -- 2.39.5