src/etpan_mime.c
author Volker Birk <vb@pep-project.org>
Sun, 29 Mar 2015 11:48:58 +0200
changeset 155 a131cef4a937
parent 154 3ba2cbfcef1d
child 156 0d9aec90828f
permissions -rw-r--r--
...
vb@48
     1
#include "etpan_mime.h"
vb@62
     2
#ifndef mailmime_param_new_with_data
vb@62
     3
#include <libetpan/mailprivacy_tools.h>
vb@62
     4
#endif
vb@48
     5
vb@130
     6
#include "platform.h"
vb@130
     7
vb@130
     8
#include <string.h>
vb@130
     9
#include <stdlib.h>
vb@130
    10
#include <assert.h>
vb@130
    11
vb@130
    12
vb@89
    13
time_t mail_mkgmtime(struct tm * tmp);
vb@89
    14
vb@48
    15
#define MAX_MESSAGE_ID 512
vb@48
    16
vb@116
    17
static char * generate_boundary(void)
vb@48
    18
{
vb@48
    19
    char id[MAX_MESSAGE_ID];
vb@116
    20
    long value1;
vb@116
    21
    long value2;
vb@116
    22
    long value3;
vb@116
    23
    long value4;
vb@54
    24
 
vb@116
    25
    // no random needed here
vb@90
    26
vb@116
    27
    value1 = random();
vb@116
    28
    value2 = random();
vb@116
    29
    value3 = random();
vb@116
    30
    value4 = random();
vb@116
    31
vb@116
    32
    snprintf(id, MAX_MESSAGE_ID, "%.4lx%.4lx%.4lx%.4lx", value1, value2,
vb@116
    33
            value3, value4);
vb@48
    34
    
vb@48
    35
    return strdup(id);
vb@48
    36
}
vb@48
    37
vb@48
    38
struct mailmime * part_new_empty(
vb@48
    39
        struct mailmime_content * content,
vb@48
    40
        struct mailmime_fields * mime_fields,
vb@48
    41
        int force_single
vb@48
    42
    )
