]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
More work on temporary queues - implement support for them in the cupsDest APIs,
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Wed, 17 Feb 2016 22:46:40 +0000 (22:46 +0000)
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Wed, 17 Feb 2016 22:46:40 +0000 (22:46 +0000)
add some duplicate printer checking code, and implement the --enum unit test.

git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@13099 a1ca3aef-8c08-0410-bb20-df032aa958be

cups/dest-job.c
cups/dest-options.c
cups/dest.c
cups/testdest.c
doc/help/spec-ipp.html
scheduler/ipp.c

index 40f0412370f241f41806631a3f789069a4f07ad7..759c5b354b6c37084adc639b19656bf14c4e99b3 100644 (file)
@@ -1,9 +1,7 @@
 /*
- * "$Id$"
- *
  * Destination job support for CUPS.
  *
- * Copyright 2012-2014 by Apple Inc.
+ * Copyright 2012-2016 by Apple Inc.
  *
  * These coded instructions, statements, and computer programs are the
  * property of Apple Inc. and are protected by Federal copyright
@@ -26,8 +24,9 @@
  *
  * The "job_id" is the number returned by cupsCreateDestJob.
  *
- * Returns IPP_STATUS_OK on success and IPP_NOT_AUTHORIZED or IPP_FORBIDDEN on
- * failure.
+ * Returns @code IPP_STATUS_OK@ on success and
+ * @code IPP_STATUS_ERRPR_NOT_AUTHORIZED@ or
+ * @code IPP_STATUS_ERROR_FORBIDDEN@ on failure.
  *
  * @since CUPS 1.6/OS X 10.8@
  */
@@ -37,13 +36,26 @@ cupsCancelDestJob(http_t      *http,        /* I - Connection to destination */
                   cups_dest_t *dest,   /* I - Destination */
                   int         job_id)  /* I - Job ID */
 {
-  /* TODO: Needs to be implemented! */
-  /* Probably also needs to be revved to accept cups_dinfo_t... */
-  (void)http;
-  (void)dest;
-  (void)job_id;
+  cups_dinfo_t *info;                  /* Destination information */
+
+
+  if ((info = cupsCopyDestInfo(http, dest)) != NULL)
+  {
+    ipp_t      *request;               /* Cancel-Job request */
+
+    request = ippNewRequest(IPP_OP_CANCEL_JOB);
+
+    ippSetVersion(request, info->version / 10, info->version % 10);
+
+    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, info->uri);
+    ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id);
+    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser());
 
-  return (IPP_STATUS_ERROR_NOT_FOUND);
+    ippDelete(cupsDoRequest(http, request, info->resource));
+    cupsFreeDestInfo(info);
+  }
+
+  return (cupsLastError());
 }
 
 
@@ -357,8 +369,3 @@ cupsStartDestDocument(
 
   return (status);
 }
-
-
-/*
- * End of "$Id$".
- */
index 442ca5dc69013845843e19c1381d8b9bf6b77b7d..43d231b2bf936aaca88c9e603ba0ea2d4944a576 100644 (file)
@@ -1,9 +1,7 @@
 /*
- * "$Id$"
- *
  * Destination option/media support for CUPS.
  *
- * Copyright 2012-2014 by Apple Inc.
+ * Copyright 2012-2016 by Apple Inc.
  *
  * These coded instructions, statements, and computer programs are the
  * property of Apple Inc. and are protected by Federal copyright
@@ -706,6 +704,7 @@ cupsFindDestDefault(
   return (ippFindAttribute(dinfo->attrs, name, IPP_TAG_ZERO));
 }
 
+
 /*
  * 'cupsFindDestReady()' - Find the default value(s) for the given option.
  *
@@ -748,6 +747,7 @@ cupsFindDestReady(
   return (ippFindAttribute(dinfo->ready_attrs, name, IPP_TAG_ZERO));
 }
 
+
 /*
  * 'cupsFindDestSupported()' - Find the default value(s) for the given option.
  *
index f54d5eec2134618427b23db760817dbb4c525257..2dc88500defabc7e981172125ddc0cd03ad745e8 100644 (file)
@@ -589,26 +589,39 @@ cupsConnectDest(
   * Grab the printer URI...
   */
 
-  if ((uri = cupsGetOption("printer-uri-supported", dest->num_options,
-                           dest->options)) == NULL)
+  if ((uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options)) == NULL)
   {
-    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0);
+    if ((uri = cupsGetOption("resolved-device-uri", dest->num_options, dest->options)) == NULL)
+    {
+      if ((uri = cupsGetOption("device-uri", dest->num_options, dest->options)) != NULL)
+      {
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+        if (strstr(uri, "._tcp"))
+          uri = cups_dnssd_resolve(dest, uri, msec, cancel, cb, user_data);
+      }
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
+    }
 
