2 * "$Id: getputfile.c 6649 2007-07-11 21:46:42Z 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...
29 #include "http-private.h"
39 #if defined(WIN32) || defined(__EMX__)
43 #endif /* WIN32 || __EMX__ */
47 * 'cupsGetFd()' - Get a file from the server.
49 * This function returns HTTP_OK when the file is successfully retrieved.
54 http_status_t
/* O - HTTP status */
55 cupsGetFd(http_t
*http
, /* I - HTTP connection to server */
56 const char *resource
, /* I - Resource name */
57 int fd
) /* I - File descriptor */
59 int bytes
; /* Number of bytes read */
60 char buffer
[8192]; /* Buffer for file */
61 http_status_t status
; /* HTTP status from server */
62 char if_modified_since
[HTTP_MAX_VALUE
];
63 /* If-Modified-Since header */
67 * Range check input...
70 DEBUG_printf(("cupsGetFd(http=%p, resource=\"%s\", fd=%d)\n", http
,
73 if (!http
|| !resource
|| fd
< 0)
82 * Then send GET requests to the HTTP server...
85 strlcpy(if_modified_since
, httpGetField(http
, HTTP_FIELD_IF_MODIFIED_SINCE
),
86 sizeof(if_modified_since
));
90 httpClearFields(http
);
91 httpSetField(http
, HTTP_FIELD_AUTHORIZATION
, http
->authstring
);
92 httpSetField(http
, HTTP_FIELD_IF_MODIFIED_SINCE
, if_modified_since
);
94 if (httpGet(http
, resource
))
96 if (httpReconnect(http
))
103 status
= HTTP_UNAUTHORIZED
;
108 while ((status
= httpUpdate(http
)) == HTTP_CONTINUE
);
110 if (status
== HTTP_UNAUTHORIZED
)
113 * Flush any error message...
119 * See if we can do authentication...
122 if (cupsDoAuthentication(http
, "GET", resource
))
125 if (httpReconnect(http
))
134 else if (status
== HTTP_UPGRADE_REQUIRED
)
136 /* Flush any error message... */
140 if (httpReconnect(http
))
146 /* Upgrade with encryption... */
147 httpEncryption(http
, HTTP_ENCRYPT_REQUIRED
);
149 /* Try again, this time with encryption enabled... */
152 #endif /* HAVE_SSL */
154 while (status
== HTTP_UNAUTHORIZED
|| status
== HTTP_UPGRADE_REQUIRED
);
157 * See if we actually got the file or an error...
160 if (status
== HTTP_OK
)
163 * Yes, copy the file...
166 while ((bytes
= httpRead2(http
, buffer
, sizeof(buffer
))) > 0)
167 write(fd
, buffer
, bytes
);
173 * Return the request status...
181 * 'cupsGetFile()' - Get a file from the server.
183 * This function returns HTTP_OK when the file is successfully retrieved.
185 * @since CUPS 1.1.20@
188 http_status_t
/* O - HTTP status */
189 cupsGetFile(http_t
*http
, /* I - HTTP connection to server */
190 const char *resource
, /* I - Resource name */
191 const char *filename
) /* I - Filename */
193 int fd
; /* File descriptor */
194 http_status_t status
; /* Status */
198 * Range check input...
201 if (!http
|| !resource
|| !filename
)
204 http
->error
= EINVAL
;
213 if ((fd
= open(filename
, O_WRONLY
| O_EXCL
| O_TRUNC
)) < 0)
216 * Couldn't open the file!
228 status
= cupsGetFd(http
, resource
, fd
);
231 * If the file couldn't be gotten, then remove the file...
236 if (status
!= HTTP_OK
)
240 * Return the HTTP status code...
248 * 'cupsPutFd()' - Put a file on the server.
250 * This function returns HTTP_CREATED when the file is stored successfully.
252 * @since CUPS 1.1.20@
255 http_status_t
/* O - HTTP status */
256 cupsPutFd(http_t
*http
, /* I - HTTP connection to server */
257 const char *resource
, /* I - Resource name */
258 int fd
) /* I - File descriptor */
260 int bytes
, /* Number of bytes read */
261 retries
; /* Number of retries */
262 char buffer
[8192]; /* Buffer for file */
263 http_status_t status
; /* HTTP status from server */
267 * Range check input...
270 DEBUG_printf(("cupsPutFd(http=%p, resource=\"%s\", fd=%d)\n", http
,
273 if (!http
|| !resource
|| fd
< 0)
276 http
->error
= EINVAL
;
282 * Then send PUT requests to the HTTP server...
289 DEBUG_printf(("cupsPutFd: starting attempt, authstring=\"%s\"...\n",
292 httpClearFields(http
);
293 httpSetField(http
, HTTP_FIELD_AUTHORIZATION
, http
->authstring
);
294 httpSetField(http
, HTTP_FIELD_TRANSFER_ENCODING
, "chunked");
295 httpSetExpect(http
, HTTP_CONTINUE
);
297 if (httpPut(http
, resource
))
299 if (httpReconnect(http
))
306 status
= HTTP_UNAUTHORIZED
;
312 * Wait up to 1 second for a 100-continue response...
315 if (httpWait(http
, 1000))
316 status
= httpUpdate(http
);
318 status
= HTTP_CONTINUE
;
320 if (status
== HTTP_CONTINUE
)
326 lseek(fd
, 0, SEEK_SET
);
328 while ((bytes
= read(fd
, buffer
, sizeof(buffer
))) > 0)
331 if ((status
= httpUpdate(http
)) != HTTP_CONTINUE
)
335 httpWrite2(http
, buffer
, bytes
);
338 if (status
== HTTP_CONTINUE
)
340 httpWrite2(http
, buffer
, 0);
342 while ((status
= httpUpdate(http
)) == HTTP_CONTINUE
);
345 if (status
== HTTP_ERROR
&& !retries
)
347 DEBUG_printf(("cupsPutFd: retry on status %d\n", status
));
351 /* Flush any error message... */
355 if (httpReconnect(http
))
365 DEBUG_printf(("cupsPutFd: status=%d\n", status
));
367 if (status
== HTTP_UNAUTHORIZED
)
370 * Flush any error message...
376 * See if we can do authentication...
379 if (cupsDoAuthentication(http
, "PUT", resource
))
382 if (httpReconnect(http
))
391 else if (status
== HTTP_UPGRADE_REQUIRED
)
393 /* Flush any error message... */
397 if (httpReconnect(http
))
403 /* Upgrade with encryption... */
404 httpEncryption(http
, HTTP_ENCRYPT_REQUIRED
);
406 /* Try again, this time with encryption enabled... */
409 #endif /* HAVE_SSL */
411 while (status
== HTTP_UNAUTHORIZED
|| status
== HTTP_UPGRADE_REQUIRED
||
412 (status
== HTTP_ERROR
&& retries
< 2));
415 * See if we actually put the file or an error...
418 if (status
!= HTTP_CREATED
)
426 * 'cupsPutFile()' - Put a file on the server.
428 * This function returns HTTP_CREATED when the file is stored successfully.
430 * @since CUPS 1.1.20@
433 http_status_t
/* O - HTTP status */
434 cupsPutFile(http_t
*http
, /* I - HTTP connection to server */
435 const char *resource
, /* I - Resource name */
436 const char *filename
) /* I - Filename */
438 int fd
; /* File descriptor */
439 http_status_t status
; /* Status */
443 * Range check input...
446 if (!http
|| !resource
|| !filename
)
449 http
->error
= EINVAL
;
455 * Open the local file...
458 if ((fd
= open(filename
, O_RDONLY
)) < 0)
461 * Couldn't open the file!
473 status
= cupsPutFd(http
, resource
, fd
);
482 * End of "$Id: getputfile.c 6649 2007-07-11 21:46:42Z mike $".