vb@48
    43
{
vb@48
    44
	struct mailmime * build_info;
vb@115
    45
	clist * list = NULL;
vb@48
    46
	int r;
vb@48
    47
	int mime_type;
vb@115
    48
    char * attr_name = NULL;
vb@115
    49
    char * attr_value = NULL;
vb@115
    50
    struct mailmime_parameter * param = NULL;
vb@115
    51
    clist * parameters = NULL;
vb@116
    52
    char *boundary = NULL;
vb@48
    53
vb@48
    54
	list = NULL;
vb@48
    55
vb@48
    56
	if (force_single) {
vb@48
    57
		mime_type = MAILMIME_SINGLE;
vb@48
    58
	}
vb@48
    59
	else {
vb@48
    60
		switch (content->ct_type->tp_type) {
vb@48
    61
			case MAILMIME_TYPE_DISCRETE_TYPE:
vb@115
    62
                mime_type = MAILMIME_SINGLE;
vb@115
    63
                break;
vb@48
    64
vb@48
    65
			case MAILMIME_TYPE_COMPOSITE_TYPE:
vb@115
    66
                switch (content->ct_type->tp_data.tp_composite_type->ct_type) {
vb@115
    67
                    case MAILMIME_COMPOSITE_TYPE_MULTIPART:
vb@115
    68
                        mime_type = MAILMIME_MULTIPLE;
vb@115
    69
                        break;
vb@48
    70
vb@115
    71
                    case MAILMIME_COMPOSITE_TYPE_MESSAGE:
vb@115
    72
                        if (strcasecmp(content->ct_subtype, "rfc822") == 0)
vb@115
    73
                            mime_type = MAILMIME_MESSAGE;
vb@115
    74
                        else
vb@115
    75
                            mime_type = MAILMIME_SINGLE;
vb@115
    76
                        break;
vb@48
    77
vb@115
    78
                    default:
vb@115
    79
                        goto enomem;
vb@115
    80
                }
vb@115
    81
                break;
vb@48
    82
vb@48
    83
			default:
vb@115
    84
                goto enomem;
vb@48
    85
		}
vb@48
    86
	}
vb@48
    87
vb@48
    88
	if (mime_type == MAILMIME_MULTIPLE) {
vb@48
    89
		list = clist_new();
vb@115
    90
        assert(list);
vb@48
    91
		if (list == NULL)
vb@115
    92
			goto enomem;
vb@48
    93
vb@48
    94
		attr_name = strdup("boundary");
vb@115
    95
        assert(attr_name);
vb@115
    96
        if (attr_name == NULL)
vb@115
    97
            goto enomem;
vb@115
    98
vb@116
    99
		boundary = generate_boundary();
vb@115
   100
        assert(boundary);
vb@48
   101
		attr_value = boundary;
vb@115
   102
		if (attr_value == NULL)
vb@115
   103
			goto enomem;
vb@48
   104
vb@48
   105
		param = mailmime_parameter_new(attr_name, attr_value);
vb@115
   106
        assert(param);
vb@115
   107
		if (param == NULL)
vb@115
   108
			goto enomem;
vb@115
   109
        attr_name = NULL;
vb@115
   110
        attr_value = NULL;
vb@48
   111
vb@48
   112
		if (content->ct_parameters == NULL) {
vb@48
   113
			parameters = clist_new();
vb@115
   114
            assert(parameters);
vb@115
   115
			if (parameters == NULL)
vb@115
   116
				goto enomem;
vb@48
   117
		}
vb@115
   118
		else {
vb@48
   119
			parameters = content->ct_parameters;
vb@115
   120
        }
vb@48
   121
vb@48
   122
		r = clist_append(parameters, param);
vb@115
   123
		if (r)
vb@115
   124
			goto enomem;
vb@115
   125
        param = NULL;
vb@48
   126
vb@48
   127
		if (content->ct_parameters == NULL)
vb@48
   128
			content->ct_parameters = parameters;
vb@48
   129
	}
vb@48
   130
vb@115
   131
    build_info = mailmime_new(mime_type, NULL, 0, mime_fields, content, NULL,
vb@115
   132
            NULL, NULL, list, NULL, NULL);
vb@115
   133
	if (build_info == NULL)
vb@115
   134
		goto enomem;
vb@48
   135
vb@48
   136
	return build_info;
vb@48
   137
vb@115
   138
enomem:
vb@115
   139
    if (list)
vb@115
   140
        clist_free(list);
vb@115
   141
    free(attr_name);
vb@115
   142
    free(attr_value);
vb@115
   143
    if (content->ct_parameters == NULL)
vb@115
   144
        if (parameters)
vb@115
   145
            clist_free(parameters);
vb@115
   146
vb@48
   147
	return NULL;
vb@48
   148
}
vb@48
   149
vb@114
   150
struct mailmime * get_pgp_encrypted_part(void)
vb@114
   151
{
vb@115
   152
	struct mailmime * mime = NULL;
vb@115
   153
	struct mailmime_fields * mime_fields = NULL;
vb@115
   154
	struct mailmime_content * content = NULL;
vb@115
   155
    int r;
vb@114
   156
vb@114
   157
	content = mailmime_content_new_with_str("application/pgp-encrypted");
vb@115
   158
    if (content == NULL)
vb@115
   159
        goto enomem;
vb@115
   160
vb@114
   161
    mime_fields = mailmime_fields_new_empty();
vb@115
   162
    if (mime_fields == NULL)
vb@115
   163
        goto enomem;
vb@115
   164
vb@116
   165
	mime = part_new_empty(content, mime_fields, 1);
vb@115
   166
    if (mime == NULL)
vb@115
   167
        goto enomem;
vb@115
   168
    mime_fields = NULL;
vb@115
   169
    content = NULL;
vb@115
   170
vb@115
   171
    r = mailmime_set_body_text(mime, "Version: 1\n", 10);
vb@115
   172
    if (r != 0)
vb@115
   173
        goto enomem;
vb@114
   174
vb@114
   175
	return mime;
vb@115
   176
vb@115
   177
enomem:
vb@115
   178
    if (content)
vb@115
   179
        mailmime_content_free(content);
vb@115
   180
    if (mime_fields)
vb@115
   181
        mailmime_fields_free(mime_fields);
vb@115
   182
    if (mime)
vb@115
   183
        mailmime_free(mime);
vb@115
   184
vb@115
   185
    return NULL;
vb@114
   186
}
vb@114
   187
vb@48
   188
