2 * "$Id: getputfile.c 6720 2007-07-25 00:40:03Z mike $"
4 * Get/put file functions for the Common UNIX Printing System (CUPS).
6 * Copyright 2007 by Apple Inc.
7 * Copyright 1997-2006 by Easy Software Products.
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
15 * This file is subject to the Apple OS-Developed Software exception.
19 * cupsGetFd() - Get a file from the server.
20 * cupsGetFile() - Get a file from the server.
21 * cupsPutFd() - Put a file on the server.
22 * cupsPutFile() - Put a file on the server.
26 * Include necessary headers...
38 #if defined(WIN32) || defined(__EMX__)
42 #endif /* WIN32 || __EMX__ */
46 * 'cupsGetFd()' - Get a file from the server.
48 * This function returns HTTP_OK when the file is successfully retrieved.
53 http_status_t
/* O - HTTP status */
54 cupsGetFd(http_t
*http
, /* I - HTTP connection to server */
55 const char *resource
, /* I - Resource name */
56 int fd
) /* I - File descriptor */
58 int bytes
; /* Number of bytes read */
59 char buffer
[8192]; /* Buffer for file */
60 http_status_t status
; /* HTTP status from server */
61 char if_modified_since
[HTTP_MAX_VALUE
];
62 /* If-Modified-Since header */
66 * Range check input...
69 DEBUG_printf(("cupsGetFd(http=%p, resource=\"%s\", fd=%d)\n", http
,
72 if (!http
|| !resource
|| fd
< 0)
81 * Then send GET requests to the HTTP server...
84 strlcpy(if_modified_since
, httpGetField(http
, HTTP_FIELD_IF_MODIFIED_SINCE
),
85 sizeof(if_modified_since
));
89 httpClearFields(http
);
90 httpSetField(http
, HTTP_FIELD_AUTHORIZATION
, http
->authstring
);
91 httpSetField(http
, HTTP_FIELD_IF_MODIFIED_SINCE
, if_modified_since
);
93 if (httpGet(http
, resource
))
95 if (httpReconnect(http
))
102 status
= HTTP_UNAUTHORIZED
;
107 while ((status
= httpUpdate(http
)) == HTTP_CONTINUE
);
109 if (status
== HTTP_UNAUTHORIZED
)
112 * Flush any error message...
118 * See if we can do authentication...
121 if (cupsDoAuthentication(http
, "GET", resource
))
124 if (httpReconnect(http
))
133 else if (status
== HTTP_UPGRADE_REQUIRED
)
135 /* Flush any error message... */
139 if (httpReconnect(http
))
145 /* Upgrade with encryption... */
146 httpEncryption(http
, HTTP_ENCRYPT_REQUIRED
);
148 /* Try again, this time with encryption enabled... */
151 #endif /* HAVE_SSL */
153 while (status
== HTTP_UNAUTHORIZED
|| status
== HTTP_UPGRADE_REQUIRED
);
156 * See if we actually got the file or an error...
159 if (status
== HTTP_OK
)
162 * Yes, copy the file...
165 while ((bytes
= httpRead2(http
, buffer
, sizeof(buffer
))) > 0)
166 write(fd
, buffer
, bytes
);
170 _cupsSetHTTPError(status
);
175 * Return the request status...
183 * 'cupsGetFile()' - Get a file from the server.
185 * This function returns HTTP_OK when the file is successfully retrieved.
187 * @since CUPS 1.1.20@
190 http_status_t
/* O - HTTP status */
191 cupsGetFile(http_t
*http
, /* I - HTTP connection to server */
192 const char *resource
, /* I - Resource name */
193 const char *filename
) /* I - Filename */
195 int fd
; /* File descriptor */
196 http_status_t status
; /* Status */
200 * Range check input...
203 if (!http
|| !resource
|| !filename
)
206 http
->error
= EINVAL
;
215 if ((fd
= open(filename
, O_WRONLY
| O_EXCL
| O_TRUNC
)) < 0)
218 * Couldn't open the file!
230 status
= cupsGetFd(http
, resource
, fd
);
233 * If the file couldn't be gotten, then remove the file...
238 if (status
!= HTTP_OK
)
242 * Return the HTTP status code...
250 * 'cupsPutFd()' - Put a file on the server.
252 * This function returns HTTP_CREATED when the file is stored successfully.
254 * @since CUPS 1.1.20@
257 http_status_t
/* O - HTTP status */
258 cupsPutFd(http_t
*http
, /* I - HTTP connection to server */
259 const char *resource
, /* I - Resource name */
260 int fd
) /* I - File descriptor */
262 int bytes
, /* Number of bytes read */
263 retries
; /* Number of retries */
264 char buffer
[8192]; /* Buffer for file */
265 http_status_t status
; /* HTTP status from server */
269 * Range check input...
272 DEBUG_printf(("cupsPutFd(http=%p, resource=\"%s\", fd=%d)\n", http
,
275 if (!http
|| !resource
|| fd
< 0)
278 http
->error
= EINVAL
;
284 * Then send PUT requests to the HTTP server...
291 DEBUG_printf(("cupsPutFd: starting attempt, authstring=\"%s\"...\n",
294 httpClearFields(http
);
295 httpSetField(http
, HTTP_FIELD_AUTHORIZATION
, http
->authstring
);
296 httpSetField(http
, HTTP_FIELD_TRANSFER_ENCODING
, "chunked");
297 httpSetExpect(http
, HTTP_CONTINUE
);
299 if (httpPut(http
, resource
))
301 if (httpReconnect(http
))
308 status
= HTTP_UNAUTHORIZED
;
314 * Wait up to 1 second for a 100-continue response...
317 if (httpWait(http
, 1000))
318 status
= httpUpdate(http
);
320 status
= HTTP_CONTINUE
;
322 if (status
== HTTP_CONTINUE
)
328 lseek(fd
, 0, SEEK_SET
);
330 while ((bytes
= read(fd
, buffer
, sizeof(buffer
))) > 0)
333 if ((status
= httpUpdate(http
)) != HTTP_CONTINUE
)
337 httpWrite2(http
, buffer
, bytes
);
340 if (status
== HTTP_CONTINUE
)
342 httpWrite2(http
, buffer
, 0);
344 while ((status
= httpUpdate(http
)) == HTTP_CONTINUE
);
347 if (status
== HTTP_ERROR
&& !retries
)
349 DEBUG_printf(("cupsPutFd: retry on status %d\n", status
));
353 /* Flush any error message... */
357 if (httpReconnect(http
))
367 DEBUG_printf(("cupsPutFd: status=%d\n", status
));
369 if (status
== HTTP_UNAUTHORIZED
)
372 * Flush any error message...
378 * See if we can do authentication...
381 if (cupsDoAuthentication(http
, "PUT", resource
))
384 if (httpReconnect(http
))
393 else if (status
== HTTP_UPGRADE_REQUIRED
)
395 /* Flush any error message... */
399 if (httpReconnect(http
))
405 /* Upgrade with encryption... */
406 httpEncryption(http
, HTTP_ENCRYPT_REQUIRED
);
408 /* Try again, this time with encryption enabled... */
411 #endif /* HAVE_SSL */
413 while (status
== HTTP_UNAUTHORIZED
|| status
== HTTP_UPGRADE_REQUIRED
||
414 (status
== HTTP_ERROR
&& retries
< 2));
417 * See if we actually put the file or an error...
420 if (status
!= HTTP_CREATED
)
422 _cupsSetHTTPError(status
);
431 * 'cupsPutFile()' - Put a file on the server.
433 * This function returns HTTP_CREATED when the file is stored successfully.
435 * @since CUPS 1.1.20@
438 http_status_t
/* O - HTTP status */
439 cupsPutFile(http_t
*http
, /* I - HTTP connection to server */
440 const char *resource
, /* I - Resource name */
441 const char *filename
) /* I - Filename */
443 int fd
; /* File descriptor */
444 http_status_t status
; /* Status */
448 * Range check input...
451 if (!http
|| !resource
|| !filename
)
454 http
->error
= EINVAL
;
460 * Open the local file...
463 if ((fd
= open(filename
, O_RDONLY
)) < 0)
466 * Couldn't open the file!
478 status
= cupsPutFd(http
, resource
, fd
);
487 * End of "$Id: getputfile.c 6720 2007-07-25 00:40:03Z mike $".