]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Implement CUPS-Get-PPDs with printer-uri (STR #2334)
authormike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Wed, 2 May 2007 00:14:56 +0000 (00:14 +0000)
committermike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Wed, 2 May 2007 00:14:56 +0000 (00:14 +0000)
scheduler/client.c:
    - cupsdWriteClient(): Make sure we stick around after all
      attributes have been written if we have a file to write.
scheduler/ipp.c:
    - cupsdProcessIPPRequest(): Add file size to length as needed.
    - get_ppd(): Add code to get printer PPD and do redirects.

git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@6504 7a7537e8-13f0-0310-91df-b6672ffda945

scheduler/client.c
scheduler/ipp.c
test/get-ppd-printer.test [new file with mode: 0644]

index 0691bd3226fc136c4d61cf95c60aa6d34b789852..07a20c23c8ff71501cdc5d2abef6c75dd4318d66 100644 (file)
@@ -2531,10 +2531,10 @@ cupsdWriteClient(cupsd_client_t *con)   /* I - Client connection */
 
 #ifdef DEBUG
   cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "cupsdWriteClient(con=%p) %d response=%p, file=%d "
+                  "cupsdWriteClient(con=%p) %d response=%p(%d), file=%d "
                  "pipe_pid=%d state=%d",
-                  con, con->http.fd, con->response, con->file, con->pipe_pid,
-                 con->http.state);
+                  con, con->http.fd, con->response, con->response->state,
+                 con->file, con->pipe_pid, con->http.state);
 #endif /* DEBUG */
 
   if (con->http.state != HTTP_GET_SEND &&
@@ -2565,7 +2565,8 @@ cupsdWriteClient(cupsd_client_t *con)     /* I - Client connection */
   if (con->response && con->response->state != IPP_DATA)
   {
     ipp_state = ippWrite(HTTP(con), con->response);
-    bytes     = ipp_state != IPP_ERROR && ipp_state != IPP_DATA;
+    bytes     = ipp_state != IPP_ERROR &&
+                (con->file >= 0 || ipp_state != IPP_DATA);
   }
   else if ((bytes = read(con->file, buf, sizeof(buf) - 1)) > 0)
   {
index ef00390bf22d6ed62b0efacdeb8eca38c3e05abf..c2cd1c8cbdd3a96d0e71a41a6090269786a0498d 100644 (file)
@@ -676,6 +676,15 @@ cupsdProcessIPPRequest(
 
        length = ippLength(con->response);
 
+       if (con->file >= 0 && !con->pipe_pid)
+       {
+         struct stat   fileinfo;       /* File information */
+
+
+          if (!fstat(con->file, &fileinfo))
+           length += fileinfo.st_size;
+       }
+
        if (httpPrintf(HTTP(con), "Content-Length: " CUPS_LLFMT "\r\n\r\n",
                       CUPS_LLCAST length) < 0)
          return (0);
@@ -685,6 +694,11 @@ cupsdProcessIPPRequest(
 
        con->http.data_encoding  = HTTP_ENCODE_LENGTH;
        con->http.data_remaining = length;
+
+       if (con->http.data_remaining <= INT_MAX)
+         con->http._data_remaining = con->http.data_remaining;
+       else
+         con->http._data_remaining = INT_MAX;
       }
 
       cupsdAddSelect(con->http.fd, (cupsd_selfunc_t)cupsdReadClient,
@@ -5907,6 +5921,8 @@ get_ppd(cupsd_client_t  *con,             /* I - Client connection */
         ipp_attribute_t *uri)          /* I - Printer URI or PPD name */
 {
   http_status_t                status;         /* Policy status */
+  cupsd_printer_t      *dest;          /* Destination */
+  cups_ptype_t         dtype;          /* Destination type */
 
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppd(%p[%d], %p[%s=%s])", con,
@@ -5962,6 +5978,74 @@ get_ppd(cupsd_client_t  *con,            /* I - Client connection */
                      _("cups-driverd failed to execute."));
     }
   }
+  else if (!strcmp(uri->name, "printer-uri") &&
+           cupsdValidateDest(uri->values[0].string.text, &dtype, &dest))
+  {
+    int        i;                      /* Looping var */
+    char       filename[1024];         /* PPD filename */
+
+
+   /*
+    * Check policy...
+    */
+
+    if ((status = cupsdCheckPolicy(dest->op_policy_ptr, con, NULL)) != HTTP_OK)
+    {
+      send_http_error(con, status, NULL);
+      return;
+    }
+
+   /*
+    * See if we need the PPD for a class or remote printer...
+    */
+
+    if (dtype & CUPS_PRINTER_REMOTE)
+    {
+      send_ipp_status(con, CUPS_SEE_OTHER, NULL);
+      ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_URI,
+                   "printer-uri", NULL, dest->uri);
+      return;
+    }
+    else if (dtype & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))
+    {
+      for (i = 0; i < dest->num_printers; i ++)
+        if (!(dest->printers[i]->type &
+             (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT |
+              CUPS_PRINTER_REMOTE)))
+         break;
+
+      if (i < dest->num_printers)
+        dest = dest->printers[i];
+      else
+      {
+       send_ipp_status(con, CUPS_SEE_OTHER, NULL);
+       ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_URI,
+                    "printer-uri", NULL, dest->printers[0]->uri);
+        return;
+      }
+    }
+
+   /*
+    * Found the printer with the PPD file, now see if there is one...
+    */
+
+    snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot,
+             dest->name);
+
+    if ((con->file = open(filename, O_RDONLY)) < 0)
+    {
+      send_ipp_status(con, IPP_NOT_FOUND,
+                      _("The PPD file \"%s\" could not be opened: %s"),
+                     uri->values[i].string.text, strerror(errno));
+      return;
+    }
+
+    fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC);
+
+    con->pipe_pid = 0;
+
+    send_ipp_status(con, IPP_OK, NULL);
+  }
   else
     send_ipp_status(con, IPP_NOT_FOUND,
                     _("The PPD file \"%s\" could not be found."),
diff --git a/test/get-ppd-printer.test b/test/get-ppd-printer.test
new file mode 100644 (file)
index 0000000..4f723f8
--- /dev/null
@@ -0,0 +1,20 @@
+# Get printer PPD file using CUPS-Get-PPD
+{
+       # The name of the test...
+       NAME "Get printer PPD file using CUPS-Get-PPD"
+
+       # The resource to use for the POST
+       # RESOURCE /admin
+
+       # The operation to use
+       OPERATION CUPS-Get-PPD
+
+       # Attributes, starting in the operation group...
+       GROUP operation
+       ATTR charset attributes-charset utf-8
+       ATTR language attributes-natural-language en
+       ATTR uri printer-uri $uri
+
+       # What statuses are OK?
+       STATUS successful-ok
+}