struct mailmime * get_text_part(
vb@114
   189
        const char * filename,
vb@48
   190
        const char * mime_type,
vb@48
   191
        const char * text,
vb@48
   192
        size_t length,
vb@48
   193
        int encoding_type
vb@48
   194
    )
vb@48
   195
{
vb@114
   196
    char * disposition_name = NULL;
vb@115
   197
	struct mailmime_fields * mime_fields = NULL;
vb@115
   198
	struct mailmime * mime = NULL;
vb@115
   199
	struct mailmime_content * content = NULL;
vb@115
   200
	struct mailmime_parameter * param = NULL;
vb@115
   201
	struct mailmime_disposition * disposition = NULL;
vb@114
   202
	struct mailmime_mechanism * encoding = NULL;
vb@115
   203
    int r;
vb@48
   204
    
vb@115
   205
    if (filename != NULL) {
vb@114
   206
        disposition_name = strdup(filename);
vb@115
   207
        if (disposition_name == NULL)
vb@115
   208
            goto enomem;
vb@115
   209
    }
vb@114
   210
vb@115
   211
    if (encoding_type) {
vb@114
   212
        encoding = mailmime_mechanism_new(encoding_type, NULL);
vb@115
   213
        if (encoding == NULL)
vb@115
   214
            goto enomem;
vb@115
   215
    }
vb@114
   216
vb@115
   217
    disposition =
vb@115
   218
            mailmime_disposition_new_with_data(MAILMIME_DISPOSITION_TYPE_INLINE,
vb@115
   219
                    disposition_name, NULL, NULL, NULL, (size_t) -1);
vb@115
   220
    if (disposition == NULL)
vb@115
   221
        goto enomem;
vb@115
   222
    disposition_name = NULL;
vb@114
   223
vb@115
   224
    mime_fields = mailmime_fields_new_with_data(encoding, NULL, NULL,
vb@115
   225
            disposition, NULL);
vb@115
   226
    if (mime_fields == NULL)
vb@115
   227
        goto enomem;
vb@115
   228
    encoding = NULL;
vb@115
   229
    disposition = NULL;
vb@48
   230
vb@48
   231
	content = mailmime_content_new_with_str(mime_type);
vb@115
   232
    if (content == NULL)
vb@115
   233
        goto enomem;
vb@114
   234
    
vb@114
   235
    if (encoding_type != MAILMIME_MECHANISM_7BIT) {
vb@114
   236
        param = mailmime_param_new_with_data("charset", "utf-8");
vb@115
   237
        r = clist_append(content->ct_parameters, param);
vb@115
   238
        if (r != 0)
vb@115
   239
            goto enomem;
vb@114
   240
    }
vb@114
   241
vb@116
   242
	mime = part_new_empty(content, mime_fields, 1);
vb@115
   243
    if (mime == NULL)
vb@115
   244
        goto enomem;
vb@115
   245
    content = NULL;
vb@115
   246
    mime_fields = NULL;
vb@114
   247
vb@115
   248
    if (text) {
vb@115
   249
        r = mailmime_set_body_text(mime, (char *) text, length);
vb@115
   250
        if (r != 0)
vb@115
   251
            goto enomem;
vb@115
   252
    }
vb@48
   253
	
vb@48
   254
	return mime;
vb@115
   255
vb@115
   256
enomem:
vb@115
   257
    free(disposition_name);
vb@115
   258
    if (mime_fields)
vb@115
   259
        mailmime_fields_free(mime_fields);
vb@115
   260
    if (mime)
vb@115
   261
        mailmime_free(mime);
vb@115
   262
    if (content)
vb@115
   263
        mailmime_content_free(content);
vb@115
   264
    if (param)
vb@115
   265
        mailmime_parameter_free(param);
vb@115
   266
    if (disposition)
vb@115
   267
        mailmime_disposition_free(disposition);
vb@115
   268
    if (encoding)
vb@115
   269
        mailmime_mechanism_free(encoding);
vb@115
   270
vb@115
   271
    return NULL;
vb@48
   272
}
vb@48
   273
vb@59
   274
struct mailmime * get_file_part(
vb@59
   275
        const char * filename,
vb@59
   276
        const char * mime_type,
vb@59
   277
        char * data,
vb@59
   278
        size_t length
vb@59
   279
    )
