src/etpan_mime.c
author vb
Sat, 21 Feb 2015 16:55:43 +0100
changeset 62 ad5e484720e1
parent 59 88429085f8da
child 89 aef5a4bc78f3
permissions -rw-r--r--
signal() and init()
vb@48
     1
#include <string.h>
vb@48
     2
#include <stdlib.h>
vb@48
     3
#include <unistd.h>
vb@48
     4
vb@48
     5
#include "etpan_mime.h"
vb@62
     6
#ifndef mailmime_param_new_with_data
vb@62
     7
#include <libetpan/mailprivacy_tools.h>
vb@62
     8
#endif
vb@48
     9
vb@48
    10
#define MAX_MESSAGE_ID 512
vb@48
    11
vb@48
    12
static char * generate_boundary(const char * boundary_prefix)
vb@48
    13
{
vb@48
    14
    char id[MAX_MESSAGE_ID];
vb@48
    15
    time_t now;
vb@48
    16
    char name[MAX_MESSAGE_ID];
vb@48
    17
    long value;
vb@54
    18
 
vb@54
    19
    id[MAX_MESSAGE_ID - 1] = 0;
vb@54
    20
    name[MAX_MESSAGE_ID - 1] = 0;
vb@54
    21
vb@48
    22
    now = time(NULL);
vb@48
    23
#ifndef WIN32
vb@48
    24
    value = random();
vb@48
    25
    
vb@54
    26
    gethostname(name, MAX_MESSAGE_ID - 1);
vb@48
    27
#else
vb@48
    28
    value = now;
vb@48
    29
    strcpy(name, "WINDOWS");
vb@48
    30
#endif
vb@48
    31
    
vb@48
    32
    if (boundary_prefix == NULL)
vb@48
    33
        boundary_prefix = "";
vb@48
    34
    
vb@48
    35
    snprintf(id, MAX_MESSAGE_ID, "%s%lx_%lx_%x", boundary_prefix, now, value,
vb@48
    36
            getpid());
vb@48
    37
    
vb@48
    38
    return strdup(id);
vb@48
    39
}
vb@48
    40
vb@48
    41
struct mailmime * part_new_empty(
vb@48
    42
        struct mailmime_content * content,
vb@48
    43
        struct mailmime_fields * mime_fields,
vb@48
    44
        const char * boundary_prefix,
vb@48
    45
        int force_single
vb@48
    46
    )
