Imported Upstream version 3.25.0
[platform/upstream/cmake.git] / Utilities / cmcurl / lib / mime.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at https://curl.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  * SPDX-License-Identifier: curl
22  *
23  ***************************************************************************/
24
25 #include "curl_setup.h"
26
27 #include <curl/curl.h>
28
29 #include "mime.h"
30 #include "warnless.h"
31 #include "urldata.h"
32 #include "sendf.h"
33
34 #if !defined(CURL_DISABLE_MIME) && (!defined(CURL_DISABLE_HTTP) ||      \
35                                     !defined(CURL_DISABLE_SMTP) ||      \
36                                     !defined(CURL_DISABLE_IMAP))
37
38 #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
39 #include <libgen.h>
40 #endif
41
42 #include "rand.h"
43 #include "slist.h"
44 #include "strcase.h"
45 #include "dynbuf.h"
46 /* The last 3 #include files should be in this order */
47 #include "curl_printf.h"
48 #include "curl_memory.h"
49 #include "memdebug.h"
50
51 #ifdef WIN32
52 # ifndef R_OK
53 #  define R_OK 4
54 # endif
55 #endif
56
57
58 #define READ_ERROR                      ((size_t) -1)
59 #define STOP_FILLING                    ((size_t) -2)
60
61 static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
62                                  void *instream, bool *hasread);
63
64 /* Encoders. */
65 static size_t encoder_nop_read(char *buffer, size_t size, bool ateof,
66                                 curl_mimepart *part);
67 static curl_off_t encoder_nop_size(curl_mimepart *part);
68 static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof,
69                                 curl_mimepart *part);
70 static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
71                                 curl_mimepart *part);
72 static curl_off_t encoder_base64_size(curl_mimepart *part);
73 static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
74                               curl_mimepart *part);
75 static curl_off_t encoder_qp_size(curl_mimepart *part);
76
77 static const struct mime_encoder encoders[] = {
78   {"binary", encoder_nop_read, encoder_nop_size},
79   {"8bit", encoder_nop_read, encoder_nop_size},
80   {"7bit", encoder_7bit_read, encoder_nop_size},
81   {"base64", encoder_base64_read, encoder_base64_size},
82   {"quoted-printable", encoder_qp_read, encoder_qp_size},
83   {ZERO_NULL, ZERO_NULL, ZERO_NULL}
84 };
85
86 /* Base64 encoding table */
87 static const char base64[] =
88   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
89
90 /* Quoted-printable character class table.
91  *
92  * We cannot rely on ctype functions since quoted-printable input data
93  * is assumed to be ascii-compatible, even on non-ascii platforms. */
94 #define QP_OK           1       /* Can be represented by itself. */
95 #define QP_SP           2       /* Space or tab. */
96 #define QP_CR           3       /* Carriage return. */
97 #define QP_LF           4       /* Line-feed. */
98 static const unsigned char qp_class[] = {
99  0,     0,     0,     0,     0,     0,     0,     0,            /* 00 - 07 */
100  0,     QP_SP, QP_LF, 0,     0,     QP_CR, 0,     0,            /* 08 - 0F */
101  0,     0,     0,     0,     0,     0,     0,     0,            /* 10 - 17 */
102  0,     0,     0,     0,     0,     0,     0,     0,            /* 18 - 1F */
103  QP_SP, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 20 - 27 */
104  QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 28 - 2F */
105  QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 30 - 37 */
106  QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, 0    , QP_OK, QP_OK,        /* 38 - 3F */
107  QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 40 - 47 */
108  QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 48 - 4F */
109  QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 50 - 57 */
110  QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 58 - 5F */
111  QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 60 - 67 */
112  QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 68 - 6F */
113  QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 70 - 77 */
114  QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, 0,            /* 78 - 7F */
115  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                /* 80 - 8F */
116  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                /* 90 - 9F */
117  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                /* A0 - AF */
118  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                /* B0 - BF */
119  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                /* C0 - CF */
120  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                /* D0 - DF */
121  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                /* E0 - EF */
122  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0                 /* F0 - FF */
123 };
124
125
126 /* Binary --> hexadecimal ASCII table. */
127 static const char aschex[] =
128   "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x41\x42\x43\x44\x45\x46";
129
130
131
132 #ifndef __VMS
133 #define filesize(name, stat_data) (stat_data.st_size)
134 #define fopen_read fopen
135
136 #else
137
138 #include <fabdef.h>
139 /*
140  * get_vms_file_size does what it takes to get the real size of the file
141  *
142  * For fixed files, find out the size of the EOF block and adjust.
143  *
144  * For all others, have to read the entire file in, discarding the contents.
145  * Most posted text files will be small, and binary files like zlib archives
146  * and CD/DVD images should be either a STREAM_LF format or a fixed format.
147  *
148  */
149 curl_off_t VmsRealFileSize(const char *name,
150                            const struct_stat *stat_buf)
151 {
152   char buffer[8192];
153   curl_off_t count;
154   int ret_stat;
155   FILE * file;
156
157   file = fopen(name, FOPEN_READTEXT); /* VMS */
158   if(!file)
159     return 0;
160
161   count = 0;
162   ret_stat = 1;
163   while(ret_stat > 0) {
164     ret_stat = fread(buffer, 1, sizeof(buffer), file);
165     if(ret_stat)
166       count += ret_stat;
167   }
168   fclose(file);
169
170   return count;
171 }
172
173 /*
174  *
175  *  VmsSpecialSize checks to see if the stat st_size can be trusted and
176  *  if not to call a routine to get the correct size.
177  *
178  */
179 static curl_off_t VmsSpecialSize(const char *name,
180                                  const struct_stat *stat_buf)
181 {
182   switch(stat_buf->st_fab_rfm) {
183   case FAB$C_VAR:
184   case FAB$C_VFC:
185     return VmsRealFileSize(name, stat_buf);
186     break;
187   default:
188     return stat_buf->st_size;
189   }
190 }
191
192 #define filesize(name, stat_data) VmsSpecialSize(name, &stat_data)
193
194 /*
195  * vmsfopenread
196  *
197  * For upload to work as expected on VMS, different optional
198  * parameters must be added to the fopen command based on
199  * record format of the file.
200  *
201  */
202 static FILE * vmsfopenread(const char *file, const char *mode)
203 {
204   struct_stat statbuf;
205   int result;
206
207   result = stat(file, &statbuf);
208
209   switch(statbuf.st_fab_rfm) {
210   case FAB$C_VAR:
211   case FAB$C_VFC:
212   case FAB$C_STMCR:
213     return fopen(file, FOPEN_READTEXT); /* VMS */
214     break;
215   default:
216     return fopen(file, FOPEN_READTEXT, "rfm=stmlf", "ctx=stm");
217   }
218 }
219
220 #define fopen_read vmsfopenread
221 #endif
222
223
224 #ifndef HAVE_BASENAME
225 /*
226   (Quote from The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004
227   Edition)
228
229   The basename() function shall take the pathname pointed to by path and
230   return a pointer to the final component of the pathname, deleting any
231   trailing '/' characters.
232
233   If the string pointed to by path consists entirely of the '/' character,
234   basename() shall return a pointer to the string "/". If the string pointed
235   to by path is exactly "//", it is implementation-defined whether '/' or "//"
236   is returned.
237
238   If path is a null pointer or points to an empty string, basename() shall
239   return a pointer to the string ".".
240
241   The basename() function may modify the string pointed to by path, and may
242   return a pointer to static storage that may then be overwritten by a
243   subsequent call to basename().
244
245   The basename() function need not be reentrant. A function that is not
246   required to be reentrant is not required to be thread-safe.
247
248 */
249 static char *Curl_basename(char *path)
250 {
251   /* Ignore all the details above for now and make a quick and simple
252      implementation here */
253   char *s1;
254   char *s2;
255
256   s1 = strrchr(path, '/');
257   s2 = strrchr(path, '\\');
258
259   if(s1 && s2) {
260     path = (s1 > s2? s1 : s2) + 1;
261   }
262   else if(s1)
263     path = s1 + 1;
264   else if(s2)
265     path = s2 + 1;
266
267   return path;
268 }
269
270 #define basename(x)  Curl_basename((x))
271 #endif
272
273
274 /* Set readback state. */
275 static void mimesetstate(struct mime_state *state,
276                          enum mimestate tok, void *ptr)
277 {
278   state->state = tok;
279   state->ptr = ptr;
280   state->offset = 0;
281 }
282
283
284 /* Escape header string into allocated memory. */
285 static char *escape_string(struct Curl_easy *data,
286                            const char *src, enum mimestrategy strategy)
287 {
288   CURLcode result;
289   struct dynbuf db;
290   const char * const *table;
291   const char * const *p;
292   /* replace first character by rest of string. */
293   static const char * const mimetable[] = {
294     "\\\\\\",
295     "\"\\\"",
296     NULL
297   };
298   /* WHATWG HTML living standard 4.10.21.8 2 specifies:
299      For field names and filenames for file fields, the result of the
300      encoding in the previous bullet point must be escaped by replacing
301      any 0x0A (LF) bytes with the byte sequence `%0A`, 0x0D (CR) with `%0D`
302      and 0x22 (") with `%22`.
303      The user agent must not perform any other escapes. */
304   static const char * const formtable[] = {
305     "\"%22",
306     "\r%0D",
307     "\n%0A",
308     NULL
309   };
310
311   table = formtable;
312   /* data can be NULL when this function is called indirectly from
313      curl_formget(). */
314   if(strategy == MIMESTRATEGY_MAIL ||
315      (data && (data->set.mime_options & CURLMIMEOPT_FORMESCAPE)))
316     table = mimetable;
317
318   Curl_dyn_init(&db, CURL_MAX_INPUT_LENGTH);
319
320   for(result = Curl_dyn_addn(&db, STRCONST("")); !result && *src; src++) {
321     for(p = table; *p && **p != *src; p++)
322       ;
323
324     if(*p)
325       result = Curl_dyn_add(&db, *p + 1);
326     else
327       result = Curl_dyn_addn(&db, src, 1);
328   }
329
330   return Curl_dyn_ptr(&db);
331 }
332
333 /* Check if header matches. */
334 static char *match_header(struct curl_slist *hdr, const char *lbl, size_t len)
335 {
336   char *value = NULL;
337
338   if(strncasecompare(hdr->data, lbl, len) && hdr->data[len] == ':')
339     for(value = hdr->data + len + 1; *value == ' '; value++)
340       ;
341   return value;
342 }
343
344 /* Get a header from an slist. */
345 static char *search_header(struct curl_slist *hdrlist,
346                            const char *hdr, size_t len)
347 {
348   char *value = NULL;
349
350   for(; !value && hdrlist; hdrlist = hdrlist->next)
351     value = match_header(hdrlist, hdr, len);
352
353   return value;
354 }
355
356 static char *strippath(const char *fullfile)
357 {
358   char *filename;
359   char *base;
360   filename = strdup(fullfile); /* duplicate since basename() may ruin the
361                                   buffer it works on */
362   if(!filename)
363     return NULL;
364   base = strdup(basename(filename));
365
366   free(filename); /* free temporary buffer */
367
368   return base; /* returns an allocated string or NULL ! */
369 }
370
371 /* Initialize data encoder state. */
372 static void cleanup_encoder_state(struct mime_encoder_state *p)
373 {
374   p->pos = 0;
375   p->bufbeg = 0;
376   p->bufend = 0;
377 }
378
379
380 /* Dummy encoder. This is used for 8bit and binary content encodings. */
381 static size_t encoder_nop_read(char *buffer, size_t size, bool ateof,
382                                struct curl_mimepart *part)
383 {
384   struct mime_encoder_state *st = &part->encstate;
385   size_t insize = st->bufend - st->bufbeg;
386
387   (void) ateof;
388
389   if(!size)
390     return STOP_FILLING;
391
392   if(size > insize)
393     size = insize;
394
395   if(size)
396     memcpy(buffer, st->buf + st->bufbeg, size);
397
398   st->bufbeg += size;
399   return size;
400 }
401
402 static curl_off_t encoder_nop_size(curl_mimepart *part)
403 {
404   return part->datasize;
405 }
406
407
408 /* 7bit encoder: the encoder is just a data validity check. */
409 static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof,
410                                 curl_mimepart *part)
411 {
412   struct mime_encoder_state *st = &part->encstate;
413   size_t cursize = st->bufend - st->bufbeg;
414
415   (void) ateof;
416
417   if(!size)
418     return STOP_FILLING;
419
420   if(size > cursize)
421     size = cursize;
422
423   for(cursize = 0; cursize < size; cursize++) {
424     *buffer = st->buf[st->bufbeg];
425     if(*buffer++ & 0x80)
426       return cursize? cursize: READ_ERROR;
427     st->bufbeg++;
428   }
429
430   return cursize;
431 }
432
433
434 /* Base64 content encoder. */
435 static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
436                                 curl_mimepart *part)
437 {
438   struct mime_encoder_state *st = &part->encstate;
439   size_t cursize = 0;
440   int i;
441   char *ptr = buffer;
442
443   while(st->bufbeg < st->bufend) {
444     /* Line full ? */
445     if(st->pos > MAX_ENCODED_LINE_LENGTH - 4) {
446       /* Yes, we need 2 characters for CRLF. */
447       if(size < 2) {
448         if(!cursize)
449           return STOP_FILLING;
450         break;
451       }
452       *ptr++ = '\r';
453       *ptr++ = '\n';
454       st->pos = 0;
455       cursize += 2;
456       size -= 2;
457     }
458
459     /* Be sure there is enough space and input data for a base64 group. */
460     if(size < 4) {
461       if(!cursize)
462         return STOP_FILLING;
463       break;
464     }
465     if(st->bufend - st->bufbeg < 3)
466       break;
467
468     /* Encode three bytes as four characters. */
469     i = st->buf[st->bufbeg++] & 0xFF;
470     i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF);
471     i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF);
472     *ptr++ = base64[(i >> 18) & 0x3F];
473     *ptr++ = base64[(i >> 12) & 0x3F];
474     *ptr++ = base64[(i >> 6) & 0x3F];
475     *ptr++ = base64[i & 0x3F];
476     cursize += 4;
477     st->pos += 4;
478     size -= 4;
479   }
480
481   /* If at eof, we have to flush the buffered data. */
482   if(ateof) {
483     if(size < 4) {
484       if(!cursize)
485         return STOP_FILLING;
486     }
487     else {
488       /* Buffered data size can only be 0, 1 or 2. */
489       ptr[2] = ptr[3] = '=';
490       i = 0;
491
492       /* If there is buffered data */
493       if(st->bufend != st->bufbeg) {
494
495         if(st->bufend - st->bufbeg == 2)
496           i = (st->buf[st->bufbeg + 1] & 0xFF) << 8;
497
498         i |= (st->buf[st->bufbeg] & 0xFF) << 16;
499         ptr[0] = base64[(i >> 18) & 0x3F];
500         ptr[1] = base64[(i >> 12) & 0x3F];
501         if(++st->bufbeg != st->bufend) {
502           ptr[2] = base64[(i >> 6) & 0x3F];
503           st->bufbeg++;
504         }
505         cursize += 4;
506         st->pos += 4;
507       }
508     }
509   }
510
511   return cursize;
512 }
513
514 static curl_off_t encoder_base64_size(curl_mimepart *part)
515 {
516   curl_off_t size = part->datasize;
517
518   if(size <= 0)
519     return size;    /* Unknown size or no data. */
520
521   /* Compute base64 character count. */
522   size = 4 * (1 + (size - 1) / 3);
523
524   /* Effective character count must include CRLFs. */
525   return size + 2 * ((size - 1) / MAX_ENCODED_LINE_LENGTH);
526 }
527
528
529 /* Quoted-printable lookahead.
530  *
531  * Check if a CRLF or end of data is in input buffer at current position + n.
532  * Return -1 if more data needed, 1 if CRLF or end of data, else 0.
533  */
534 static int qp_lookahead_eol(struct mime_encoder_state *st, int ateof, size_t n)
535 {
536   n += st->bufbeg;
537   if(n >= st->bufend && ateof)
538     return 1;
539   if(n + 2 > st->bufend)
540     return ateof? 0: -1;
541   if(qp_class[st->buf[n] & 0xFF] == QP_CR &&
542      qp_class[st->buf[n + 1] & 0xFF] == QP_LF)
543     return 1;
544   return 0;
545 }
546
547 /* Quoted-printable encoder. */
548 static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
549                               curl_mimepart *part)
550 {
551   struct mime_encoder_state *st = &part->encstate;
552   char *ptr = buffer;
553   size_t cursize = 0;
554   int softlinebreak;
555   char buf[4];
556
557   /* On all platforms, input is supposed to be ASCII compatible: for this
558      reason, we use hexadecimal ASCII codes in this function rather than
559      character constants that can be interpreted as non-ascii on some
560      platforms. Preserve ASCII encoding on output too. */
561   while(st->bufbeg < st->bufend) {
562     size_t len = 1;
563     size_t consumed = 1;
564     int i = st->buf[st->bufbeg];
565     buf[0] = (char) i;
566     buf[1] = aschex[(i >> 4) & 0xF];
567     buf[2] = aschex[i & 0xF];
568
569     switch(qp_class[st->buf[st->bufbeg] & 0xFF]) {
570     case QP_OK:          /* Not a special character. */
571       break;
572     case QP_SP:          /* Space or tab. */
573       /* Spacing must be escaped if followed by CRLF. */
574       switch(qp_lookahead_eol(st, ateof, 1)) {
575       case -1:          /* More input data needed. */
576         return cursize;
577       case 0:           /* No encoding needed. */
578         break;
579       default:          /* CRLF after space or tab. */
580         buf[0] = '\x3D';    /* '=' */
581         len = 3;
582         break;
583       }
584       break;
585     case QP_CR:         /* Carriage return. */
586       /* If followed by a line-feed, output the CRLF pair.
587          Else escape it. */
588       switch(qp_lookahead_eol(st, ateof, 0)) {
589       case -1:          /* Need more data. */
590         return cursize;
591       case 1:           /* CRLF found. */
592         buf[len++] = '\x0A';    /* Append '\n'. */
593         consumed = 2;
594         break;
595       default:          /* Not followed by LF: escape. */
596         buf[0] = '\x3D';    /* '=' */
597         len = 3;
598         break;
599       }
600       break;
601     default:            /* Character must be escaped. */
602       buf[0] = '\x3D';    /* '=' */
603       len = 3;
604       break;
605     }
606
607     /* Be sure the encoded character fits within maximum line length. */
608     if(buf[len - 1] != '\x0A') {    /* '\n' */
609       softlinebreak = st->pos + len > MAX_ENCODED_LINE_LENGTH;
610       if(!softlinebreak && st->pos + len == MAX_ENCODED_LINE_LENGTH) {
611         /* We may use the current line only if end of data or followed by
612            a CRLF. */
613         switch(qp_lookahead_eol(st, ateof, consumed)) {
614         case -1:        /* Need more data. */
615           return cursize;
616         case 0:         /* Not followed by a CRLF. */
617           softlinebreak = 1;
618           break;
619         }
620       }
621       if(softlinebreak) {
622         strcpy(buf, "\x3D\x0D\x0A");    /* "=\r\n" */
623         len = 3;
624         consumed = 0;
625       }
626     }
627
628     /* If the output buffer would overflow, do not store. */
629     if(len > size) {
630       if(!cursize)
631         return STOP_FILLING;
632       break;
633     }
634
635     /* Append to output buffer. */
636     memcpy(ptr, buf, len);
637     cursize += len;
638     ptr += len;
639     size -= len;
640     st->pos += len;
641     if(buf[len - 1] == '\x0A')    /* '\n' */
642       st->pos = 0;
643     st->bufbeg += consumed;
644   }
645
646   return cursize;
647 }
648
649 static curl_off_t encoder_qp_size(curl_mimepart *part)
650 {
651   /* Determining the size can only be done by reading the data: unless the
652      data size is 0, we return it as unknown (-1). */
653   return part->datasize? -1: 0;
654 }
655
656
657 /* In-memory data callbacks. */
658 /* Argument is a pointer to the mime part. */
659 static size_t mime_mem_read(char *buffer, size_t size, size_t nitems,
660                             void *instream)
661 {
662   curl_mimepart *part = (curl_mimepart *) instream;
663   size_t sz = curlx_sotouz(part->datasize - part->state.offset);
664   (void) size;   /* Always 1.*/
665
666   if(!nitems)
667     return STOP_FILLING;
668
669   if(sz > nitems)
670     sz = nitems;
671
672   if(sz)
673     memcpy(buffer, part->data + curlx_sotouz(part->state.offset), sz);
674
675   return sz;
676 }
677
678 static int mime_mem_seek(void *instream, curl_off_t offset, int whence)
679 {
680   curl_mimepart *part = (curl_mimepart *) instream;
681
682   switch(whence) {
683   case SEEK_CUR:
684     offset += part->state.offset;
685     break;
686   case SEEK_END:
687     offset += part->datasize;
688     break;
689   }
690
691   if(offset < 0 || offset > part->datasize)
692     return CURL_SEEKFUNC_FAIL;
693
694   part->state.offset = offset;
695   return CURL_SEEKFUNC_OK;
696 }
697
698 static void mime_mem_free(void *ptr)
699 {
700   Curl_safefree(((curl_mimepart *) ptr)->data);
701 }
702
703
704 /* Named file callbacks. */
705 /* Argument is a pointer to the mime part. */
706 static int mime_open_file(curl_mimepart *part)
707 {
708   /* Open a MIMEKIND_FILE part. */
709
710   if(part->fp)
711     return 0;
712   part->fp = fopen_read(part->data, "rb");
713   return part->fp? 0: -1;
714 }
715
716 static size_t mime_file_read(char *buffer, size_t size, size_t nitems,
717                              void *instream)
718 {
719   curl_mimepart *part = (curl_mimepart *) instream;
720
721   if(!nitems)
722     return STOP_FILLING;
723
724   if(mime_open_file(part))
725     return READ_ERROR;
726
727   return fread(buffer, size, nitems, part->fp);
728 }
729
730 static int mime_file_seek(void *instream, curl_off_t offset, int whence)
731 {
732   curl_mimepart *part = (curl_mimepart *) instream;
733
734   if(whence == SEEK_SET && !offset && !part->fp)
735     return CURL_SEEKFUNC_OK;   /* Not open: implicitly already at BOF. */
736
737   if(mime_open_file(part))
738     return CURL_SEEKFUNC_FAIL;
739
740   return fseek(part->fp, (long) offset, whence)?
741                CURL_SEEKFUNC_CANTSEEK: CURL_SEEKFUNC_OK;
742 }
743
744 static void mime_file_free(void *ptr)
745 {
746   curl_mimepart *part = (curl_mimepart *) ptr;
747
748   if(part->fp) {
749     fclose(part->fp);
750     part->fp = NULL;
751   }
752   Curl_safefree(part->data);
753   part->data = NULL;
754 }
755
756
757 /* Subparts callbacks. */
758 /* Argument is a pointer to the mime structure. */
759
760 /* Readback a byte string segment. */
761 static size_t readback_bytes(struct mime_state *state,
762                              char *buffer, size_t bufsize,
763                              const char *bytes, size_t numbytes,
764                              const char *trail, size_t traillen)
765 {
766   size_t sz;
767   size_t offset = curlx_sotouz(state->offset);
768
769   if(numbytes > offset) {
770     sz = numbytes - offset;
771     bytes += offset;
772   }
773   else {
774     sz = offset - numbytes;
775     if(sz >= traillen)
776       return 0;
777     bytes = trail + sz;
778     sz = traillen - sz;
779   }
780
781   if(sz > bufsize)
782     sz = bufsize;
783
784   memcpy(buffer, bytes, sz);
785   state->offset += sz;
786   return sz;
787 }
788
789 /* Read a non-encoded part content. */
790 static size_t read_part_content(curl_mimepart *part,
791                                 char *buffer, size_t bufsize, bool *hasread)
792 {
793   size_t sz = 0;
794
795   switch(part->lastreadstatus) {
796   case 0:
797   case CURL_READFUNC_ABORT:
798   case CURL_READFUNC_PAUSE:
799   case READ_ERROR:
800     return part->lastreadstatus;
801   default:
802     break;
803   }
804
805   /* If we can determine we are at end of part data, spare a read. */
806   if(part->datasize != (curl_off_t) -1 &&
807      part->state.offset >= part->datasize) {
808     /* sz is already zero. */
809   }
810   else {
811     switch(part->kind) {
812     case MIMEKIND_MULTIPART:
813       /*
814        * Cannot be processed as other kinds since read function requires
815        * an additional parameter and is highly recursive.
816        */
817        sz = mime_subparts_read(buffer, 1, bufsize, part->arg, hasread);
818        break;
819     case MIMEKIND_FILE:
820       if(part->fp && feof(part->fp))
821         break;  /* At EOF. */
822       /* FALLTHROUGH */
823     default:
824       if(part->readfunc) {
825         if(!(part->flags & MIME_FAST_READ)) {
826           if(*hasread)
827             return STOP_FILLING;
828           *hasread = TRUE;
829         }
830         sz = part->readfunc(buffer, 1, bufsize, part->arg);
831       }
832       break;
833     }
834   }
835
836   switch(sz) {
837   case STOP_FILLING:
838     break;
839   case 0:
840   case CURL_READFUNC_ABORT:
841   case CURL_READFUNC_PAUSE:
842   case READ_ERROR:
843     part->lastreadstatus = sz;
844     break;
845   default:
846     part->state.offset += sz;
847     part->lastreadstatus = sz;
848     break;
849   }
850
851   return sz;
852 }
853
854 /* Read and encode part content. */
855 static size_t read_encoded_part_content(curl_mimepart *part, char *buffer,
856                                         size_t bufsize, bool *hasread)
857 {
858   struct mime_encoder_state *st = &part->encstate;
859   size_t cursize = 0;
860   size_t sz;
861   bool ateof = FALSE;
862
863   for(;;) {
864     if(st->bufbeg < st->bufend || ateof) {
865       /* Encode buffered data. */
866       sz = part->encoder->encodefunc(buffer, bufsize, ateof, part);
867       switch(sz) {
868       case 0:
869         if(ateof)
870           return cursize;
871         break;
872       case READ_ERROR:
873       case STOP_FILLING:
874         return cursize? cursize: sz;
875       default:
876         cursize += sz;
877         buffer += sz;
878         bufsize -= sz;
879         continue;
880       }
881     }
882
883     /* We need more data in input buffer. */
884     if(st->bufbeg) {
885       size_t len = st->bufend - st->bufbeg;
886
887       if(len)
888         memmove(st->buf, st->buf + st->bufbeg, len);
889       st->bufbeg = 0;
890       st->bufend = len;
891     }
892     if(st->bufend >= sizeof(st->buf))
893       return cursize? cursize: READ_ERROR;    /* Buffer full. */
894     sz = read_part_content(part, st->buf + st->bufend,
895                            sizeof(st->buf) - st->bufend, hasread);
896     switch(sz) {
897     case 0:
898       ateof = TRUE;
899       break;
900     case CURL_READFUNC_ABORT:
901     case CURL_READFUNC_PAUSE:
902     case READ_ERROR:
903     case STOP_FILLING:
904       return cursize? cursize: sz;
905     default:
906       st->bufend += sz;
907       break;
908     }
909   }
910
911   /* NOTREACHED */
912 }
913
914 /* Readback a mime part. */
915 static size_t readback_part(curl_mimepart *part,
916                             char *buffer, size_t bufsize, bool *hasread)
917 {
918   size_t cursize = 0;
919
920   /* Readback from part. */
921
922   while(bufsize) {
923     size_t sz = 0;
924     struct curl_slist *hdr = (struct curl_slist *) part->state.ptr;
925     switch(part->state.state) {
926     case MIMESTATE_BEGIN:
927       mimesetstate(&part->state,
928                    (part->flags & MIME_BODY_ONLY)?
929                      MIMESTATE_BODY: MIMESTATE_CURLHEADERS,
930                    part->curlheaders);
931       break;
932     case MIMESTATE_USERHEADERS:
933       if(!hdr) {
934         mimesetstate(&part->state, MIMESTATE_EOH, NULL);
935         break;
936       }
937       if(match_header(hdr, "Content-Type", 12)) {
938         mimesetstate(&part->state, MIMESTATE_USERHEADERS, hdr->next);
939         break;
940       }
941       /* FALLTHROUGH */
942     case MIMESTATE_CURLHEADERS:
943       if(!hdr)
944         mimesetstate(&part->state, MIMESTATE_USERHEADERS, part->userheaders);
945       else {
946         sz = readback_bytes(&part->state, buffer, bufsize,
947                             hdr->data, strlen(hdr->data), STRCONST("\r\n"));
948         if(!sz)
949           mimesetstate(&part->state, part->state.state, hdr->next);
950       }
951       break;
952     case MIMESTATE_EOH:
953       sz = readback_bytes(&part->state, buffer, bufsize, STRCONST("\r\n"),
954                           STRCONST(""));
955       if(!sz)
956         mimesetstate(&part->state, MIMESTATE_BODY, NULL);
957       break;
958     case MIMESTATE_BODY:
959       cleanup_encoder_state(&part->encstate);
960       mimesetstate(&part->state, MIMESTATE_CONTENT, NULL);
961       break;
962     case MIMESTATE_CONTENT:
963       if(part->encoder)
964         sz = read_encoded_part_content(part, buffer, bufsize, hasread);
965       else
966         sz = read_part_content(part, buffer, bufsize, hasread);
967       switch(sz) {
968       case 0:
969         mimesetstate(&part->state, MIMESTATE_END, NULL);
970         /* Try sparing open file descriptors. */
971         if(part->kind == MIMEKIND_FILE && part->fp) {
972           fclose(part->fp);
973           part->fp = NULL;
974         }
975         /* FALLTHROUGH */
976       case CURL_READFUNC_ABORT:
977       case CURL_READFUNC_PAUSE:
978       case READ_ERROR:
979       case STOP_FILLING:
980         return cursize? cursize: sz;
981       }
982       break;
983     case MIMESTATE_END:
984       return cursize;
985     default:
986       break;    /* Other values not in part state. */
987     }
988
989     /* Bump buffer and counters according to read size. */
990     cursize += sz;
991     buffer += sz;
992     bufsize -= sz;
993   }
994
995   return cursize;
996 }
997
998 /* Readback from mime. Warning: not a read callback function. */
999 static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
1000                                  void *instream, bool *hasread)
1001 {
1002   curl_mime *mime = (curl_mime *) instream;
1003   size_t cursize = 0;
1004   (void) size;   /* Always 1. */
1005
1006   while(nitems) {
1007     size_t sz = 0;
1008     curl_mimepart *part = mime->state.ptr;
1009     switch(mime->state.state) {
1010     case MIMESTATE_BEGIN:
1011     case MIMESTATE_BODY:
1012       mimesetstate(&mime->state, MIMESTATE_BOUNDARY1, mime->firstpart);
1013       /* The first boundary always follows the header termination empty line,
1014          so is always preceded by a CRLF. We can then spare 2 characters
1015          by skipping the leading CRLF in boundary. */
1016       mime->state.offset += 2;
1017       break;
1018     case MIMESTATE_BOUNDARY1:
1019       sz = readback_bytes(&mime->state, buffer, nitems, STRCONST("\r\n--"),
1020                           STRCONST(""));
1021       if(!sz)
1022         mimesetstate(&mime->state, MIMESTATE_BOUNDARY2, part);
1023       break;
1024     case MIMESTATE_BOUNDARY2:
1025       if(part)
1026         sz = readback_bytes(&mime->state, buffer, nitems, mime->boundary,
1027                             MIME_BOUNDARY_LEN, STRCONST("\r\n"));
1028       else
1029         sz = readback_bytes(&mime->state, buffer, nitems, mime->boundary,
1030                             MIME_BOUNDARY_LEN, STRCONST("--\r\n"));
1031       if(!sz) {
1032         mimesetstate(&mime->state, MIMESTATE_CONTENT, part);
1033       }
1034       break;
1035     case MIMESTATE_CONTENT:
1036       if(!part) {
1037         mimesetstate(&mime->state, MIMESTATE_END, NULL);
1038         break;
1039       }
1040       sz = readback_part(part, buffer, nitems, hasread);
1041       switch(sz) {
1042       case CURL_READFUNC_ABORT:
1043       case CURL_READFUNC_PAUSE:
1044       case READ_ERROR:
1045       case STOP_FILLING:
1046         return cursize? cursize: sz;
1047       case 0:
1048         mimesetstate(&mime->state, MIMESTATE_BOUNDARY1, part->nextpart);
1049         break;
1050       }
1051       break;
1052     case MIMESTATE_END:
1053       return cursize;
1054     default:
1055       break;    /* other values not used in mime state. */
1056     }
1057
1058     /* Bump buffer and counters according to read size. */
1059     cursize += sz;
1060     buffer += sz;
1061     nitems -= sz;
1062   }
1063
1064   return cursize;
1065 }
1066
1067 static int mime_part_rewind(curl_mimepart *part)
1068 {
1069   int res = CURL_SEEKFUNC_OK;
1070   enum mimestate targetstate = MIMESTATE_BEGIN;
1071
1072   if(part->flags & MIME_BODY_ONLY)
1073     targetstate = MIMESTATE_BODY;
1074   cleanup_encoder_state(&part->encstate);
1075   if(part->state.state > targetstate) {
1076     res = CURL_SEEKFUNC_CANTSEEK;
1077     if(part->seekfunc) {
1078       res = part->seekfunc(part->arg, (curl_off_t) 0, SEEK_SET);
1079       switch(res) {
1080       case CURL_SEEKFUNC_OK:
1081       case CURL_SEEKFUNC_FAIL:
1082       case CURL_SEEKFUNC_CANTSEEK:
1083         break;
1084       case -1:    /* For fseek() error. */
1085         res = CURL_SEEKFUNC_CANTSEEK;
1086         break;
1087       default:
1088         res = CURL_SEEKFUNC_FAIL;
1089         break;
1090       }
1091     }
1092   }
1093
1094   if(res == CURL_SEEKFUNC_OK)
1095     mimesetstate(&part->state, targetstate, NULL);
1096
1097   part->lastreadstatus = 1; /* Successful read status. */
1098   return res;
1099 }
1100
1101 static int mime_subparts_seek(void *instream, curl_off_t offset, int whence)
1102 {
1103   curl_mime *mime = (curl_mime *) instream;
1104   curl_mimepart *part;
1105   int result = CURL_SEEKFUNC_OK;
1106
1107   if(whence != SEEK_SET || offset)
1108     return CURL_SEEKFUNC_CANTSEEK;    /* Only support full rewind. */
1109
1110   if(mime->state.state == MIMESTATE_BEGIN)
1111    return CURL_SEEKFUNC_OK;           /* Already rewound. */
1112
1113   for(part = mime->firstpart; part; part = part->nextpart) {
1114     int res = mime_part_rewind(part);
1115     if(res != CURL_SEEKFUNC_OK)
1116       result = res;
1117   }
1118
1119   if(result == CURL_SEEKFUNC_OK)
1120     mimesetstate(&mime->state, MIMESTATE_BEGIN, NULL);
1121
1122   return result;
1123 }
1124
1125 /* Release part content. */
1126 static void cleanup_part_content(curl_mimepart *part)
1127 {
1128   if(part->freefunc)
1129     part->freefunc(part->arg);
1130
1131   part->readfunc = NULL;
1132   part->seekfunc = NULL;
1133   part->freefunc = NULL;
1134   part->arg = (void *) part;          /* Defaults to part itself. */
1135   part->data = NULL;
1136   part->fp = NULL;
1137   part->datasize = (curl_off_t) 0;    /* No size yet. */
1138   cleanup_encoder_state(&part->encstate);
1139   part->kind = MIMEKIND_NONE;
1140   part->flags &= ~MIME_FAST_READ;
1141   part->lastreadstatus = 1; /* Successful read status. */
1142   part->state.state = MIMESTATE_BEGIN;
1143 }
1144
1145 static void mime_subparts_free(void *ptr)
1146 {
1147   curl_mime *mime = (curl_mime *) ptr;
1148
1149   if(mime && mime->parent) {
1150     mime->parent->freefunc = NULL;  /* Be sure we won't be called again. */
1151     cleanup_part_content(mime->parent);  /* Avoid dangling pointer in part. */
1152   }
1153   curl_mime_free(mime);
1154 }
1155
1156 /* Do not free subparts: unbind them. This is used for the top level only. */
1157 static void mime_subparts_unbind(void *ptr)
1158 {
1159   curl_mime *mime = (curl_mime *) ptr;
1160
1161   if(mime && mime->parent) {
1162     mime->parent->freefunc = NULL;  /* Be sure we won't be called again. */
1163     cleanup_part_content(mime->parent);  /* Avoid dangling pointer in part. */
1164     mime->parent = NULL;
1165   }
1166 }
1167
1168
1169 void Curl_mime_cleanpart(curl_mimepart *part)
1170 {
1171   cleanup_part_content(part);
1172   curl_slist_free_all(part->curlheaders);
1173   if(part->flags & MIME_USERHEADERS_OWNER)
1174     curl_slist_free_all(part->userheaders);
1175   Curl_safefree(part->mimetype);
1176   Curl_safefree(part->name);
1177   Curl_safefree(part->filename);
1178   Curl_mime_initpart(part, part->easy);
1179 }
1180
1181 /* Recursively delete a mime handle and its parts. */
1182 void curl_mime_free(curl_mime *mime)
1183 {
1184   curl_mimepart *part;
1185
1186   if(mime) {
1187     mime_subparts_unbind(mime);  /* Be sure it's not referenced anymore. */
1188     while(mime->firstpart) {
1189       part = mime->firstpart;
1190       mime->firstpart = part->nextpart;
1191       Curl_mime_cleanpart(part);
1192       free(part);
1193     }
1194     free(mime);
1195   }
1196 }
1197
1198 CURLcode Curl_mime_duppart(curl_mimepart *dst, const curl_mimepart *src)
1199 {
1200   curl_mime *mime;
1201   curl_mimepart *d;
1202   const curl_mimepart *s;
1203   CURLcode res = CURLE_OK;
1204
1205   DEBUGASSERT(dst);
1206
1207   /* Duplicate content. */
1208   switch(src->kind) {
1209   case MIMEKIND_NONE:
1210     break;
1211   case MIMEKIND_DATA:
1212     res = curl_mime_data(dst, src->data, (size_t) src->datasize);
1213     break;
1214   case MIMEKIND_FILE:
1215     res = curl_mime_filedata(dst, src->data);
1216     /* Do not abort duplication if file is not readable. */
1217     if(res == CURLE_READ_ERROR)
1218       res = CURLE_OK;
1219     break;
1220   case MIMEKIND_CALLBACK:
1221     res = curl_mime_data_cb(dst, src->datasize, src->readfunc,
1222                             src->seekfunc, src->freefunc, src->arg);
1223     break;
1224   case MIMEKIND_MULTIPART:
1225     /* No one knows about the cloned subparts, thus always attach ownership
1226        to the part. */
1227     mime = curl_mime_init(dst->easy);
1228     res = mime? curl_mime_subparts(dst, mime): CURLE_OUT_OF_MEMORY;
1229
1230     /* Duplicate subparts. */
1231     for(s = ((curl_mime *) src->arg)->firstpart; !res && s; s = s->nextpart) {
1232       d = curl_mime_addpart(mime);
1233       res = d? Curl_mime_duppart(d, s): CURLE_OUT_OF_MEMORY;
1234     }
1235     break;
1236   default:  /* Invalid kind: should not occur. */
1237     res = CURLE_BAD_FUNCTION_ARGUMENT;  /* Internal error? */
1238     break;
1239   }
1240
1241   /* Duplicate headers. */
1242   if(!res && src->userheaders) {
1243     struct curl_slist *hdrs = Curl_slist_duplicate(src->userheaders);
1244
1245     if(!hdrs)
1246       res = CURLE_OUT_OF_MEMORY;
1247     else {
1248       /* No one but this procedure knows about the new header list,
1249          so always take ownership. */
1250       res = curl_mime_headers(dst, hdrs, TRUE);
1251       if(res)
1252         curl_slist_free_all(hdrs);
1253     }
1254   }
1255
1256   if(!res) {
1257     /* Duplicate other fields. */
1258     dst->encoder = src->encoder;
1259     res = curl_mime_type(dst, src->mimetype);
1260   }
1261   if(!res)
1262     res = curl_mime_name(dst, src->name);
1263   if(!res)
1264     res = curl_mime_filename(dst, src->filename);
1265
1266   /* If an error occurred, rollback. */
1267   if(res)
1268     Curl_mime_cleanpart(dst);
1269
1270   return res;
1271 }
1272
1273 /*
1274  * Mime build functions.
1275  */
1276
1277 /* Create a mime handle. */
1278 curl_mime *curl_mime_init(struct Curl_easy *easy)
1279 {
1280   curl_mime *mime;
1281
1282   mime = (curl_mime *) malloc(sizeof(*mime));
1283
1284   if(mime) {
1285     mime->easy = easy;
1286     mime->parent = NULL;
1287     mime->firstpart = NULL;
1288     mime->lastpart = NULL;
1289
1290     memset(mime->boundary, '-', MIME_BOUNDARY_DASHES);
1291     if(Curl_rand_hex(easy,
1292                      (unsigned char *) &mime->boundary[MIME_BOUNDARY_DASHES],
1293                      MIME_RAND_BOUNDARY_CHARS + 1)) {
1294       /* failed to get random separator, bail out */
1295       free(mime);
1296       return NULL;
1297     }
1298     mimesetstate(&mime->state, MIMESTATE_BEGIN, NULL);
1299   }
1300
1301   return mime;
1302 }
1303
1304 /* Initialize a mime part. */
1305 void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy)
1306 {
1307   memset((char *) part, 0, sizeof(*part));
1308   part->easy = easy;
1309   part->lastreadstatus = 1; /* Successful read status. */
1310   mimesetstate(&part->state, MIMESTATE_BEGIN, NULL);
1311 }
1312
1313 /* Create a mime part and append it to a mime handle's part list. */
1314 curl_mimepart *curl_mime_addpart(curl_mime *mime)
1315 {
1316   curl_mimepart *part;
1317
1318   if(!mime)
1319     return NULL;
1320
1321   part = (curl_mimepart *) malloc(sizeof(*part));
1322
1323   if(part) {
1324     Curl_mime_initpart(part, mime->easy);
1325     part->parent = mime;
1326
1327     if(mime->lastpart)
1328       mime->lastpart->nextpart = part;
1329     else
1330       mime->firstpart = part;
1331
1332     mime->lastpart = part;
1333   }
1334
1335   return part;
1336 }
1337
1338 /* Set mime part name. */
1339 CURLcode curl_mime_name(curl_mimepart *part, const char *name)
1340 {
1341   if(!part)
1342     return CURLE_BAD_FUNCTION_ARGUMENT;
1343
1344   Curl_safefree(part->name);
1345   part->name = NULL;
1346
1347   if(name) {
1348     part->name = strdup(name);
1349     if(!part->name)
1350       return CURLE_OUT_OF_MEMORY;
1351   }
1352
1353   return CURLE_OK;
1354 }
1355
1356 /* Set mime part remote file name. */
1357 CURLcode curl_mime_filename(curl_mimepart *part, const char *filename)
1358 {
1359   if(!part)
1360     return CURLE_BAD_FUNCTION_ARGUMENT;
1361
1362   Curl_safefree(part->filename);
1363   part->filename = NULL;
1364
1365   if(filename) {
1366     part->filename = strdup(filename);
1367     if(!part->filename)
1368       return CURLE_OUT_OF_MEMORY;
1369   }
1370
1371   return CURLE_OK;
1372 }
1373
1374 /* Set mime part content from memory data. */
1375 CURLcode curl_mime_data(curl_mimepart *part,
1376                         const char *data, size_t datasize)
1377 {
1378   if(!part)
1379     return CURLE_BAD_FUNCTION_ARGUMENT;
1380
1381   cleanup_part_content(part);
1382
1383   if(data) {
1384     if(datasize == CURL_ZERO_TERMINATED)
1385       datasize = strlen(data);
1386
1387     part->data = malloc(datasize + 1);
1388     if(!part->data)
1389       return CURLE_OUT_OF_MEMORY;
1390
1391     part->datasize = datasize;
1392
1393     if(datasize)
1394       memcpy(part->data, data, datasize);
1395     part->data[datasize] = '\0';    /* Set a null terminator as sentinel. */
1396
1397     part->readfunc = mime_mem_read;
1398     part->seekfunc = mime_mem_seek;
1399     part->freefunc = mime_mem_free;
1400     part->flags |= MIME_FAST_READ;
1401     part->kind = MIMEKIND_DATA;
1402   }
1403
1404   return CURLE_OK;
1405 }
1406
1407 /* Set mime part content from named local file. */
1408 CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
1409 {
1410   CURLcode result = CURLE_OK;
1411
1412   if(!part)
1413     return CURLE_BAD_FUNCTION_ARGUMENT;
1414
1415   cleanup_part_content(part);
1416
1417   if(filename) {
1418     char *base;
1419     struct_stat sbuf;
1420
1421     if(stat(filename, &sbuf) || access(filename, R_OK))
1422       result = CURLE_READ_ERROR;
1423
1424     part->data = strdup(filename);
1425     if(!part->data)
1426       result = CURLE_OUT_OF_MEMORY;
1427
1428     part->datasize = -1;
1429     if(!result && S_ISREG(sbuf.st_mode)) {
1430       part->datasize = filesize(filename, sbuf);
1431       part->seekfunc = mime_file_seek;
1432     }
1433
1434     part->readfunc = mime_file_read;
1435     part->freefunc = mime_file_free;
1436     part->kind = MIMEKIND_FILE;
1437
1438     /* As a side effect, set the filename to the current file's base name.
1439        It is possible to withdraw this by explicitly calling
1440        curl_mime_filename() with a NULL filename argument after the current
1441        call. */
1442     base = strippath(filename);
1443     if(!base)
1444       result = CURLE_OUT_OF_MEMORY;
1445     else {
1446       CURLcode res = curl_mime_filename(part, base);
1447
1448       if(res)
1449         result = res;
1450       free(base);
1451     }
1452   }
1453   return result;
1454 }
1455
1456 /* Set mime part type. */
1457 CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype)
1458 {
1459   if(!part)
1460     return CURLE_BAD_FUNCTION_ARGUMENT;
1461
1462   Curl_safefree(part->mimetype);
1463   part->mimetype = NULL;
1464
1465   if(mimetype) {
1466     part->mimetype = strdup(mimetype);
1467     if(!part->mimetype)
1468       return CURLE_OUT_OF_MEMORY;
1469   }
1470
1471   return CURLE_OK;
1472 }
1473
1474 /* Set mime data transfer encoder. */
1475 CURLcode curl_mime_encoder(curl_mimepart *part, const char *encoding)
1476 {
1477   CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT;
1478   const struct mime_encoder *mep;
1479
1480   if(!part)
1481     return result;
1482
1483   part->encoder = NULL;
1484
1485   if(!encoding)
1486     return CURLE_OK;    /* Removing current encoder. */
1487
1488   for(mep = encoders; mep->name; mep++)
1489     if(strcasecompare(encoding, mep->name)) {
1490       part->encoder = mep;
1491       result = CURLE_OK;
1492     }
1493
1494   return result;
1495 }
1496
1497 /* Set mime part headers. */
1498 CURLcode curl_mime_headers(curl_mimepart *part,
1499                            struct curl_slist *headers, int take_ownership)
1500 {
1501   if(!part)
1502     return CURLE_BAD_FUNCTION_ARGUMENT;
1503
1504   if(part->flags & MIME_USERHEADERS_OWNER) {
1505     if(part->userheaders != headers)  /* Allow setting twice the same list. */
1506       curl_slist_free_all(part->userheaders);
1507     part->flags &= ~MIME_USERHEADERS_OWNER;
1508   }
1509   part->userheaders = headers;
1510   if(headers && take_ownership)
1511     part->flags |= MIME_USERHEADERS_OWNER;
1512   return CURLE_OK;
1513 }
1514
1515 /* Set mime part content from callback. */
1516 CURLcode curl_mime_data_cb(curl_mimepart *part, curl_off_t datasize,
1517                            curl_read_callback readfunc,
1518                            curl_seek_callback seekfunc,
1519                            curl_free_callback freefunc, void *arg)
1520 {
1521   if(!part)
1522     return CURLE_BAD_FUNCTION_ARGUMENT;
1523
1524   cleanup_part_content(part);
1525
1526   if(readfunc) {
1527     part->readfunc = readfunc;
1528     part->seekfunc = seekfunc;
1529     part->freefunc = freefunc;
1530     part->arg = arg;
1531     part->datasize = datasize;
1532     part->kind = MIMEKIND_CALLBACK;
1533   }
1534
1535   return CURLE_OK;
1536 }
1537
1538 /* Set mime part content from subparts. */
1539 CURLcode Curl_mime_set_subparts(curl_mimepart *part,
1540                                 curl_mime *subparts, int take_ownership)
1541 {
1542   curl_mime *root;
1543
1544   if(!part)
1545     return CURLE_BAD_FUNCTION_ARGUMENT;
1546
1547   /* Accept setting twice the same subparts. */
1548   if(part->kind == MIMEKIND_MULTIPART && part->arg == subparts)
1549     return CURLE_OK;
1550
1551   cleanup_part_content(part);
1552
1553   if(subparts) {
1554     /* Must belong to the same data handle. */
1555     if(part->easy && subparts->easy && part->easy != subparts->easy)
1556       return CURLE_BAD_FUNCTION_ARGUMENT;
1557
1558     /* Should not have been attached already. */
1559     if(subparts->parent)
1560       return CURLE_BAD_FUNCTION_ARGUMENT;
1561
1562     /* Should not be the part's root. */
1563     root = part->parent;
1564     if(root) {
1565       while(root->parent && root->parent->parent)
1566         root = root->parent->parent;
1567       if(subparts == root) {
1568         if(part->easy)
1569           failf(part->easy, "Can't add itself as a subpart");
1570         return CURLE_BAD_FUNCTION_ARGUMENT;
1571       }
1572     }
1573
1574     subparts->parent = part;
1575     /* Subparts are processed internally: no read callback. */
1576     part->seekfunc = mime_subparts_seek;
1577     part->freefunc = take_ownership? mime_subparts_free: mime_subparts_unbind;
1578     part->arg = subparts;
1579     part->datasize = -1;
1580     part->kind = MIMEKIND_MULTIPART;
1581   }
1582
1583   return CURLE_OK;
1584 }
1585
1586 CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts)
1587 {
1588   return Curl_mime_set_subparts(part, subparts, TRUE);
1589 }
1590
1591
1592 /* Readback from top mime. */
1593 /* Argument is the dummy top part. */
1594 size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream)
1595 {
1596   curl_mimepart *part = (curl_mimepart *) instream;
1597   size_t ret;
1598   bool hasread;
1599
1600   (void) size;   /* Always 1. */
1601
1602   do {
1603     hasread = FALSE;
1604     ret = readback_part(part, buffer, nitems, &hasread);
1605     /*
1606      * If this is not possible to get some data without calling more than
1607      * one read callback (probably because a content encoder is not able to
1608      * deliver a new bunch for the few data accumulated so far), force another
1609      * read until we get enough data or a special exit code.
1610      */
1611   } while(ret == STOP_FILLING);
1612
1613   return ret;
1614 }
1615
1616 /* Rewind mime stream. */
1617 CURLcode Curl_mime_rewind(curl_mimepart *part)
1618 {
1619   return mime_part_rewind(part) == CURL_SEEKFUNC_OK?
1620          CURLE_OK: CURLE_SEND_FAIL_REWIND;
1621 }
1622
1623 /* Compute header list size. */
1624 static size_t slist_size(struct curl_slist *s,
1625                          size_t overhead, const char *skip, size_t skiplen)
1626 {
1627   size_t size = 0;
1628
1629   for(; s; s = s->next)
1630     if(!skip || !match_header(s, skip, skiplen))
1631       size += strlen(s->data) + overhead;
1632   return size;
1633 }
1634
1635 /* Get/compute multipart size. */
1636 static curl_off_t multipart_size(curl_mime *mime)
1637 {
1638   curl_off_t size;
1639   size_t boundarysize;
1640   curl_mimepart *part;
1641
1642   if(!mime)
1643     return 0;           /* Not present -> empty. */
1644
1645   boundarysize = 4 + MIME_BOUNDARY_LEN + 2;
1646   size = boundarysize;  /* Final boundary - CRLF after headers. */
1647
1648   for(part = mime->firstpart; part; part = part->nextpart) {
1649     curl_off_t sz = Curl_mime_size(part);
1650
1651     if(sz < 0)
1652       size = sz;
1653
1654     if(size >= 0)
1655       size += boundarysize + sz;
1656   }
1657
1658   return size;
1659 }
1660
1661 /* Get/compute mime size. */
1662 curl_off_t Curl_mime_size(curl_mimepart *part)
1663 {
1664   curl_off_t size;
1665
1666   if(part->kind == MIMEKIND_MULTIPART)
1667     part->datasize = multipart_size(part->arg);
1668
1669   size = part->datasize;
1670
1671   if(part->encoder)
1672     size = part->encoder->sizefunc(part);
1673
1674   if(size >= 0 && !(part->flags & MIME_BODY_ONLY)) {
1675     /* Compute total part size. */
1676     size += slist_size(part->curlheaders, 2, NULL, 0);
1677     size += slist_size(part->userheaders, 2, STRCONST("Content-Type"));
1678     size += 2;    /* CRLF after headers. */
1679   }
1680   return size;
1681 }
1682
1683 /* Add a header. */
1684 /* VARARGS2 */
1685 CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...)
1686 {
1687   struct curl_slist *hdr = NULL;
1688   char *s = NULL;
1689   va_list ap;
1690
1691   va_start(ap, fmt);
1692   s = curl_mvaprintf(fmt, ap);
1693   va_end(ap);
1694
1695   if(s) {
1696     hdr = Curl_slist_append_nodup(*slp, s);
1697     if(hdr)
1698       *slp = hdr;
1699     else
1700       free(s);
1701   }
1702
1703   return hdr? CURLE_OK: CURLE_OUT_OF_MEMORY;
1704 }
1705
1706 /* Add a content type header. */
1707 static CURLcode add_content_type(struct curl_slist **slp,
1708                                  const char *type, const char *boundary)
1709 {
1710   return Curl_mime_add_header(slp, "Content-Type: %s%s%s", type,
1711                               boundary? "; boundary=": "",
1712                               boundary? boundary: "");
1713 }
1714
1715 const char *Curl_mime_contenttype(const char *filename)
1716 {
1717   /*
1718    * If no content type was specified, we scan through a few well-known
1719    * extensions and pick the first we match!
1720    */
1721   struct ContentType {
1722     const char *extension;
1723     const char *type;
1724   };
1725   static const struct ContentType ctts[] = {
1726     {".gif",  "image/gif"},
1727     {".jpg",  "image/jpeg"},
1728     {".jpeg", "image/jpeg"},
1729     {".png",  "image/png"},
1730     {".svg",  "image/svg+xml"},
1731     {".txt",  "text/plain"},
1732     {".htm",  "text/html"},
1733     {".html", "text/html"},
1734     {".pdf",  "application/pdf"},
1735     {".xml",  "application/xml"}
1736   };
1737
1738   if(filename) {
1739     size_t len1 = strlen(filename);
1740     const char *nameend = filename + len1;
1741     unsigned int i;
1742
1743     for(i = 0; i < sizeof(ctts) / sizeof(ctts[0]); i++) {
1744       size_t len2 = strlen(ctts[i].extension);
1745
1746       if(len1 >= len2 && strcasecompare(nameend - len2, ctts[i].extension))
1747           return ctts[i].type;
1748     }
1749   }
1750   return NULL;
1751 }
1752
1753 static bool content_type_match(const char *contenttype,
1754                                const char *target, size_t len)
1755 {
1756   if(contenttype && strncasecompare(contenttype, target, len))
1757     switch(contenttype[len]) {
1758     case '\0':
1759     case '\t':
1760     case '\r':
1761     case '\n':
1762     case ' ':
1763     case ';':
1764       return TRUE;
1765     }
1766   return FALSE;
1767 }
1768
1769 CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
1770                                    const char *contenttype,
1771                                    const char *disposition,
1772                                    enum mimestrategy strategy)
1773 {
1774   curl_mime *mime = NULL;
1775   const char *boundary = NULL;
1776   char *customct;
1777   const char *cte = NULL;
1778   CURLcode ret = CURLE_OK;
1779
1780   /* Get rid of previously prepared headers. */
1781   curl_slist_free_all(part->curlheaders);
1782   part->curlheaders = NULL;
1783
1784   /* Be sure we won't access old headers later. */
1785   if(part->state.state == MIMESTATE_CURLHEADERS)
1786     mimesetstate(&part->state, MIMESTATE_CURLHEADERS, NULL);
1787
1788   /* Check if content type is specified. */
1789   customct = part->mimetype;
1790   if(!customct)
1791     customct = search_header(part->userheaders, STRCONST("Content-Type"));
1792   if(customct)
1793     contenttype = customct;
1794
1795   /* If content type is not specified, try to determine it. */
1796   if(!contenttype) {
1797     switch(part->kind) {
1798     case MIMEKIND_MULTIPART:
1799       contenttype = MULTIPART_CONTENTTYPE_DEFAULT;
1800       break;
1801     case MIMEKIND_FILE:
1802       contenttype = Curl_mime_contenttype(part->filename);
1803       if(!contenttype)
1804         contenttype = Curl_mime_contenttype(part->data);
1805       if(!contenttype && part->filename)
1806         contenttype = FILE_CONTENTTYPE_DEFAULT;
1807       break;
1808     default:
1809       contenttype = Curl_mime_contenttype(part->filename);
1810       break;
1811     }
1812   }
1813
1814   if(part->kind == MIMEKIND_MULTIPART) {
1815     mime = (curl_mime *) part->arg;
1816     if(mime)
1817       boundary = mime->boundary;
1818   }
1819   else if(contenttype && !customct &&
1820           content_type_match(contenttype, STRCONST("text/plain")))
1821     if(strategy == MIMESTRATEGY_MAIL || !part->filename)
1822       contenttype = NULL;
1823
1824   /* Issue content-disposition header only if not already set by caller. */
1825   if(!search_header(part->userheaders, STRCONST("Content-Disposition"))) {
1826     if(!disposition)
1827       if(part->filename || part->name ||
1828         (contenttype && !strncasecompare(contenttype, "multipart/", 10)))
1829           disposition = DISPOSITION_DEFAULT;
1830     if(disposition && curl_strequal(disposition, "attachment") &&
1831      !part->name && !part->filename)
1832       disposition = NULL;
1833     if(disposition) {
1834       char *name = NULL;
1835       char *filename = NULL;
1836
1837       if(part->name) {
1838         name = escape_string(part->easy, part->name, strategy);
1839         if(!name)
1840           ret = CURLE_OUT_OF_MEMORY;
1841       }
1842       if(!ret && part->filename) {
1843         filename = escape_string(part->easy, part->filename, strategy);
1844         if(!filename)
1845           ret = CURLE_OUT_OF_MEMORY;
1846       }
1847       if(!ret)
1848         ret = Curl_mime_add_header(&part->curlheaders,
1849                                    "Content-Disposition: %s%s%s%s%s%s%s",
1850                                    disposition,
1851                                    name? "; name=\"": "",
1852                                    name? name: "",
1853                                    name? "\"": "",
1854                                    filename? "; filename=\"": "",
1855                                    filename? filename: "",
1856                                    filename? "\"": "");
1857       Curl_safefree(name);
1858       Curl_safefree(filename);
1859       if(ret)
1860         return ret;
1861       }
1862     }
1863
1864   /* Issue Content-Type header. */
1865   if(contenttype) {
1866     ret = add_content_type(&part->curlheaders, contenttype, boundary);
1867     if(ret)
1868       return ret;
1869   }
1870
1871   /* Content-Transfer-Encoding header. */
1872   if(!search_header(part->userheaders,
1873                     STRCONST("Content-Transfer-Encoding"))) {
1874     if(part->encoder)
1875       cte = part->encoder->name;
1876     else if(contenttype && strategy == MIMESTRATEGY_MAIL &&
1877      part->kind != MIMEKIND_MULTIPART)
1878       cte = "8bit";
1879     if(cte) {
1880       ret = Curl_mime_add_header(&part->curlheaders,
1881                                  "Content-Transfer-Encoding: %s", cte);
1882       if(ret)
1883         return ret;
1884     }
1885   }
1886
1887   /* If we were reading curl-generated headers, restart with new ones (this
1888      should not occur). */
1889   if(part->state.state == MIMESTATE_CURLHEADERS)
1890     mimesetstate(&part->state, MIMESTATE_CURLHEADERS, part->curlheaders);
1891
1892   /* Process subparts. */
1893   if(part->kind == MIMEKIND_MULTIPART && mime) {
1894     curl_mimepart *subpart;
1895
1896     disposition = NULL;
1897     if(content_type_match(contenttype, STRCONST("multipart/form-data")))
1898       disposition = "form-data";
1899     for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart) {
1900       ret = Curl_mime_prepare_headers(subpart, NULL, disposition, strategy);
1901       if(ret)
1902         return ret;
1903     }
1904   }
1905   return ret;
1906 }
1907
1908 /* Recursively reset paused status in the given part. */
1909 void Curl_mime_unpause(curl_mimepart *part)
1910 {
1911   if(part) {
1912     if(part->lastreadstatus == CURL_READFUNC_PAUSE)
1913       part->lastreadstatus = 1; /* Successful read status. */
1914     if(part->kind == MIMEKIND_MULTIPART) {
1915       curl_mime *mime = (curl_mime *) part->arg;
1916
1917       if(mime) {
1918         curl_mimepart *subpart;
1919
1920         for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart)
1921           Curl_mime_unpause(subpart);
1922       }
1923     }
1924   }
1925 }
1926
1927
1928 #else /* !CURL_DISABLE_MIME && (!CURL_DISABLE_HTTP ||
1929                                 !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP) */
1930
1931 /* Mime not compiled in: define stubs for externally-referenced functions. */
1932 curl_mime *curl_mime_init(CURL *easy)
1933 {
1934   (void) easy;
1935   return NULL;
1936 }
1937
1938 void curl_mime_free(curl_mime *mime)
1939 {
1940   (void) mime;
1941 }
1942
1943 curl_mimepart *curl_mime_addpart(curl_mime *mime)
1944 {
1945   (void) mime;
1946   return NULL;
1947 }
1948
1949 CURLcode curl_mime_name(curl_mimepart *part, const char *name)
1950 {
1951   (void) part;
1952   (void) name;
1953   return CURLE_NOT_BUILT_IN;
1954 }
1955
1956 CURLcode curl_mime_filename(curl_mimepart *part, const char *filename)
1957 {
1958   (void) part;
1959   (void) filename;
1960   return CURLE_NOT_BUILT_IN;
1961 }
1962
1963 CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype)
1964 {
1965   (void) part;
1966   (void) mimetype;
1967   return CURLE_NOT_BUILT_IN;
1968 }
1969
1970 CURLcode curl_mime_encoder(curl_mimepart *part, const char *encoding)
1971 {
1972   (void) part;
1973   (void) encoding;
1974   return CURLE_NOT_BUILT_IN;
1975 }
1976
1977 CURLcode curl_mime_data(curl_mimepart *part,
1978                         const char *data, size_t datasize)
1979 {
1980   (void) part;
1981   (void) data;
1982   (void) datasize;
1983   return CURLE_NOT_BUILT_IN;
1984 }
1985
1986 CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
1987 {
1988   (void) part;
1989   (void) filename;
1990   return CURLE_NOT_BUILT_IN;
1991 }
1992
1993 CURLcode curl_mime_data_cb(curl_mimepart *part,
1994                            curl_off_t datasize,
1995                            curl_read_callback readfunc,
1996                            curl_seek_callback seekfunc,
1997                            curl_free_callback freefunc,
1998                            void *arg)
1999 {
2000   (void) part;
2001   (void) datasize;
2002   (void) readfunc;
2003   (void) seekfunc;
2004   (void) freefunc;
2005   (void) arg;
2006   return CURLE_NOT_BUILT_IN;
2007 }
2008
2009 CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts)
2010 {
2011   (void) part;
2012   (void) subparts;
2013   return CURLE_NOT_BUILT_IN;
2014 }
2015
2016 CURLcode curl_mime_headers(curl_mimepart *part,
2017                            struct curl_slist *headers, int take_ownership)
2018 {
2019   (void) part;
2020   (void) headers;
2021   (void) take_ownership;
2022   return CURLE_NOT_BUILT_IN;
2023 }
2024
2025 CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...)
2026 {
2027   (void)slp;
2028   (void)fmt;
2029   return CURLE_NOT_BUILT_IN;
2030 }
2031
2032 #endif /* if disabled */