vb@59
   280
{
vb@115
   281
    char * disposition_name = NULL;
vb@59
   282
    int encoding_type;
vb@115
   283
    struct mailmime_disposition * disposition = NULL;
vb@115
   284
    struct mailmime_mechanism * encoding = NULL;
vb@115
   285
    struct mailmime_content * content = NULL;
vb@115
   286
    struct mailmime * mime = NULL;
vb@115
   287
    struct mailmime_fields * mime_fields = NULL;
vb@115
   288
    int r;
vb@59
   289
vb@59
   290
    if (filename != NULL) {
vb@59
   291
        disposition_name = strdup(filename);
vb@115
   292
        if (disposition_name == NULL)
vb@115
   293
            goto enomem;
vb@59
   294
    }
vb@115
   295
vb@59
   296
    disposition =
vb@115
   297
            mailmime_disposition_new_with_data(MAILMIME_DISPOSITION_TYPE_ATTACHMENT,
vb@115
   298
                    disposition_name, NULL, NULL, NULL, (size_t) -1);
vb@115
   299
    if (disposition == NULL)
vb@115
   300
        goto enomem;
vb@115
   301
    disposition_name = NULL;
vb@115
   302
vb@59
   303
    content = mailmime_content_new_with_str(mime_type);
vb@115
   304
    if (content == NULL)
vb@115
   305
        goto enomem;
vb@59
   306
vb@59
   307
    encoding_type = MAILMIME_MECHANISM_BASE64;
vb@59
   308
    encoding = mailmime_mechanism_new(encoding_type, NULL);
vb@115
   309
    if (encoding == NULL)
vb@115
   310
        goto enomem;
vb@115
   311
vb@115
   312
    mime_fields = mailmime_fields_new_with_data(encoding, NULL, NULL,
vb@115
   313
            disposition, NULL);
vb@115
   314
    if (mime_fields == NULL)
vb@115
   315
        goto enomem;
vb@115
   316
    encoding = NULL;
vb@115
   317
    disposition = NULL;
vb@115
   318
vb@116
   319
    mime = part_new_empty(content, mime_fields, 1);
vb@115
   320
    if (mime == NULL)
vb@115
   321
        goto enomem;
vb@115
   322
    content = NULL;
vb@115
   323
    mime_fields = NULL;
vb@115
   324
vb@115
   325
    r = mailmime_set_body_text(mime, data, length);
vb@115
   326
    if (r != 0)
vb@115
   327
        goto enomem;
vb@59
   328
vb@59
   329
    return mime;
vb@115
   330
vb@115
   331
enomem:
vb@115
   332
    free(disposition_name);
vb@115
   333
    if (disposition)
vb@115
   334
        mailmime_disposition_free(disposition);
vb@115
   335
    if (encoding)
vb@115
   336
        mailmime_mechanism_free(encoding);
vb@115
   337
    if (content)
vb@115
   338
        mailmime_content_free(content);
vb@115
   339
    if (mime_fields)
vb@115
   340
        mailmime_fields_free(mime_fields);
vb@115
   341
    if (mime)
vb@115
   342
        mailmime_free(mime);
vb@115
   343
vb@115
   344
    return NULL;
vb@59
   345
}
vb@59
   346
vb@116
   347
struct mailmime * part_multiple_new(const char *type)
vb@48
   348
{
vb@115
   349
    struct mailmime_fields *mime_fields = NULL;
vb@115
   350
    struct mailmime_content *content = NULL;
vb@115
   351
    struct mailmime *mp = NULL;
vb@48
   352
    
vb@48
   353
    mime_fields = mailmime_fields_new_empty();
vb@48
   354
    if (mime_fields == NULL)
vb@115
   355
        goto enomem;
vb@48
   356
    
vb@48
   357
    content = mailmime_content_new_with_str(type);
vb@48
   358
    if (content == NULL)
vb@115
   359
        goto enomem;
vb@48
   360
    
vb@116
   361
    mp = part_new_empty(content, mime_fields, 0);
vb@48
   362
    if (mp == NULL)
vb@115
   363
        goto enomem;
vb@48
   364
    
vb@48
   365
    return mp;
vb@48
   366
    
vb@115
   367
enomem:
vb@115
   368
    if (content)
vb@115
   369
        mailmime_content_free(content);
vb@115
   370
    if (mime_fields)
vb@115
   371
        mailmime_fields_free(mime_fields);
vb@115
   372
vb@48
   373
    return NULL;
vb@48
   374
}
vb@48
   375
