Load cups into easysw/current.
[thirdparty/cups.git] / cups / getputfile.c
1 /*
2  * "$Id: getputfile.c 4918 2006-01-12 05:14:40Z 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       httpReconnect(http);
129
130       continue;
131     }
132 #ifdef HAVE_SSL
133     else if (status == HTTP_UPGRADE_REQUIRED)
134     {
135       /* Flush any error message... */
136       httpFlush(http);
137
138       /* Reconnect... */
139       httpReconnect(http);
140
141       /* Upgrade with encryption... */
142       httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
143
144       /* Try again, this time with encryption enabled... */
145       continue;
146     }
147 #endif /* HAVE_SSL */
148   }
149   while (status == HTTP_UNAUTHORIZED || status == HTTP_UPGRADE_REQUIRED);
150
151  /*
152   * See if we actually got the file or an error...
153   */
154
155   if (status == HTTP_OK)
156   {
157    /*
158     * Yes, copy the file...
159     */
160
161     while ((bytes = httpRead(http, buffer, sizeof(buffer))) > 0)
162       write(fd, buffer, bytes);
163   }
164   else
165     httpFlush(http);
166
167  /*
168   * Return the request status...
169   */
170
171   return (status);
172 }
173
174
175 /*
176  * 'cupsGetFile()' - Get a file from the server.
177  *
178  * This function returns HTTP_OK when the file is successfully retrieved.
179  *
180  * @since CUPS 1.1.20@
181  */
182
183 http_status_t                           /* O - Status */
184 cupsGetFile(http_t     *http,           /* I - HTTP connection to server */
185             const char *resource,       /* I - Resource name */
186             const char *filename)       /* I - Filename */
187 {
188   int           fd;                     /* File descriptor */
189   http_status_t status;                 /* Status */
190
191
192  /*
193   * Range check input...
194   */
195
196   if (!http || !resource || !filename)
197   {
198     if (http)
199       http->error = EINVAL;
200
201     return (HTTP_ERROR);
202   }
203
204  /*
205   * Create the file...
206   */
207
208   if ((fd = open(filename, O_WRONLY | O_EXCL | O_TRUNC)) < 0)
209   {
210    /*
211     * Couldn't open the file!
212     */
213
214     http->error = errno;
215
216     return (HTTP_ERROR);
217   }
218
219  /*
220   * Get the file...
221   */
222
223   status = cupsGetFd(http, resource, fd);
224
225  /*
226   * If the file couldn't be gotten, then remove the file...
227   */
228
229   close(fd);
230
231   if (status != HTTP_OK)
232     unlink(filename);
233
234  /*
235   * Return the HTTP status code...
236   */
237
238   return (status);
239 }
240
241
242 /*
243  * 'cupsPutFd()' - Put a file on the server.
244  *
245  * This function returns HTTP_CREATED when the file is stored successfully.
246  *
247  * @since CUPS 1.1.20@
248  */
249
250 http_status_t                           /* O - Status */
251 cupsPutFd(http_t     *http,             /* I - HTTP connection to server */
252           const char *resource,         /* I - Resource name */
253           int        fd)                /* I - File descriptor */
254 {
255   int           bytes;                  /* Number of bytes read */
256   char          buffer[8192];           /* Buffer for file */
257   http_status_t status;                 /* HTTP status from server */
258
259
260  /*
261   * Range check input...
262   */
263
264   DEBUG_printf(("cupsPutFd(http=%p, resource=\"%s\", fd=%d)\n", http,
265                 resource, fd));
266
267   if (!http || !resource || fd < 0)
268   {
269     if (http)
270       http->error = EINVAL;
271
272     return (HTTP_ERROR);
273   }
274
275  /*
276   * Then send PUT requests to the HTTP server...
277   */
278
279   do
280   {
281     DEBUG_printf(("cupsPutFd: starting attempt, authstring=\"%s\"...\n",
282                   http->authstring));
283
284     httpClearFields(http);
285     httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
286     httpSetField(http, HTTP_FIELD_TRANSFER_ENCODING, "chunked");
287
288     if (httpPut(http, resource))
289     {
290       if (httpReconnect(http))
291       {
292         status = HTTP_ERROR;
293         break;
294       }
295       else
296       {
297         status = HTTP_UNAUTHORIZED;
298         continue;
299       }
300     }
301
302    /*
303     * Copy the file...
304     */
305
306     lseek(fd, 0, SEEK_SET);
307
308     status = HTTP_CONTINUE;
309
310     while ((bytes = read(fd, buffer, sizeof(buffer))) > 0)
311       if (httpCheck(http))
312       {
313         if ((status = httpUpdate(http)) != HTTP_CONTINUE)
314           break;
315       }
316       else
317         httpWrite(http, buffer, bytes);
318
319     if (status == HTTP_CONTINUE)
320     {
321       httpWrite(http, buffer, 0);
322
323       while ((status = httpUpdate(http)) == HTTP_CONTINUE);
324     }
325
326     DEBUG_printf(("cupsPutFd: status=%d\n", status));
327
328     if (status == HTTP_UNAUTHORIZED)
329     {
330      /*
331       * Flush any error message...
332       */
333
334       httpFlush(http);
335
336      /*
337       * See if we can do authentication...
338       */
339
340       if (cupsDoAuthentication(http, "PUT", resource))
341         break;
342
343       httpReconnect(http);
344
345       continue;
346     }
347 #ifdef HAVE_SSL
348     else if (status == HTTP_UPGRADE_REQUIRED)
349     {
350       /* Flush any error message... */
351       httpFlush(http);
352
353       /* Reconnect... */
354       httpReconnect(http);
355
356       /* Upgrade with encryption... */
357       httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
358
359       /* Try again, this time with encryption enabled... */
360       continue;
361     }
362 #endif /* HAVE_SSL */
363   }
364   while (status == HTTP_UNAUTHORIZED || status == HTTP_UPGRADE_REQUIRED);
365
366  /*
367   * See if we actually put the file or an error...
368   */
369
370   if (status != HTTP_CREATED)
371     httpFlush(http);
372
373   return (status);
374 }
375
376
377 /*
378  * 'cupsPutFile()' - Put a file on the server.
379  *
380  * This function returns HTTP_CREATED when the file is stored successfully.
381  *
382  * @since CUPS 1.1.20@
383  */
384
385 http_status_t                           /* O - Status */
386 cupsPutFile(http_t     *http,           /* I - HTTP connection to server */
387             const char *resource,       /* I - Resource name */
388             const char *filename)       /* I - Filename */
389 {
390   int           fd;                     /* File descriptor */
391   http_status_t status;                 /* Status */
392
393
394  /*
395   * Range check input...
396   */
397
398   if (!http || !resource || !filename)
399   {
400     if (http)
401       http->error = EINVAL;
402
403     return (HTTP_ERROR);
404   }
405
406  /*
407   * Open the local file...
408   */
409
410   if ((fd = open(filename, O_RDONLY)) < 0)
411   {
412    /*
413     * Couldn't open the file!
414     */
415
416     http->error = errno;
417
418     return (HTTP_ERROR);
419   }
420
421  /*
422   * Put the file...
423   */
424
425   status = cupsPutFd(http, resource, fd);
426
427   close(fd);
428
429   return (status);
430 }
431
432
433 /*
434  * End of "$Id: getputfile.c 4918 2006-01-12 05:14:40Z mike $".
435  */