]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/request.c
Load cups into easysw/current.
[thirdparty/cups.git] / cups / request.c
index 95870a8fc7d024a3490408d223443e49e6244216..5e80fd645f60b7b1e081cc76883181fdfa1a91e7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: request.c 6416 2007-03-30 18:30:33Z mike $"
+ * "$Id: request.c 6506 2007-05-03 18:12:35Z mike $"
  *
  *   IPP utilities for the Common UNIX Printing System (CUPS).
  *
@@ -45,6 +45,9 @@
 #else
 #  include <unistd.h>
 #endif /* WIN32 || __EMX__ */
+#ifndef O_BINARY
+#  define O_BINARY 0
+#endif /* O_BINARY */
 
 
 /*
@@ -60,20 +63,71 @@ cupsDoFileRequest(http_t     *http, /* I - HTTP connection to server */
                   ipp_t      *request, /* I - IPP request */
                   const char *resource,        /* I - HTTP resource for POST */
                  const char *filename) /* I - File to send or NULL for none */
+{
+  ipp_t                *response;              /* IPP response data */
+  int          infile;                 /* Input file */
+
+
+  if (filename)
+  {
+    if ((infile = open(filename, O_RDONLY | O_BINARY)) < 0)
+    {
+     /*
+      * Can't get file information!
+      */
+
+      _cupsSetError(errno == ENOENT ? IPP_NOT_FOUND : IPP_NOT_AUTHORIZED,
+                    strerror(errno));
+
+      ippDelete(request);
+
+      return (NULL);
+    }
+  }
+  else
+    infile = -1;
+
+  response = cupsDoIORequest(http, request, resource, infile, -1);
+
+  if (infile >= 0)
+    close(infile);
+
+  return (response);
+}
+
+
+/*
+ * 'cupsDoIORequest()' - Do an IPP request with file descriptors.
+ *
+ * This function sends the IPP request to the specified server, retrying
+ * and authenticating as necessary.  The request is freed with ippDelete()
+ * after receiving a valid IPP response.
+ *
+ * If "infile" is a valid file descriptor, cupsDoIORequest() copies
+ * all of the data from the file after the IPP request message.
+ *
+ * If "outfile" is a valid file descriptor, cupsDoIORequest() copies
+ * all of the data after the IPP response message to the file.
+ *
+ * @since CUPS 1.3@
+ */
+
+ipp_t *                                        /* O - Response data */
+cupsDoIORequest(http_t     *http,      /* I - HTTP connection to server */
+                ipp_t      *request,   /* I - IPP request */
+                const char *resource,  /* I - HTTP resource for POST */
+               int        infile,      /* I - File to read from or -1 for none */
+               int        outfile)     /* I - File to write to or -1 for none */
 {
   ipp_t                *response;              /* IPP response data */
   size_t       length;                 /* Content-Length value */
   http_status_t        status;                 /* Status of HTTP request */
   int          got_status;             /* Did we get the status? */
   ipp_state_t  state;                  /* State of IPP processing */
-  FILE         *file;                  /* File to send */
   struct stat  fileinfo;               /* File information */
   int          bytes;                  /* Number of bytes read/written */
   char         buffer[32768];          /* Output buffer */
   http_status_t        expect;                 /* Expect: header to use */
-#ifdef HAVE_AUTHORIZATION_H
-  _cups_globals_t *cg = _cupsGlobals();        /* Global data */
-#endif /* HAVE_AUTHORIZATION_H */
 
 
   DEBUG_printf(("cupsDoFileRequest(%p, %p, \'%s\', \'%s\')\n",
@@ -94,16 +148,16 @@ cupsDoFileRequest(http_t     *http,        /* I - HTTP connection to server */
   * See if we have a file to send...
   */
 
-  if (filename != NULL)
+  if (infile >= 0)
   {
-    if (stat(filename, &fileinfo))
+    if (fstat(infile, &fileinfo))
     {
      /*
       * Can't get file information!
       */
 
       _cupsSetError(errno == ENOENT ? IPP_NOT_FOUND : IPP_NOT_AUTHORIZED,
-                     strerror(errno));
+                    strerror(errno));
 
       ippDelete(request);
 
@@ -126,23 +180,7 @@ cupsDoFileRequest(http_t     *http,        /* I - HTTP connection to server */
 
       return (NULL);
     }
-
-    if ((file = fopen(filename, "rb")) == NULL)
-    {
-     /*
-      * Can't open file!
-      */
-
-      _cupsSetError(errno == ENOENT ? IPP_NOT_FOUND : IPP_NOT_AUTHORIZED,
-                     strerror(errno));
-
-      ippDelete(request);
-
-      return (NULL);
-    }
   }
-  else
-    file = NULL;
 
 #ifdef HAVE_SSL
  /*
@@ -174,8 +212,15 @@ cupsDoFileRequest(http_t     *http,        /* I - HTTP connection to server */
     */
 
     length = ippLength(request);
-    if (filename)
+    if (infile >= 0)
+    {
+#ifndef WIN32
+      if (!S_ISREG(fileinfo.st_mode))
+        length = 0;                    /* Chunk when piping */
+      else
+#endif /* !WIN32 */
       length += fileinfo.st_size;
+    }
 
     httpClearFields(http);
     httpSetLength(http, length);
@@ -235,7 +280,7 @@ cupsDoFileRequest(http_t     *http, /* I - HTTP connection to server */
     else if (httpCheck(http))
       status = httpUpdate(http);
 
-    if (status == HTTP_CONTINUE && state == IPP_DATA && filename)
+    if (status == HTTP_CONTINUE && state == IPP_DATA && infile >= 0)
     {
       DEBUG_puts("cupsDoFileRequest: file write...");
 
@@ -243,9 +288,12 @@ cupsDoFileRequest(http_t     *http,        /* I - HTTP connection to server */
       * Send the file...
       */
 
-      rewind(file);
+#ifndef WIN32
+      if (S_ISREG(fileinfo.st_mode))
+#endif /* WIN32 */
+      lseek(infile, 0, SEEK_SET);
 
-      while ((bytes = (int)fread(buffer, 1, sizeof(buffer), file)) > 0)
+      while ((bytes = (int)read(infile, buffer, sizeof(buffer))) > 0)
       {
        if (httpCheck(http))
        {
@@ -377,21 +425,26 @@ cupsDoFileRequest(http_t     *http,       /* I - HTTP connection to server */
 
        break;
       }
-    }
-  }
-
- /*
-  * Close the file if needed...
-  */
-
-  if (filename != NULL)
-    fclose(file);
+      else if (outfile >= 0)
+      {
+       /*
+        * Write trailing data to file...
+       */
 
- /*
-  * Flush any remaining data...
-  */
+       while ((bytes = (int)httpRead2(http, buffer, sizeof(buffer))) > 0)
+         if (write(outfile, buffer, bytes) < bytes)
+           break;
+      }
+      else
+      {
+       /*
+        * Flush any remaining data...
+        */
 
-  httpFlush(http);
+        httpFlush(http);
+      }
+    }
+  }
 
  /*
   * Delete the original request and return the response...
@@ -450,18 +503,6 @@ cupsDoFileRequest(http_t     *http,        /* I - HTTP connection to server */
     }
   }
 
-#ifdef HAVE_AUTHORIZATION_H
- /*
-  * Delete any authorization reference created for this request...
-  */
-  
-  if (cg->auth_ref)
-  {
-    AuthorizationFree(cg->auth_ref, kAuthorizationFlagDefaults);
-    cg->auth_ref = NULL;
-  }
-#endif /* HAVE_AUTHORIZATION_H */
-
   return (response);
 }
 
@@ -510,5 +551,5 @@ _cupsSetError(ipp_status_t status,  /* I - IPP status code */
 
 
 /*
- * End of "$Id: request.c 6416 2007-03-30 18:30:33Z mike $".
+ * End of "$Id: request.c 6506 2007-05-03 18:12:35Z mike $".
  */