From fb2d54701f47ac6fc156f6d0aee6c42a175edc71 Mon Sep 17 00:00:00 2001 From: msweet Date: Thu, 12 Feb 2015 20:18:11 +0000 Subject: [PATCH] Last bits of IPP Everywhere PPD support - web interface and cups-driverd (STR #4258) git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@12516 a1ca3aef-8c08-0410-bb20-df032aa958be --- cgi-bin/admin.c | 97 +++++++++++++++++++++++++--- cups/ppd-cache.c | 87 ++++++++++++++++++++++++- doc/help/man-lpadmin.html | 10 ++- scheduler/cups-driverd.cxx | 8 +-- systemv/lpadmin.c | 18 +++++- xcode/CUPS.xcodeproj/project.pbxproj | 5 +- 6 files changed, 206 insertions(+), 19 deletions(-) diff --git a/cgi-bin/admin.c b/cgi-bin/admin.c index 170d88b3a..e3123986e 100644 --- a/cgi-bin/admin.c +++ b/cgi-bin/admin.c @@ -3,7 +3,7 @@ * * Administration CGI for CUPS. * - * Copyright 2007-2014 by Apple Inc. + * Copyright 2007-2015 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -18,6 +18,8 @@ */ #include "cgi-private.h" +#include +#include #include #include #include @@ -38,12 +40,7 @@ static int current_device = 0; /* Current device shown */ * Local functions... */ -static void choose_device_cb(const char *device_class, - const char *device_id, const char *device_info, - const char *device_make_and_model, - const char *device_uri, - const char *device_location, - const char *title); +static void choose_device_cb(const char *device_class, const char *device_id, const char *device_info, const char *device_make_and_model, const char *device_uri, const char *device_location, const char *title); static void do_add_rss_subscription(http_t *http); static void do_am_class(http_t *http, int modify); static void do_am_printer(http_t *http, int modify); @@ -61,6 +58,7 @@ static void do_set_sharing(http_t *http); static char *get_option_value(ppd_file_t *ppd, const char *name, char *buffer, size_t bufsize); static double get_points(double number, const char *uval); +static char *get_printer_ppd(const char *uri, char *buffer, size_t bufsize); /* @@ -832,7 +830,8 @@ do_am_printer(http_t *http, /* I - HTTP connection */ const cgi_file_t *file; /* Uploaded file, if any */ const char *var; /* CGI variable */ char uri[HTTP_MAX_URI], /* Device or printer URI */ - *uriptr; /* Pointer into URI */ + *uriptr, /* Pointer into URI */ + evefile[1024] = ""; /* IPP Everywhere PPD file */ int maxrate; /* Maximum baud rate */ char baudrate[255]; /* Baud rate string */ const char *name, /* Pointer to class name */ @@ -1331,7 +1330,9 @@ do_am_printer(http_t *http, /* I - HTTP connection */ if (!file) { var = cgiGetVariable("PPD_NAME"); - if (strcmp(var, "__no_change__")) + if (!strcmp(var, "everywhere")) + get_printer_ppd(cgiGetVariable("DEVICE_URI"), evefile, sizeof(evefile)); + else if (strcmp(var, "__no_change__")) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name", NULL, var); } @@ -1384,6 +1385,11 @@ do_am_printer(http_t *http, /* I - HTTP connection */ if (file) ippDelete(cupsDoFileRequest(http, request, "/admin/", file->tempfile)); + else if (evefile[0]) + { + ippDelete(cupsDoFileRequest(http, request, "/admin/", evefile)); + unlink(evefile); + } else ippDelete(cupsDoRequest(http, request, "/admin/")); @@ -4197,6 +4203,79 @@ get_points(double number, /* I - Original number */ } +/* + * 'get_printer_ppd()' - Get an IPP Everywhere PPD file for the given URI. + */ + +static char * /* O - Filename or NULL */ +get_printer_ppd(const char *uri, /* I - Printer URI */ + char *buffer, /* I - Filename buffer */ + size_t bufsize) /* I - Size of filename buffer */ +{ + http_t *http; /* Connection to printer */ + ipp_t *request, /* Get-Printer-Attributes request */ + *response; /* Get-Printer-Attributes response */ + char resolved[1024], /* Resolved URI */ + scheme[32], /* URI scheme */ + userpass[256], /* Username:password */ + host[256], /* Hostname */ + resource[256]; /* Resource path */ + int port; /* Port number */ + + + /* + * Connect to the printer... + */ + + if (strstr(uri, "._tcp")) + { + /* + * Resolve URI... + */ + + if (!_httpResolveURI(uri, resolved, sizeof(resolved), _HTTP_RESOLVE_DEFAULT, NULL, NULL)) + { + fprintf(stderr, "ERROR: Unable to resolve \"%s\".\n", uri); + return (NULL); + } + + uri = resolved; + } + + if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK) + { + fprintf(stderr, "ERROR: Bad printer URI \"%s\".\n", uri); + return (NULL); + } + + http = httpConnect2(host, port, NULL, AF_UNSPEC, !strcmp(scheme, "ipps") ? HTTP_ENCRYPTION_ALWAYS : HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL); + if (!http) + { + fprintf(stderr, "ERROR: Unable to connect to \"%s:%d\": %s\n", host, port, cupsLastErrorString()); + return (NULL); + } + + /* + * Send a Get-Printer-Attributes request... + */ + + request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); + response = cupsDoRequest(http, request, resource); + + if (!_ppdCreateFromIPP(buffer, bufsize, response)) + fprintf(stderr, "ERROR: Unable to create PPD file: %s\n", strerror(errno)); + + ippDelete(response); + httpClose(http); + + if (buffer[0]) + return (buffer); + else + return (NULL); +} + + /* * End of "$Id$". */ diff --git a/cups/ppd-cache.c b/cups/ppd-cache.c index 18b9510d3..5445cadf0 100644 --- a/cups/ppd-cache.c +++ b/cups/ppd-cache.c @@ -2864,6 +2864,11 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ cupsFilePrintf(fp, "*NickName: \"%s\"\n", model); cupsFilePrintf(fp, "*ShortNickName: \"%s\"\n", model); + if ((attr = ippFindAttribute(response, "color-supported", IPP_TAG_BOOLEAN)) != NULL && ippGetBoolean(attr, 0)) + cupsFilePuts(fp, "*ColorDevice: True\n"); + else + cupsFilePuts(fp, "*ColorDevice: False\n"); + cupsFilePrintf(fp, "*cupsVersion: %d.%d\n", CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR); cupsFilePuts(fp, "*cupsSNMPSupplies: False\n"); cupsFilePuts(fp, "*cupsLanguages: \"en\"\n"); @@ -2881,7 +2886,9 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ if (!_cups_strcasecmp(format, "application/pdf")) cupsFilePuts(fp, "*cupsFilter2: \"application/vnd.cups-pdf application/pdf 10 -\"\n"); - else if (_cups_strcasecmp(format, "application/octet-stream")) + else if (!_cups_strcasecmp(format, "application/postscript")) + cupsFilePuts(fp, "*cupsFilter2: \"application/vnd.cups-postscript application/postscript 10 -\"\n"); + else if (_cups_strcasecmp(format, "application/octet-stream") && _cups_strcasecmp(format, "application/vnd.hp-pcl") && _cups_strcasecmp(format, "text/plain")) cupsFilePrintf(fp, "*cupsFilter2: \"%s %s 10 -\"\n", format, format); } } @@ -3153,7 +3160,7 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ const char *keyword = ippGetString(attr, i, NULL); /* Keyword for color/bit depth */ - if (!strcmp(keyword, "black_1")) + if (!strcmp(keyword, "black_1") || !strcmp(keyword, "bi-level") || !strcmp(keyword, "process-bi-level")) { cupsFilePuts(fp, "*ColorModel FastGray/Fast Grayscale: \"<>setpagedevice\"\n"); @@ -3209,6 +3216,35 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ else cupsFilePuts(fp, "*cupsBackSide: Rotated\n"); } + else if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL) + { + for (i = 0, count = ippGetCount(attr); i < count; i ++) + { + const char *dm = ippGetString(attr, i, NULL); + /* DM value */ + + if (!_cups_strcasecmp(dm, "DM1")) + { + cupsFilePuts(fp, "*cupsBackSide: Normal\n"); + break; + } + else if (!_cups_strcasecmp(dm, "DM2")) + { + cupsFilePuts(fp, "*cupsBackSide: Flipped\n"); + break; + } + else if (!_cups_strcasecmp(dm, "DM3")) + { + cupsFilePuts(fp, "*cupsBackSide: Rotated\n"); + break; + } + else if (!_cups_strcasecmp(dm, "DM4")) + { + cupsFilePuts(fp, "*cupsBackSide: ManualTumble\n"); + break; + } + } + } } /* @@ -3240,6 +3276,53 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n"); } + else if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL) + { + int lowdpi = 0, hidpi = 0; /* Lower and higher resolution */ + + for (i = 0, count = ippGetCount(attr); i < count; i ++) + { + const char *rs = ippGetString(attr, i, NULL); + /* RS value */ + + if (_cups_strncasecmp(rs, "RS", 2)) + continue; + + lowdpi = atoi(rs + 2); + if ((rs = strrchr(rs, '-')) != NULL) + hidpi = atoi(rs + 1); + else + hidpi = lowdpi; + break; + } + + if (lowdpi == 0) + { + /* + * Invalid "urf-supported" value... + */ + + cupsFilePuts(fp, "*DefaultResolution: 300dpi\n"); + } + else + { + /* + * Generate print qualities based on low and high DPIs... + */ + + cupsFilePrintf(fp, "*DefaultResolution: %ddpi\n", lowdpi); + + cupsFilePuts(fp, "*OpenUI *cupsPrintQuality/Print Quality: PickOne\n" + "*OrderDependency: 10 AnySetup *cupsPrintQuality\n" + "*DefaultcupsPrintQuality: Normal\n"); + if ((lowdpi & 1) == 0) + cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<>setpagedevice\"\n", lowdpi, lowdpi / 2); + cupsFilePrintf(fp, "*cupsPrintQuality Normal: \"<>setpagedevice\"\n", lowdpi, lowdpi); + if (hidpi > lowdpi) + cupsFilePrintf(fp, "*cupsPrintQuality High: \"<>setpagedevice\"\n", hidpi, hidpi); + cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n"); + } + } else if ((attr = ippFindAttribute(response, "printer-resolution-default", IPP_TAG_RESOLUTION)) != NULL) { pwg_ppdize_resolution(attr, 0, &xres, &yres, ppdname, sizeof(ppdname)); diff --git a/doc/help/man-lpadmin.html b/doc/help/man-lpadmin.html index 1f8502991..2a74cf06c 100644 --- a/doc/help/man-lpadmin.html +++ b/doc/help/man-lpadmin.html @@ -79,6 +79,7 @@ This option cannot be specified with the -P option (PPD file) and is inte Use the -m option with the lpinfo(8) command to get a list of supported models. +The model "raw" clears any existing interface script or PPD file and the model "everywhere" queries the printer referred to by the specified IPP device-uri.
-o cupsIPPSupplies=true
-o cupsIPPSupplies=false
Specifies whether IPP supply level values should be reported. @@ -161,6 +162,13 @@ Finally, the CUPS version of lpadmin may ask the user for an access passw This differs from the System V version which requires the root user to execute this command.

Notes

The CUPS version of lpadmin does not support all of the System V or Solaris printing system configuration options. +

Example

+Create an IPP Everywhere print queue: +
+
+    lpadmin -p myprinter -E -v ipp://myprinter.local/ipp/print -m everywhere
+
+

See Also

cupsaccept(8), cupsenable(8), @@ -168,7 +176,7 @@ The CUPS version of lpadmin does not support all of the System V or Solar lpoptions(1), CUPS Online Help (http://localhost:631/help)

Copyright

-Copyright © 2007-2014 by Apple Inc. +Copyright © 2007-2015 by Apple Inc. diff --git a/scheduler/cups-driverd.cxx b/scheduler/cups-driverd.cxx index 7924bc95b..573d2e1e2 100644 --- a/scheduler/cups-driverd.cxx +++ b/scheduler/cups-driverd.cxx @@ -7,7 +7,7 @@ * created from driver information files, and dynamically generated PPD files * using driver helper programs. * - * Copyright 2007-2014 by Apple Inc. + * Copyright 2007-2015 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -1172,11 +1172,11 @@ list_ppds(int request_id, /* I - Request ID */ load_drivers(include, exclude); /* - * Add the raw driver... + * Add the raw and IPP Everywhere drivers... */ - add_ppd("", "raw", "en", "Raw", "Raw Queue", "", "", "", 0, 0, 0, - PPD_TYPE_UNKNOWN, "raw"); + add_ppd("", "everywhere", "en", "Generic", "IPP Everywhere", "", "", "", 0, 0, 0, PPD_TYPE_UNKNOWN, "everywhere"); + add_ppd("", "raw", "en", "Raw", "Raw Queue", "", "", "", 0, 0, 0, PPD_TYPE_UNKNOWN, "raw"); /* * Send IPP attributes... diff --git a/systemv/lpadmin.c b/systemv/lpadmin.c index 9381c8eb0..492ff9d6f 100644 --- a/systemv/lpadmin.c +++ b/systemv/lpadmin.c @@ -1184,7 +1184,8 @@ get_printer_ppd(const char *uri, /* I - Printer URI */ http_t *http; /* Connection to printer */ ipp_t *request, /* Get-Printer-Attributes request */ *response; /* Get-Printer-Attributes response */ - char scheme[32], /* URI scheme */ + char resolved[1024], /* Resolved URI */ + scheme[32], /* URI scheme */ userpass[256], /* Username:password */ host[256], /* Hostname */ resource[256]; /* Resource path */ @@ -1195,6 +1196,21 @@ get_printer_ppd(const char *uri, /* I - Printer URI */ * Connect to the printer... */ + if (strstr(uri, "._tcp")) + { + /* + * Resolve URI... + */ + + if (!_httpResolveURI(uri, resolved, sizeof(resolved), _HTTP_RESOLVE_DEFAULT, NULL, NULL)) + { + _cupsLangPrintf(stderr, _("%s: Unable to resolve \"%s\"."), "lpadmin", uri); + return (NULL); + } + + uri = resolved; + } + if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK) { _cupsLangPrintf(stderr, _("%s: Bad printer URI \"%s\"."), "lpadmin", uri); diff --git a/xcode/CUPS.xcodeproj/project.pbxproj b/xcode/CUPS.xcodeproj/project.pbxproj index a403fc9cc..37c0a3110 100644 --- a/xcode/CUPS.xcodeproj/project.pbxproj +++ b/xcode/CUPS.xcodeproj/project.pbxproj @@ -1552,7 +1552,7 @@ 7271882313746EA8001A2036 /* rastertolabel.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = rastertolabel.c; path = ../filter/rastertolabel.c; sourceTree = ""; }; 7271883C1374AB14001A2036 /* mime-private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "mime-private.h"; path = "../scheduler/mime-private.h"; sourceTree = ""; }; 727AD5B619100A58009F6862 /* tls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tls.c; path = ../cups/tls.c; sourceTree = ""; }; - 727EF02F192E3498001EF690 /* admin.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = admin.c; path = "../cgi-bin/admin.c"; sourceTree = ""; }; + 727EF02F192E3498001EF690 /* admin.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = admin.c; path = "../cgi-bin/admin.c"; sourceTree = ""; wrapsLines = 1; }; 727EF030192E3498001EF690 /* cgi-private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "cgi-private.h"; path = "../cgi-bin/cgi-private.h"; sourceTree = ""; }; 727EF031192E3498001EF690 /* cgi.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cgi.h; path = "../cgi-bin/cgi.h"; sourceTree = ""; }; 727EF032192E3498001EF690 /* classes.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = classes.c; path = "../cgi-bin/classes.c"; sourceTree = ""; }; @@ -2491,7 +2491,7 @@ indentWidth = 2; sourceTree = ""; tabWidth = 8; - wrapsLines = 0; + wrapsLines = 1; }; 72E65BA218DC796500097E89 /* Autoconf Files */ = { isa = PBXGroup; @@ -5238,6 +5238,7 @@ 27A034801A8BDB1300650675 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; 720DD6CB1358FD600064AA82 /* Build configuration list for PBXNativeTarget "snmp" */ = { isa = XCConfigurationList; -- 2.39.5