From 229681c188bf1940a4963a5796df4be65bb00825 Mon Sep 17 00:00:00 2001 From: msweet Date: Fri, 3 Dec 2010 06:58:01 +0000 Subject: [PATCH] Merge changes from CUPS 1.5svn-r9400 git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@2890 a1ca3aef-8c08-0410-bb20-df032aa958be --- CHANGES-1.4.txt | 10 + CHANGES.txt | 4 +- Makefile | 2 + backend/snmp-supplies.c | 36 ++- conf/cupsd.conf.in | 3 + config-scripts/cups-common.m4 | 6 + config-scripts/cups-defaults.m4 | 25 ++ config.h.in | 16 +- cups/http-support.c | 3 + cups/http.h | 3 +- doc/help/ref-cupsd-conf.html.in | 13 ++ filter/bannertops.c | 2 +- filter/pstext.c | 4 +- filter/pstops.c | 10 +- filter/texttops.c | 4 +- locale/Makefile | 17 +- man/cupsd.conf.man.in | 5 + scheduler/client.c | 107 ++++++++- scheduler/conf.c | 4 +- scheduler/conf.h | 4 +- scheduler/ipp.c | 400 ++++++++++++++++++++++++++++---- scheduler/job.c | 2 +- systemv/lpstat.c | 43 ++-- 23 files changed, 621 insertions(+), 102 deletions(-) diff --git a/CHANGES-1.4.txt b/CHANGES-1.4.txt index 2dfb2c414..97ccb0631 100644 --- a/CHANGES-1.4.txt +++ b/CHANGES-1.4.txt @@ -1,6 +1,16 @@ CHANGES-1.4.txt --------------- +CHANGES IN CUPS V1.4.7 + + - The scheduler did not always show the most recent status message from + the print filters (STR #3731) + - The PostScript filter did not apply the mirror and number-up options + properly, leading to offset and clipped output (STR #3732) + - The network backends always reported "low toner" or "out of toner" + states, even for inkjet printers (STR #3733) + + CHANGES IN CUPS V1.4.6 - Regression: The pstops filter did not support landscape printing of diff --git a/CHANGES.txt b/CHANGES.txt index 008b91b37..66066105b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,8 +1,10 @@ -CHANGES.txt - 2010-11-05 +CHANGES.txt - 2010-12-01 ------------------------ CHANGES IN CUPS V1.5b1 + - The web interface can now be disabled using the WebInterface directive + in cupsd.conf (STR #2625) - The scheduler now provides privacy controls for jobs and subscriptions (STR #2969) - Added new cupsArrayNew3 API which offers memory management of array diff --git a/Makefile b/Makefile index d2dafad75..3babe2cc3 100644 --- a/Makefile +++ b/Makefile @@ -160,6 +160,8 @@ install: install-data install-headers install-libs install-exec # install-data: + echo Making all in cups... + (cd cups; $(MAKE) $(MFLAGS) all) for dir in $(DIRS); do\ echo Installing data files in $$dir... ;\ (cd $$dir; $(MAKE) $(MFLAGS) install-data) || exit 1;\ diff --git a/backend/snmp-supplies.c b/backend/snmp-supplies.c index 8ee031d69..af2ba7d95 100644 --- a/backend/snmp-supplies.c +++ b/backend/snmp-supplies.c @@ -66,7 +66,9 @@ static http_addr_t current_addr; /* Current address */ static int current_state = -1; /* Current device state bits */ static int charset = -1; /* Character set for supply names */ -static int num_supplies = 0; +static int laser_printer = -1, + /* Laser printer with toner? */ + num_supplies = 0; /* Number of supplies found */ static backend_supplies_t supplies[CUPS_MAX_SUPPLIES]; /* Supply information */ @@ -197,7 +199,6 @@ backendSNMPSupplies( /* marker-levels value string */ *ptr; /* Pointer into value string */ cups_snmp_t packet; /* SNMP response packet */ - /* * Generate the marker-levels value string... @@ -242,13 +243,33 @@ backendSNMPSupplies( else change_state = current_state ^ new_state; + fprintf(stderr, "DEBUG: new_state=%x, change_state=%x, laser_printer=%d\n", + new_state, change_state, laser_printer); + for (i = 0; i < (int)(sizeof(printer_states) / sizeof(printer_states[0])); i ++) if (change_state & printer_states[i].bit) - fprintf(stderr, "STATE: %c%s\n", - (new_state & printer_states[i].bit) ? '+' : '-', - printer_states[i].keyword); + { + if (!laser_printer && !strncmp(printer_states[i].keyword, "toner-", 6)) + { + /* + * Map toner-xxx to marker-supply-xxx to avoid confusing "out of toner" + * messages on inkjet print queues... + */ + + if (printer_states[i].bit == CUPS_TC_lowToner) + fprintf(stderr, "STATE: %cmarker-supply-low-report\n", + (new_state & CUPS_TC_lowToner) ? '+' : '-'); + else + fprintf(stderr, "STATE: %cmarker-supply-empty-warning\n", + (new_state & CUPS_TC_noToner) ? '+' : '-'); + } + else + fprintf(stderr, "STATE: %c%s\n", + (new_state & printer_states[i].bit) ? '+' : '-', + printer_states[i].keyword); + } current_state = new_state; @@ -590,6 +611,8 @@ backend_init_supplies( * Output the marker-types attribute... */ + laser_printer = 0; + for (i = 0, ptr = value; i < num_supplies; i ++, ptr += strlen(ptr)) { if (i) @@ -597,6 +620,9 @@ backend_init_supplies( type = supplies[i].type; + if (type == CUPS_TC_toner) + laser_printer = 1; + if (type < CUPS_TC_other || type > CUPS_TC_covers) strcpy(ptr, "unknown"); else diff --git a/conf/cupsd.conf.in b/conf/cupsd.conf.in index 1a2037cfa..1950e05e3 100644 --- a/conf/cupsd.conf.in +++ b/conf/cupsd.conf.in @@ -26,6 +26,9 @@ BrowseLocalProtocols @CUPS_BROWSE_LOCAL_PROTOCOLS@ # Default authentication type, when authentication is required... DefaultAuthType Basic +# Web interface setting... +WebInterface @CUPS_WEBIF@ + # Restrict access to the server... Order allow,deny diff --git a/config-scripts/cups-common.m4 b/config-scripts/cups-common.m4 index d99b86301..1c2f4d25b 100644 --- a/config-scripts/cups-common.m4 +++ b/config-scripts/cups-common.m4 @@ -323,6 +323,12 @@ case $uname in dnl Check for dynamic store function... AC_CHECK_FUNCS(SCDynamicStoreCopyComputerName) + dnl Check for new ColorSync APIs... + SAVELIBS="$LIBS" + LIBS="$LIBS -framework ApplicationServices" + AC_CHECK_FUNCS(ColorSyncRegisterDevice) + LIBS="$SAVELIBS" + 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)) diff --git a/config-scripts/cups-defaults.m4 b/config-scripts/cups-defaults.m4 index 5e98f124d..314426632 100644 --- a/config-scripts/cups-defaults.m4 +++ b/config-scripts/cups-defaults.m4 @@ -470,6 +470,31 @@ fi AC_SUBST(FONTS) +dnl Web interface... +AC_ARG_ENABLE(webif, [ --enable-webif enable the web interface by default, default=no for Mac OS X]) +case "x$enable_webif" in + xno) + CUPS_WEBIF=No + CUPS_DEFAULT_WEBIF=0 + ;; + xyes) + CUPS_WEBIF=Yes + CUPS_DEFAULT_WEBIF=1 + ;; + *) + if test $uname = Darwin; then + CUPS_WEBIF=No + CUPS_DEFAULT_WEBIF=0 + else + CUPS_WEBIF=Yes + CUPS_DEFAULT_WEBIF=1 + fi + ;; +esac + +AC_SUBST(CUPS_WEBIF) +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_WEBIF, $CUPS_DEFAULT_WEBIF) + dnl dnl End of "$Id: cups-defaults.m4 7959 2008-09-17 19:30:58Z mike $". dnl diff --git a/config.h.in b/config.h.in index f1c5fd300..1e0c22d2f 100644 --- a/config.h.in +++ b/config.h.in @@ -100,12 +100,19 @@ /* - * Do we have domain socket support? + * Do we have domain socket support, and if so what is the default one? */ #undef CUPS_DEFAULT_DOMAINSOCKET +/* + * Default WebInterface value... + */ + +#undef CUPS_DEFAULT_WEBIF + + /* * Where are files stored? * @@ -694,6 +701,13 @@ #undef CUPS_BUNDLEDIR +/* + * Do we have the ColorSyncRegisterDevice function? + */ + +#undef HAVE_COLORSYNCREGISTERDEVICE + + #endif /* !_CUPS_CONFIG_H_ */ /* diff --git a/cups/http-support.c b/cups/http-support.c index 1c5697cc6..255f760e5 100644 --- a/cups/http-support.c +++ b/cups/http-support.c @@ -1253,6 +1253,9 @@ httpStatus(http_status_t status) /* I - HTTP status code */ case HTTP_PKI_ERROR : s = _("SSL/TLS Negotiation Error"); break; + case HTTP_WEBIF_DISABLED : + s = _("Web Interface is Disabled"); + break; default : s = _("Unknown"); diff --git a/cups/http.h b/cups/http.h index 8dc79096c..bd6e4571d 100644 --- a/cups/http.h +++ b/cups/http.h @@ -251,7 +251,8 @@ typedef enum http_status_e /**** HTTP status codes ****/ HTTP_NOT_SUPPORTED, /* HTTP version not supported */ HTTP_AUTHORIZATION_CANCELED = 1000, /* User canceled authorization @since CUPS 1.4@ */ - HTTP_PKI_ERROR /* Error negotiating a secure connection @since CUPS 1.5@ */ + HTTP_PKI_ERROR, /* Error negotiating a secure connection @since CUPS 1.5@ */ + HTTP_WEBIF_DISABLED /* Web interface is disabled @private@ */ } http_status_t; typedef enum http_uri_status_e /**** URI separation status @since CUPS 1.2@ ****/ diff --git a/doc/help/ref-cupsd-conf.html.in b/doc/help/ref-cupsd-conf.html.in index d3610cb84..9114c489c 100644 --- a/doc/help/ref-cupsd-conf.html.in +++ b/doc/help/ref-cupsd-conf.html.in @@ -3180,5 +3180,18 @@ user whose ID is 0.

+

CUPS 1.5WebInterface

+ +

Examples

+ +
+WebInterface yes
+WebInterface no
+
+ +

Description

+ +

The WebInterface directive specifies whether the web interface is enabled. The default value is @CUPS_WEBIF@.

+ diff --git a/filter/bannertops.c b/filter/bannertops.c index ff7c2d187..db485f1fb 100644 --- a/filter/bannertops.c +++ b/filter/bannertops.c @@ -180,7 +180,7 @@ load_banner(const char *filename) /* I - Filename or NULL for stdin */ if (!fp) { - _cupsLangPrintError(stderr, "ERROR", _("Unable to open print file")); + _cupsLangPrintError("ERROR", _("Unable to open print file")); exit(1); } diff --git a/filter/pstext.c b/filter/pstext.c index 7d11885ce..2b38b3af7 100644 --- a/filter/pstext.c +++ b/filter/pstext.c @@ -244,7 +244,7 @@ psTextInitialize(void) } else { - _cupsLangPrintError(stderr, "ERROR", _("Unable to open print file")); + _cupsLangPrintError("ERROR", _("Unable to open print file")); exit(1); } @@ -260,7 +260,7 @@ psTextInitialize(void) * Can't open charset file! */ - _cupsLangPrintError(stderr, "ERROR", _("Unable to open print file")); + _cupsLangPrintError("ERROR", _("Unable to open print file")); exit(1); } diff --git a/filter/pstops.c b/filter/pstops.c index 14bf86dbf..12ed2714b 100644 --- a/filter/pstops.c +++ b/filter/pstops.c @@ -2917,9 +2917,6 @@ start_nup(pstops_doc_t *doc, /* I - Document information */ else if (doc->number_up > 1 || doc->fitplot) doc_printf(doc, "%.1f %.1f translate\n", PageLeft, PageBottom); - if (doc->mirror) - doc_printf(doc, "%.1f 0.0 translate -1 1 scale\n", PageWidth); - switch (doc->number_up) { default : @@ -3269,6 +3266,13 @@ start_nup(pstops_doc_t *doc, /* I - Document information */ bboxx + margin, bboxy + margin, bboxw - 2 * margin, bboxl - 2 * margin); } + + /* + * Mirror the page as needed... + */ + + if (doc->mirror) + doc_printf(doc, "%.1f 0.0 translate -1 1 scale\n", PageWidth); } diff --git a/filter/texttops.c b/filter/texttops.c index ecf5f6adc..af549cefa 100644 --- a/filter/texttops.c +++ b/filter/texttops.c @@ -260,7 +260,7 @@ WriteProlog(const char *title, /* I - Title of job */ } else { - _cupsLangPrintError(stderr, "ERROR", _("Unable to open psglyphs")); + _cupsLangPrintError("ERROR", _("Unable to open psglyphs")); exit(1); } @@ -279,7 +279,7 @@ WriteProlog(const char *title, /* I - Title of job */ * Can't open charset file! */ - _cupsLangPrintError(stderr, "ERROR", _("Unable to open charset file")); + _cupsLangPrintError("ERROR", _("Unable to open charset file")); exit(1); } diff --git a/locale/Makefile b/locale/Makefile index fcfd30178..1039addc7 100644 --- a/locale/Makefile +++ b/locale/Makefile @@ -157,8 +157,9 @@ pot: checkpo po2strings checkpo: checkpo.o ../cups/$(LIBCUPSSTATIC) echo Linking $<... - $(CC) $(LDFLAGS) -o checkpo checkpo.o ../cups/$(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o checkpo checkpo.o \ + ../cups/$(LIBCUPSSTATIC) $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \ + $(COMMONLIBS) $(LIBZ) checkall: checkpo for file in *.po; do \ @@ -175,8 +176,9 @@ checkall: checkpo po2strings: po2strings.o ../cups/$(LIBCUPSSTATIC) echo Linking $<... - $(CC) $(LDFLAGS) -o po2strings po2strings.o ../cups/$(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o po2strings po2strings.o \ + ../cups/$(LIBCUPSSTATIC) $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \ + $(COMMONLIBS) $(LIBZ) # @@ -188,7 +190,7 @@ po2strings: po2strings.o ../cups/$(LIBCUPSSTATIC) strings2po: strings2po.o echo Linking $<... - $(CC) $(LDFLAGS) -o strings2po strings2po.o + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o strings2po strings2po.o # @@ -200,8 +202,9 @@ strings2po: strings2po.o translate: translate.o ../cups/$(LIBCUPSSTATIC) echo Linking $<... - $(CC) $(LDFLAGS) -o translate translate.o ../cups/$(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o translate translate.o \ + ../cups/$(LIBCUPSSTATIC) $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \ + $(COMMONLIBS) $(LIBZ) # diff --git a/man/cupsd.conf.man.in b/man/cupsd.conf.man.in index d32412110..6582de577 100644 --- a/man/cupsd.conf.man.in +++ b/man/cupsd.conf.man.in @@ -742,6 +742,11 @@ Specifies the HTTP request timeout in seconds. User user-name .br Specifies the user name or ID that is used when running external programs. +.TP 5 +WebInterface yes +.TP 5 +WebInterface no +Specifies whether the web interface is enabled. .SH SEE ALSO \fIclasses.conf(5)\fR, \fIcupsd(8)\fR, \fImime.convs(5)\fR, \fImime.types(5)\fR, \fIprinters.conf(5)\fR, diff --git a/scheduler/client.c b/scheduler/client.c index f6a446195..1d0dcf12e 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -1369,13 +1369,27 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ } } - if ((!strncmp(con->uri, "/admin", 6) && - strncmp(con->uri, "/admin/conf/", 12) && - strncmp(con->uri, "/admin/log/", 11)) || - !strncmp(con->uri, "/printers", 9) || - !strncmp(con->uri, "/classes", 8) || - !strncmp(con->uri, "/help", 5) || - !strncmp(con->uri, "/jobs", 5)) + if (!WebInterface) + { + /* + * Web interface is disabled. Show an appropriate message... + */ + + if (!cupsdSendError(con, HTTP_WEBIF_DISABLED, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + break; + } + else if ((!strncmp(con->uri, "/admin", 6) && + strncmp(con->uri, "/admin/conf/", 12) && + strncmp(con->uri, "/admin/log/", 11)) || + !strncmp(con->uri, "/printers", 9) || + !strncmp(con->uri, "/classes", 8) || + !strncmp(con->uri, "/help", 5) || + !strncmp(con->uri, "/jobs", 5)) { /* * Send CGI output... @@ -1580,6 +1594,20 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ if (!strcmp(con->http.fields[HTTP_FIELD_CONTENT_TYPE], "application/ipp")) con->request = ippNew(); + else if (!WebInterface) + { + /* + * Web interface is disabled. Show an appropriate message... + */ + + if (!cupsdSendError(con, HTTP_WEBIF_DISABLED, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + break; + } else if ((!strncmp(con->uri, "/admin", 6) && strncmp(con->uri, "/admin/conf/", 12) && strncmp(con->uri, "/admin/log/", 11)) || @@ -1796,6 +1824,52 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ break; } } + else if (!strncmp(con->uri, "/printers/", 10) && + !strcmp(con->uri + strlen(con->uri) - 4, ".png")) + { + /* + * Send PNG file - get the real printer name since printer + * names are not case sensitive but filenames can be... + */ + + con->uri[strlen(con->uri) - 4] = '\0'; /* Drop ".ppd" */ + + if ((p = cupsdFindPrinter(con->uri + 10)) != NULL) + snprintf(con->uri, sizeof(con->uri), "/icons/%s.png", p->name); + else + { + if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + break; + } + } + else if (!WebInterface) + { + if (!cupsdSendHeader(con, HTTP_OK, line, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + if (httpPrintf(HTTP(con), "\r\n") < 0) + { + cupsdCloseClient(con); + return; + } + + if (cupsdFlushHeader(con) < 0) + { + cupsdCloseClient(con); + return; + } + + con->http.state = HTTP_WAITING; + break; + } if ((!strncmp(con->uri, "/admin", 6) && strncmp(con->uri, "/admin/conf/", 12) && @@ -2411,6 +2485,10 @@ cupsdSendError(cupsd_client_t *con, /* I - Connection */ "CONTENT=\"3;URL=https://%s:%d%s\">\n", con->servername, con->serverport, con->uri); } + else if (code == HTTP_WEBIF_DISABLED) + text = _cupsLangString(con->language, + _("The web interface is currently disabled. Run " + "\"cupsctl WebInterface=yes\" to enable it.")); else text = ""; @@ -2421,17 +2499,17 @@ cupsdSendError(cupsd_client_t *con, /* I - Connection */ "\n" "\t\n" - "\t%d %s\n" + "\t%s - " CUPS_SVERSION "\n" "\t\n" "%s" "\n" "\n" - "

%d %s

\n" + "

%s

\n" "

%s

\n" "\n" "\n", - code, httpStatus(code), redirect, code, httpStatus(code), text); + httpStatus(code), redirect, httpStatus(code), text); if (httpPrintf(HTTP(con), "Content-Type: text/html; charset=utf-8\r\n") < 0) return (0); @@ -2486,6 +2564,15 @@ cupsdSendHeader( return (httpPrintf(HTTP(con), "HTTP/%d.%d 100 Continue\r\n\r\n", con->http.version / 100, con->http.version % 100) > 0); } + else if (code == HTTP_WEBIF_DISABLED) + { + /* + * Treat our special "web interface is disabled" status as "200 OK" for web + * browsers. + */ + + code = HTTP_OK; + } httpFlushWrite(HTTP(con)); diff --git a/scheduler/conf.c b/scheduler/conf.c index b85c79ce6..1f629e5c4 100644 --- a/scheduler/conf.c +++ b/scheduler/conf.c @@ -180,7 +180,8 @@ static const cupsd_var_t variables[] = #endif /* HAVE_AUTHORIZATION_H */ { "TempDir", &TempDir, CUPSD_VARTYPE_PATHNAME }, { "Timeout", &Timeout, CUPSD_VARTYPE_INTEGER }, - { "UseNetworkDefault", &UseNetworkDefault, CUPSD_VARTYPE_BOOLEAN } + { "UseNetworkDefault", &UseNetworkDefault, CUPSD_VARTYPE_BOOLEAN }, + { "WebInterface", &WebInterface, CUPSD_VARTYPE_BOOLEAN } }; #define NUM_VARS (sizeof(variables) / sizeof(variables[0])) @@ -632,6 +633,7 @@ cupsdReadConfiguration(void) RootCertDuration = 300; Timeout = DEFAULT_TIMEOUT; NumSystemGroups = 0; + WebInterface = CUPS_DEFAULT_WEBIF; BrowseInterval = DEFAULT_INTERVAL; BrowsePort = ippPort(); diff --git a/scheduler/conf.h b/scheduler/conf.h index c98e89a00..86a3e5a07 100644 --- a/scheduler/conf.h +++ b/scheduler/conf.h @@ -219,8 +219,10 @@ VAR int MaxClients VALUE(100), /* Format of printcap file? */ DefaultShared VALUE(TRUE), /* Share printers by default? */ - MultipleOperationTimeout VALUE(DEFAULT_TIMEOUT); + MultipleOperationTimeout VALUE(DEFAULT_TIMEOUT), /* multiple-operation-time-out value */ + WebInterface VALUE(CUPS_DEFAULT_WEBIF); + /* Enable the web interface? */ VAR cups_file_t *AccessFile VALUE(NULL), /* Access log file */ *ErrorFile VALUE(NULL), diff --git a/scheduler/ipp.c b/scheduler/ipp.c index 207596c08..1122665bc 100644 --- a/scheduler/ipp.c +++ b/scheduler/ipp.c @@ -116,6 +116,9 @@ #ifdef __APPLE__ # include +# ifdef HAVE_COLORSYNCREGISTERDEVICE +extern CFUUIDRef ColorSyncCreateUUIDFromUInt32(unsigned id); +# endif /* HAVE_COLORSYNCREGISTERDEVICE */ # include # ifdef HAVE_MEMBERSHIP_H # include @@ -149,9 +152,13 @@ static void add_printer_state_reasons(cupsd_client_t *con, static void add_queued_job_count(cupsd_client_t *con, cupsd_printer_t *p); #ifdef __APPLE__ static void apple_init_profile(ppd_file_t *ppd, cups_array_t *languages, - CMDeviceProfileInfo *profile, unsigned id, - const char *name, const char *text, - const char *iccfile); +# ifdef HAVE_COLORSYNCREGISTERDEVICE + CFMutableDictionaryRef profile, +# else + CMDeviceProfileInfo *profile, +# endif /* HAVE_COLORSYNCREGISTERDEVICE */ + unsigned id, const char *name, + const char *text, const char *iccfile); static void apple_register_profiles(cupsd_printer_t *p); static void apple_unregister_profiles(cupsd_printer_t *p); #endif /* __APPLE__ */ @@ -3108,15 +3115,21 @@ add_queued_job_count( static void apple_init_profile( - ppd_file_t *ppd, /* I - PPD file */ - cups_array_t *languages, /* I - Languages in the PPD file */ - CMDeviceProfileInfo *profile, /* I - Profile record */ - unsigned id, /* I - Profile ID */ - const char *name, /* I - Profile name */ - const char *text, /* I - Profile UI text */ - const char *iccfile) /* I - ICC filename */ + ppd_file_t *ppd, /* I - PPD file */ + cups_array_t *languages, /* I - Languages in the PPD file */ +# ifdef HAVE_COLORSYNCREGISTERDEVICE + CFMutableDictionaryRef profile, /* I - Profile dictionary */ +# else + CMDeviceProfileInfo *profile, /* I - Profile record */ +# endif /* HAVE_COLORSYNCREGISTERDEVICE */ + unsigned id, /* I - Profile ID */ + const char *name, /* I - Profile name */ + const char *text, /* I - Profile UI text */ + const char *iccfile) /* I - ICC filename */ { - char url[1024]; /* URL for profile filename */ +# ifdef HAVE_COLORSYNCREGISTERDEVICE + CFURLRef url; /* URL for profile filename */ +# endif /* HAVE_COLORSYNCREGISTERDEVICE */ CFMutableDictionaryRef dict; /* Dictionary for name */ char *language; /* Current language */ ppd_attr_t *attr; /* Profile attribute */ @@ -3137,7 +3150,7 @@ apple_init_profile( if (cftext) { - CFDictionarySetValue(dict, CFSTR("en"), cftext); + CFDictionarySetValue(dict, CFSTR("en_US"), cftext); CFRelease(cftext); } @@ -3187,10 +3200,24 @@ apple_init_profile( * Fill in the profile data... */ - if (iccfile) - httpAssembleURI(HTTP_URI_CODING_ALL, url, sizeof(url), "file", NULL, "", 0, - iccfile); +# ifdef HAVE_COLORSYNCREGISTERDEVICE + if (iccfile) + { + url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, + (const UInt8 *)iccfile, + strlen(iccfile), false); + if (url) + { + CFDictionarySetValue(profile, kColorSyncDeviceProfileURL, url); + CFRelease(url); + } + } + + CFDictionarySetValue(profile, kColorSyncDeviceModeDescriptions, dict); + CFRelease(dict); + +# else profile->dataVersion = cmDeviceProfileInfoVersion1; profile->profileID = id; profile->profileLoc.locType = iccfile ? cmPathBasedProfile : cmNoProfileBase; @@ -3199,6 +3226,7 @@ apple_init_profile( if (iccfile) strlcpy(profile->profileLoc.u.pathLoc.path, iccfile, sizeof(profile->profileLoc.u.pathLoc.path)); +# endif /* HAVE_COLORSYNCREGISTERDEVICE */ } @@ -3230,13 +3258,19 @@ apple_register_profiles( ppd_option_t *cm_option; /* Color model option */ ppd_choice_t *cm_choice; /* Color model choice */ int num_profiles; /* Number of profiles */ - CMError error; /* Last error */ + CMError error = 0; /* Last error */ unsigned device_id, /* Printer device ID */ profile_id, /* Profile ID */ default_profile_id = 0; /* Default profile ID */ CFMutableDictionaryRef device_name; /* Printer device name dictionary */ CFStringRef printer_name; /* Printer name string */ + cups_array_t *languages; /* Languages array */ +# ifdef HAVE_COLORSYNCREGISTERDEVICE + CFMutableDictionaryRef profiles, /* Dictionary of profiles */ + profile; /* Current profile info dictionary */ + CFStringRef dict_key; /* Key in factory profile dictionary */ +# else CMDeviceScope scope = /* Scope of the registration */ { kCFPreferencesAnyUser, @@ -3244,15 +3278,21 @@ apple_register_profiles( }; CMDeviceProfileArrayPtr profiles; /* Profiles */ CMDeviceProfileInfo *profile; /* Current profile */ - cups_array_t *languages; /* Languages array */ +# endif /* HAVE_COLORSYNCREGISTERDEVICE */ /* * Make sure ColorSync is available... */ +# ifdef HAVE_COLORSYNCREGISTERDEVICE + if (ColorSyncRegisterDevice == NULL) + return; + +# else if (CMRegisterColorDevice == NULL) return; +# endif /* HAVE_COLORSYNCREGISTERDEVICE */ /* * Try opening the PPD file for this printer... @@ -3289,6 +3329,22 @@ apple_register_profiles( num_profiles ++; } +# ifdef HAVE_COLORSYNCREGISTERDEVICE + /* + * Create a dictionary for the factory profiles... + */ + + profiles = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + if (!profiles) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate memory for factory profiles."); + ppdClose(ppd); + return; + } +# endif /* HAVE_COLORSYNCREGISTERDEVICE */ /* * If we have profiles, add them... @@ -3358,6 +3414,7 @@ apple_register_profiles( q3_choice = NULL; } +# ifndef HAVE_COLORSYNCREGISTERDEVICE /* * Build the array of profiles... * @@ -3367,17 +3424,22 @@ apple_register_profiles( if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL) { cupsdLogMessage(CUPSD_LOG_ERROR, - "Unable to allocate memory for %d profiles", - num_profiles); + "Unable to allocate memory for factory profiles."); ppdClose(ppd); return; } profiles->profileCount = num_profiles; - languages = _ppdGetLanguages(ppd); + profile = profiles->profiles; +# endif /* !HAVE_COLORSYNCREGISTERDEVICE */ - for (profile = profiles->profiles, - attr = ppdFindAttr(ppd, profile_key, NULL); + /* + * Loop through the profiles listed in the PPD... + */ + + languages = _ppdGetLanguages(ppd); + + for (attr = ppdFindAttr(ppd, profile_key, NULL); attr; attr = ppdFindNextAttr(ppd, profile_key, NULL)) if (attr->spec[0] && attr->value && attr->value[0]) @@ -3411,10 +3473,38 @@ apple_register_profiles( else profile_id = atoi(attr->spec); +# ifdef HAVE_COLORSYNCREGISTERDEVICE + profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + if (!profile) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate memory for color profile."); + CFRelease(profiles); + ppdClose(ppd); + return; + } + + apple_init_profile(ppd, languages, profile, profile_id, attr->spec, + attr->text[0] ? attr->text : attr->spec, iccfile); + + dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, + CFSTR("%u"), profile_id); + if (dict_key) + { + CFDictionarySetValue(profiles, dict_key, profile); + CFRelease(dict_key); + } + + CFRelease(profile); + +# else apple_init_profile(ppd, languages, profile, profile_id, attr->spec, attr->text[0] ? attr->text : attr->spec, iccfile); profile ++; +# endif /* HAVE_COLORSYNCREGISTERDEVICE */ /* * See if this is the default profile... @@ -3471,21 +3561,26 @@ apple_register_profiles( num_profiles = cm_option->num_choices; +# ifndef HAVE_COLORSYNCREGISTERDEVICE + /* + * Create an array for the factory profiles... + */ + if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL) { cupsdLogMessage(CUPSD_LOG_ERROR, - "Unable to allocate memory for %d profiles", - num_profiles); + "Unable to allocate memory for factory profiles."); ppdClose(ppd); return; } profiles->profileCount = num_profiles; + profile = profiles->profiles; +# endif /* HAVE_COLORSYNCREGISTERDEVICE */ - for (profile = profiles->profiles, i = cm_option->num_choices, - cm_choice = cm_option->choices; + for (i = cm_option->num_choices, cm_choice = cm_option->choices; i > 0; - i --, cm_choice ++, profile ++) + i --, cm_choice ++) { if (!strcmp(cm_choice->choice, "Gray") || !strcmp(cm_choice->choice, "Black")) @@ -3502,9 +3597,38 @@ apple_register_profiles( snprintf(selector, sizeof(selector), "%s..", profile_name); profile_id = _ppdHashName(selector); +# ifdef HAVE_COLORSYNCREGISTERDEVICE + profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + if (!profile) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate memory for color profile."); + CFRelease(profiles); + ppdClose(ppd); + return; + } + apple_init_profile(ppd, NULL, profile, profile_id, cm_choice->choice, cm_choice->text, NULL); + dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, + CFSTR("%u"), profile_id); + if (dict_key) + { + CFDictionarySetValue(profiles, dict_key, profile); + CFRelease(dict_key); + } + + CFRelease(profile); + +# else + apple_init_profile(ppd, NULL, profile, profile_id, cm_choice->choice, + cm_choice->text, NULL); + profile ++; +# endif /* HAVE_COLORSYNCREGISTERDEVICE */ + if (cm_choice->marked) default_profile_id = profile_id; } @@ -3519,31 +3643,133 @@ apple_register_profiles( num_profiles = (attr && ppd->colorspace == PPD_CS_GRAY) ? 1 : 2; +# ifdef HAVE_COLORSYNCREGISTERDEVICE + /* + * Add the grayscale profile first. We always have a grayscale profile. + */ + + profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + if (!profile) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate memory for color profile."); + CFRelease(profiles); + ppdClose(ppd); + return; + } + + profile_id = _ppdHashName("Gray.."); + apple_init_profile(ppd, NULL, profile, profile_id, "Gray", "Gray", NULL); + + dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"), + profile_id); + if (dict_key) + { + CFDictionarySetValue(profiles, dict_key, profile); + CFRelease(dict_key); + } + + CFRelease(profile); + + /* + * Then add the RGB/CMYK/DeviceN color profile... + */ + + profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + if (!profile) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate memory for color profile."); + CFRelease(profiles); + ppdClose(ppd); + return; + } + + switch (ppd->colorspace) + { + case PPD_CS_RGB : + case PPD_CS_CMY : + profile_id = _ppdHashName("RGB.."); + apple_init_profile(ppd, NULL, profile, profile_id, "RGB", "RGB", + NULL); + break; + case PPD_CS_RGBK : + case PPD_CS_CMYK : + profile_id = _ppdHashName("CMYK.."); + apple_init_profile(ppd, NULL, profile, profile_id, "CMYK", "CMYK", + NULL); + break; + + case PPD_CS_GRAY : + if (attr) + break; + + case PPD_CS_N : + profile_id = _ppdHashName("DeviceN.."); + apple_init_profile(ppd, NULL, profile, profile_id, "DeviceN", + "DeviceN", NULL); + break; + } + + if (CFDictionaryGetCount(profile) > 0) + { + dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, + CFSTR("%u"), profile_id); + if (dict_key) + { + CFDictionarySetValue(profiles, dict_key, profile); + CFRelease(dict_key); + } + } + + CFRelease(profile); + +# else + /* + * Create an array for the factory profiles... + */ + if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL) { cupsdLogMessage(CUPSD_LOG_ERROR, - "Unable to allocate memory for %d profiles", - num_profiles); + "Unable to allocate memory for factory profiles."); ppdClose(ppd); return; } profiles->profileCount = num_profiles; - apple_init_profile(ppd, NULL, profiles->profiles, _ppdHashName("Gray.."), - "Gray", "Gray", NULL); + /* + * Add the grayscale profile first. We always have a grayscale profile. + */ + + profile_id = _ppdHashName("Gray.."); + apple_init_profile(ppd, NULL, profiles->profiles, profile_id, "Gray", + "Gray", NULL); + + /* + * Then add the RGB/CMYK/DeviceN color profile... + */ switch (ppd->colorspace) { case PPD_CS_RGB : case PPD_CS_CMY : - apple_init_profile(ppd, NULL, profiles->profiles + 1, - _ppdHashName("RGB.."), "RGB", "RGB", NULL); + profile_id = _ppdHashName("RGB.."); + apple_init_profile(ppd, NULL, profiles->profiles + 1, profile_id, + "RGB", "RGB", NULL); break; case PPD_CS_RGBK : case PPD_CS_CMYK : - apple_init_profile(ppd, NULL, profiles->profiles + 1, - _ppdHashName("CMYK.."), "CMYK", "CMYK", NULL); + profile_id = _ppdHashName("CMYK.."); + apple_init_profile(ppd, NULL, profiles->profiles + 1, profile_id, + "CMYK", "CMYK", NULL); break; case PPD_CS_GRAY : @@ -3551,11 +3777,12 @@ apple_register_profiles( break; case PPD_CS_N : - apple_init_profile(ppd, NULL, profiles->profiles + 1, - _ppdHashName("DeviceN.."), "DeviceN", "DeviceN", - NULL); + profile_id = _ppdHashName("DeviceN.."); + apple_init_profile(ppd, NULL, profiles->profiles + 1, profile_id, + "DeviceN", "DeviceN", NULL); break; } +# endif /* HAVE_COLORSYNCREGISTERDEVICE */ } if (num_profiles > 0) @@ -3565,7 +3792,18 @@ apple_register_profiles( */ if (!default_profile_id) - default_profile_id = profiles->profiles[num_profiles - 1].profileID; + default_profile_id = profile_id; /* Last profile */ + +# ifdef HAVE_COLORSYNCREGISTERDEVICE + dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"), + default_profile_id); + if (dict_key) + { + CFDictionarySetValue(profiles, kColorSyncDeviceDefaultProfileID, + dict_key); + CFRelease(dict_key); + } +# endif /* HAVE_COLORSYNCREGISTERDEVICE */ /* * Get the device ID hash and pathelogical name dictionary. @@ -3583,12 +3821,50 @@ apple_register_profiles( if (device_name && printer_name) { - CFDictionarySetValue(device_name, CFSTR("en"), printer_name); + CFDictionarySetValue(device_name, CFSTR("en_US"), printer_name); /* * Register the device with ColorSync... */ +# ifdef HAVE_COLORSYNCREGISTERDEVICE + CFTypeRef deviceDictKeys[] = + { /* Device keys */ + kColorSyncDeviceDescriptions, + kColorSyncFactoryProfiles, + kColorSyncDeviceUserScope, + kColorSyncDeviceHostScope + }; + CFTypeRef deviceDictVals[] = + { /* Device values */ + device_name, + profiles, + kCFPreferencesAnyUser, + kCFPreferencesCurrentHost + }; + CFDictionaryRef deviceDict; /* Device dictionary */ + CFUUIDRef deviceUUID; /* Device UUID (TODO: use printer-uuid value) */ + + deviceDict = CFDictionaryCreate(kCFAllocatorDefault, + (const void **)deviceDictKeys, + (const void **)deviceDictVals, + sizeof(deviceDictKeys) / + sizeof(deviceDictVals), + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + deviceUUID = ColorSyncCreateUUIDFromUInt32(device_id); + if (deviceDict && deviceUUID && + !ColorSyncRegisterDevice(kColorSyncPrinterDeviceClass, deviceUUID, + deviceDict)) + error = 1001; + + if (deviceUUID) + CFRelease(deviceUUID); + + if (deviceDict) + CFRelease(deviceDict); + +# else error = CMRegisterColorDevice(cmPrinterDeviceClass, device_id, device_name, &scope); @@ -3599,6 +3875,7 @@ apple_register_profiles( if (error == noErr) error = CMSetDeviceFactoryProfiles(cmPrinterDeviceClass, device_id, default_profile_id, profiles); +# endif /* HAVE_COLORSYNCREGISTERDEVICE */ } else error = 1000; @@ -3609,22 +3886,34 @@ apple_register_profiles( if (error != noErr) cupsdLogMessage(CUPSD_LOG_ERROR, - "Unable to register ICC color profiles for \"%s\" - %d", + "Unable to register ICC color profiles for \"%s\": %d", p->name, (int)error); + if (printer_name) + CFRelease(printer_name); + + if (device_name) + CFRelease(device_name); + } + + /* + * Free any memory we used... + */ + +# ifdef HAVE_COLORSYNCREGISTERDEVICE + CFRelease(profiles); + +# else + if (num_profiles > 0) + { for (profile = profiles->profiles; num_profiles > 0; profile ++, num_profiles --) CFRelease(profile->profileName); free(profiles); - - if (printer_name) - CFRelease(printer_name); - - if (device_name) - CFRelease(device_name); } +# endif /* HAVE_COLORSYNCREGISTERDEVICE */ ppdClose(ppd); } @@ -3643,8 +3932,25 @@ apple_unregister_profiles( * Make sure ColorSync is available... */ +# ifdef HAVE_COLORSYNCREGISTERDEVICE + if (ColorSyncUnregisterDevice != NULL) + { + CFUUIDRef deviceUUID; /* Printer UUID */ + + deviceUUID = ColorSyncCreateUUIDFromUInt32(_ppdHashName(p->name)); + /* TODO: Use printer-uuid value */ + + if (deviceUUID) + { + ColorSyncUnregisterDevice(kColorSyncPrinterDeviceClass, deviceUUID); + CFRelease(deviceUUID); + } + } + +# else if (CMUnregisterColorDevice != NULL) CMUnregisterColorDevice(cmPrinterDeviceClass, _ppdHashName(p->name)); +# endif /* HAVE_COLORSYNCREGISTERDEVICE */ } #endif /* __APPLE__ */ diff --git a/scheduler/job.c b/scheduler/job.c index a58ab311d..94fc08844 100644 --- a/scheduler/job.c +++ b/scheduler/job.c @@ -4427,7 +4427,7 @@ update_job(cupsd_job_t *job) /* I - Job to check */ event |= CUPSD_EVENT_PRINTER_STATE | CUPSD_EVENT_JOB_PROGRESS; - if (loglevel < job->status_level) + if (loglevel <= job->status_level && job->status_level > CUPSD_LOG_ERROR) { /* * Some messages show in the job-printer-state-message attribute... diff --git a/systemv/lpstat.c b/systemv/lpstat.c index 445588c01..4b96ebf8e 100644 --- a/systemv/lpstat.c +++ b/systemv/lpstat.c @@ -1271,7 +1271,8 @@ show_jobs(const char *dests, /* I - Destinations */ *reasons; /* Job state reasons attribute */ const char *dest, /* Pointer into job-printer-uri */ *username, /* Pointer to job-originating-user-name */ - *title; /* Pointer to job-name */ + *title, /* Pointer to job-name */ + *message; /* Pointer to job-printer-state-message */ int rank, /* Rank in queue */ jobid, /* job-id */ size; /* job-k-octets */ @@ -1285,6 +1286,7 @@ show_jobs(const char *dests, /* I - Destinations */ "job-k-octets", "job-name", "job-originating-user-name", + "job-printer-state-message", "job-printer-uri", "job-state-reasons", "time-at-creation" @@ -1366,6 +1368,7 @@ show_jobs(const char *dests, /* I - Destinations */ dest = NULL; jobtime = 0; title = "no title"; + message = NULL; reasons = NULL; while (attr != NULL && attr->group_tag == IPP_TAG_JOB) @@ -1373,30 +1376,29 @@ show_jobs(const char *dests, /* I - Destinations */ if (!strcmp(attr->name, "job-id") && attr->value_tag == IPP_TAG_INTEGER) jobid = attr->values[0].integer; - - if (!strcmp(attr->name, "job-k-octets") && - attr->value_tag == IPP_TAG_INTEGER) + else if (!strcmp(attr->name, "job-k-octets") && + attr->value_tag == IPP_TAG_INTEGER) size = attr->values[0].integer; - - if (!strcmp(attr->name, "time-at-creation") && - attr->value_tag == IPP_TAG_INTEGER) + else if (!strcmp(attr->name, "time-at-creation") && + attr->value_tag == IPP_TAG_INTEGER) jobtime = attr->values[0].integer; - - if (!strcmp(attr->name, "job-printer-uri") && - attr->value_tag == IPP_TAG_URI) + else if (!strcmp(attr->name, "job-printer-state-message") && + attr->value_tag == IPP_TAG_TEXT) + message = attr->values[0].string.text; + else if (!strcmp(attr->name, "job-printer-uri") && + attr->value_tag == IPP_TAG_URI) + { if ((dest = strrchr(attr->values[0].string.text, '/')) != NULL) dest ++; - - if (!strcmp(attr->name, "job-originating-user-name") && - attr->value_tag == IPP_TAG_NAME) + } + else if (!strcmp(attr->name, "job-originating-user-name") && + attr->value_tag == IPP_TAG_NAME) username = attr->values[0].string.text; - - if (!strcmp(attr->name, "job-name") && - attr->value_tag == IPP_TAG_NAME) + else if (!strcmp(attr->name, "job-name") && + attr->value_tag == IPP_TAG_NAME) title = attr->values[0].string.text; - - if (!strcmp(attr->name, "job-state-reasons") && - attr->value_tag == IPP_TAG_KEYWORD) + else if (!strcmp(attr->name, "job-state-reasons") && + attr->value_tag == IPP_TAG_KEYWORD) reasons = attr; attr = attr->next; @@ -1453,6 +1455,9 @@ show_jobs(const char *dests, /* I - Destinations */ 1024.0 * size, date); if (long_status) { + if (message) + _cupsLangPrintf(stdout, _("\tStatus: %s"), message); + if (reasons) { char alerts[1024], /* Alerts string */ -- 2.39.2