+ int infile; /* Input file */
+
+
+ DEBUG_printf(("cupsDoFileRequest(http=%p, request=%p(%s), resource=\"%s\", "
+ "filename=\"%s\")", http, request,
+ request ? ippOpString(request->request.op.operation_id) : "?",
+ resource, filename));
+
+ 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,
+ NULL, 0);
+
+ 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/Mac OS X 10.5@
+ */
+
+ipp_t * /* O - Response data */
+cupsDoIORequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
+ 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 = NULL; /* IPP response data */
+ size_t length = 0; /* Content-Length value */