]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Last bits of IPP Everywhere PPD support - web interface and cups-driverd
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Thu, 12 Feb 2015 20:18:11 +0000 (20:18 +0000)
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Thu, 12 Feb 2015 20:18:11 +0000 (20:18 +0000)
(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
cups/ppd-cache.c
doc/help/man-lpadmin.html
scheduler/cups-driverd.cxx
systemv/lpadmin.c
xcode/CUPS.xcodeproj/project.pbxproj

index 170d88b3ae77169d8d3ce24098a2c61974948a04..e3123986ebb831b4e98e8a04d3f5253cfe93e323 100644 (file)
@@ -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 <cups/http-private.h>
+#include <cups/ppd-private.h>
 #include <cups/adminutil.h>
 #include <cups/ppd.h>
 #include <errno.h>
@@ -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$".
  */
index 18b9510d3192980bb56da28d355352d2f9314fc6..5445cadf0f050b210e06fee5f12591a81d097ac7 100644 (file)
@@ -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: \"<</cupsColorSpace 3/cupsBitsPerColor 1/cupsColorOrder 0/cupsCompression 0>>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: \"<</HWResolution[%d %d]>>setpagedevice\"\n", lowdpi, lowdpi / 2);
+      cupsFilePrintf(fp, "*cupsPrintQuality Normal: \"<</HWResolution[%d %d]>>setpagedevice\"\n", lowdpi, lowdpi);
+      if (hidpi > lowdpi)
+       cupsFilePrintf(fp, "*cupsPrintQuality High: \"<</HWResolution[%d %d]>>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));
index 1f8502991a06aed4aac715ef73232be26da6dc41..2a74cf06c50dac046a7a606eaa4e2cfc84a36e73 100644 (file)
@@ -79,6 +79,7 @@ This option cannot be specified with the <i>-P</i> option (PPD file) and is inte
 Use the <i>-m</i> option with the
 <a href="man-lpinfo.html?TOPIC=Man+Pages"><b>lpinfo</b>(8)</a>
 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 <i>device-uri</i>.
 <dt><b>-o cupsIPPSupplies=true</b>
 <dd style="margin-left: 5.0em"><dt><b>-o cupsIPPSupplies=false</b>
 <dd style="margin-left: 5.0em">Specifies whether IPP supply level values should be reported.
@@ -161,6 +162,13 @@ Finally, the CUPS version of <b>lpadmin</b> may ask the user for an access passw
 This differs from the System V version which requires the root user to execute this command.
 <h2 class="title"><a name="NOTES">Notes</a></h2>
 The CUPS version of <b>lpadmin</b> does not support all of the System V or Solaris printing system configuration options.
+<h2 class="title"><a name="EXAMPLE">Example</a></h2>
+Create an IPP Everywhere print queue:
+<pre class="man">
+
+    lpadmin -p myprinter -E -v ipp://myprinter.local/ipp/print -m everywhere
+
+</pre>
 <h2 class="title"><a name="SEE_ALSO">See Also</a></h2>
 <a href="man-cupsaccept.html?TOPIC=Man+Pages"><b>cupsaccept</b>(8),</a>
 <a href="man-cupsenable.html?TOPIC=Man+Pages"><b>cupsenable</b>(8),</a>
@@ -168,7 +176,7 @@ The CUPS version of <b>lpadmin</b> does not support all of the System V or Solar
 <a href="man-lpoptions.html?TOPIC=Man+Pages"><b>lpoptions</b>(1),</a>
 CUPS Online Help (<a href="http://localhost:631/help">http://localhost:631/help</a>)
 <h2 class="title"><a name="COPYRIGHT">Copyright</a></h2>
-Copyright &copy; 2007-2014 by Apple Inc.
+Copyright &copy; 2007-2015 by Apple Inc.
 
 </body>
 </html>
index 7924bc95bd97eef508599b6c1b1147e0fbc61a51..573d2e1e2fa9a66afe43356cde1f0df58a6a74bc 100644 (file)
@@ -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...
index 9381c8eb024a10aea67e2d431fd485e1048941cc..492ff9d6fa360946164c3f64aadb22f1b0c79b80 100644 (file)
@@ -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);
index a403fc9cce07053739ab2a7a5e32462e10d378d9..37c0a31101fcd5af687746741fed2ac3485728b4 100644 (file)
                7271882313746EA8001A2036 /* rastertolabel.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = rastertolabel.c; path = ../filter/rastertolabel.c; sourceTree = "<group>"; };
                7271883C1374AB14001A2036 /* mime-private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "mime-private.h"; path = "../scheduler/mime-private.h"; sourceTree = "<group>"; };
                727AD5B619100A58009F6862 /* tls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tls.c; path = ../cups/tls.c; sourceTree = "<group>"; };
-               727EF02F192E3498001EF690 /* admin.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = admin.c; path = "../cgi-bin/admin.c"; sourceTree = "<group>"; };
+               727EF02F192E3498001EF690 /* admin.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = admin.c; path = "../cgi-bin/admin.c"; sourceTree = "<group>"; wrapsLines = 1; };
                727EF030192E3498001EF690 /* cgi-private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "cgi-private.h"; path = "../cgi-bin/cgi-private.h"; sourceTree = "<group>"; };
                727EF031192E3498001EF690 /* cgi.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cgi.h; path = "../cgi-bin/cgi.h"; sourceTree = "<group>"; };
                727EF032192E3498001EF690 /* classes.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = classes.c; path = "../cgi-bin/classes.c"; sourceTree = "<group>"; };
                        indentWidth = 2;
                        sourceTree = "<group>";
                        tabWidth = 8;
-                       wrapsLines = 0;
+                       wrapsLines = 1;
                };
                72E65BA218DC796500097E89 /* Autoconf Files */ = {
                        isa = PBXGroup;
                                27A034801A8BDB1300650675 /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
                };
                720DD6CB1358FD600064AA82 /* Build configuration list for PBXNativeTarget "snmp" */ = {
                        isa = XCConfigurationList;