#include <libetpan/libetpan.h> enum { MAILMIME_COMPOSITE_TYPE_ERROR, MAILMIME_COMPOSITE_TYPE_MESSAGE, MAILMIME_COMPOSITE_TYPE_MULTIPART, MAILMIME_COMPOSITE_TYPE_EXTENSION }; struct mailmime_composite_type { int ct_type; char * ct_token; }; struct mailmime_composite_type * mailmime_composite_type_new(int ct_type, char * ct_token); void mailmime_composite_type_free(struct mailmime_composite_type * ct);
This is a MIME composite type such as message or multipart.
ct_type can have one of the 3 following values : MAILMIME_COMPOSITE_TYPE_MESSAGE when the composite MIME type is message, MAILMIME_COMPOSITE_TYPE_MULTIPART when the composite MIME type is multipart, MAILMIME_COMPOSITE_TYPE_EXTENSION for other and ct_token is set in this case. MAILMIME_COMPOSITE_TYPE_ERROR is used internally on parse error.
mailmime_composite_type_new() creates and initializes a data structure with a value. Structures given as argument are referenced by the created object and will be freed if the object is released.
mailmime_composite_type_free() frees memory used by the structure and substructures will also be released.
Example 4-1. create and display MIME composite type
#include <libetpan/libetpan.h> int main(void) { struct mailmime_composite_type * ct; ct = mailmime_composite_type_new(MAILMIME_COMPOSITE_TYPE_MULTIPART, NULL); /* do your things ... */ mailmime_composite_type_free(ct); exit(EXIT_SUCCESS); } void display_composite_type() { switch (ct->type) { case MAILMIME_COMPOSITE_TYPE_MESSAGE: printf("composite type is message\n"); break; case MAILMIME_COMPOSITE_TYPE_MULTIPART: printf("composite type is multipart\n"); break; case MAILMIME_COMPOSITE_TYPE_EXTENSION: printf("composite type: %s\n", ct->ct_token); break; } }
#include <libetpan/libetpan.h> struct mailmime_content { struct mailmime_type * ct_type; char * ct_subtype; clist * ct_parameters; /* elements are (struct mailmime_parameter *) */ }; struct mailmime_content * mailmime_content_new(struct mailmime_type * ct_type, char * ct_subtype, clist * ct_parameters); void mailmime_content_free(struct mailmime_content * content);
This is a MIME content type such as message/rfc822 or text/plain.
ct_type is the main MIME type, for example text in plain/text (see the Section called mailmime_type - MIME main type).
ct_subtype is the MIME subtype, for example plain in plain/text.
ct_parameters is the list of parameters for the given MIME type. For example, for plain/text, we can find charset=iso-8859-1, format=flowed. Each element of the list if of type struct mailmime_parameter * (see the Section called mailmime_parameter - MIME type parameter).
mailmime_content_new() creates and initializes a data structure with a value. Structures given as argument are referenced by the created object and will be freed if the object is released.
mailmime_content_free() frees memory used by the structure and substructures will also be released.
Example 4-2. Creation and display of MIME content type
#include <libetpan/libetpan.h> int main(void) { struct mailmime_content * content; struct mailmime_type * type; struct mailmime_discrete_type * dt; struct mailmime_parameter * param; clist * param_list; dt = mailmime_discrete_type_new(MAILMIME_DISCRETE_TYPE_TEXT, NULL); type = mailmime_type_new(MAILMIME_TYPE_DISCRETE_TYPE, dt, NUL); param_list = clist_new(); param = mailmime_parameter_new(strdup("charset"), strdup("iso-8859-1")); clist_append(param_list, param); content = mailmime_content_new(type, strdup("plain"), param_list); /* do your things */ exit(EXIT_SUCCESS); } void display_mime_content(struct mailmime_content * content_type) { clistiter * cur; printf("type:\n"); display_type(content_type->ct_type); printf("\n"); printf("subtype: %s\n", content_type->ct_subtype); printf("\n"); for(cur = clist_begin(content_type->ct_parameters) ; cur != NULL ; cur = clist_next(cur)) { struct mailmime_parameter * param; param = clist_content(cur); display_mime_parameter(param); printf("\n"); } printf("\n"); }
#include <libetpan/libetpan.h> enum { MAILMIME_DISCRETE_TYPE_ERROR, MAILMIME_DISCRETE_TYPE_TEXT, MAILMIME_DISCRETE_TYPE_IMAGE, MAILMIME_DISCRETE_TYPE_AUDIO, MAILMIME_DISCRETE_TYPE_VIDEO, MAILMIME_DISCRETE_TYPE_APPLICATION, MAILMIME_DISCRETE_TYPE_EXTENSION }; struct mailmime_discrete_type { int dt_type; char * dt_extension; }; struct mailmime_discrete_type * mailmime_discrete_type_new(int dt_type, char * dt_extension); void mailmime_discrete_type_free(struct mailmime_discrete_type * discrete_type);
This is a MIME discrete type such as text or image. This is also known as single part. This kind of part does not have any child.
dt_type is one of the given values : MAILMIME_DISCRETE_TYPE_TEXT if part is text, MAILMIME_DISCRETE_TYPE_IMAGE if part is an image, MAILMIME_DISCRETE_TYPE_AUDIO if part is audio data, MAILMIME_DISCRETE_TYPE_VIDEO if part is video, MAILMIME_DISCRETE_TYPE_APPLICATION if part is application data or MAILMIME_DISCRETE_TYPE_EXTENSION for other. In the case of MAILMIME_DISCRETE_TYPE_EXTENSION, dt_extension is filled in. MAILMIME_DISCRETE_TYPE_ERROR is used internally.
mailmime_discrete_type_new() creates and initializes a data structure with a value. Structures given as argument are referenced by the created object and will be freed if the object is released.
mailmime_discrete_type_free() frees memory used by the structure and substructures will also be released.
Example 4-3. Creation and display of MIME discrete type
#include <libetpan/libetpan.h> /* standard type */ int main(int argc, char ** argv) { struct mailmime_discrete_type * discrete_type; discrete_type = mailmime_discrete_type_new(MAILMIME_DISCRETE_TYPE_TEXT, NULL); /* do the things */ mailmime_discrete_type_free(discrete_type); } /* extension */ int main(int argc, char ** argv) { struct mailmime_discrete_type * discrete_type; discrete_type = mailmime_discrete_type_new(MAILMIME_DISCRETE_TYPE_EXTENSION, strdup("my-type")); /* do the things */ mailmime_discrete_type_free(discrete_type); } void display_mime_discrete_type(struct mailmime_discrete_type * discrete_type) { switch (discrete_type->dt_type) { case MAILMIME_DISCRETE_TYPE_TEXT: printf("text\n"); break; case MAILMIME_DISCRETE_TYPE_IMAGE: printf("image\n"); break; case MAILMIME_DISCRETE_TYPE_AUDIO: printf("audio\n"); break; case MAILMIME_DISCRETE_TYPE_VIDEO: printf("video\n"); break; case MAILMIME_DISCRETE_TYPE_APPLICATION: printf("application\n"); break; case MAILMIME_DISCRETE_TYPE_EXTENSION: printf("extension : %s\n", discrete_type->dt_extension); break; } }
#include <libetpan/libetpan.h> enum { MAILMIME_FIELD_NONE, MAILMIME_FIELD_TYPE, MAILMIME_FIELD_TRANSFER_ENCODING, MAILMIME_FIELD_ID, MAILMIME_FIELD_DESCRIPTION, MAILMIME_FIELD_VERSION, MAILMIME_FIELD_DISPOSITION, MAILMIME_FIELD_LANGUAGE, }; struct mailmime_field { int fld_type; union { struct mailmime_content * fld_content; struct mailmime_mechanism * fld_encoding; char * fld_id; char * fld_description; uint32_t fld_version; struct mailmime_disposition * fld_disposition; struct mailmime_language * fld_language; } fld_data; }; struct mailmime_field * mailmime_field_new(int fld_type, struct mailmime_content * fld_content, struct mailmime_mechanism * fld_encoding, char * fld_id, char * fld_description, uint32_t fld_version, struct mailmime_disposition * fld_disposition, struct mailmime_language * fld_language); void mailmime_field_free(struct mailmime_field * field);
This is a parsed MIME header field;
fld_type is the type of MIME header field. The value can be MAILMIME_FIELD_TYPE if field is Content-Type, MAILMIME_FIELD_TRANSFER_ENCODING if field is Content-Transfer-Encoding, MAILMIME_FIELD_ID if field is Content-ID, MAILMIME_FIELD_DESCRIPTION if field is Content-Description, MAILMIME_FIELD_VERSION if field is MIME-Version, MAILMIME_FIELD_DISPOSITION if field is Content-Disposition or MAILMIME_FIELD_LANGUAGE if field is Content-Language. MAILMIME_FIELD_NONE is used internally.
fld_data.fld_content is set in case of Content-Type. (see the Section called mailmime_content - MIME content type (Content-Type)).
fld_data.fld_encoding is set in case of Content-Transfer-Encoding. (see the Section called mailmime_mechanism - MIME transfer encoding mechanism (Content-Transfer-Encoding)).
fld_data.fld_id is set in case of Content-ID. This is a string.
fld_data.fld_description is set in case of Content-Description. This is a string.
fld_data.fld_version is set in case of MIME-Version. This is an integer built using the following formula : fld_version = major * 2^16 + minor. Currenly MIME-Version is always 1.0, this means that fld_version will always be 2^16 (in C language, this is 1 << 16).
fld_data.fld_disposition is set in case of Content-Disposition. (see the Section called mailmime_disposition - MIME disposition information (Content-Disposition)).
fld_data.fld_language is set in case of Content-Language. (see the Section called mailmime_language - Language of MIME part).
mailmime_field_new() creates and initializes a data structure with a value. Structures given as argument are referenced by the created object and will be freed if the object is released.
mailmime_field_free() frees memory used by the structure and substructures will also be released.
Example 4-4. Creation and display of MIME header field
#include <libetpan/libetpan.h> int main(int argc, char ** argv) { struct mailmime_field * field; struct mailmime_mechanism * encoding; encoding = mailmime_mechanism_new(MAILMIME_MECHANISM_BASE64, NULL); field = mailmime_field_new(MAILMIME_FIELD_TRANSFER_ENCODING, NULL, encoding, NULL, NULL, 0, NULL, NULL); /* do the things */ mailmime_field_free(field); } void display_mime_field(struct mailmime_field * field) { switch (field->fld_type) { case MAILMIME_FIELD_TYPE: printf("content-type:"); display_mime_content(field->fld_data.fld_content); break; case MAILMIME_FIELD_TRANSFER_ENCODING: printf("content-transfer-encoding:"); display_mime_mechanism(field->fld_data.fld_encoding); break; case MAILMIME_FIELD_ID: printf("content-id: %s\n", field->fld_data.fld_id); break; case MAILMIME_FIELD_DESCRIPTION: printf("content-description: %s\n", field->fld_data.fld_description); break; case MAILMIME_FIELD_VERSION: printf("mime-version: %i.%i\n", field->version>> 16, field->fld_data.fld_version & 0xFFFF); break; case MAILMIME_FIELD_DISPOSITION: printf("content-disposition:"); display_mime_disposition(field->fld_data.fld_disposition); break; case MAILMIME_FIELD_LANGUAGE: printf("content-language:"); display_mime_language(field->fld_data.fld_language); break; } }
#include <libetpan/libetpan.h> enum { MAILMIME_MECHANISM_ERROR, MAILMIME_MECHANISM_7BIT, MAILMIME_MECHANISM_8BIT, MAILMIME_MECHANISM_BINARY, MAILMIME_MECHANISM_QUOTED_PRINTABLE, MAILMIME_MECHANISM_BASE64, MAILMIME_MECHANISM_TOKEN }; struct mailmime_mechanism { int enc_type; char * enc_token; }; struct mailmime_mechanism * mailmime_mechanism_new(int enc_type, char * enc_token); void mailmime_mechanism_free(struct mailmime_mechanism * mechanism);
This is a MIME transfer encoding mechanism description.
enc_type is an encoding type. The value of this field can be MAILMIME_MECHANISM_7BIT if mechanism is 7bit, MAILMIME_MECHANISM_8BIT if mechanism is 8bit, MAILMIME_MECHANISM_BINARY if mechanism is binary, MAILMIME_MECHANISM_QUOTED_PRINTABLE if mechanism is quoted-printable, MAILMIME_MECHANISM_BASE64 if mechanism is base64 or MAILMIME_MECHANISM_TOKEN for other. In case of MAILMIME_MECHANISM_TOKEN, field enc_token is filled in. MAILMIME_MECHANISM_ERROR is used internally.
mailmime_mechanism_new() creates and initializes a data structure with a value. Structures given as argument are referenced by the created object and will be freed if the object is released.
mailmime_mechanism_free() frees memory used by the structure and substructures will also be released.
Example 4-5. Creation and display of MIME transfer encoding mechanism
#include <libetpan/libetpan.h> int main(int argc, char ** argv) { struct mailmime_mechanism * encoding; encoding = mailmime_mechanism_new(MAILMIME_MECHANISM_QUOTED_PRINTABLE, NULL); /* do the things */ mailmime_mechanism_free(encoding); } int main(int argc, char ** argv) { struct mailmime_mechanism * encoding; encoding = mailmime_mechanism_new(MAILMIME_MECHANISM_TOKEN, strdup("uuencoding")); /* do the things */ mailmime_mechanism_free(encoding); } void display_mime_mechanism(struct mailmime_mechanism * encoding) { switch (encoding->enc_type) { case MAILMIME_MECHANISM_7BIT: printf("7bit\n"); break; case MAILMIME_MECHANISM_8BIT: printf("8bit\n"); break; case MAILMIME_MECHANISM_BINARY: printf("binary\n"); break; case MAILMIME_MECHANISM_QUOTED_PRINTABLE: printf("quoted-printable\n"); break; case MAILMIME_MECHANISM_BASE64: printf("base64\n"); break; case MAILMIME_MECHANISM_TOKEN: printf("extension : %s\n", encoding->enc_token); break; } }
#include <libetpan/libetpan.h> struct mailmime_fields { clist * fld_list; /* list of (struct mailmime_field *) */ }; struct mailmime_fields * mailmime_fields_new(clist * fld_list); void mailmime_fields_free(struct mailmime_fields * fields);
This is the header fields of a MIME part.
fld_list is the list of the header fields. Each element of the list is a mailmime_field (See the Section called mailmime_field - MIME header field).
mailmime_fields_new() creates and initializes a data structure with a value. Structures given as argument are referenced by the created object and will be freed if the object is released.
mailmime_fields_free() frees memory used by the structure and substructures will also be released.
Example 4-6. Creation and display of MIME fields
#include <libetpan/libetpan.h> int main(int argc, char ** argv) { struct mailmime_field * field; struct mailmime_fields * fields; clist * list; struct mailmime_mechanism * encoding; struct mailmime_disposition * disposition; list = clist_new(); encoding = mailmime_mechanism_new(MAILMIME_MECHANISM_BASE64, NULL); field = mailmime_field_new(MAILMIME_FIELD_TRANSFER_ENCODING, NULL, encoding, NULL, NULL, 0, NULL, NULL); clist_append(list, field); field = mailmime_field_new(MAILMIME_FIELD_VERSION, NULL, NULL, NULL, NULL, 1 << 16, NULL, NULL); clist_append(list, field); /* look at the example in mailmime_disposition to see how to build a mailmime_disposition */ disposition = build_mime_disposition(); field = mailmime_field_new(MAILMIME_FIELD_DISPOSITION, NULL, NULL, NULL, NULL, 0, disposition, NULL); clist_append(list, field); fields = mailmime_fields_new(list); /* do the things */ mailmime_fields_free(fields); } void display_mime_fields(struct mailmime_fields * fields) { clistiter * cur; for(cur = clist_begin(fields->fld_list ; cur != NULL ; cur = clist_next(cur)) { struct mailmime_field * field; field = clist_content(cur); display_field(field); } }
struct mailmime_parameter { char * pa_name; char * pa_value; };
This is the MIME type parameter in Content-Type MIME header field. For example, this can be charset="iso-8859-1".
pa_name is the name of the parameter, for example : charset.
pa_value is the value of the parameter, for example : iso-8859-1.
mailmime_parameter_new() creates and initializes a data structure with a value. Structures given as argument are referenced by the created object and will be freed if the object is released.
mailmime_parameter_free() frees memory used by the structure and substructures will also be released.
Example 4-7. Creation and display of MIME type parameter
#include <libetpan/libetpan.h> int main(int argc, char ** argv) { struct mailmime_parameter * param; param = mailmime_parameter_new(strdup("charset"), strdup("iso-8859-1")); /* do the things */ mailmime_parameter_free(param); } void display_mime_parameter(struct mailmime_parameter * param) { printf("%s = %s\n", param->pa_name, param->pa_value); }
#include <libetpan/libetpan.h> enum { MAILMIME_TYPE_ERROR, MAILMIME_TYPE_DISCRETE_TYPE, MAILMIME_TYPE_COMPOSITE_TYPE }; struct mailmime_type { int tp_type; union { struct mailmime_discrete_type * tp_discrete_type; struct mailmime_composite_type * tp_composite_type; } tp_data; }; struct mailmime_type * mailmime_type_new(int tp_type, struct mailmime_discrete_type * tp_discrete_type, struct mailmime_composite_type * tp_composite_type); void mailmime_type_free(struct mailmime_type * type);
This is the MIME main type (no subtype, no parameter).
tp_type. The value of this field is either MAILMIME_TYPE_DISCRETE_TYPE for MIME discrete type, or MAILMIME_TYPE_COMPOSITE_TYPE for MIME composite type. MAILMIME_TYPE_ERROR is used internally.
tp_data.tp_discrete_type is set when tp_type is MAILMIME_TYPE_DISCRETE_TYPE (see the Section called mailmime_discrete_type - MIME discrete type).
tp_data.tp_composite_type is set when tp_type is MAILMIME_TYPE_COMPOSITE_TYPE (see the Section called mailmime_composite_type - Composite MIME type).
mailmime_discrete_type_new() creates and initializes a data structure with a value. Structures given as argument are referenced by the created object and will be freed if the object is released.
mailmime_discrete_type_free() frees memory used by the structure and substructures will also be released.
Example 4-8. Creation and display of MIME main type
#include <libetpan/libetpan.h> int main(int argc, char ** argv) { struct mailmime_type * type; struct mailmime_discrete_type * discrete_type; discrete_type = mailmime_discrete_type_new(MAILMIME_DISCRETE_TYPE_TEXT, NULL); type = mailmime_type_new(MAILMIME_TYPE_DISCRETE_TYPE, discrete_type, NULL); /* do the things */ mailmime_type_free(type); } int main(int argc, char ** argv) { struct mailmime_type * type; struct mailmime_composite_type * composite_type; composite_type = mailmime_composite_type_new(MAILMIME_COMPOSITE_TYPE_MULTIPART, NULL); type = mailmime_type_new(MAILMIME_TYPE_COMPOSITE_TYPE, NULL, composite_type); /* do the things */ mailmime_type_free(type); } void display_mime_type(struct mailmime_type * type) { printf("mime type:\n"); switch (type->tp_type) { case MAILMIME_TYPE_DISCRETE_TYPE: printf("discrete type:\n"); display_mime_discrete_type(type->tp_data.tp_discrete_type); break; case MAILMIME_TYPE_COMPOSITE_TYPE: printf("composite type:\n"); display_mime_composite_type(type->tp_data.tp_composite_type); break; } printf("\n"); }
#include <libetpan/libetpan.h> struct mailmime_language { clist * lg_list; /* atom (char *) */ }; struct mailmime_language * mailmime_language_new(clist * lg_list); void mailmime_language_free(struct mailmime_language * lang);
This is the language used in the MIME part.
lg_list is the list of codes of languages used in the MIME part. This is a list of strings.
mailmime_language_new() creates and initializes a data structure with a value. Structures given as argument are referenced by the created object and will be freed if the object is released.
mailmime_language_free() frees memory used by the structure and substructures will also be released.
Example 4-9. Creation and display of language of MIME part
#include <libetpan/libetpan.h> int main(int argc, char ** argv) { struct mailmime_language * language; clist * list; list = clist_new(); clist_append(list, strdup("fr")); clist_append(list, strdup("en")); language = mailmime_language_new(list); /* do the things */ mailmime_language_free(language); } void display_mime_language(struct mailmime_language * language) { clistiter * cur; printf("languages: "); for(cur = clist_begin(language->lg_list) ; cur != NULL ; cur = clist_next(cur)) { char * name; name = clist_content(cur); printf("%s ", name); } printf("\n"); }
#include <libetpan/libetpan.h> enum { MAILMIME_DATA_TEXT, MAILMIME_DATA_FILE, }; enum { MAILMIME_MECHANISM_ERROR, MAILMIME_MECHANISM_7BIT, MAILMIME_MECHANISM_8BIT, MAILMIME_MECHANISM_BINARY, MAILMIME_MECHANISM_QUOTED_PRINTABLE, MAILMIME_MECHANISM_BASE64, MAILMIME_MECHANISM_TOKEN }; struct mailmime_data { int dt_type; int dt_encoding; int dt_encoded; union { struct { const char * dt_data; size_t dt_length; } dt_text; char * dt_filename; } dt_data; }; struct mailmime_data * mailmime_data_new(int dt_type, int dt_encoding, int dt_encoded, const char * dt_data, size_t dt_length, char * dt_filename); void mailmime_data_free(struct mailmime_data * mime_
This is the content of MIME part, content of preamble or content of epilogue.
dt_type can be MAILMIME_DATA_TEXT if the content is a string in memory, MAILMIME_DATA_FILE if the content is in a file,
dt_encoding is the encoding mechanism of the part. The value of this field can be MAILMIME_MECHANISM_7BIT if mechanism is 7bit, MAILMIME_MECHANISM_8BIT if mechanism is 8bit, MAILMIME_MECHANISM_BINARY if mechanism is binary, MAILMIME_MECHANISM_QUOTED_PRINTABLE if mechanism is quoted-printable, MAILMIME_MECHANISM_BASE64 if mechanism is base64 or MAILMIME_MECHANISM_TOKEN for other. If MAILMIME_MECHANISM_TOKEN, the part will be considered as binary. MAILMIME_MECHANISM_ERROR is used internally.
dt_encoded is set to 1 if the part is already encoded with the mechanism given in dt_encoding. It is set to 0 if the part is already decoded or if it is necessary to encode that part before rendering it.
dt_data.dt_text.dt_data is a pointer to the content of the part and dt_data.dt_text.dt_length is the length of the data if dt_type is MAILMIME_DATA_TEXT.
dt_data.dt_filename is the name of the file if dt_type is MAILMIME_DATA_FILE.
mailmime_data_new() creates and initializes a data structure with a value. Structures given as argument are referenced by the created object and will be freed if the object is released.
mailmime_data_free() frees memory used by the structure and substructures will also be released.
Example 4-10. Creation and display of MIME part content
#include <libetpan/libetpan.h> /* build data with a string */ int main(int argc, char ** argv) { struct mailmime_data * data; data = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_BASE64, 0, "foo bar", 7, NULL); /* do the things */ mailmime_data_free(data); } /* build data with a file */ int main(int argc, char ** argv) { struct mailmime_data * data; data = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_BASE64, 0, NULL, 0, strdup("foo.txt")); /* do the things */ mailmime_data_free(data); } void display_mime_data(struct mailmime_data * data) { switch (data->dt_encoding) { case MAILMIME_MECHANISM_7BIT: printf("7bit\n"); break; case MAILMIME_MECHANISM_8BIT: printf("8bit\n"); break; case MAILMIME_MECHANISM_BINARY: printf("binary\n"); break; case MAILMIME_MECHANISM_QUOTED_PRINTABLE: printf("quoted-printable\n"); break; case MAILMIME_MECHANISM_BASE64: printf("base64\n"); break; case MAILMIME_MECHANISM_TOKEN: printf("other\n"); break; } if (data->dt_encoded) printf("already encoded\n"); else printf("not encoded\n"); switch (data->dt_type) { MAILMIME_DATA_TEXT: printf("data : %p %i\n", data->dt_data.dt_text.dt_data, data->dt_data.dt_text.dt_length); break; MAILMIME_DATA_FILE, printf("data (file) : %s\n", data->dt_data.dt_filename); break; } }
#include <libetpan/libetpan.h> enum { MAILMIME_NONE, MAILMIME_SINGLE, MAILMIME_MULTIPLE, MAILMIME_MESSAGE, }; struct mailmime { /* parent information */ int mm_parent_type; struct mailmime * mm_parent; clistiter * mm_multipart_pos; int mm_type; const char * mm_mime_start; size_t mm_length; struct mailmime_fields * mm_mime_fields; struct mailmime_content * mm_content_type; struct mailmime_data * mm_body; union { /* single part */ struct mailmime_data * mm_single; /* XXX - was body */ /* multi-part */ struct { struct mailmime_data * mm_preamble; struct mailmime_data * mm_epilogue; clist * mm_mp_list; } mm_multipart; /* message */ struct { struct mailimf_fields * mm_fields; struct mailmime * mm_msg_mime; } mm_message; } mm_data; }; struct mailmime * mailmime_new(int mm_type, const char * mm_mime_start, size_t mm_length, struct mailmime_fields * mm_mime_fields, struct mailmime_content * mm_content_type, struct mailmime_data * mm_body, struct mailmime_data * mm_preamble, struct mailmime_data * mm_epilogue, clist * mm_mp_list, struct mailimf_fields * mm_fields, struct mailmime * mm_msg_mime); void mailmime_free(struct mailmime * mime);
This describes the MIME structure of a message or a subpart of a message.
mm_parent_type. MIME part type can be single part, multipart or message part. This describes the MIME part type of the parent. The value can be MAILMIME_NONE if there is no parent part, MAILMIME_SINGLE if parent is a single part, MAILMIME_MULTIPLE if parent is a multipart, MAILMIME_MESSAGE if parent is a mesage part.
mm_parent is the parent MIME structure.
mm_multipart_pos. In the case the parent is a multipart. This is the position in the list of children of the parent. This position is given by a clisiter *.
mm_type. This describes the MIME part type of this part. The value can be MAILMIME_SINGLE if this is a single part, MAILMIME_MULTIPLE if this is a multipart, MAILMIME_MESSAGE if this is a mesage part.
mm_mime_start. This is used mostly internally. This gives the beginning of the header of the MIME part, when this is parsed from a string in memory.
mm_length. This gives the length of the MIME part, including the MIME header fields.
mm_mime_fields is the list of parsed MIME headers of this part. Content-Type must be excluded and stored in mm_content_type instead (see the Section called mailmime_fields - header fields).
mm_content_type is the parsed Content-Type field (see the Section called mailmime_content - MIME content type (Content-Type)).
mm_body is the content of the MIME part (excluding MIME header), when it is parsed from a string in memory (see the Section called mailmime_data - Content of MIME part).
When the part is a single part (mm_type is MAILMIME_SINGLE). The following fields are valid.
mm_data.mm_single is the content of the MIME part (excluding MIME header), when it is parsed from a string in memory. This must have the same value as mm_body when it is set (see the Section called mailmime_data - Content of MIME part).
When the part is a multipart (mm_type is MAILMIME_MULTIPLE). The following fields are valid.
mm_data.mm_multipart.mm_preamble is the content of the preamble of the multipart (see the Section called mailmime_data - Content of MIME part).
mm_data.mm_multipart.mm_epilogue is the content of the epilogue of the multipart (see the Section called mailmime_data - Content of MIME part).
mm_data.mm_multipart.mm_mp_list is the list of sub parts
When the part is a message (mm_type is MAILMIME_MESSAGE). The following fields are valid.
mm_data.mm_message.mm_fields is the list of the header fields of the message (see the Section called mailimf_fields - list of header fields in Chapter 3).
mm_data.mm_message.mm_msg_mime is the subpart of the message part.
mailmime_new() creates and initializes a data structure with a value. Structures given as argument are referenced by the created object and will be freed if the object is released.
mailmime_free() frees memory used by the structure and substructures will also be released.
Example 4-11. Creation and display of MIME part
#include <libetpan/libetpan.h> /* build one single MIME part */ int main(int argc, char ** argv) { struct mailmime * mime; struct mailimf_fields * fields; struct mailmime_fields * mime_fields; struct mailmime_content * content_type; struct mailmime_data * body; /* look at the example in mailimf_fields to see how to build a mailimf_fields */ fields = build_fields(); /* look at the example in mailmime_fields to see how to build a mailmime_fields */ mime_fields = build_mime_fields(); /* look at the example in mailmime_content to see how to build a mailmime_content */ content_type = build_mime_content(); body = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_8BIT, 0, "foo", 3, NULL); mime = mailmime_new(MAILMIME_SINGLE, NULL, 0, fields, mime_fields, content_type, body, NULL, NULL, NULL, NULL, NULL); /* do the things */ mailmime_free(mime); } /* build one single MIME part */ int main(int argc, char ** argv) { struct mailmime * mime; struct mailimf_fields * fields; struct mailmime_fields * mime_fields; struct mailmime_content * content_type; char * str; struct mailmime_data * body; /* look at the example in mailimf_fields to see how to build a mailimf_fields */ fields = build_fields(); /* look at the example in mailmime_fields to see how to build a mailmime_fields */ mime_fields = build_mime_fields(); /* look at the example in mailmime_content to see how to build a mailmime_content */ content_type = build_mime_content(); str = malloc(4); strcpy(str, "foo"); body = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_8BIT, 0, str, 3, NULL); mime = mailmime_new(MAILMIME_SINGLE, NULL, 0, fields, mime_fields, content_type, body, NULL, NULL, NULL, NULL, NULL); /* do the things */ mailmime_free(mime); free(str); } /* build a MIME part with a sub-message */ int main(int argc, char ** argv) { struct mailmime * mime; struct mailimf_fields * fields; struct mailmime_fields * mime_fields; struct mailmime_content * content_type; char * str; struct mailmime_type * type; struct mailmime_composite_type * composite_type; /* look at the example in mailimf_fields to see how to build a mailimf_fields */ fields = build_fields(); /* look at the example in mailmime_fields to see how to build a mailmime_fields */ mime_fields = build_mime_fields(); composite_type = mailmime_composite_type_new(MAILMIME_COMPOSITE_TYPE_MESSAGE, NULL); type = mailmime_type_new(MAILMIME_TYPE_COMPOSITE_TYPE, NULL, composite_type); content_type = mailmime_content_new(type, strdup("rfc2822"), NULL); /* build_mime_message() is a function that will build a mime message part */ sub_mime = build_mime_message(); mime = mailmime_new(MAILMIME_MESSAGE, NULL, 0, fields, mime_fields, content_type, NULL, NULL, NULL, NULL, sub_mime, NULL); /* do the things */ mailmime_free(mime); } /* build a MIME part with a sub-message (given by a string) */ int main(int argc, char ** argv) { struct mailmime * mime; struct mailimf_fields * fields; struct mailmime_fields * mime_fields; struct mailmime_content * content_type; char * str; struct mailmime_data * msg_content; struct mailmime_type * type; struct mailmime_composite_type * composite_type; /* look at the example in mailimf_fields to see how to build a mailimf_fields */ fields = build_fields(); /* look at the example in mailmime_fields to see how to build a mailmime_fields */ mime_fields = build_mime_fields(); composite_type = mailmime_composite_type_new(MAILMIME_COMPOSITE_TYPE_MESSAGE, NULL); type = mailmime_type_new(MAILMIME_TYPE_COMPOSITE_TYPE, NULL, composite_type); content_type = mailmime_content_new(type, strdup("rfc2822"), NULL); str = malloc(sizeof(SUB_MESSAGE)); strcpy(str, SUB_MESSAGE); msg_content = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_8BIT, 0, str, sizeof(SUB_MESSAGE), NULL); mime = mailmime_new(MAILMIME_MESSAGE, NULL, 0, fields, mime_fields, content_type, NULL, NULL, NULL, NULL, NULL, msg_content); /* do the things */ mailmime_free(mime); free(str); } /* build a multipart message */ int main(int argc, char ** argv) { struct mailmime * mime; struct mailimf_fields * fields; struct mailmime_fields * mime_fields; struct mailmime_content * content_type; struct mailmime_type * type; struct mailmime_composite_type * composite_type; struct mailmime_data * body; struct mailmime_data * preamble; struct mailmime_data * epilogue; clist * list; /* look at the example in mailimf_fields to see how to build a mailimf_fields */ fields = build_fields(); /* look at the example in mailmime_fields to see how to build a mailmime_fields */ mime_fields = build_mime_fields(); composite_type = mailmime_composite_type_new(MAILMIME_COMPOSITE_TYPE_MULTIPART, NULL); type = mailmime_type_new(MAILMIME_TYPE_COMPOSITE_TYPE, NULL, composite_type); content_type = mailmime_content_new(type, strdup("mixed"), NULL); list = clist_new(); /* build_mime_message() is a function that will build a mime message part */ sub_mime = build_mime_message(); clist_append(list, sub_mime); sub_mime = build_mime_message(); clist_append(list, sub_mime); preamble = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_8BIT, 0, PREAMBLE, sizeof(PREAMBLE), NULL); epilogue = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_8BIT, 0, EPILOGUE, sizeof(EPILOGUE), NULL); mime = mailmime_new(MAILMIME_SINGLE, NULL, 0, fields, mime_fields, content_type, NULL, preamble, epilogue, list, NULL, NULL); /* do the things */ mailmime_free(mime); } /* display mime part info */ void display_mime(struct mailmime * mime) { clistiter * cur; switch (mime->mm_type) { case MAILMIME_SINGLE: printf("single part\n"); break; case MAILMIME_MULTIPLE: printf("multipart\n"); break; case MAILMIME_MESSAGE: printf("message\n"); break; } printf("part : %p, length : %i\n", mime->mm_mime_start, mime->mm_length); printf("\n"); if (mime->mm_mime_fields != NULL) { printf("MIME headers :\n"); display_mime_fields(mime->mm_mime_fields); printf("\n"); } printf("content type :\n"); display_content(mime->mm_content_type); printf("\n"); switch (mime->mm_type) { case MAILMIME_SINGLE: display_mime_data(mime->mm_data.mm_single); break; case MAILMIME_MULTIPLE: if (mime->mm_data.mm_multipart.mm_preamble) { printf("preamble :\n"); display_mime_data(mime->mm_data.mm_multipart.mm_preamble); printf("\n"); } for(cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) { display_mime(clist_content(cur)); } if (mime->mm_data.mm_multipart.mm_epilogue) { printf("epilogue :\n"); display_mime_data(mime->mm_data.mm_multipart.mm_epilogue); printf("\n"); } break; case MAILMIME_MESSAGE: if (mime->mm_data.mm_message.mm_fields) { printf("headers :\n"); display_field(mime->mm_data.mm_message.mm_msg_fields); printf("\n"); if (mime->mm_data.mm_message.mm_msg_mime != NULL) { printf("sub message %p :\n", mime->mm_data.mm_message.mm_msg_mime); display_mime(mime->mm_data.mm_message.mm_msg_mime); printf("end of sub message %p\n", mime->mm_data.mm_message.mm_msg_mime); } break; } }
#include <libetpan/libetpan.h> struct mailmime_disposition { struct mailmime_disposition_type * dsp_type; clist * dsp_parms; /* struct mailmime_disposition_parm */ };
This is the parsed Content-Disposition header field.
dsp_type is the type of disposition (see the Section called mailmime_disposition_type - Type of MIME disposition).
dsp_parms is the list of parameters of Content-Disposition header field. Each element is of type mailmime_disposition_parm (see the Section called mailmime_disposition_parm - MIME disposition parameter).
Example 4-12. Creation and display of MIME disposition information
#include <libetpan/libetpan.h> int main(int argc, char ** argv) { struct mailmime_disposition * disposition; struct mailmime_disposition_type * disposition_type; clist * disposition_parms; struct mailmime_disposition_parm * param; disposition_type = mailmime_disposition_type_new(MAILMIME_DISPOSITION_TYPE_ATTACHMENT, NULL); disposition_parms = clist_new(); param = mailmime_disposition_parm_new(MAILMIME_DISPOSITION_PARM_FILENAME, strdup("foo.txt"), NULL, NULL, NULL, -1, NULL); clist_append(disposition_parms, param); disposition = mailmime_disposition_new(disposition_type, disposition_parms); /* do the things */ mailmime_disposition_free(disposition); } void display_mime_disposition(struct mailmime_disposition * disposition) { clistiter * cur; printf("disposition type:\n"); display_mailmime_disposition_type(disposition->dsp_type); printf("\n"); printf("disposition parameters:\n"); for(cur = clist_begin(disposition->dsp_parms) ; cur != NULL ; cur = clist_next(cur)) { struct mailmime_parm * param; param = clist_content(cur); display_mime_disposition_parm(param); } printf("\n"); }
#include <libetpan/libetpan.h> enum { MAILMIME_DISPOSITION_TYPE_ERROR, MAILMIME_DISPOSITION_TYPE_INLINE, MAILMIME_DISPOSITION_TYPE_ATTACHMENT, MAILMIME_DISPOSITION_TYPE_EXTENSION }; struct mailmime_disposition_type { int dsp_type; char * dsp_extension; };
This is the type of MIME disposition. Parsed Content-Disposition field without parameters.
dsp_type is the type of disposition. The value can be MAILMIME_DISPOSITION_TYPE_INLINE if MIME disposition is inline, MAILMIME_DISPOSITION_TYPE_ATTACHMENT if MIME disposition is attachment, MAILMIME_DISPOSITION_TYPE_EXTENSION for other. In this case, dsp_extension must be set. MAILMIME_DISPOSITION_TYPE_ERROR is used internally.
Example 4-13. Creation and display of MIME disposition type
#include <libetpan/libetpan.h> /* standard disposition type */ int main(int argc, char ** argv) { struct mailmime_disposition_type * disposition_type; disposition_type = mailmime_disposition_type_new(MAILMIME_DISPOSITION_TYPE_ATTACHMENT, NULL); /* do the things */ mailmime_disposition_type_free(disposition_type); } /* disposition type extension */ int main(int argc, char ** argv) { struct mailmime_disposition_type * disposition_type; disposition_type = mailmime_disposition_type_new(MAILMIME_DISPOSITION_TYPE_EXTENSION, strdup("mydisposition")); /* do the things */ mailmime_disposition_type_free(disposition_type); } void display_mime_disposition_type(struct mailmime_disposition_type * disposition_type) { switch (disposition->dsp_type) { case MAILMIME_DISPOSITION_TYPE_INLINE: printf("inline\n"); break; case MAILMIME_DISPOSITION_TYPE_ATTACHMENT: printf("attachment\n"); break; case MAILMIME_DISPOSITION_TYPE_EXTENSION: printf("extension : %s\n", disposition_type->dsp_extension); break; } }
#include <libetpan/libetpan.h> enum { MAILMIME_DISPOSITION_PARM_FILENAME, MAILMIME_DISPOSITION_PARM_CREATION_DATE, MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE, MAILMIME_DISPOSITION_PARM_READ_DATE, MAILMIME_DISPOSITION_PARM_SIZE, MAILMIME_DISPOSITION_PARM_PARAMETER }; struct mailmime_disposition_parm { int pa_type; union { char * pa_filename; char * pa_creation_date; char * pa_modification_date; char * pa_read_date; size_t pa_size; struct mailmime_parameter * pa_parameter; } pa_data; };
This is a parameter of MIME disposition information. For example, this can be filename="foo.jpg".
pa_type is the type of disposition. The value can be MAILMIME_DISPOSITION_PARM_FILENAME for a filename parameter, MAILMIME_DISPOSITION_PARM_CREATION_DATE for a creation date parameter, MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE for a modification date parameter, MAILMIME_DISPOSITION_PARM_READ_DATE for a last read date parameter, MAILMIME_DISPOSITION_PARM_SIZE for a file size parameter or MAILMIME_DISPOSITION_PARM_PARAMETER for other parameters.
pa_data.pa_filename is the filename parameter when pa_type is MAILMIME_DISPOSITION_PARM_FILENAME This is a string containing the name of the file.
pa_data.pa_creation_date is the creation date parameter when pa_type is MAILMIME_DISPOSITION_PARM_CREATION_DATE. This is a string containing the formatted creation date.
pa_data.pa_modification_date is the modification date parameter when pa_type is MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE. This is a string containing the formatted modification date.
pa_data.pa_read_date is the last read date parameter when pa_type is MAILMIME_DISPOSITION_PARM_READ_DATE. This is a string containing the formatted last read date.
pa_data.pa_size is the size parameter when pa_type is MAILMIME_DISPOSITION_PARM_SIZE. This gives the size of the file.
pa_data.pa_parameter is the name and the value of the parameter when pa_type is MAILMIME_DISPOSITION_PARM_PARAMETER (see the Section called mailmime_parameter - MIME type parameter)
Example 4-14. Creation and display of MIME disposition parameter
int main(int argc, char ** argv) { struct mailmime_disposition_parm * param; disposition_parms = clist_new(); param = mailmime_disposition_parm_new(MAILMIME_DISPOSITION_PARM_FILENAME, strdup("foo.txt"), NULL, NULL, NULL, -1, NULL); /* do the things */ mailmime_disposition_parm_free(param); } void display_mime_dsp_parm(struct mailmime_disposition_parm * param) { switch (param->pa_type) { case MAILMIME_DISPOSITION_PARM_FILENAME: printf("filename: %s\n", param->pa_data.pa_filename); break; case MAILMIME_DISPOSITION_PARM_CREATION_DATE: printf("creation date: %s\n", param->pa_data.pa_creation_date); break; case MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE: printf("modification date: %s\n", param->pa_data.pa_modification_date); break; case MAILMIME_DISPOSITION_PARM_READ_DATE: printf("read date: %s\n", param->pa_data.pa_read_date); break; case MAILMIME_DISPOSITION_PARM_SIZE: printf("size: %lu\n", (unsigned long) param->pa_data.pa_size); break; case MAILMIME_DISPOSITION_PARM_PARAMETER: printf("MIME disposition param:\n"); display_mime_parameter(param->pa_data.pa_parameter); break; } }
#include <libetpan/libetpan.h> struct mailmime_single_fields { struct mailmime_content * fld_content; char * fld_content_charset; char * fld_content_boundary; char * fld_content_name; struct mailmime_mechanism * fld_encoding; char * fld_id; char * fld_description; uint32_t fld_version; struct mailmime_disposition * fld_disposition; char * fld_disposition_filename; char * fld_disposition_creation_date; char * fld_disposition_modification_date; char * fld_disposition_read_date; size_t fld_disposition_size; struct mailmime_language * fld_language; }; struct mailmime_single_fields * mailmime_single_fields_new(struct mailmime_fields * fld_fields, struct mailmime_content * fld_content); void mailmime_single_fields_free(struct mailmime_single_fields * single_fields); void mailmime_single_fields_init(struct mailmime_single_fields * single_fields, struct mailmime_fields * fld_fields, struct mailmime_content * fld_content);
mailmime_fields (see the Section called mailmime_fields - header fields) is the native structure that MIME module will use, this module will provide an easier structure to use when parsing fields. mailmime_single_fields is an easier structure to get parsed fields, rather than iteration over the list of fields.
fld_content is the MIME content type (see the Section called mailmime_content - MIME content type (Content-Type)).
fld_content_charset is the value of the MIME type parameter charset.
fld_content_boundary is the value of the MIME type parameter boundary.
fld_content_name is the value of the MIME type parameter name.
fld_encoding is the MIME encoding mechanism used (see the Section called mailmime_mechanism - MIME transfer encoding mechanism (Content-Transfer-Encoding)).
fld_id is the content of the field Content-ID.
fld_description is the content of the field Content-Description.
fld_version is the version of MIME in use.
fld_disposition is the MIME disposition information (see the Section called mailmime_disposition - MIME disposition information (Content-Disposition)).
fld_disposition_filename is the filename parameter of the MIME disposition information.
fld_disposition_creation_date is the creation-date parameter of the MIME disposition information.
fld_disposition_modification_date is the modification-date parameter of the MIME disposition information.
fld_disposition_read_date is the read-date parameter of the MIME disposition information.
fld_disposition_size is the size parameter of the MIME disposition information.
fld_language is the language of the MIME part (see the Section called mailmime_language - Language of MIME part).
single_fields is the structure to fill.
fld_fields is the MIME fields list to use to fill the single_fields.
mailmime_single_fields_new() creates and initializes a data structure with a value. Structures given as argument are referenced by the created object and will NOT be freed if the object is released.
mailmime_single_fields_free() frees memory used by the structure and substructures will NOT be released. They should be released by the application.
mailimf_single_fields_init() will initialize fill the data structure, using the given argument (fld_fields and fld_content). The interesting fields will be filled into single_fields.
Example 4-15. Creation and display of single fields
#include <libetpan/libetpan.h> int main(int argc, char ** argv) { struct mailmime_single_fields * single_fields; struct mailmime_fields * mime_fields; struct mailmime_content * content_type; /* look at the example in mailmime_fields to see how to build a mailmime_fields */ mime_fields = build_mime_fields(); /* look at the example in mailmime_content to see how to build a mailmime_content */ content_type = build_mime_content(); single_fields = mailmime_single_fields_new(mime_fields, content_type); /* do the things */ mailmime_single_fields_free(single_fields); mailmime_fields_free(mime_fields); } void display_mime_single_fields(struct mailmime_single_fields * single_fields) { if (single_fields->fld_content != NULL) { printf("content type:\n"); display_mime_content(single_fields->fld_content); printf("\n"); } if (single_fields->fld_content_charset != NULL) { printf("content type charset: %s\n", single_fields->fld_content_charset); printf("\n"); } if (single_fields->fld_content_boundary != NULL) { printf("content type boundary: %s\n", single_fields->fld_content_boundary); printf("\n"); } if (single_fields->content_name != NULL) { printf("content type name: %s\n", single_fields->content_name); printf("\n"); } if (single_fields->fld_encoding != NULL) { printf("content transfer encoding:\n"); display_mime_mechanism(single_fields->fld_encoding); printf("\n"); } if (single_fields->fld_id != NULL) { printf("content id: %s\n", single_fields->fld_id); printf("\n"); } if (single_fields->fld_description != NULL) { printf("content description: %s\n", single_fields->fld_description); printf("\n"); } if (single_fields->fld_version != 0) { printf("mime version: %i.%i\n", single_fields->fld_version>> 16, single_fields->fld_version & 0xFFFF); printf("\n"); } if (single_fields->fld_disposition != NULL) { printf("content disposition:\n"); display_mime_disposition(single_fields->fld_disposition); printf("\n"); } if (single_fields->fld_disposition_filename != NULL) { printf("content disposition filename: %s\n", single_fields->fld_disposition_filename); printf("\n"); } if (single_fields->fld_disposition_creation_date != NULL) { printf("content disposition creation date: %s\n", single_fields->fld_disposition_creation_date); printf("\n"); } if (single_fields->fld_disposition_modification_date != NULL) { printf("content disposition modification date: %s\n", single_fields->fld_disposition_modification_date); printf("\n"); } if (single_fields->fld_disposition_read_date != NULL) { printf("content disposition read date: %s\n", single_fields->fld_disposition_read_date; printf("\n"); } if (single_fields->fld_disposition_size != (size_t) -1) { printf("content disposition size : %i\n", single_fields->fld_disposition_size); printf("\n"); } if (single_fields->language != NULL) { printf("content language:\n"); display_mime_language(single_fields->fld_language); printf("\n"); } }