vb@48
    47
{
vb@48
    48
	struct mailmime * build_info;
vb@48
    49
	clist * list;
vb@48
    50
	int r;
vb@48
    51
	int mime_type;
vb@48
    52
vb@48
    53
	list = NULL;
vb@48
    54
vb@48
    55
	if (force_single) {
vb@48
    56
		mime_type = MAILMIME_SINGLE;
vb@48
    57
	}
vb@48
    58
	else {
vb@48
    59
		switch (content->ct_type->tp_type) {
vb@48
    60
			case MAILMIME_TYPE_DISCRETE_TYPE:
vb@48
    61
			mime_type = MAILMIME_SINGLE;
vb@48
    62
			break;
vb@48
    63
vb@48
    64
			case MAILMIME_TYPE_COMPOSITE_TYPE:
vb@48
    65
			switch (content->ct_type->tp_data.tp_composite_type->ct_type) {
vb@48
    66
				case MAILMIME_COMPOSITE_TYPE_MULTIPART:
vb@48
    67
				mime_type = MAILMIME_MULTIPLE;
vb@48
    68
				break;
vb@48
    69
vb@48
    70
				case MAILMIME_COMPOSITE_TYPE_MESSAGE:
vb@48
    71
				if (strcasecmp(content->ct_subtype, "rfc822") == 0)
vb@48
    72
					mime_type = MAILMIME_MESSAGE;
vb@48
    73
				else
vb@48
    74
					mime_type = MAILMIME_SINGLE;
vb@48
    75
				break;
vb@48
    76
vb@48
    77
				default:
vb@48
    78
				goto err;
vb@48
    79
			}
vb@48
    80
			break;
vb@48
    81
vb@48
    82
			default:
vb@48
    83
			goto err;
vb@48
    84
		}
vb@48
    85
	}
vb@48
    86
vb@48
    87
	if (mime_type == MAILMIME_MULTIPLE) {
vb@48
    88
		char * attr_name;
vb@48
    89
		char * attr_value;
vb@48
    90
		struct mailmime_parameter * param;
vb@48
    91
		clist * parameters;
vb@48
    92
		char * boundary;
vb@48
    93
vb@48
    94
		list = clist_new();
vb@48
    95
		if (list == NULL)
vb@48
    96
			goto err;
vb@48
    97
vb@48
    98
		attr_name = strdup("boundary");
vb@48
    99
		boundary = generate_boundary(boundary_prefix);
vb@48
   100
		attr_value = boundary;
vb@48
   101
		if (attr_name == NULL) {
vb@48
   102
			free(attr_name);
vb@48
   103
			goto free_list;
vb@48
   104
		}
vb@48
   105
vb@48
   106
		param = mailmime_parameter_new(attr_name, attr_value);
vb@48
   107
		if (param == NULL) {
vb@48
   108
			free(attr_value);
vb@48
   109
			free(attr_name);
vb@48
   110
			goto free_list;
vb@48
   111
		}
vb@48
   112
vb@48
   113
		if (content->ct_parameters == NULL) {
vb@48
   114
			parameters = clist_new();
vb@48
   115
			if (parameters == NULL) {
vb@48
   116
				mailmime_parameter_free(param);
vb@48
   117
				goto free_list;
vb@48
   118
			}
vb@48
   119
		}
vb@48
   120
		else
vb@48
   121
			parameters = content->ct_parameters;
vb@48
   122
vb@48
   123
		r = clist_append(parameters, param);
vb@48
   124
		if (r != 0) {
vb@48
   125
			clist_free(parameters);
vb@48
   126
			mailmime_parameter_free(param);
vb@48
   127
			goto free_list;
vb@48
   128
		}
vb@48
   129
vb@48
   130
		if (content->ct_parameters == NULL)
vb@48
   131
			content->ct_parameters = parameters;
vb@48
   132
	}
vb@48
   133
vb@48
   134
	build_info = mailmime_new(mime_type,
vb@48
   135
		NULL, 0, mime_fields, content,
vb@48
   136
		NULL, NULL, NULL, list,
vb@48
   137
		NULL, NULL);
vb@48
   138
	if (build_info == NULL) {
vb@48
   139
		clist_free(list);
vb@48
   140
		return NULL;
vb@48
   141
	}
vb@48
   142
vb@48
   143
	return build_info;
vb@48
   144
vb@48
   145
	free_list:
vb@48
   146
	clist_free(list);
vb@48
   147
	err:
vb@48
   148
	return NULL;
vb@48
   149
}
vb@48
   150
vb@48
   151
struct mailmime * get_text_part(
vb@48
   152
        const char * mime_type,
vb@48
   153
        const char * text,
vb@48
   154
        size_t length,
vb@48
   155
        int encoding_type
vb@48
   156
    )
