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