]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/getputfile.c
Load cups into easysw/current.
[thirdparty/cups.git] / cups / getputfile.c
1 /*
2 * "$Id: getputfile.c 5103 2006-02-14 19:27:42Z mike $"
3 *
4 * Get/put file functions for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1997-2006 by Easy Software Products.
7 *
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
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
19 *
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * This file is subject to the Apple OS-Developed Software exception.
25 *
26 * Contents:
27 *
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.
32 */
33
34 /*
35 * Include necessary headers...
36 */
37
38 #include "cups.h"
39 #include "ipp.h"
40 #include "language.h"
41 #include "string.h"
42 #include "debug.h"
43 #include <stdlib.h>
44 #include <ctype.h>
45 #include <errno.h>
46 #include <fcntl.h>
47 #include <sys/stat.h>
48 #if defined(WIN32) || defined(__EMX__)
49 # include <io.h>
50 #else
51 # include <unistd.h>
52 #endif /* WIN32 || __EMX__ */
53
54
55 /*
56 * 'cupsGetFd()' - Get a file from the server.
57 *
58 * This function returns HTTP_OK when the file is successfully retrieved.
59 *
60 * @since CUPS 1.1.20@
61 */
62
63 http_status_t /* O - Status */
64 cupsGetFd(http_t *http, /* I - HTTP connection to server */
65 const char *resource, /* I - Resource name */
66 int fd) /* I - File descriptor */
67 {
68 int bytes; /* Number of bytes read */
69 char buffer[8192]; /* Buffer for file */
70 http_status_t status; /* HTTP status from server */
71
72
73 /*
74 * Range check input...
75 */
76
77 DEBUG_printf(("cupsGetFd(http=%p, resource=\"%s\", fd=%d)\n", http,
78 resource, fd));
79
80 if (!http || !resource || fd < 0)
81 {
82 if (http)
83 http->error = EINVAL;
84
85 return (HTTP_ERROR);
86 }
87
88 /*
89 * Then send GET requests to the HTTP server...
90 */
91
92 do
93 {
94 httpClearFields(http);
95 httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
96
97 if (httpGet(http, resource))
98 {
99 if (httpReconnect(http))
100 {
101 status = HTTP_ERROR;
102 break;
103 }
104 else
105 {
106 status = HTTP_UNAUTHORIZED;
107 continue;
108 }
109 }
110
111 while ((status = httpUpdate(http)) == HTTP_CONTINUE);
112
113 if (status == HTTP_UNAUTHORIZED)
114 {
115 /*
116 * Flush any error message...
117 */
118
119 httpFlush(http);
120
121 /*
122 * See if we can do authentication...
123 */
124
125 if (cupsDoAuthentication(http, "GET", resource))
126 break;
127
128 if (httpReconnect(http))
129 {
130 status = HTTP_ERROR;
131 break;
132 }
133
134 continue;
135 }
136 #ifdef HAVE_SSL
137 else if (status == HTTP_UPGRADE_REQUIRED)
138 {
139 /* Flush any error message... */
140 httpFlush(http);
141
142 /* Reconnect... */
143 if (httpReconnect(http))
144 {
145 status = HTTP_ERROR;
146 break;
147 }
148
149 /* Upgrade with encryption... */
150 httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
151
152 /* Try again, this time with encryption enabled... */
153 continue;
154 }
155 #endif /* HAVE_SSL */
156 }
157 while (status == HTTP_UNAUTHORIZED || status == HTTP_UPGRADE_REQUIRED);
158
159 /*
160 * See if we actually got the file or an error...
161 */
162
163 if (status == HTTP_OK)
164 {
165 /*
166 * Yes, copy the file...
167 */
168
169 while ((bytes = httpRead2(http, buffer, sizeof(buffer))) > 0)
170 write(fd, buffer, bytes);
171 }
172 else
173 httpFlush(http);
174
175 /*
176 * Return the request status...
177 */
178
179 return (status);
180 }
181
182
183 /*
184 * 'cupsGetFile()' - Get a file from the server.
185 *
186 * This function returns HTTP_OK when the file is successfully retrieved.
187 *
188 * @since CUPS 1.1.20@
189 */
190
191 http_status_t /* O - Status */
192 cupsGetFile(http_t *http, /* I - HTTP connection to server */
193 const char *resource, /* I - Resource name */
194 const char *filename) /* I - Filename */
195 {
196 int fd; /* File descriptor */
197 http_status_t status; /* Status */
198
199
200 /*
201 * Range check input...
202 */
203
204 if (!http || !resource || !filename)
205 {
206 if (http)
207 http->error = EINVAL;
208
209 return (HTTP_ERROR);
210 }
211
212 /*
213 * Create the file...
214 */
215
216 if ((fd = open(filename, O_WRONLY | O_EXCL | O_TRUNC)) < 0)
217 {
218 /*
219 * Couldn't open the file!
220 */
221
222 http->error = errno;
223
224 return (HTTP_ERROR);
225 }
226
227 /*
228 * Get the file...
229 */
230
231 status = cupsGetFd(http, resource, fd);
232
233 /*
234 * If the file couldn't be gotten, then remove the file...
235 */
236
237 close(fd);
238
239 if (status != HTTP_OK)
240 unlink(filename);
241
242 /*
243 * Return the HTTP status code...
244 */
245
246 return (status);
247 }
248
249
250 /*
251 * 'cupsPutFd()' - Put a file on the server.
252 *
253 * This function returns HTTP_CREATED when the file is stored successfully.
254 *
255 * @since CUPS 1.1.20@
256 */
257
258 http_status_t /* O - Status */
259 cupsPutFd(http_t *http, /* I - HTTP connection to server */
260 const char *resource, /* I - Resource name */
261 int fd) /* I - File descriptor */
262 {
263 int bytes, /* Number of bytes read */
264 retries; /* Number of retries */
265 char buffer[8192]; /* Buffer for file */
266 http_status_t status; /* HTTP status from server */
267
268
269 /*
270 * Range check input...
271 */
272
273 DEBUG_printf(("cupsPutFd(http=%p, resource=\"%s\", fd=%d)\n", http,
274 resource, fd));
275
276 if (!http || !resource || fd < 0)
277 {
278 if (http)
279 http->error = EINVAL;
280
281 return (HTTP_ERROR);
282 }
283
284 /*
285 * Then send PUT requests to the HTTP server...
286 */
287
288 retries = 0;
289
290 do
291 {
292 DEBUG_printf(("cupsPutFd: starting attempt, authstring=\"%s\"...\n",
293 http->authstring));
294
295 httpClearFields(http);
296 httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
297 httpSetField(http, HTTP_FIELD_TRANSFER_ENCODING, "chunked");
298
299 if (httpPut(http, resource))
300 {
301 if (httpReconnect(http))
302 {
303 status = HTTP_ERROR;
304 break;
305 }
306 else
307 {
308 status = HTTP_UNAUTHORIZED;
309 continue;
310 }
311 }
312
313 /*
314 * Copy the file...
315 */
316
317 lseek(fd, 0, SEEK_SET);
318
319 status = HTTP_CONTINUE;
320
321 while ((bytes = read(fd, buffer, sizeof(buffer))) > 0)
322 if (httpCheck(http))
323 {
324 if ((status = httpUpdate(http)) != HTTP_CONTINUE)
325 break;
326 }
327 else
328 httpWrite2(http, buffer, bytes);
329
330 if (status == HTTP_CONTINUE)
331 {
332 httpWrite2(http, buffer, 0);
333
334 while ((status = httpUpdate(http)) == HTTP_CONTINUE);
335 }
336
337 if (status == HTTP_ERROR && !retries)
338 {
339 DEBUG_printf(("cupsPutFd: retry on status %d\n", status));
340
341 retries ++;
342
343 /* Flush any error message... */
344 httpFlush(http);
345
346 /* Reconnect... */
347 if (httpReconnect(http))
348 {
349 status = HTTP_ERROR;
350 break;
351 }
352
353 /* Try again... */
354 continue;
355 }
356
357 DEBUG_printf(("cupsPutFd: status=%d\n", status));
358
359 if (status == HTTP_UNAUTHORIZED)
360 {
361 /*
362 * Flush any error message...
363 */
364
365 httpFlush(http);
366
367 /*
368 * See if we can do authentication...
369 */
370
371 if (cupsDoAuthentication(http, "PUT", resource))
372 break;
373
374 if (httpReconnect(http))
375 {
376 status = HTTP_ERROR;
377 break;
378 }
379
380 continue;
381 }
382 #ifdef HAVE_SSL
383 else if (status == HTTP_UPGRADE_REQUIRED)
384 {
385 /* Flush any error message... */
386 httpFlush(http);
387
388 /* Reconnect... */
389 if (httpReconnect(http))
390 {
391 status = HTTP_ERROR;
392 break;
393 }
394
395 /* Upgrade with encryption... */
396 httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
397
398 /* Try again, this time with encryption enabled... */
399 continue;
400 }
401 #endif /* HAVE_SSL */
402 }
403 while (status == HTTP_UNAUTHORIZED || status == HTTP_UPGRADE_REQUIRED ||
404 (status == HTTP_ERROR && retries < 2));
405
406 /*
407 * See if we actually put the file or an error...
408 */
409
410 if (status != HTTP_CREATED)
411 httpFlush(http);
412
413 return (status);
414 }
415
416
417 /*
418 * 'cupsPutFile()' - Put a file on the server.
419 *
420 * This function returns HTTP_CREATED when the file is stored successfully.
421 *
422 * @since CUPS 1.1.20@
423 */
424
425 http_status_t /* O - Status */
426 cupsPutFile(http_t *http, /* I - HTTP connection to server */
427 const char *resource, /* I - Resource name */
428 const char *filename) /* I - Filename */
429 {
430 int fd; /* File descriptor */
431 http_status_t status; /* Status */
432
433
434 /*
435 * Range check input...
436 */
437
438 if (!http || !resource || !filename)
439 {
440 if (http)
441 http->error = EINVAL;
442
443 return (HTTP_ERROR);
444 }
445
446 /*
447 * Open the local file...
448 */
449
450 if ((fd = open(filename, O_RDONLY)) < 0)
451 {
452 /*
453 * Couldn't open the file!
454 */
455
456 http->error = errno;
457
458 return (HTTP_ERROR);
459 }
460
461 /*
462 * Put the file...
463 */
464
465 status = cupsPutFd(http, resource, fd);
466
467 close(fd);
468
469 return (status);
470 }
471
472
473 /*
474 * End of "$Id: getputfile.c 5103 2006-02-14 19:27:42Z mike $".
475 */