vb@89
   376
struct mailimf_field * _new_field(
vb@89
   377
        int type,
vb@89
   378
        _new_func_t new_func,
vb@89
   379
        void *value
vb@89
   380
    )
vb@89
   381
{
vb@89
   382
    void *data = new_func(value);
vb@89
   383
    assert(data);
vb@89
   384
    if (data == NULL)
vb@89
   385
        return NULL;
vb@89
   386
vb@89
   387
    struct mailimf_field * result = calloc(1, sizeof(struct mailimf_field));
vb@89
   388
    assert(result);
vb@89
   389
    if (result == NULL) {
vb@89
   390
        free(data);
vb@89
   391
        return NULL;
vb@89
   392
    }
vb@89
   393
vb@89
   394
    result->fld_type = type;
vb@89
   395
    result->fld_data.fld_return_path = data;
vb@89
   396
vb@89
   397
    return result;
vb@89
   398
}
vb@89
   399
vb@89
   400
void _free_field(struct mailimf_field *field)
vb@89
   401
{
vb@89
   402
    if (field)
vb@89
   403
        free(field->fld_data.fld_return_path);
vb@89
   404
    free(field);
vb@89
   405
}
vb@89
   406
vb@89
   407
int _append_field(
vb@89
   408
        clist *list,
vb@89
   409
        int type,
vb@89
   410
        _new_func_t new_func,
vb@89
   411
        void *value
vb@89
   412
    )
vb@89
   413
{
vb@89
   414
    int r;
vb@89
   415
    struct mailimf_field * field;
vb@89
   416
vb@89
   417
    assert(list);
vb@89
   418
    assert(new_func);
vb@89
   419
    assert(value);
vb@89
   420
vb@89
   421
    field = _new_field(type, new_func, value);
vb@89
   422
    if (field == NULL)
vb@89
   423
        return -1;
vb@89
   424
vb@89
   425
    r = clist_append(list, field);
vb@90
   426
    if (r)
vb@89
   427
        _free_field(field);
vb@89
   428
vb@89
   429
    return r;
vb@89
   430
}
vb@89
   431
vb@92
   432
// http://media2.giga.de/2014/02/Image-28.jpg
vb@92
   433
vb@89
   434
struct mailimf_date_time * timestamp_to_etpantime(const struct tm *ts)
vb@89
   435
{
vb@89
   436
    struct mailimf_date_time * result = calloc(1,
vb@89
   437
            sizeof(struct mailimf_date_time));
vb@89
   438
    assert(result);
vb@89
   439
    if (result == NULL)
vb@89
   440
        return NULL;
vb@89
   441
vb@89
   442
    assert(ts);
vb@89
   443
vb@89
   444
    result->dt_sec = ts->tm_sec;
vb@89
   445
    result->dt_min = ts->tm_min;
vb@89
   446
    result->dt_hour = ts->tm_hour;
vb@89
   447
    result->dt_day = ts->tm_mday;
vb@89
   448
    result->dt_month = ts->tm_mon + 1;
vb@89
   449
    result->dt_year = ts->tm_year + 1900;
vb@130
   450
#ifndef WIN32
vb@89
   451
    result->dt_zone = (int) (ts->tm_gmtoff / 36L);
vb@130
   452
#endif
vb@89
   453
    return result;
vb@89
   454
}
vb@89
   455
vb@89
   456
struct tm * etpantime_to_timestamp(const struct mailimf_date_time *et)
vb@89
   457
{
vb@89
   458
    struct tm * result = calloc(1, sizeof(struct tm));
vb@89
   459
    assert(result);
vb@89
   460
    if (result == NULL)
vb@89
   461
        return NULL;
vb@89
   462
vb@89
   463
    assert(et);
vb@89
   464
vb@89
   465
    result->tm_sec = et->dt_sec;
vb@89
   466
    result->tm_min = et->dt_min;
vb@89
   467
    result->tm_hour = et->dt_hour;
vb@89
   468
    result->tm_mday = et->dt_day;
vb@89
   469
    result->tm_mon = et->dt_month - 1;
vb@89
   470
    result->tm_year = et->dt_year - 1900;
vb@130
   471
#ifndef WIN32
vb@89
   472
    result->tm_gmtoff = 36L * (long) et->dt_zone;
vb@130
   473
#endif
vb@89
   474
    return result;
vb@89
   475
}
vb@89
   476