-    if (cb)
-      (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_ERROR,
-            dest);
+    if (uri)
+      uri = _cupsCreateDest(dest->name, cupsGetOption("printer-info", dest->num_options, dest->options), NULL, uri, tempresource, sizeof(tempresource));
 
-    return (NULL);
+    if (uri)
+    {
+      dest->num_options = cupsAddOption("printer-uri-supported", uri, dest->num_options, &dest->options);
+
+      uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options);
+    }
   }
 
-#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
-  if (strstr(uri, "._tcp"))
+  if (!uri)
   {
-    if ((uri = cups_dnssd_resolve(dest, uri, msec, cancel, cb,
-                                  user_data)) == NULL)
-      return (NULL);
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0);
+
+    if (cb)
+      (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_ERROR, dest);
+
+    return (NULL);
   }
-#endif /* HAVE_DNSSD || HAVE_AVAHI */
 
   if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme),
                       userpass, sizeof(userpass), hostname, sizeof(hostname),
@@ -628,16 +641,14 @@ cupsConnectDest(
   */
 
   if (cb)
-    (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_RESOLVING,
-          dest);
+    (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_RESOLVING, dest);
 
   snprintf(portstr, sizeof(portstr), "%d", port);
 
   if ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portstr)) == NULL)
   {
     if (cb)
-      (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_ERROR,
-            dest);
+      (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_ERROR, dest);
 
     return (NULL);
   }
@@ -647,8 +658,7 @@ cupsConnectDest(
     httpAddrFreeList(addrlist);
 
     if (cb)
-      (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_CANCELED,
-            dest);
+      (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_CANCELED, dest);
 
     return (NULL);
   }
@@ -662,8 +672,7 @@ cupsConnectDest(
   else
     encryption = HTTP_ENCRYPTION_IF_REQUESTED;
 
-  http = httpConnect2(hostname, port, addrlist, AF_UNSPEC, encryption, 1, 0,
-                      NULL);
+  http = httpConnect2(hostname, port, addrlist, AF_UNSPEC, encryption, 1, 0, NULL);
   httpAddrFreeList(addrlist);
 
  /*
@@ -678,17 +687,14 @@ cupsConnectDest(
   else
   {
     if (cb)
-      (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_CONNECTING,
-            dest);
+      (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_CONNECTING, dest);
 
     if (!httpReconnect2(http, msec, cancel) && cb)
     {
       if (cancel && *cancel)
-       (*cb)(user_data,
-             CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_CONNECTING, dest);
+       (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_CONNECTING, dest);
       else
-       (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_ERROR,
-             dest);
+       (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_ERROR, dest);
     }
     else if (cb)
       (*cb)(user_data, CUPS_DEST_FLAGS_NONE, dest);
@@ -3327,22 +3333,28 @@ cups_dnssd_query_cb(
         */
 
         const char     *start, *next;  /* Pointer into value */
-        int            have_pdf = 0;   /* Have PDF? */
+        int            have_pdf = 0,   /* Have PDF? */
+                       have_raster = 0;/* Have raster format support? */
 
         for (start = value; start && *start; start = next)
         {
-          if (!_cups_strncasecmp(start, "application/pdf", 15) &&
-              (!start[15] || start[15] == ','))
+          if (!_cups_strncasecmp(start, "application/pdf", 15) && (!start[15] || start[15] == ','))
           {
             have_pdf = 1;
             break;
           }
+          else if ((!_cups_strncasecmp(start, "image/pwg-raster", 16) && (!start[16] || start[16] == ',')) ||
+                  (!_cups_strncasecmp(start, "image/urf", 9) && (!start[9] || start[9] == ',')))
+          {
+            have_raster = 1;
+            break;
+          }
 
           if ((next = strchr(start, ',')) != NULL)
             next ++;
         }
 
-        if (!have_pdf)
+        if (!have_pdf && !have_raster)
           device->state = _CUPS_DNSSD_INCOMPATIBLE;
       }
       else if (!_cups_strcasecmp(key, "printer-type"))
