src/mime.c
author vb
Wed, 04 Mar 2015 10:39:29 +0100
changeset 87 060a95de62a8
parent 70 c0382670c294
child 88 ac617f70bd7f
permissions -rw-r--r--
fixing Makefile
     1 #include "mime.h"
     2 
     3 #include <libetpan/mailmime.h>
     4 #include <string.h>
     5 #include <stdlib.h>
     6 #include <assert.h>
     7 #include <errno.h>
     8 #include <unistd.h>
     9 
    10 #include "etpan_mime.h"
    11 #include "wrappers.h"
    12 
    13 DYNAMIC_API PEP_STATUS mime_encode_text(
    14         const char *plaintext,
    15         const char *htmltext,
    16         bloblist_t *attachments,
    17         char **mimetext
    18     )
    19 {
    20     struct mailmime * mime = NULL;
    21     struct mailmime * submime = NULL;
    22     int col;
    23     int r;
    24     int fd;
    25     FILE *file = NULL;
    26     size_t size;
    27     char *buf = NULL;
    28     PEP_STATUS error;
    29 
    30     assert(plaintext);
    31     assert(mimetext);
    32 
    33     *mimetext = NULL;
    34 
    35     if (htmltext) {
    36         mime = part_multiple_new("multipart/alternative", NULL);
    37         assert(mime);
    38         if (mime == NULL)
    39             goto enomem;
    40 
    41         submime = get_text_part("text/plain", plaintext, strlen(plaintext),
    42                 MAILMIME_MECHANISM_QUOTED_PRINTABLE);
    43         assert(submime);
    44         if (submime == NULL)
    45             goto enomem;
    46 
    47         r = mailmime_smart_add_part(mime, submime);
    48         assert(r == MAILIMF_NO_ERROR);
    49         if (r == MAILIMF_ERROR_MEMORY) {
    50             goto enomem;
    51         }
    52         else {
    53             // mailmime_smart_add_part() takes ownership of submime
    54             submime = NULL;
    55         }
    56 
    57         submime = get_text_part("text/html", htmltext, strlen(htmltext),
    58                 MAILMIME_MECHANISM_QUOTED_PRINTABLE);
    59         assert(submime);
    60         if (submime == NULL)
    61             goto enomem;
    62 
    63         r = mailmime_smart_add_part(mime, submime);
    64         assert(r == MAILIMF_NO_ERROR);
    65         if (r == MAILIMF_ERROR_MEMORY)
    66             goto enomem;
    67         else {
    68             // mailmime_smart_add_part() takes ownership of submime
    69             submime = NULL;
    70         }
    71     }
    72     else {
    73         mime = get_text_part("text/plain", plaintext, strlen(plaintext),
    74                 MAILMIME_MECHANISM_QUOTED_PRINTABLE);
    75         assert(mime);
    76         if (mime == NULL)
    77             goto enomem;
    78     }
    79 
    80     if (attachments) {
    81         submime = mime;
    82         mime = part_multiple_new("multipart/mixed", NULL);
    83         assert(mime);
    84         if (mime == NULL)
    85             goto enomem;
    86 
    87         r = mailmime_smart_add_part(mime, submime);
    88         assert(r == MAILIMF_NO_ERROR);
    89         if (r == MAILIMF_ERROR_MEMORY) {
    90             goto enomem;
    91         }
    92         else {
    93             // mailmime_smart_add_part() takes ownership of submime
    94             submime = NULL;
    95         }
    96 
    97         bloblist_t *_a;
    98         for (_a = attachments; _a != NULL; _a = _a->next) {
    99             char * mime_type;
   100 
   101             assert(_a->data);
   102             assert(_a->size);
   103 
   104             if (_a->mime_type == NULL)
   105                 mime_type = "application/octet-stream";
   106             else
   107                 mime_type = _a->mime_type;
   108 
   109             submime = get_file_part(_a->file_name, mime_type, _a->data, _a->size);
   110             assert(submime);
   111             if (submime == NULL)
   112                 goto enomem;
   113 
   114             r = mailmime_smart_add_part(mime, submime);
   115             assert(r == MAILIMF_NO_ERROR);
   116             if (r == MAILIMF_ERROR_MEMORY) {
   117                 goto enomem;
   118             }
   119             else {
   120                 // mailmime_smart_add_part() takes ownership of submime
   121                 submime = NULL;
   122             }
   123         }
   124     }
   125 
   126     char *template = strdup("/tmp/pEp.XXXXXXXXXXXXXXXXXXXX");
   127     assert(template);
   128     if (template == NULL)
   129         goto enomem;
   130 
   131     fd = Mkstemp(template);
   132     assert(fd != -1);
   133     if (fd == -1)
   134         goto err_file;
   135 
   136     r = unlink(template);
   137     assert(r == 0);
   138     if (r == -1)
   139         goto err_file;
   140 
   141     free(template);
   142     template = NULL;
   143 
   144     file = Fdopen(fd, "w+");
   145     assert(file);
   146     if (file == NULL) {
   147         switch (errno) {
   148             case ENOMEM:
   149                 goto enomem;
   150             default:
   151                 goto err_file;
   152         }
   153     }
   154 
   155     fd = -1;
   156 
   157     col = 0;
   158     r = mailmime_write_file(file, &col, mime);
   159     assert(r == MAILIMF_NO_ERROR);
   160     if (r == MAILIMF_ERROR_MEMORY)
   161         goto enomem;
   162     else if (r != MAILIMF_NO_ERROR)
   163         goto err_file;
   164 
   165     off_t len = ftello(file);
   166     assert(len != -1);
   167     if (len == -1 && errno == EOVERFLOW)
   168         goto err_file;
   169 
   170     if (len + 1 > SIZE_MAX)
   171         goto err_buffer;
   172 
   173     size = (size_t) len;
   174 
   175     errno = 0;
   176     rewind(file);
   177     assert(errno == 0);
   178 #ifdef NDEBUG
   179     switch (errno) {
   180         case 0:
   181             break;
   182         case ENOMEM:
   183             goto enomem;
   184         default:
   185             goto err_file;
   186     }
   187 #endif
   188 
   189     buf = calloc(1, size + 1);
   190     assert(buf);
   191     if (buf == NULL)
   192         goto enomem;
   193  
   194     size_t _read;
   195     _read = Fread1(buf, size, file);
   196     assert(_read == size);
   197 
   198     r = Fclose(file);
   199     assert(r == 0);
   200 
   201     mailmime_free(mime);
   202     *mimetext = buf;
   203     return PEP_STATUS_OK;
   204 
   205 err_buffer:
   206     error = PEP_BUFFER_TOO_SMALL;
   207     goto release;
   208 
   209 err_file:
   210     error = PEP_CANNOT_CREATE_TEMP_FILE;
   211     goto release;
   212 
   213 enomem:
   214     error = PEP_OUT_OF_MEMORY;
   215 
   216 release:
   217     free(buf);
   218     free(template);
   219 
   220     if (file) {
   221         r = Fclose(file);
   222         assert(r == 0);
   223     }
   224     else if (fd != -1) {
   225         r = Close(fd);
   226         assert(r == 0);
   227     }
   228 
   229     if (mime)
   230         mailmime_free(mime);
   231     if (submime)
   232         mailmime_free(submime);
   233 
   234     return error;
   235 }