vb@90
   477
struct mailimf_mailbox * mailbox_from_string(
vb@90
   478
        const char *name,
vb@90
   479
        const char *address
vb@90
   480
    )
vb@90
   481
{
vb@90
   482
    struct mailimf_mailbox *mb = NULL;
vb@90
   483
    char *_name = NULL;
vb@90
   484
    char *_address = NULL;
vb@90
   485
vb@90
   486
    assert(address);
vb@90
   487
vb@90
   488
    _name = name ? strdup(name) : strdup("");
vb@90
   489
    if (_name == NULL)
vb@90
   490
        goto enomem;
vb@90
   491
vb@90
   492
    _address = strdup(address);
vb@90
   493
    if (_address == NULL)
vb@90
   494
        goto enomem;
vb@90
   495
vb@90
   496
    mb = mailimf_mailbox_new(_name, _address);
vb@90
   497
    assert(mb);
vb@90
   498
    if (mb == NULL)
vb@90
   499
        goto enomem;
vb@90
   500
vb@90
   501
    return mb;
vb@90
   502
vb@90
   503
enomem:
vb@90
   504
    free(_name);
vb@90
   505
    free(_address);
vb@90
   506
vb@90
   507
    return NULL;
vb@90
   508
}
vb@90
   509
vb@94
   510
struct mailimf_field * create_optional_field(
vb@94
   511
        const char *field,
vb@94
   512
        const char *value
vb@94
   513
    )
vb@94
   514
{
vb@94
   515
    char *_field = NULL;
vb@94
   516
    char *_value = NULL;
vb@94
   517
    struct mailimf_optional_field *optional_field = NULL;
vb@94
   518
vb@94
   519
    _field = strdup(field);
vb@94
   520
    if (_field == NULL)
vb@94
   521
        goto enomem;
vb@94
   522
vb@94
   523
    _value = mailmime_encode_subject_header("utf-8", value, 0);
vb@94
   524
    if (_value == NULL)
vb@94
   525
        goto enomem;
vb@94
   526
vb@94
   527
    optional_field = mailimf_optional_field_new(_field, _value);
vb@94
   528
    if (optional_field == NULL)
vb@94
   529
        goto enomem;
vb@94
   530
vb@94
   531
    struct mailimf_field * result = calloc(1, sizeof(struct mailimf_field));
vb@94
   532
    assert(result);
vb@94
   533
    if (result == NULL)
vb@94
   534
        goto enomem;
vb@94
   535
vb@94
   536
    result->fld_type = MAILIMF_FIELD_OPTIONAL_FIELD;
vb@94
   537
    result->fld_data.fld_optional_field = optional_field;
vb@94
   538
vb@94
   539
    return result;
vb@94
   540
vb@94
   541
enomem:
vb@94
   542
    if (optional_field) {
vb@94
   543
        mailimf_optional_field_free(optional_field);
vb@94
   544
    }
vb@94
   545
    else {
vb@94
   546
        free(_field);
vb@94
   547
        free(_value);
vb@94
   548
    }
vb@94
   549
vb@94
   550
    return NULL;
vb@94
   551
}
vb@94
   552
vb@94
   553
int _append_optional_field(
vb@94
   554
        clist *list,
vb@94
   555
        const char *field,
vb@94
   556
        const char *value
vb@94
   557
    )
vb@94
   558
{
vb@94
   559
    int r;
vb@94
   560
    struct mailimf_field * optional_field =
vb@94
   561
            create_optional_field(field, value);
vb@94
   562
vb@94
   563
    if (optional_field == NULL)
vb@94
   564
        return -1;
vb@94
   565
vb@94
   566
    r = clist_append(list, optional_field);
vb@94
   567
    if (r)
vb@94
   568
        mailimf_field_free(optional_field);
vb@94
   569
vb@94
   570
    return r;
vb@94
   571
}
vb@94
   572
vb@147
   573