@@ -3408,31 +3420,21 @@ cups_dnssd_query_cb(
     * Save the printer-xxx values...
     */
 
-    device->dest.num_options = cupsAddOption("printer-info", name,
-                                            device->dest.num_options,
-                                            &device->dest.options);
+    device->dest.num_options = cupsAddOption("printer-info", name, device->dest.num_options, &device->dest.options);
 
     if (make_and_model[0])
     {
       strlcat(make_and_model, " ", sizeof(make_and_model));
       strlcat(make_and_model, model, sizeof(make_and_model));
 
-      device->dest.num_options = cupsAddOption("printer-make-and-model",
-                                              make_and_model,
-                                              device->dest.num_options,
-                                              &device->dest.options);
+      device->dest.num_options = cupsAddOption("printer-make-and-model", make_and_model, device->dest.num_options, &device->dest.options);
     }
     else
-      device->dest.num_options = cupsAddOption("printer-make-and-model",
-                                              model,
-                                              device->dest.num_options,
-                                              &device->dest.options);
+      device->dest.num_options = cupsAddOption("printer-make-and-model", model, device->dest.num_options, &device->dest.options);
 
     device->type = type;
     snprintf(value, sizeof(value), "%u", type);
-    device->dest.num_options = cupsAddOption("printer-type", value,
-                                            device->dest.num_options,
-                                            &device->dest.options);
+    device->dest.num_options = cupsAddOption("printer-type", value, device->dest.num_options, &device->dest.options);
 
    /*
     * Save the URI...
@@ -3443,11 +3445,9 @@ cups_dnssd_query_cb(
                     !strcmp(device->regtype, "_ipps._tcp") ? "ipps" : "ipp",
                     NULL, uriname, 0, saw_printer_type ? "/cups" : "/");
 
-    DEBUG_printf(("6cups_dnssd_query: printer-uri-supported=\"%s\"", uri));
+    DEBUG_printf(("6cups_dnssd_query: device-uri=\"%s\"", uri));
 
-    device->dest.num_options = cupsAddOption("printer-uri-supported", uri,
-                                            device->dest.num_options,
-                                            &device->dest.options);
+    device->dest.num_options = cupsAddOption("device-uri", uri, device->dest.num_options, &device->dest.options);
   }
   else
     DEBUG_printf(("6cups_dnssd_query: Ignoring TXT record for '%s'.",
@@ -3496,15 +3496,12 @@ cups_dnssd_resolve(
     (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_RESOLVING,
          dest);
 
-  if ((uri = _httpResolveURI(uri, tempuri, sizeof(tempuri),
-                            _HTTP_RESOLVE_FQDN, cups_dnssd_resolve_cb,
-                            &resolve)) == NULL)
+  if ((uri = _httpResolveURI(uri, tempuri, sizeof(tempuri), _HTTP_RESOLVE_FQDN, cups_dnssd_resolve_cb, &resolve)) == NULL)
   {
     _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to resolve printer-uri."), 1);
 
     if (cb)
-      (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_ERROR,
-           dest);
+      (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_ERROR, dest);
 
     return (NULL);
   }
@@ -3513,11 +3510,9 @@ cups_dnssd_resolve(
   * Save the resolved URI...
   */
 
-  dest->num_options = cupsAddOption("printer-uri-supported", uri,
-                                   dest->num_options, &dest->options);
+  dest->num_options = cupsAddOption("resolved-device-uri", uri, dest->num_options, &dest->options);
 
-  return (cupsGetOption("printer-uri-supported", dest->num_options,
-                        dest->options));
+  return (cupsGetOption("resolved-device-uri", dest->num_options, dest->options));
 }
 
 
index aefe8818e65bbb03340892f8a01b79e2e1a554a3..c940d3b1a6eef5d034866decbc16273396433f9f 100644 (file)
@@ -1,9 +1,7 @@
 /*
- * "$Id$"
- *
  * CUPS destination API test program for CUPS.
  *
- * Copyright 2014 by Apple Inc.
+ * Copyright 2016 by Apple Inc.
  *
  * These coded instructions, statements, and computer programs are the
  * property of Apple Inc. and are protected by Federal copyright
@@ -26,6 +24,7 @@
  * Local functions...
  */
 
+static int     enum_cb(void *user_data, unsigned flags, cups_dest_t *dest);
 static void    localize(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option, const char *value);
 static void    print_file(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *filename, int num_options, cups_option_t *options);
 static void    show_conflicts(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, int num_options, cups_option_t *options);
