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