clist * _get_fields(struct mailmime * mime)
vb@147
   574
{
vb@147
   575
    clist * _fieldlist = NULL;
vb@147
   576
vb@147
   577
    assert(mime);
vb@147
   578
vb@147
   579
    if (mime->mm_data.mm_message.mm_fields &&
vb@147
   580
            mime->mm_data.mm_message.mm_fields->fld_list) {
vb@147
   581
        _fieldlist = mime->mm_data.mm_message.mm_fields->fld_list;
vb@147
   582
    }
vb@147
   583
vb@147
   584
    return _fieldlist;
vb@147
   585
}
vb@147
   586
vb@147
   587
struct mailmime_content * _get_content(struct mailmime * mime)
vb@147
   588
{
vb@147
   589
    struct mailmime_content * content = NULL;
vb@147
   590
vb@147
   591
    assert(mime);
vb@147
   592
vb@147
   593
    if (mime->mm_data.mm_message.mm_msg_mime)
vb@147
   594
        content = mime->mm_data.mm_message.mm_msg_mime->mm_content_type;
vb@147
   595
vb@147
   596
    return content;
vb@147
   597
}
vb@147
   598
vb@154
   599
char * _get_filename(struct mailmime *mime)
vb@154
   600
{
vb@154
   601
    clist * _fieldlist = NULL;
vb@154
   602
vb@154
   603
    assert(mime);
vb@154
   604
vb@154
   605
    if (mime->mm_mime_fields && mime->mm_mime_fields->fld_list)
vb@154
   606
        _fieldlist = mime->mm_mime_fields->fld_list;
vb@154
   607
    else
vb@154
   608
        return NULL;
vb@154
   609
vb@154
   610
    clistiter *cur;
vb@154
   611
    for (cur = clist_begin(_fieldlist); cur; cur = clist_next(cur)) {
vb@154
   612
        struct mailmime_field * _field = clist_content(cur);
vb@154
   613
        if (_field && _field->fld_type == MAILMIME_FIELD_DISPOSITION) {
vb@154
   614
            if (_field->fld_data.fld_disposition &&
vb@154
   615
                    _field->fld_data.fld_disposition->dsp_parms) {
vb@154
   616
                clist * _parmlist =
vb@154
   617
                        _field->fld_data.fld_disposition->dsp_parms;
vb@154
   618
                clistiter *cur2;
vb@154
   619
                for (cur2 = clist_begin(_parmlist); cur2; cur2 =
vb@154
   620
                        clist_next(cur2)) {
vb@154
   621
                    struct mailmime_parameter * param = clist_content(cur2);
vb@155
   622
                    if (param && param->pa_name == NULL)
vb@154
   623
                        return param->pa_value;
vb@154
   624
                }
vb@154
   625
            }
vb@154
   626
        }
vb@154
   627
    }
vb@154
   628
vb@154
   629
    return NULL;
vb@154
   630
}
vb@154
   631
vb@152
   632
bool parameter_has_value(
vb@152
   633
        struct mailmime_content *content,       
vb@152
   634
        const char *name,
vb@152
   635
        const char *value
vb@152
   636
    )
vb@152
   637
{
vb@152
   638
    clistiter *cur;
vb@152
   639
vb@152
   640
    assert(name);
vb@152
   641
    assert(value);
vb@152
   642
vb@152
   643
    clist * list = content->ct_parameters;
vb@152
   644
    if (list == NULL)
vb@152
   645
        return false;
vb@152
   646
vb@152
   647
    for (cur = clist_begin(list); cur != NULL ; cur = clist_next(cur)) {
vb@152
   648
        struct mailmime_parameter * param = clist_content(cur);
vb@152
   649
        if (param &&
vb@152
   650
                param->pa_name && strcmp(name, param->pa_name) == 0 &&
vb@152
   651
                param->pa_value && strcmp(value, param->pa_value) == 0)
vb@152
   652
            return true;
vb@152
   653
    }
vb@152
   654
vb@152
   655
    return false;
vb@152
   656
}
vb@152
   657
vb@151
   658
bool _is_multipart(struct mailmime_content *content, const char *subtype)
vb@147
   659
{
vb@147
   660
    assert(content);
vb@147
   661
vb@147
   662
    if (content->ct_type && content->ct_type->tp_type ==
vb@147
   663
            MAILMIME_TYPE_COMPOSITE_TYPE &&
vb@147
   664
            content->ct_type->tp_data.tp_composite_type &&
vb@147
   665
            content->ct_type->tp_data.tp_composite_type->ct_type ==
vb@151
   666
            MAILMIME_COMPOSITE_TYPE_MULTIPART) {
vb@151
   667
        if (subtype)
vb@151
   668
            return content->ct_subtype &&
vb@151
   669
                    strcmp(content->ct_subtype, subtype) == 0;
vb@151
   670
        else
vb@151
   671
            return true;
vb@151
   672
    }
vb@147
   673
vb@151
   674
    return false;
vb@147
   675
}
vb@147
   676