@@ -53,6 +52,54 @@ main(int  argc,                              /* I - Number of command-line arguments */
 
   if (!strcmp(argv[1], "--enum"))
   {
+    int                        i;              /* Looping var */
+    cups_ptype_t       type = 0,       /* Printer type filter */
+                       mask = 0;       /* Printer type mask */
+
+
+    for (i = 2; i < argc; i ++)
+    {
+      if (!strcmp(argv[i], "grayscale"))
+      {
+        type |= CUPS_PRINTER_BW;
+       mask |= CUPS_PRINTER_BW;
+      }
+      else if (!strcmp(argv[i], "color"))
+      {
+        type |= CUPS_PRINTER_COLOR;
+       mask |= CUPS_PRINTER_COLOR;
+      }
+      else if (!strcmp(argv[i], "duplex"))
+      {
+        type |= CUPS_PRINTER_DUPLEX;
+       mask |= CUPS_PRINTER_DUPLEX;
+      }
+      else if (!strcmp(argv[i], "staple"))
+      {
+        type |= CUPS_PRINTER_STAPLE;
+       mask |= CUPS_PRINTER_STAPLE;
+      }
+      else if (!strcmp(argv[i], "small"))
+      {
+        type |= CUPS_PRINTER_SMALL;
+       mask |= CUPS_PRINTER_SMALL;
+      }
+      else if (!strcmp(argv[i], "medium"))
+      {
+        type |= CUPS_PRINTER_MEDIUM;
+       mask |= CUPS_PRINTER_MEDIUM;
+      }
+      else if (!strcmp(argv[i], "large"))
+      {
+        type |= CUPS_PRINTER_LARGE;
+       mask |= CUPS_PRINTER_LARGE;
+      }
+      else
+        usage(argv[i]);
+    }
+
+    cupsEnumDests(CUPS_DEST_FLAGS_NONE, 5000, NULL, type, mask, enum_cb, NULL);
+
     return (0);
   }
   else if (!strncmp(argv[1], "ipp://", 6) || !strncmp(argv[1], "ipps://", 7))
@@ -149,6 +196,33 @@ main(int  argc,                            /* I - Number of command-line arguments */
 }
 
 
+/*
+ * 'enum_cb()' - Print the results from the enumeration of destinations.
+ */
+
+static int                             /* O - 1 to continue */
+enum_cb(void        *user_data,                /* I - User data (unused) */
+        unsigned    flags,             /* I - Flags */
+       cups_dest_t *dest)              /* I - Destination */
+{
+  int  i;                              /* Looping var */
+
+
+  (void)user_data;
+  (void)flags;
+
+  if (dest->instance)
+    printf("%s/%s:\n", dest->name, dest->instance);
+  else
+    printf("%s:\n", dest->name);
+
+  for (i = 0; i < dest->num_options; i ++)
+    printf("    %s=\"%s\"\n", dest->options[i].name, dest->options[i].value);
+
+  return (1);
+}
+
+
 /*
  * 'localize()' - Localize an option and value.
  */
index 7095443b53277b9de51353e281767ebd4ca92f95..16af6dfae505317d5f5d648875f0f20769eb608d 100644 (file)
@@ -1334,6 +1334,8 @@ CUPS-Get-PPDs Response:
 
 <p>At a minimum, the scheduler requires a name and URI for the Printer to add. When successful, the local "printer-uri" values are returned and may be used by the Client to submit Job Creation Requests, monitor for state changes, and so forth.</p>
 
+<p>If the named printer already exists, the scheduler will reject the request with the 'client-error-not-possible' status code.</p>
+
 <p>Access Rights: The authenticated user performing this operation MUST be a Local User of the system, and the request MUST be made over a local (domain socket or loopback interface) address. Otherwise, the request will be rejected with the 'client-error-forbidden' status code.</p>
 
 <h4>CUPS-Create-Local-Printer Request</h4>
index bbd5058598e39ed8498d22ad999ab27eda561733..8c266c7c9db13a34db2b2a8617ca5dc6da6d9b7f 100644 (file)
@@ -5382,6 +5382,16 @@ create_local_printer(
   printer_info         = ippFindAttribute(con->request, "printer-info", IPP_TAG_TEXT);
   printer_location     = ippFindAttribute(con->request, "printer-location", IPP_TAG_TEXT);
 
+ /*
+  * See if the printer already exists...
+  */
+
+  if ((printer = cupsdFindDest(name)) != NULL)
+  {
+    send_ipp_status(con, IPP_STATUS_ERROR_NOT_POSSIBLE, _("Printer \"%s\" already exists."), name);
+    goto add_printer_attributes;
+  }
+
  /*
   * Create the printer...
   */
@@ -5415,6 +5425,8 @@ create_local_printer(
 
   send_ipp_status(con, IPP_STATUS_OK, _("Local printer created."));
 
+  add_printer_attributes:
+
   ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-accepting-jobs", (char)printer->accepting);
   ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", printer->state);
   add_printer_state_reasons(con, printer);