vb@48
   157
{
vb@48
   158
	struct mailmime_fields * mime_fields;
vb@48
   159
	struct mailmime * mime;
vb@48
   160
	struct mailmime_content * content;
vb@48
   161
	struct mailmime_parameter * param;
vb@48
   162
	struct mailmime_disposition * disposition;
vb@48
   163
	struct mailmime_mechanism * encoding;
vb@48
   164
    
vb@48
   165
	encoding = mailmime_mechanism_new(encoding_type, NULL);
vb@48
   166
	disposition = mailmime_disposition_new_with_data(MAILMIME_DISPOSITION_TYPE_INLINE,
vb@48
   167
		NULL, NULL, NULL, NULL, (size_t) -1);
vb@48
   168
	mime_fields = mailmime_fields_new_with_data(encoding,
vb@48
   169
		NULL, NULL, disposition, NULL);
vb@48
   170
vb@48
   171
	content = mailmime_content_new_with_str(mime_type);
vb@48
   172
	param = mailmime_param_new_with_data("charset", "utf-8");
vb@48
   173
	clist_append(content->ct_parameters, param);
vb@48
   174
	mime = part_new_empty(content, mime_fields, NULL, 1);
vb@48
   175
	mailmime_set_body_text(mime, (char *) text, length);
vb@48
   176
	
vb@48
   177
	return mime;
vb@48
   178
}
vb@48
   179
vb@59
   180
struct mailmime * get_file_part(
vb@59
   181
        const char * filename,
vb@59
   182
        const char * mime_type,
vb@59
   183
        char * data,
vb@59
   184
        size_t length
vb@59
   185
    )
vb@59
   186
{
vb@59
   187
    char * disposition_name;
vb@59
   188
    int encoding_type;
vb@59
   189
    struct mailmime_disposition * disposition;
vb@59
   190
    struct mailmime_mechanism * encoding;
vb@59
   191
    struct mailmime_content * content;
vb@59
   192
    struct mailmime * mime;
vb@59
   193
    struct mailmime_fields * mime_fields;
vb@59
   194
vb@59
   195
    disposition_name = NULL;
vb@59
   196
    if (filename != NULL) {
vb@59
   197
        disposition_name = strdup(filename);
vb@59
   198
    }
vb@59
   199
    disposition =
vb@59
   200
        mailmime_disposition_new_with_data(MAILMIME_DISPOSITION_TYPE_ATTACHMENT,
vb@59
   201
                disposition_name, NULL, NULL, NULL, (size_t) -1);
vb@59
   202
    content = mailmime_content_new_with_str(mime_type);
vb@59
   203
vb@59
   204
    encoding_type = MAILMIME_MECHANISM_BASE64;
vb@59
   205
    encoding = mailmime_mechanism_new(encoding_type, NULL);
vb@59
   206
    mime_fields = mailmime_fields_new_with_data(encoding,
vb@59
   207
        NULL, NULL, disposition, NULL);
vb@59
   208
    mime = part_new_empty(content, mime_fields, NULL, 1);
vb@59
   209
    mailmime_set_body_text(mime, data, length);
vb@59
   210
vb@59
   211
    return mime;
vb@59
   212
}
vb@59
   213
vb@48
   214
struct mailmime * part_multiple_new(
vb@48
   215
        const char * type,
vb@48
   216
        const char * boundary_prefix
vb@48
   217
    )
vb@48
   218
{
vb@48
   219
    struct mailmime_fields * mime_fields;
vb@48
   220
    struct mailmime_content * content;
vb@48
   221
    struct mailmime * mp;
vb@48
   222
    
vb@48
   223
    mime_fields = mailmime_fields_new_empty();
vb@48
   224
    if (mime_fields == NULL)
vb@48
   225
        goto err;
vb@48
   226
    
vb@48
   227
    content = mailmime_content_new_with_str(type);
vb@48
   228
    if (content == NULL)
vb@48
   229
        goto free_fields;
vb@48
   230
    
vb@48
   231
    mp = part_new_empty(content, mime_fields, boundary_prefix, 0);
vb@48
   232
    if (mp == NULL)
vb@48
   233
        goto free_content;
vb@48
   234
    
vb@48
   235
    return mp;
vb@48
   236
    
vb@48
   237
free_content:
vb@48
   238
    mailmime_content_free(content);
vb@48
   239
free_fields:
vb@48
   240
    mailmime_fields_free(mime_fields);
vb@48
   241
err:
vb@48
   242
    return NULL;
vb@48
   243
}
vb@48
   244