vb@147
   677
bool _is_PGP_MIME(struct mailmime_content *content)
vb@147
   678
{
vb@147
   679
    assert(content);
vb@147
   680
vb@151
   681
    if (_is_multipart(content, "encrypted") &&
vb@152
   682
            parameter_has_value(content, "protocol",
vb@147
   683
                    "application/pgp-encrypted"))
vb@151
   684
        return true;
vb@147
   685
vb@151
   686
    return false;
vb@147
   687
}
vb@147
   688
vb@152
   689
bool _is_text_part(struct mailmime_content *content, const char *subtype)
vb@152
   690
{
vb@152
   691
    assert(content);
vb@152
   692
vb@153
   693
    if (content->ct_type && content->ct_type->tp_type ==
vb@153
   694
            MAILMIME_TYPE_DISCRETE_TYPE &&
vb@153
   695
            content->ct_type->tp_data.tp_discrete_type &&
vb@152
   696
            content->ct_type->tp_data.tp_discrete_type->dt_type ==
vb@152
   697
            MAILMIME_DISCRETE_TYPE_TEXT) {
vb@152
   698
        if (subtype)
vb@152
   699
            return content->ct_subtype &&
vb@152
   700
                    strcmp(content->ct_subtype, subtype) == 0;
vb@152
   701
        else
vb@152
   702
            return true;
vb@152
   703
    }
vb@152
   704
vb@152
   705
    return false;
vb@152
   706
}
vb@152
   707
vb@154
   708
char * _get_content_type(struct mailmime_content *content)
vb@154
   709
{
vb@154
   710
    const char *_type;
vb@154
   711
vb@154
   712
    assert(content);
vb@154
   713
vb@154
   714
    if (content->ct_subtype == NULL)
vb@154
   715
        return NULL;
vb@154
   716
vb@154
   717
    if (content->ct_type && content->ct_type->tp_data.tp_discrete_type) {
vb@154
   718
        size_t len;
vb@154
   719
        char *type;
vb@154
   720
vb@154
   721
        switch  (content->ct_type->tp_data.tp_discrete_type->dt_type) {
vb@154
   722
            case MAILMIME_DISCRETE_TYPE_TEXT:
vb@154
   723
                _type = "text";
vb@154
   724
                break;
vb@154
   725
            case MAILMIME_DISCRETE_TYPE_IMAGE:
vb@154
   726
                _type = "image";
vb@154
   727
                break;
vb@154
   728
            case MAILMIME_DISCRETE_TYPE_AUDIO:
vb@154
   729
                _type = "audio";
vb@154
   730
                break;
vb@154
   731
            case MAILMIME_DISCRETE_TYPE_VIDEO:
vb@154
   732
                _type = "video";
vb@154
   733
                break;
vb@154
   734
            case MAILMIME_DISCRETE_TYPE_APPLICATION:
vb@154
   735
                _type = "application";
vb@154
   736
                break;
vb@154
   737
            case MAILMIME_DISCRETE_TYPE_EXTENSION:
vb@154
   738
                _type = "extension";
vb@154
   739
                break;
vb@154
   740
            default:
vb@154
   741
                return NULL;
vb@154
   742
        }
vb@154
   743
vb@154
   744
        len = strlen(_type) + 1 + strlen(content->ct_subtype) + 1;
vb@154
   745
        type = calloc(1, len);
vb@154
   746
        assert(type);
vb@154
   747
        // BUG: out of memory cannot be signaled
vb@154
   748
        if (type == NULL)
vb@154
   749
            return NULL;
vb@154
   750
vb@154
   751
        strcpy(type, _type);
vb@154
   752
        strcat(type, "/");
vb@154
   753
        strcat(type, content->ct_subtype);
vb@154
   754
vb@154
   755
        return type;
vb@154
   756
    }
vb@154
   757
vb@154
   758
    return NULL;
vb@154
   759
}
vb@154
   760