2 * "$Id: getputfile.c 7359 2008-02-29 19:01:35Z mike $"
4 * Get/put file functions for the Common UNIX Printing System (CUPS).
6 * Copyright 2007-2008 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 @code HTTP_OK@ when the file is successfully retrieved.
53 http_status_t
/* O - HTTP status */
54 cupsGetFd(http_t
*http
, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
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 (!resource
|| fd
< 0)
81 if ((http
= _cupsConnect()) == NULL
)
82 return (HTTP_SERVICE_UNAVAILABLE
);
85 * Then send GET requests to the HTTP server...
88 strlcpy(if_modified_since
, httpGetField(http
, HTTP_FIELD_IF_MODIFIED_SINCE
),
89 sizeof(if_modified_since
));
93 httpClearFields(http
);
94 httpSetField(http
, HTTP_FIELD_AUTHORIZATION
, http
->authstring
);
95 httpSetField(http
, HTTP_FIELD_IF_MODIFIED_SINCE
, if_modified_since
);
97 if (httpGet(http
, resource
))
99 if (httpReconnect(http
))
106 status
= HTTP_UNAUTHORIZED
;
111 while ((status
= httpUpdate(http
)) == HTTP_CONTINUE
);
113 if (status
== HTTP_UNAUTHORIZED
)
116 * Flush any error message...
122 * See if we can do authentication...
125 if (cupsDoAuthentication(http
, "GET", resource
))
128 if (httpReconnect(http
))
137 else if (status
== HTTP_UPGRADE_REQUIRED
)
139 /* Flush any error message... */
143 if (httpReconnect(http
))
149 /* Upgrade with encryption... */
150 httpEncryption(http
, HTTP_ENCRYPT_REQUIRED
);
152 /* Try again, this time with encryption enabled... */
155 #endif /* HAVE_SSL */
157 while (status
== HTTP_UNAUTHORIZED
|| status
== HTTP_UPGRADE_REQUIRED
);
160 * See if we actually got the file or an error...
163 if (status
== HTTP_OK
)
166 * Yes, copy the file...
169 while ((bytes
= httpRead2(http
, buffer
, sizeof(buffer
))) > 0)
170 write(fd
, buffer
, bytes
);
174 _cupsSetHTTPError(status
);
179 * Return the request status...
187 * 'cupsGetFile()' - Get a file from the server.
189 * This function returns @code HTTP_OK@ when the file is successfully retrieved.
191 * @since CUPS 1.1.20@
194 http_status_t
/* O - HTTP status */
195 cupsGetFile(http_t
*http
, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
196 const char *resource
, /* I - Resource name */
197 const char *filename
) /* I - Filename */
199 int fd
; /* File descriptor */
200 http_status_t status
; /* Status */
204 * Range check input...
207 if (!http
|| !resource
|| !filename
)
210 http
->error
= EINVAL
;
219 if ((fd
= open(filename
, O_WRONLY
| O_EXCL
| O_TRUNC
)) < 0)
222 * Couldn't open the file!
234 status
= cupsGetFd(http
, resource
, fd
);
237 * If the file couldn't be gotten, then remove the file...
242 if (status
!= HTTP_OK
)
246 * Return the HTTP status code...
254 * 'cupsPutFd()' - Put a file on the server.
256 * This function returns @code HTTP_CREATED@ when the file is stored
259 * @since CUPS 1.1.20@
262 http_status_t
/* O - HTTP status */
263 cupsPutFd(http_t
*http
, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
264 const char *resource
, /* I - Resource name */
265 int fd
) /* I - File descriptor */
267 int bytes
, /* Number of bytes read */
268 retries
; /* Number of retries */
269 char buffer
[8192]; /* Buffer for file */
270 http_status_t status
; /* HTTP status from server */
274 * Range check input...
277 DEBUG_printf(("cupsPutFd(http=%p, resource=\"%s\", fd=%d)\n", http
,
280 if (!resource
|| fd
< 0)
283 http
->error
= EINVAL
;
289 if ((http
= _cupsConnect()) == NULL
)
290 return (HTTP_SERVICE_UNAVAILABLE
);
293 * Then send PUT requests to the HTTP server...
300 DEBUG_printf(("cupsPutFd: starting attempt, authstring=\"%s\"...\n",
303 httpClearFields(http
);
304 httpSetField(http
, HTTP_FIELD_AUTHORIZATION
, http
->authstring
);
305 httpSetField(http
, HTTP_FIELD_TRANSFER_ENCODING
, "chunked");
306 httpSetExpect(http
, HTTP_CONTINUE
);
308 if (httpPut(http
, resource
))
310 if (httpReconnect(http
))
317 status
= HTTP_UNAUTHORIZED
;
323 * Wait up to 1 second for a 100-continue response...
326 if (httpWait(http
, 1000))
327 status
= httpUpdate(http
);
329 status
= HTTP_CONTINUE
;
331 if (status
== HTTP_CONTINUE
)
337 lseek(fd
, 0, SEEK_SET
);
339 while ((bytes
= read(fd
, buffer
, sizeof(buffer
))) > 0)
342 if ((status
= httpUpdate(http
)) != HTTP_CONTINUE
)
346 httpWrite2(http
, buffer
, bytes
);
349 if (status
== HTTP_CONTINUE
)
351 httpWrite2(http
, buffer
, 0);
353 while ((status
= httpUpdate(http
)) == HTTP_CONTINUE
);
356 if (status
== HTTP_ERROR
&& !retries
)
358 DEBUG_printf(("cupsPutFd: retry on status %d\n", status
));
362 /* Flush any error message... */
366 if (httpReconnect(http
))
376 DEBUG_printf(("cupsPutFd: status=%d\n", status
));
378 if (status
== HTTP_UNAUTHORIZED
)
381 * Flush any error message...
387 * See if we can do authentication...
390 if (cupsDoAuthentication(http
, "PUT", resource
))
393 if (httpReconnect(http
))
402 else if (status
== HTTP_UPGRADE_REQUIRED
)
404 /* Flush any error message... */
408 if (httpReconnect(http
))
414 /* Upgrade with encryption... */
415 httpEncryption(http
, HTTP_ENCRYPT_REQUIRED
);
417 /* Try again, this time with encryption enabled... */
420 #endif /* HAVE_SSL */
422 while (status
== HTTP_UNAUTHORIZED
|| status
== HTTP_UPGRADE_REQUIRED
||
423 (status
== HTTP_ERROR
&& retries
< 2));
426 * See if we actually put the file or an error...
429 if (status
!= HTTP_CREATED
)
431 _cupsSetHTTPError(status
);
440 * 'cupsPutFile()' - Put a file on the server.
442 * This function returns @code HTTP_CREATED@ when the file is stored
445 * @since CUPS 1.1.20@
448 http_status_t
/* O - HTTP status */
449 cupsPutFile(http_t
*http
, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
450 const char *resource
, /* I - Resource name */
451 const char *filename
) /* I - Filename */
453 int fd
; /* File descriptor */
454 http_status_t status
; /* Status */
458 * Range check input...
461 if (!http
|| !resource
|| !filename
)
464 http
->error
= EINVAL
;
470 * Open the local file...
473 if ((fd
= open(filename
, O_RDONLY
)) < 0)
476 * Couldn't open the file!
488 status
= cupsPutFd(http
, resource
, fd
);
497 * End of "$Id: getputfile.c 7359 2008-02-29 19:01:35Z mike $".