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