6 #include "etpan_mime.h"
7 #ifndef mailmime_param_new_with_data
8 #include <libetpan/mailprivacy_tools.h>
11 time_t mail_mkgmtime(struct tm * tmp);
13 #define MAX_MESSAGE_ID 512
15 static char * generate_boundary(const char * boundary_prefix)
17 char id[MAX_MESSAGE_ID];
19 char name[MAX_MESSAGE_ID];
23 id[MAX_MESSAGE_ID - 1] = 0;
24 name[MAX_MESSAGE_ID - 1] = 0;
29 r = gethostname(name, MAX_MESSAGE_ID - 1);
33 if (boundary_prefix == NULL)
36 snprintf(id, MAX_MESSAGE_ID, "%s%lx_%lx_%x", boundary_prefix, now, value,
42 struct mailmime * part_new_empty(
43 struct mailmime_content * content,
44 struct mailmime_fields * mime_fields,
45 const char * boundary_prefix,
49 struct mailmime * build_info;
53 char * attr_name = NULL;
54 char * attr_value = NULL;
55 struct mailmime_parameter * param = NULL;
56 clist * parameters = NULL;
57 char * boundary = NULL;
63 mime_type = MAILMIME_SINGLE;
66 switch (content->ct_type->tp_type) {
67 case MAILMIME_TYPE_DISCRETE_TYPE:
68 mime_type = MAILMIME_SINGLE;
71 case MAILMIME_TYPE_COMPOSITE_TYPE:
72 switch (content->ct_type->tp_data.tp_composite_type->ct_type) {
73 case MAILMIME_COMPOSITE_TYPE_MULTIPART:
74 mime_type = MAILMIME_MULTIPLE;
77 case MAILMIME_COMPOSITE_TYPE_MESSAGE:
78 if (strcasecmp(content->ct_subtype, "rfc822") == 0)
79 mime_type = MAILMIME_MESSAGE;
81 mime_type = MAILMIME_SINGLE;
94 if (mime_type == MAILMIME_MULTIPLE) {
100 attr_name = strdup("boundary");
102 if (attr_name == NULL)
105 boundary = generate_boundary(boundary_prefix);
107 attr_value = boundary;
108 if (attr_value == NULL)
111 param = mailmime_parameter_new(attr_name, attr_value);
118 if (content->ct_parameters == NULL) {
119 parameters = clist_new();
121 if (parameters == NULL)
125 parameters = content->ct_parameters;
128 r = clist_append(parameters, param);
133 if (content->ct_parameters == NULL)
134 content->ct_parameters = parameters;
137 build_info = mailmime_new(mime_type, NULL, 0, mime_fields, content, NULL,
138 NULL, NULL, list, NULL, NULL);
139 if (build_info == NULL)
149 if (content->ct_parameters == NULL)
151 clist_free(parameters);
156 struct mailmime * get_pgp_encrypted_part(void)
158 struct mailmime * mime = NULL;
159 struct mailmime_fields * mime_fields = NULL;
160 struct mailmime_content * content = NULL;
163 content = mailmime_content_new_with_str("application/pgp-encrypted");
167 mime_fields = mailmime_fields_new_empty();
168 if (mime_fields == NULL)
171 mime = part_new_empty(content, mime_fields, NULL, 1);
177 r = mailmime_set_body_text(mime, "Version: 1\n", 10);
185 mailmime_content_free(content);
187 mailmime_fields_free(mime_fields);
194 struct mailmime * get_text_part(
195 const char * filename,
196 const char * mime_type,
202 char * disposition_name = NULL;
203 struct mailmime_fields * mime_fields = NULL;
204 struct mailmime * mime = NULL;
205 struct mailmime_content * content = NULL;
206 struct mailmime_parameter * param = NULL;
207 struct mailmime_disposition * disposition = NULL;
208 struct mailmime_mechanism * encoding = NULL;
211 if (filename != NULL) {
212 disposition_name = strdup(filename);
213 if (disposition_name == NULL)
218 encoding = mailmime_mechanism_new(encoding_type, NULL);
219 if (encoding == NULL)
224 mailmime_disposition_new_with_data(MAILMIME_DISPOSITION_TYPE_INLINE,
225 disposition_name, NULL, NULL, NULL, (size_t) -1);
226 if (disposition == NULL)
228 disposition_name = NULL;
230 mime_fields = mailmime_fields_new_with_data(encoding, NULL, NULL,
232 if (mime_fields == NULL)
237 content = mailmime_content_new_with_str(mime_type);
241 if (encoding_type != MAILMIME_MECHANISM_7BIT) {
242 param = mailmime_param_new_with_data("charset", "utf-8");
243 r = clist_append(content->ct_parameters, param);
248 mime = part_new_empty(content, mime_fields, NULL, 1);
255 r = mailmime_set_body_text(mime, (char *) text, length);
263 free(disposition_name);
265 mailmime_fields_free(mime_fields);
269 mailmime_content_free(content);
271 mailmime_parameter_free(param);
273 mailmime_disposition_free(disposition);
275 mailmime_mechanism_free(encoding);
280 struct mailmime * get_file_part(
281 const char * filename,
282 const char * mime_type,
287 char * disposition_name = NULL;
289 struct mailmime_disposition * disposition = NULL;
290 struct mailmime_mechanism * encoding = NULL;
291 struct mailmime_content * content = NULL;
292 struct mailmime * mime = NULL;
293 struct mailmime_fields * mime_fields = NULL;
296 if (filename != NULL) {
297 disposition_name = strdup(filename);
298 if (disposition_name == NULL)
303 mailmime_disposition_new_with_data(MAILMIME_DISPOSITION_TYPE_ATTACHMENT,
304 disposition_name, NULL, NULL, NULL, (size_t) -1);
305 if (disposition == NULL)
307 disposition_name = NULL;
309 content = mailmime_content_new_with_str(mime_type);
313 encoding_type = MAILMIME_MECHANISM_BASE64;
314 encoding = mailmime_mechanism_new(encoding_type, NULL);
315 if (encoding == NULL)
318 mime_fields = mailmime_fields_new_with_data(encoding, NULL, NULL,
320 if (mime_fields == NULL)
325 mime = part_new_empty(content, mime_fields, NULL, 1);
331 r = mailmime_set_body_text(mime, data, length);
338 free(disposition_name);
340 mailmime_disposition_free(disposition);
342 mailmime_mechanism_free(encoding);
344 mailmime_content_free(content);
346 mailmime_fields_free(mime_fields);
353 struct mailmime * part_multiple_new(
355 const char * boundary_prefix
358 struct mailmime_fields *mime_fields = NULL;
359 struct mailmime_content *content = NULL;
360 struct mailmime *mp = NULL;
362 mime_fields = mailmime_fields_new_empty();
363 if (mime_fields == NULL)
366 content = mailmime_content_new_with_str(type);
370 mp = part_new_empty(content, mime_fields, boundary_prefix, 0);
378 mailmime_content_free(content);
380 mailmime_fields_free(mime_fields);
385 struct mailimf_field * _new_field(
387 _new_func_t new_func,
391 void *data = new_func(value);
396 struct mailimf_field * result = calloc(1, sizeof(struct mailimf_field));
398 if (result == NULL) {
403 result->fld_type = type;
404 result->fld_data.fld_return_path = data;
409 void _free_field(struct mailimf_field *field)
412 free(field->fld_data.fld_return_path);
419 _new_func_t new_func,
424 struct mailimf_field * field;
430 field = _new_field(type, new_func, value);
434 r = clist_append(list, field);
441 // http://media2.giga.de/2014/02/Image-28.jpg
443 struct mailimf_date_time * timestamp_to_etpantime(const struct tm *ts)
445 struct mailimf_date_time * result = calloc(1,
446 sizeof(struct mailimf_date_time));
453 result->dt_sec = ts->tm_sec;
454 result->dt_min = ts->tm_min;
455 result->dt_hour = ts->tm_hour;
456 result->dt_day = ts->tm_mday;
457 result->dt_month = ts->tm_mon + 1;
458 result->dt_year = ts->tm_year + 1900;
459 result->dt_zone = (int) (ts->tm_gmtoff / 36L);
464 struct tm * etpantime_to_timestamp(const struct mailimf_date_time *et)
466 struct tm * result = calloc(1, sizeof(struct tm));
473 result->tm_sec = et->dt_sec;
474 result->tm_min = et->dt_min;
475 result->tm_hour = et->dt_hour;
476 result->tm_mday = et->dt_day;
477 result->tm_mon = et->dt_month - 1;
478 result->tm_year = et->dt_year - 1900;
479 result->tm_gmtoff = 36L * (long) et->dt_zone;
484 struct mailimf_mailbox * mailbox_from_string(
489 struct mailimf_mailbox *mb = NULL;
491 char *_address = NULL;
495 _name = name ? strdup(name) : strdup("");
499 _address = strdup(address);
500 if (_address == NULL)
503 mb = mailimf_mailbox_new(_name, _address);
517 struct mailimf_field * create_optional_field(
524 struct mailimf_optional_field *optional_field = NULL;
526 _field = strdup(field);
530 _value = mailmime_encode_subject_header("utf-8", value, 0);
534 optional_field = mailimf_optional_field_new(_field, _value);
535 if (optional_field == NULL)
538 struct mailimf_field * result = calloc(1, sizeof(struct mailimf_field));
543 result->fld_type = MAILIMF_FIELD_OPTIONAL_FIELD;
544 result->fld_data.fld_optional_field = optional_field;
549 if (optional_field) {
550 mailimf_optional_field_free(optional_field);
560 int _append_optional_field(
567 struct mailimf_field * optional_field =
568 create_optional_field(field, value);
570 if (optional_field == NULL)
573 r = clist_append(list, optional_field);
575 mailimf_field_free(optional_field);