2 * "$Id: getputfile.c 5633 2006-06-06 14:47:42Z mike $"
4 * Get/put file functions for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2006 by Easy Software Products.
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
24 * This file is subject to the Apple OS-Developed Software exception.
28 * cupsGetFd() - Get a file from the server.
29 * cupsGetFile() - Get a file from the server.
30 * cupsPutFd() - Put a file on the server.
31 * cupsPutFile() - Put a file on the server.
35 * Include necessary headers...
38 #include "http-private.h"
48 #if defined(WIN32) || defined(__EMX__)
52 #endif /* WIN32 || __EMX__ */
56 * 'cupsGetFd()' - Get a file from the server.
58 * This function returns HTTP_OK when the file is successfully retrieved.
63 http_status_t
/* O - HTTP status */
64 cupsGetFd(http_t
*http
, /* I - HTTP connection to server */
65 const char *resource
, /* I - Resource name */
66 int fd
) /* I - File descriptor */
68 int bytes
; /* Number of bytes read */
69 char buffer
[8192]; /* Buffer for file */
70 http_status_t status
; /* HTTP status from server */
71 char if_modified_since
[HTTP_MAX_VALUE
];
72 /* If-Modified-Since header */
76 * Range check input...
79 DEBUG_printf(("cupsGetFd(http=%p, resource=\"%s\", fd=%d)\n", http
,
82 if (!http
|| !resource
|| fd
< 0)
91 * Then send GET requests to the HTTP server...
94 strlcpy(if_modified_since
, httpGetField(http
, HTTP_FIELD_IF_MODIFIED_SINCE
),
95 sizeof(if_modified_since
));
99 httpClearFields(http
);
100 httpSetField(http
, HTTP_FIELD_AUTHORIZATION
, http
->authstring
);
101 httpSetField(http
, HTTP_FIELD_IF_MODIFIED_SINCE
, if_modified_since
);
103 if (httpGet(http
, resource
))
105 if (httpReconnect(http
))
112 status
= HTTP_UNAUTHORIZED
;
117 while ((status
= httpUpdate(http
)) == HTTP_CONTINUE
);
119 if (status
== HTTP_UNAUTHORIZED
)
122 * Flush any error message...
128 * See if we can do authentication...
131 if (cupsDoAuthentication(http
, "GET", resource
))
134 if (httpReconnect(http
))
143 else if (status
== HTTP_UPGRADE_REQUIRED
)
145 /* Flush any error message... */
149 if (httpReconnect(http
))
155 /* Upgrade with encryption... */
156 httpEncryption(http
, HTTP_ENCRYPT_REQUIRED
);
158 /* Try again, this time with encryption enabled... */
161 #endif /* HAVE_SSL */
163 while (status
== HTTP_UNAUTHORIZED
|| status
== HTTP_UPGRADE_REQUIRED
);
166 * See if we actually got the file or an error...
169 if (status
== HTTP_OK
)
172 * Yes, copy the file...
175 while ((bytes
= httpRead2(http
, buffer
, sizeof(buffer
))) > 0)
176 write(fd
, buffer
, bytes
);
182 * Return the request status...
190 * 'cupsGetFile()' - Get a file from the server.
192 * This function returns HTTP_OK when the file is successfully retrieved.
194 * @since CUPS 1.1.20@
197 http_status_t
/* O - HTTP status */
198 cupsGetFile(http_t
*http
, /* I - HTTP connection to server */
199 const char *resource
, /* I - Resource name */
200 const char *filename
) /* I - Filename */
202 int fd
; /* File descriptor */
203 http_status_t status
; /* Status */
207 * Range check input...
210 if (!http
|| !resource
|| !filename
)
213 http
->error
= EINVAL
;
222 if ((fd
= open(filename
, O_WRONLY
| O_EXCL
| O_TRUNC
)) < 0)
225 * Couldn't open the file!
237 status
= cupsGetFd(http
, resource
, fd
);
240 * If the file couldn't be gotten, then remove the file...
245 if (status
!= HTTP_OK
)
249 * Return the HTTP status code...
257 * 'cupsPutFd()' - Put a file on the server.
259 * This function returns HTTP_CREATED when the file is stored successfully.
261 * @since CUPS 1.1.20@
264 http_status_t
/* O - HTTP status */
265 cupsPutFd(http_t
*http
, /* I - HTTP connection to server */
266 const char *resource
, /* I - Resource name */
267 int fd
) /* I - File descriptor */
269 int bytes
, /* Number of bytes read */
270 retries
; /* Number of retries */
271 char buffer
[8192]; /* Buffer for file */
272 http_status_t status
; /* HTTP status from server */
276 * Range check input...
279 DEBUG_printf(("cupsPutFd(http=%p, resource=\"%s\", fd=%d)\n", http
,
282 if (!http
|| !resource
|| fd
< 0)
285 http
->error
= EINVAL
;
291 * Then send PUT requests to the HTTP server...
298 DEBUG_printf(("cupsPutFd: starting attempt, authstring=\"%s\"...\n",
301 httpClearFields(http
);
302 httpSetField(http
, HTTP_FIELD_AUTHORIZATION
, http
->authstring
);
303 httpSetField(http
, HTTP_FIELD_TRANSFER_ENCODING
, "chunked");
304 httpSetExpect(http
, HTTP_CONTINUE
);
306 if (httpPut(http
, resource
))
308 if (httpReconnect(http
))
315 status
= HTTP_UNAUTHORIZED
;
321 * Wait up to 1 second for a 100-continue response...
324 if (httpWait(http
, 1000))
325 status
= httpUpdate(http
);
327 status
= HTTP_CONTINUE
;
329 if (status
== HTTP_CONTINUE
)
335 lseek(fd
, 0, SEEK_SET
);
337 while ((bytes
= read(fd
, buffer
, sizeof(buffer
))) > 0)
340 if ((status
= httpUpdate(http
)) != HTTP_CONTINUE
)
344 httpWrite2(http
, buffer
, bytes
);
347 if (status
== HTTP_CONTINUE
)
349 httpWrite2(http
, buffer
, 0);
351 while ((status
= httpUpdate(http
)) == HTTP_CONTINUE
);
354 if (status
== HTTP_ERROR
&& !retries
)
356 DEBUG_printf(("cupsPutFd: retry on status %d\n", status
));
360 /* Flush any error message... */
364 if (httpReconnect(http
))
374 DEBUG_printf(("cupsPutFd: status=%d\n", status
));
376 if (status
== HTTP_UNAUTHORIZED
)
379 * Flush any error message...
385 * See if we can do authentication...
388 if (cupsDoAuthentication(http
, "PUT", resource
))
391 if (httpReconnect(http
))
400 else if (status
== HTTP_UPGRADE_REQUIRED
)
402 /* Flush any error message... */
406 if (httpReconnect(http
))
412 /* Upgrade with encryption... */
413 httpEncryption(http
, HTTP_ENCRYPT_REQUIRED
);
415 /* Try again, this time with encryption enabled... */
418 #endif /* HAVE_SSL */
420 while (status
== HTTP_UNAUTHORIZED
|| status
== HTTP_UPGRADE_REQUIRED
||
421 (status
== HTTP_ERROR
&& retries
< 2));
424 * See if we actually put the file or an error...
427 if (status
!= HTTP_CREATED
)
435 * 'cupsPutFile()' - Put a file on the server.
437 * This function returns HTTP_CREATED when the file is stored successfully.
439 * @since CUPS 1.1.20@
442 http_status_t
/* O - HTTP status */
443 cupsPutFile(http_t
*http
, /* I - HTTP connection to server */
444 const char *resource
, /* I - Resource name */
445 const char *filename
) /* I - Filename */
447 int fd
; /* File descriptor */
448 http_status_t status
; /* Status */
452 * Range check input...
455 if (!http
|| !resource
|| !filename
)
458 http
->error
= EINVAL
;
464 * Open the local file...
467 if ((fd
= open(filename
, O_RDONLY
)) < 0)
470 * Couldn't open the file!
482 status
= cupsPutFd(http
, resource
, fd
);
491 * End of "$Id: getputfile.c 5633 2006-06-06 14:47:42Z mike $".