readability
authorVolker Birk <vb@pep-project.org>
Sat, 28 Mar 2015 10:52:40 +0100
changeset 147b03a10242e4c
parent 142 025a3d115c2b
child 148 817eae99bca2
readability
src/etpan_mime.c
src/etpan_mime.h
src/mime.c
test/mime_test.cc
     1.1 --- a/src/etpan_mime.c	Fri Mar 27 13:36:57 2015 +0100
     1.2 +++ b/src/etpan_mime.c	Sat Mar 28 10:52:40 2015 +0100
     1.3 @@ -570,3 +570,97 @@
     1.4      return r;
     1.5  }
     1.6  
     1.7 +static bool parameter_has_value(
     1.8 +        clist *list,
     1.9 +        const char *name,
    1.10 +        const char *value
    1.11 +    )
    1.12 +{
    1.13 +    clistiter *cur;
    1.14 +
    1.15 +    assert(list);
    1.16 +    assert(name);
    1.17 +    assert(value);
    1.18 +
    1.19 +    for (cur = clist_begin(list); cur != NULL ; cur = clist_next(cur)) {
    1.20 +        struct mailmime_parameter * param = clist_content(cur);
    1.21 +        if (param &&
    1.22 +                param->pa_name && strcmp(name, param->pa_name) == 0 &&
    1.23 +                param->pa_value && strcmp(value, param->pa_value) == 0)
    1.24 +            return true;
    1.25 +    }
    1.26 +
    1.27 +    return false;
    1.28 +}
    1.29 +
    1.30 +clist * _get_fields(struct mailmime * mime)
    1.31 +{
    1.32 +    clist * _fieldlist = NULL;
    1.33 +
    1.34 +    assert(mime);
    1.35 +
    1.36 +    if (mime->mm_data.mm_message.mm_fields &&
    1.37 +            mime->mm_data.mm_message.mm_fields->fld_list) {
    1.38 +        _fieldlist = mime->mm_data.mm_message.mm_fields->fld_list;
    1.39 +    }
    1.40 +
    1.41 +    return _fieldlist;
    1.42 +}
    1.43 +
    1.44 +struct mailmime_content * _get_content(struct mailmime * mime)
    1.45 +{
    1.46 +    struct mailmime_content * content = NULL;
    1.47 +
    1.48 +    assert(mime);
    1.49 +
    1.50 +    if (mime->mm_data.mm_message.mm_msg_mime)
    1.51 +        content = mime->mm_data.mm_message.mm_msg_mime->mm_content_type;
    1.52 +
    1.53 +    return content;
    1.54 +}
    1.55 +
    1.56 +bool _is_multipart(struct mailmime_content *content)
    1.57 +{
    1.58 +    bool result = false;
    1.59 +
    1.60 +    assert(content);
    1.61 +
    1.62 +    if (content->ct_type && content->ct_type->tp_type ==
    1.63 +            MAILMIME_TYPE_COMPOSITE_TYPE &&
    1.64 +            content->ct_type->tp_data.tp_composite_type &&
    1.65 +            content->ct_type->tp_data.tp_composite_type->ct_type ==
    1.66 +            MAILMIME_COMPOSITE_TYPE_MULTIPART)
    1.67 +        result = true;
    1.68 +
    1.69 +    return result;
    1.70 +}
    1.71 +
    1.72 +bool _is_multipart_alternative(struct mailmime_content *content)
    1.73 +{
    1.74 +    bool result = false;
    1.75 +
    1.76 +    assert(content);
    1.77 +
    1.78 +    if (_is_multipart(content) && content->ct_subtype &&
    1.79 +            strcmp(content->ct_subtype, "alternative") == 0)
    1.80 +        result = true;
    1.81 +
    1.82 +    return result;
    1.83 +}
    1.84 +
    1.85 +bool _is_PGP_MIME(struct mailmime_content *content)
    1.86 +{
    1.87 +    bool result = false;
    1.88 +
    1.89 +    assert(content);
    1.90 +
    1.91 +    if (_is_multipart(content) && content->ct_subtype &&
    1.92 +            strcmp(content->ct_subtype, "encrypted") == 0 &&
    1.93 +            content->ct_parameters &&
    1.94 +            parameter_has_value(content->ct_parameters, "protocol",
    1.95 +                    "application/pgp-encrypted"))
    1.96 +        result = true;
    1.97 +
    1.98 +    return result;
    1.99 +}
   1.100 +
     2.1 --- a/src/etpan_mime.h	Fri Mar 27 13:36:57 2015 +0100
     2.2 +++ b/src/etpan_mime.h	Sat Mar 28 10:52:40 2015 +0100
     2.3 @@ -65,3 +65,9 @@
     2.4          const char *value
     2.5      );
     2.6  
     2.7 +clist * _get_fields(struct mailmime * mime);
     2.8 +struct mailmime_content * _get_content(struct mailmime * mime);
     2.9 +bool _is_multipart(struct mailmime_content *content);
    2.10 +bool _is_multipart_alternative(struct mailmime_content * content);
    2.11 +bool _is_PGP_MIME(struct mailmime_content *content);
    2.12 +
     3.1 --- a/src/mime.c	Fri Mar 27 13:36:57 2015 +0100
     3.2 +++ b/src/mime.c	Sat Mar 28 10:52:40 2015 +0100
     3.3 @@ -1176,6 +1176,57 @@
     3.4      return status;
     3.5  }
     3.6  
     3.7 +static PEP_STATUS interpret_body(struct mailmime *part, char **longmsg, size_t *size)
     3.8 +{
     3.9 +    const char *text;
    3.10 +    size_t length;
    3.11 +    size_t s;
    3.12 +    int code;
    3.13 +    int r;
    3.14 +    size_t index;
    3.15 +
    3.16 +    assert(part);
    3.17 +    assert(longmsg);
    3.18 +
    3.19 +    *longmsg = NULL;
    3.20 +    if (size)
    3.21 +        *size = 0;
    3.22 +
    3.23 +    if (part->mm_body == NULL)
    3.24 +        return PEP_ILLEGAL_VALUE;
    3.25 +
    3.26 +    text = part->mm_body-> dt_data.dt_text.dt_data;
    3.27 +    if (text == NULL)
    3.28 +        return PEP_ILLEGAL_VALUE;
    3.29 +
    3.30 +    length = part->mm_body->dt_data.dt_text.dt_length;
    3.31 +
    3.32 +    if (part->mm_body->dt_encoded) {
    3.33 +        code = part->mm_body->dt_encoding;
    3.34 +        index = 0;
    3.35 +        r = mailmime_part_parse(text, length, &index, code, longmsg, &s);
    3.36 +        switch (r) {
    3.37 +            case MAILIMF_NO_ERROR:
    3.38 +                break;
    3.39 +            case MAILIMF_ERROR_MEMORY:
    3.40 +                return PEP_OUT_OF_MEMORY;
    3.41 +            default:
    3.42 +                return PEP_ILLEGAL_VALUE;
    3.43 +        }
    3.44 +        if (size)
    3.45 +            *size = s;
    3.46 +    }
    3.47 +    else {
    3.48 +        *longmsg = strndup(text, length);
    3.49 +        if (*longmsg == NULL)
    3.50 +            return PEP_OUT_OF_MEMORY;
    3.51 +        if (size)
    3.52 +            *size = length;
    3.53 +    }
    3.54 +
    3.55 +    return PEP_STATUS_OK;
    3.56 +}
    3.57 +
    3.58  static PEP_STATUS interpret_MIME(
    3.59          struct mailmime *mime,
    3.60          message *msg
    3.61 @@ -1188,14 +1239,7 @@
    3.62  
    3.63      struct mailmime_content *content = mime->mm_content_type;
    3.64      if (content) {
    3.65 -        if (msg->longmsg == NULL && content->ct_type &&
    3.66 -                content->ct_type->tp_type == MAILMIME_TYPE_COMPOSITE_TYPE
    3.67 -                && content->ct_type->tp_data.tp_composite_type
    3.68 -                && content->ct_type->tp_data.tp_composite_type->ct_type ==
    3.69 -                        MAILMIME_COMPOSITE_TYPE_MULTIPART
    3.70 -                && content->ct_subtype
    3.71 -                && strcmp(content->ct_subtype, "alternative") == 0) {
    3.72 -
    3.73 +        if (msg->longmsg == NULL && _is_multipart_alternative(content)) {
    3.74              clist *partlist = mime->mm_data.mm_multipart.mm_mp_list;
    3.75              if (partlist == NULL)
    3.76                  return PEP_ILLEGAL_VALUE;
    3.77 @@ -1226,97 +1270,37 @@
    3.78                              case MAILMIME_DISCRETE_TYPE_TEXT:
    3.79                                  if (strcmp(content->ct_subtype, "plain") ==
    3.80                                          0) {
    3.81 -                                    const char *text;
    3.82 -                                    size_t length;
    3.83 -                                    size_t s;
    3.84 -                                    int code;
    3.85 -
    3.86 -                                    if (part->mm_body == NULL)
    3.87 -                                        return PEP_ILLEGAL_VALUE;
    3.88 -
    3.89 -                                    text = part->mm_body->
    3.90 -                                            dt_data.dt_text.dt_data;
    3.91 -                                    if (text == NULL)
    3.92 -                                        return PEP_ILLEGAL_VALUE;
    3.93 -
    3.94 -                                    length =
    3.95 -                                        part->mm_body->dt_data.dt_text.dt_length;
    3.96 -
    3.97 -                                    if (part->mm_body->dt_encoded) {
    3.98 -                                        code = part->mm_body->dt_encoding;
    3.99 -                                        index = 0;
   3.100 -                                        r = mailmime_part_parse(text, length,
   3.101 -                                                &index, code, &msg->longmsg,
   3.102 -                                                &s);
   3.103 -                                        switch (r) {
   3.104 -                                            case MAILIMF_NO_ERROR:
   3.105 -                                                break;
   3.106 -                                            case MAILIMF_ERROR_MEMORY:
   3.107 -                                                return PEP_OUT_OF_MEMORY;
   3.108 -                                            default:
   3.109 -                                                return PEP_ILLEGAL_VALUE;
   3.110 -                                        }
   3.111 -                                    }
   3.112 -                                    else {
   3.113 -                                        msg->longmsg = strdup(text);
   3.114 -                                        if (msg->longmsg == NULL)
   3.115 -                                            return PEP_OUT_OF_MEMORY;
   3.116 -                                    }
   3.117 +                                    status = interpret_body(part,
   3.118 +                                            &msg->longmsg, NULL);
   3.119 +                                    if (status)
   3.120 +                                        return status;
   3.121                                  }
   3.122                                  else if (strcmp(content->ct_subtype, "html") ==
   3.123                                          0) {
   3.124 -                                    const char *html;
   3.125 -                                    size_t length;
   3.126 -                                    size_t s;
   3.127 -                                    int code;
   3.128 -
   3.129 -                                    if (part->mm_body == NULL)
   3.130 -                                        return PEP_ILLEGAL_VALUE;
   3.131 -
   3.132 -                                    html = part->mm_body->
   3.133 -                                            dt_data.dt_text.dt_data;
   3.134 -                                    if (html == NULL)
   3.135 -                                        return PEP_ILLEGAL_VALUE;
   3.136 -
   3.137 -                                    length =
   3.138 -                                        part->mm_body->dt_data.dt_text.dt_length;
   3.139 -
   3.140 -                                    if (part->mm_body->dt_encoded) {
   3.141 -                                        code = part->mm_body->dt_encoding;
   3.142 -                                        index = 0;
   3.143 -                                        r = mailmime_part_parse(html, length,
   3.144 -                                                &index, code,
   3.145 -                                                &msg->longmsg_formatted, &s);
   3.146 -                                        switch (r) {
   3.147 -                                            case MAILIMF_NO_ERROR:
   3.148 -                                                break;
   3.149 -                                            case MAILIMF_ERROR_MEMORY:
   3.150 -                                                return PEP_OUT_OF_MEMORY;
   3.151 -                                            default:
   3.152 -                                                return PEP_ILLEGAL_VALUE;
   3.153 -                                        }
   3.154 -                                    }
   3.155 -                                    else {
   3.156 -                                        msg->longmsg_formatted = strdup(html);
   3.157 -                                        if (msg->longmsg_formatted == NULL)
   3.158 -                                            return PEP_OUT_OF_MEMORY;
   3.159 -                                    }
   3.160 +                                    status = interpret_body(part,
   3.161 +                                            &msg->longmsg_formatted, NULL);
   3.162 +                                    if (status)
   3.163 +                                        return status;
   3.164                                  }
   3.165 -                                else {
   3.166 -                                    return interpret_MIME(part, msg);
   3.167 -                                }
   3.168 -
   3.169                                  break;
   3.170                                  
   3.171                              case MAILMIME_DISCRETE_TYPE_IMAGE:
   3.172                              case MAILMIME_DISCRETE_TYPE_AUDIO:
   3.173                              case MAILMIME_DISCRETE_TYPE_VIDEO:
   3.174                              case MAILMIME_DISCRETE_TYPE_APPLICATION:
   3.175 -                            case MAILMIME_DISCRETE_TYPE_EXTENSION:
   3.176 -                                    return interpret_MIME(part, msg);
   3.177 -
   3.178 +                            case MAILMIME_DISCRETE_TYPE_EXTENSION: {
   3.179 +                                char *data = NULL;
   3.180 +                                size_t size;
   3.181 +                                char * mime_type = NULL;
   3.182 +                                char * filename = NULL;
   3.183 +                                status = interpret_body(part, &data, &size);
   3.184 +                                if (status)
   3.185 +                                    return status;
   3.186 +                                msg->attachments =
   3.187 +                                    bloblist_add(msg->attachments, data, size,
   3.188 +                                            mime_type, filename);
   3.189                                  break;
   3.190 -                                
   3.191 +                            }
   3.192                              default:
   3.193                                  return PEP_ILLEGAL_VALUE;
   3.194                          }
   3.195 @@ -1400,29 +1384,6 @@
   3.196      return PEP_STATUS_OK;
   3.197  }
   3.198  
   3.199 -static bool parameter_has_value(
   3.200 -        clist *list,
   3.201 -        const char *name,
   3.202 -        const char *value
   3.203 -    )
   3.204 -{
   3.205 -    clistiter *cur;
   3.206 -
   3.207 -    assert(list);
   3.208 -    assert(name);
   3.209 -    assert(value);
   3.210 -
   3.211 -    for (cur = clist_begin(list); cur != NULL ; cur = clist_next(cur)) {
   3.212 -        struct mailmime_parameter * param = clist_content(cur);
   3.213 -        if (param &&
   3.214 -                param->pa_name && strcmp(name, param->pa_name) == 0 &&
   3.215 -                param->pa_value && strcmp(value, param->pa_value) == 0)
   3.216 -            return true;
   3.217 -    }
   3.218 -
   3.219 -    return false;
   3.220 -}
   3.221 -
   3.222  DYNAMIC_API PEP_STATUS mime_decode_message(
   3.223          const char *mimetext,
   3.224          message **msg
   3.225 @@ -1455,29 +1416,17 @@
   3.226      if (_msg == NULL)
   3.227          goto enomem;
   3.228  
   3.229 -    if (mime->mm_data.mm_message.mm_fields
   3.230 -            && mime->mm_data.mm_message.mm_fields->fld_list) {
   3.231 -        clist * _fieldlist = mime->mm_data.mm_message.mm_fields->fld_list;
   3.232 +    clist * _fieldlist = _get_fields(mime);
   3.233 +    if (_fieldlist) {
   3.234          status = read_fields(_msg, _fieldlist);
   3.235          if (status != PEP_STATUS_OK)
   3.236              goto pep_error;
   3.237      }
   3.238  
   3.239 -    if (mime->mm_data.mm_message.mm_msg_mime) {
   3.240 -        struct mailmime_content *content =
   3.241 -                mime->mm_data.mm_message.mm_msg_mime->mm_content_type;
   3.242 +    struct mailmime_content *content = _get_content(mime);
   3.243  
   3.244 -        if (content->ct_type &&
   3.245 -                content->ct_type->tp_type == MAILMIME_TYPE_COMPOSITE_TYPE
   3.246 -                && content->ct_type->tp_data.tp_composite_type
   3.247 -                && content->ct_type->tp_data.tp_composite_type->ct_type ==
   3.248 -                        MAILMIME_COMPOSITE_TYPE_MULTIPART
   3.249 -                && content->ct_subtype
   3.250 -                && strcmp(content->ct_subtype, "encrypted") == 0
   3.251 -                && content->ct_parameters
   3.252 -                && parameter_has_value(content->ct_parameters, "protocol",
   3.253 -                        "application/pgp-encrypted")) {
   3.254 -
   3.255 +    if (content) {
   3.256 +        if (_is_PGP_MIME(content)) {
   3.257              status = interpret_PGP_MIME(mime->mm_data.mm_message.mm_msg_mime,
   3.258                      _msg);
   3.259              if (status != PEP_STATUS_OK)
     4.1 --- a/test/mime_test.cc	Fri Mar 27 13:36:57 2015 +0100
     4.2 +++ b/test/mime_test.cc	Sat Mar 28 10:52:40 2015 +0100
     4.3 @@ -58,8 +58,19 @@
     4.4      }
     4.5      inFile3.close();
     4.6  
     4.7 +    cout << "decoding message…\n";
     4.8      message *msg3;
     4.9      PEP_STATUS status3 = mime_decode_message(mimetext3.c_str(), &msg3);
    4.10 +    assert(status3 == PEP_STATUS_OK);
    4.11 +    assert(msg3);
    4.12 +    cout << "decoded.\n\n";
    4.13 +    cout << "Subject: " << msg3->shortmsg << "\n\n";
    4.14 +    if (msg3->longmsg)
    4.15 +        cout << msg3->longmsg << "\n\n";
    4.16 +    if (msg3->longmsg_formatted)
    4.17 +        cout << msg3->longmsg_formatted << "\n\n";
    4.18 +
    4.19 +    free_message(msg3);
    4.20  
    4.21      cout << "calling release()\n";
    4.22      release(session);