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