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"); } }
#include <libetpan/libetpan.h> int mailmime_content_parse(const char * message, size_t length, size_t * index, struct mailmime_content ** result);
This function will parse the content of a Content-Type header field.
message is a string containing the MIME content type.
length is the size of the given string.
index is a pointer to the start of the address in the given string, (* index) is modified to point at the end of the parsed data.
result. The result of the parse operation is stored in (* result) (see the Section called mailmime_content - MIME content type (Content-Type)).
Example 4-16. Parsing MIME content type
#include <libetpan/libetpan.h> #include <sys/stat.h> #include <sys/mman.h> int main(int argc, char ** argv) { int fd; int r; status = EXIT_FAILURE; fd = open("message.rfc2822", O_RDONLY); if (fd >= 0) { void * mem; struct stat stat_info; r = fstat(fd, &stat_info); if (r >= 0) { mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE); if (mem != MAP_FAILED) { struct mailimf_fields * f; size_t current_index; current_index = 0; r = mailimf_fields_parse(mem, stat_info.st_size, ¤t_index, &f); if (r == MAILIMF_NO_ERROR) { clistiter * cur; for(cur = clist_begin(f->fld_list) ; cur != NULL ; cur = clist_next(cur)) { struct mailmime_field * mime_field; struct mailimf_field * field; field = clist_content(cur); if (field->fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) { if (strcasecmp(field->fld_data.fld_optional_field->fld_name, "Content-Type") == 0) { struct mailmime_content * content_type; size_t current_index; current_index = 0; r = mailmime_content_parse(field->fld_data.fld_optional_field->fld_value, strlen(field->fld_data.fld_optional_field->fld_value), ¤t_index, &content_type); if (r == MAILIMF_NO_ERROR) { display_mime_content(content_type); /* do the things */ status = EXIT_SUCCESS; mailmime_content_free(content_type); } } } } mailimf_fields_free(f); } } munmap(mem, stat_info.st_size); } close(fd); } exit(status); }
#include >libetpan/libetpan.h< int mailmime_description_parse(const char * message, size_t length, size_t * index, char ** result);
This will parse the content of Content-Description MIME header field.
message is a string containing the MIME content description.
length is the size of the given string.
index is a pointer to the start of the address in the given string, (* index) is modified to point at the end of the parsed data.
result. The result of the parse operation is stored in (* result). The result string must be freed with free().
Example 4-17. Parsing MIME description
#include <libetpan/libetpan.h> #include <sys/stat.h> #include <sys/mman.h> int main(int argc, char ** argv) { int fd; int r; status = EXIT_FAILURE; fd = open("message.rfc2822", O_RDONLY); if (fd >= 0) { void * mem; struct stat stat_info; r = fstat(fd, &stat_info); if (r >= 0) { mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE); if (mem != MAP_FAILED) { struct mailimf_fields * f; size_t current_index; current_index = 0; r = mailimf_fields_parse(mem, stat_info.st_size, ¤t_index, &f); if (r == MAILIMF_NO_ERROR) { clistiter * cur; for(cur = clist_begin(f->fld_list) ; cur != NULL ; cur = clist_next(cur)) { struct mailmime_field * mime_field; struct mailimf_field * field; field = clist_content(cur); if (field->fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) { if (strcasecmp(field->fld_data.fld_optional_field->fld_name, "Content-Description") == 0) { char * description; size_t current_index; current_index = 0; r = mailmime_description_parse(field->fld_data.fld_optional_field->fld_value, strlen(field->fld_data.fld_optional_field->fld_value), ¤t_index, &description); if (r == MAILIMF_NO_ERROR) { printf("%s\n", description); /* do the things */ status = EXIT_SUCCESS; free(description); } } } } mailimf_fields_free(f); } } munmap(mem, stat_info.st_size); } close(fd); } exit(status); }
#include >libetpan/libetpan.h< int mailmime_encoding_parse(const char * message, size_t length, size_t * index, struct mailmime_mechanism ** result);
This function will parse the content of Content-Transfer-Encoding header field.
message is a string containing the MIME encoding mechanism.
length is the size of the given string.
index is a pointer to the start of the address in the given string, (* index) is modified to point at the end of the parsed data.
result. The result of the parse operation is stored in (* result) (see the Section called mailmime_mechanism - MIME transfer encoding mechanism (Content-Transfer-Encoding)).
Example 4-18. parsing MIME encoding mechanism
#include <libetpan/libetpan.h> #include <sys/stat.h> #include <sys/mman.h> int main(int argc, char ** argv) { int fd; int r; status = EXIT_FAILURE; fd = open("message.rfc2822", O_RDONLY); if (fd >= 0) { void * mem; struct stat stat_info; r = fstat(fd, &stat_info); if (r >= 0) { mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE); if (mem != MAP_FAILED) { struct mailimf_fields * f; size_t current_index; current_index = 0; r = mailimf_fields_parse(mem, stat_info.st_size, ¤t_index, &f); if (r == MAILIMF_NO_ERROR) { clistiter * cur; for(cur = clist_begin(f->fld_list) ; cur != NULL ; cur = clist_next(cur)) { struct mailmime_field * mime_field; struct mailimf_field * field; field = clist_content(cur); if (field->fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) { if (strcasecmp(field->fld_data.fld_optional_field->fld_name, "Content-Transfer-Encoding") == 0) { struct mailmime_content * encoding; size_t current_index; current_index = 0; r = mailmime_encoding_parse(field->fld_data.fld_optional_field->fld_value, strlen(field->fld_data.fld_optional_field->fld_value), ¤t_index, &encoding); if (r == MAILIMF_NO_ERROR) { display_mime_mechanism(encoding); /* do the things */ status = EXIT_SUCCESS; mailmime_mechanism_free(encoding); } } } } mailimf_fields_free(f); } } munmap(mem, stat_info.st_size); } close(fd); } exit(status); }
#include <libetpan/libetpan.h> int mailmime_field_parse(struct mailimf_optional_field * field, struct mailmime_field ** result);
This function will parse a MIME header field.
field is a non-parsed field (see the Section called mailimf_optional_field - non-standard header in Chapter 3).
result. The result of the parse operation is stored in (* result) (see the Section called mailmime_field - MIME header field).
Example 4-19. parsing MIME header field
#include <libetpan/libetpan.h> #include <sys/stat.h> #include <sys/mman.h> int main(int argc, char ** argv) { int fd; int r; status = EXIT_FAILURE; fd = open("message.rfc2822", O_RDONLY); if (fd >= 0) { void * mem; struct stat stat_info; r = fstat(fd, &stat_info); if (r >= 0) { mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE); if (mem != MAP_FAILED) { struct mailimf_fields * f; size_t current_index; current_index = 0; r = mailimf_fields_parse(mem, stat_info.st_size, ¤t_index, &f); if (r == MAILIMF_NO_ERROR) { clistiter * cur; for(cur = clist_begin(f->fld_list) ; cur != NULL ; cur = clist_next(cur)) { struct mailmime_field * mime_field; struct mailimf_field * field; field = clist_content(cur); if (field->fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) { r = mailmime_field_parse(field->fld_data.fld_optional_field, &mime_fields); if (r == MAILIMF_NO_ERROR) { display_mime_field(mime_field); mailmime_field_free(mime_field); status = EXIT_SUCCESS; } } } mailimf_fields_free(f); } } munmap(mem, stat_info.st_size); } close(fd); } exit(status); }
#include >libetpan/libetpan.h< int mailmime_id_parse(const char * message, size_t length, size_t * index, char ** result);
This will parse the content of Content-ID MIME header field.
message is a string containing the MIME content identifier.
length is the size of the given string.
index is a pointer to the start of the address in the given string, (* index) is modified to point at the end of the parsed data.
result. The result of the parse operation is stored in (* result). The result string must be freed with free().
Example 4-20. Parsing MIME content identifier
#include <libetpan/libetpan.h> #include <sys/stat.h> #include <sys/mman.h> int main(int argc, char ** argv) { int fd; int r; status = EXIT_FAILURE; fd = open("message.rfc2822", O_RDONLY); if (fd >= 0) { void * mem; struct stat stat_info; r = fstat(fd, &stat_info); if (r >= 0) { mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE); if (mem != MAP_FAILED) { struct mailimf_fields * f; size_t current_index; current_index = 0; r = mailimf_fields_parse(mem, stat_info.st_size, ¤t_index, &f); if (r == MAILIMF_NO_ERROR) { clistiter * cur; for(cur = clist_begin(f->fld_list) ; cur != NULL ; cur = clist_next(cur)) { struct mailmime_field * mime_field; struct mailimf_field * field; field = clist_content(cur); if (field->fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) { if (strcasecmp(field->fld_data.fld_optional_field->fld_name, "Content-ID") == 0) { char * id; size_t current_index; current_index = 0; r = mailmime_id_parse(field->fld_data.fld_optional_field->fld_value, strlen(field->fld_data.fld_optional_field->fld_value), ¤t_index, &id); if (r == MAILIMF_NO_ERROR) { printf("%s\n", id); /* do the things */ status = EXIT_SUCCESS; free(id); } } } } mailimf_fields_free(f); } } munmap(mem, stat_info.st_size); } close(fd); } exit(status); }
#include <libetpan/libetpan.h> int mailmime_fields_parse(struct mailimf_fields * fields, struct mailmime_fields ** result);
This function will parse a MIME header fields.
fields is a list of RFC 2822 fields (see the Section called mailimf_fields - list of header fields in Chapter 3).
result. The result of the parse operation is stored in (* result) (see the Section called mailmime_fields - header fields).
Example 4-21. parsing MIME header fields
#include <libetpan/libetpan.h> #include <sys/stat.h> #include <sys/mman.h> int main(int argc, char ** argv) { int fd; int r; status = EXIT_FAILURE; fd = open("message.rfc2822", O_RDONLY); if (fd >= 0) { void * mem; struct stat stat_info; r = fstat(fd, &stat_info); if (r >= 0) { mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE); if (mem != MAP_FAILED) { struct mailimf_fields * f; size_t current_index; current_index = 0; r = mailimf_fields_parse(mem, stat_info.st_size, ¤t_index, &f); if (r == MAILIMF_NO_ERROR) { struct mailmime_fields * mime_fields; r = mailmime_fields_parse(f, &mime_fields); if (r == MAILIMF_NO_ERROR) { display_mime_fields(mime_fields); mailmime_fields_free(mime_fields); status = EXIT_SUCCESS; } mailimf_fields_free(f); } } munmap(mem, stat_info.st_size); } close(fd); } exit(status); }
#include <libetpan/libetpan.h> int mailmime_version_parse(const char * message, size_t length, size_t * index, uint32_t * result);
This will parse the content of MIME-Version MIME header field.
message is a string containing the MIME version.
length is the size of the given string.
index is a pointer to the start of the address in the given string, (* index) is modified to point at the end of the parsed data.
result. The result of the parse operation is stored in (* result) (see the Section called mailmime_field - MIME header field).
Example 4-22. parsing MIME version
#include <libetpan/libetpan.h> #include <sys/stat.h> #include <sys/mman.h> int main(int argc, char ** argv) { int fd; int r; status = EXIT_FAILURE; fd = open("message.rfc2822", O_RDONLY); if (fd >= 0) { void * mem; struct stat stat_info; r = fstat(fd, &stat_info); if (r >= 0) { mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE); if (mem != MAP_FAILED) { struct mailimf_fields * f; size_t current_index; current_index = 0; r = mailimf_fields_parse(mem, stat_info.st_size, ¤t_index, &f); if (r == MAILIMF_NO_ERROR) { clistiter * cur; for(cur = clist_begin(f->fld_list) ; cur != NULL ; cur = clist_next(cur)) { struct mailmime_field * mime_field; struct mailimf_field * field; field = clist_content(cur); if (field->fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) { if (strcasecmp(field->fld_data.fld_optional_field->fld_name, "MIME-Version") == 0) { uint32_t version; size_t current_index; current_index = 0; r = mailmime_version_parse(field->fld_data.fld_optional_field->fld_value, strlen(field->fld_data.fld_optional_field->fld_value), ¤t_index, &version); if (r == MAILIMF_NO_ERROR) { printf("%i.%i\n", version >> 16, version & 0xFFFF); /* do the things */ status = EXIT_SUCCESS; free(description); } } } } mailimf_fields_free(f); } } munmap(mem, stat_info.st_size); } close(fd); } exit(status); }
#include <libetpan/libetpan.h> int mailmime_parameter_parse(const char * message, size_t length, size_t * index, struct mailmime_parameter ** result);
This will parse a MIME parameter (parameter of Content-Type or parameter of Content-Disposition).
message is a string containing the MIME parameter.
length is the size of the given string.
index is a pointer to the start of the address in the given string, (* index) is modified to point at the end of the parsed data.
result. The result of the parse operation is stored in (* result) (see the Section called mailmime_parameter - MIME type parameter).
Example 4-23. parsing a MIME parameter
#include <libetpan/libetpan.h> #define PARAM_STR "foo=bar" int main(int argc, char ** argv) { int fd; int r; size_t current_index; struct mailmime_parameter * param; int status; status = EXIT_FAILURE; current_index = 0; r = mailmime_parameter_parse(PARAM_STR, sizeof(PARAM_STR) - 1, ¤t_index, ¶m); if (r == MAILIMF_NO_ERROR) { display_mime_parameter(param); /* do the things */ mailmime_parameter_free(param); status = EXIT_SUCCESS; } exit(status); }
#include <libetpan/libetpan.h> int mailmime_language_parse(const char * message, size_t length, size_t * index, struct mailmime_language ** result);
This function will parse the content of a Content-Language header.
message is a string containing the MIME content language.
length is the size of the given string.
index is a pointer to the start of the address in the given string, (* index) is modified to point at the end of the parsed data.
result. The result of the parse operation is stored in (* result) (see the Section called mailmime_language - Language of MIME part).
Example 4-24. Parsing the MIME content langage
#include <libetpan/libetpan.h> #include <sys/stat.h> #include <sys/mman.h> int main(int argc, char ** argv) { int fd; int r; status = EXIT_FAILURE; fd = open("message.rfc2822", O_RDONLY); if (fd >= 0) { void * mem; struct stat stat_info; r = fstat(fd, &stat_info); if (r >= 0) { mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE); if (mem != MAP_FAILED) { struct mailimf_fields * f; size_t current_index; current_index = 0; r = mailimf_fields_parse(mem, stat_info.st_size, ¤t_index, &f); if (r == MAILIMF_NO_ERROR) { clistiter * cur; for(cur = clist_begin(f->fld_list) ; cur != NULL ; cur = clist_next(cur)) { struct mailmime_field * mime_field; struct mailimf_field * field; field = clist_content(cur); if (field->fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) { if (strcasecmp(field->fld_data.fld_optional_field->fld_name, "Content-Language") == 0) { struct mailmime_language * lang; size_t current_index; current_index = 0; r = mailmime_id_parse(field->fld_data.fld_optional_field->fld_value, strlen(field->fld_data.fld_optional_field->fld_value), ¤t_index, &lang); if (r == MAILIMF_NO_ERROR) { display_mime_language(lang); /* do the things */ status = EXIT_SUCCESS; free(id); } } } } mailimf_fields_free(f); } } munmap(mem, stat_info.st_size); } close(fd); } exit(status); }
#include <libetpan/libetpan.h> int mailmime_disposition_parse(const char * message, size_t length, size_t * index, struct mailmime_disposition ** result);
This function will parse the content of a Content-Disposition MIME header field.
message is a string containing the MIME content disposition.
length is the size of the given string.
index is a pointer to the start of the address in the given string, (* index) is modified to point at the end of the parsed data.
result. The result of the parse operation is stored in (* result) (see the Section called mailmime_disposition - MIME disposition information (Content-Disposition)).
Example 4-25. Parsing the MIME content disposition
#include <libetpan/libetpan.h> #include <sys/stat.h> #include <sys/mman.h> int main(int argc, char ** argv) { int fd; int r; status = EXIT_FAILURE; fd = open("message.rfc2822", O_RDONLY); if (fd >= 0) { void * mem; struct stat stat_info; r = fstat(fd, &stat_info); if (r >= 0) { mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE); if (mem != MAP_FAILED) { struct mailimf_fields * f; size_t current_index; current_index = 0; r = mailimf_fields_parse(mem, stat_info.st_size, ¤t_index, &f); if (r == MAILIMF_NO_ERROR) { clistiter * cur; for(cur = clist_begin(f->fld_list) ; cur != NULL ; cur = clist_next(cur)) { struct mailmime_field * mime_field; struct mailimf_field * field; field = clist_content(cur); if (field->fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) { if (strcasecmp(field->fld_data.fld_optional_field->fld_name, "Content-Disposition") == 0) { struct mailmime_disposition * dsp; size_t current_index; current_index = 0; r = mailmime_id_parse(field->fld_data.fld_optional_field->fld_value, strlen(field->fld_data.fld_optional_field->fld_value), ¤t_index, &dsp); if (r == MAILIMF_NO_ERROR) { display_mime_disposition(dsp); /* do the things */ status = EXIT_SUCCESS; free(id); } } } } mailimf_fields_free(f); } } munmap(mem, stat_info.st_size); } close(fd); } exit(status); }
#include <libetpan/libetpan.h> int mailmime_disposition_type_parse(const char * message, size_t length, size_t * index, struct mailmime_disposition_type ** result);
This function will parse the type of MIME content disposition.
message is a string containing the MIME content disposition type.
length is the size of the given string.
index is a pointer to the start of the address in the given string, (* index) is modified to point at the end of the parsed data.
result. The result of the parse operation is stored in (* result) (see the Section called mailmime_disposition_type - Type of MIME disposition).
Example 4-26. parsing a MIME content disposition type
#include <libetpan/libetpan.h> #define DSP_TYPE_STR "attachment" int main(int argc, char ** argv) { int fd; int r; size_t current_index; struct mailmime_disposition_type * dsp_type; int status; status = EXIT_FAILURE; current_index = 0; r = mailmime_disposition_type_parse(DSP_TYPE_STR, sizeof(DSP_TYPE_STR) - 1, ¤t_index, &dsp_type); if (r == MAILIMF_NO_ERROR) { display_mime_disposition_type(dsp_type); /* do the things */ mailmime_disposition_type_free(dsp_type); status = EXIT_SUCCESS; } exit(status); }
#include <libetpan/libetpan.h> int mailmime_encoded_phrase_parse(const char * default_fromcode, const char * message, size_t length, size_t * index, const char * tocode, char ** result);
This function will decode a MIME encoded header string, encoded with RFC 2047.
default_fromcode is the default code to use for parts of string that are not marked with charset.
message is the string to decode.
length is the size of the given string.
index is a pointer to the start of the address in the given string, (* index) is modified to point at the end of the parsed data.
tocode is the destination charset for decoding.
result. The result of the parse operation is stored in (* result).
Example 4-27. decoding a MIME encoded header string
#include <libetpan/libetpan.h> #define TEST_STRING "=?iso-8859-1?ab?= =?iso-8859-15?cd?=" int main(int argc, char ** argv) { size_t cur_token; char * decoded_subject; cur_token = 0; mailmime_encoded_phrase_parse("iso-8859-1", TEST_STRING, sizeof(TEST_STRING), &cur_token, "iso-8859-1", &decoded_subject); printf("%s\n", decoded_subject); /* do the things */ free(decoded_subject); }
#include <libetpan/libetpan.h> int mailmime_parse(const char * message, size_t length, size_t * index, struct mailmime ** result);
This will parse a MIME message.
message is a string containing the MIME message.
length is the size of the given string.
index is a pointer to the start of the address in the given string, (* index) is modified to point at the end of the parsed data.
result. The result of the parse operation is stored in (* result) (see the Section called mailmime - MIME part).
Example 4-28. parsing a MIME message
#include <libetpan/libetpan.h> #include <sys/stat.h> #include <sys/mman.h> int main(int argc, char ** argv) { int fd; int r; status = EXIT_FAILURE; fd = open("message.rfc2822", O_RDONLY); if (fd >= 0) { void * mem; struct stat stat_info; r = fstat(fd, &stat_info); if (r >= 0) { mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE); if (mem != MAP_FAILED) { struct mailmime * mime; size_t current_index; current_index = 0; r = mailmime_parse(mem, stat_info.st_size, ¤t_index, &mime); if (r == MAILIMF_NO_ERROR) { display_mime(mime); /* do the things */ status = EXIT_SUCCESS; mailmime_free(mime); } } munmap(mem, stat_info.st_size); } close(fd); } exit(status); }
#include <libetpan/libetpan.h> int mailmime_base64_body_parse(const char * message, size_t length, size_t * index, char ** result, size_t * result_len);
This function will parse a body part encoded using base64.
message is a string encoded using base64.
length is the size of the given string.
index is a pointer to the start of the address in the given string, (* index) is modified to point at the end of the parsed data.
result. The result of the parse operation is stored in (* result) The result must be freed with mmap_string_unref().
Example 4-29. Parsing a base64 encoded part
#include <libetpan/libetpan.h> #include <sys/stat.h> #include <sys/mman.h> int main(int argc, char ** argv) { int fd; int r; status = EXIT_FAILURE; fd = open("message.rfc2822", O_RDONLY); if (fd >= 0) { void * mem; struct stat stat_info; r = fstat(fd, &stat_info); if (r >= 0) { mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE); if (mem != MAP_FAILED) { struct mailimf_fields * f; size_t current_index; char * result; size_t result_len; current_index = 0; r = mailmime_base64_body_parse(mem, stat_info.st_size, ¤t_index, &result, &result_len); if (r == MAILIMF_NO_ERROR) { /* do the things */ mailmime_decoded_part_free(mem); status = EXIT_SUCCESS; } } munmap(mem, stat_info.st_size); } close(fd); } exit(status); }
#include <libetpan/libetpan.h> int mailmime_quoted_printable_body_parse(const char * message, size_t length, size_t * index, char ** result, size_t * result_len, int in_header);
This function will parse a body part encoded using quoted printable.
message is a string encoded using quoted printable.
length is the size of the given string.
index is a pointer to the start of the address in the given string, (* index) is modified to point at the end of the parsed data.
result. The result of the parse operation is stored in (* result) The result must be freed with mmap_string_unref().
Example 4-30. Parsing a quoted printable encoded part
#include <libetpan/libetpan.h> #include <sys/stat.h> #include <sys/mman.h> int main(int argc, char ** argv) { int fd; int r; status = EXIT_FAILURE; fd = open("message.rfc2822", O_RDONLY); if (fd >= 0) { void * mem; struct stat stat_info; r = fstat(fd, &stat_info); if (r >= 0) { mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE); if (mem != MAP_FAILED) { struct mailimf_fields * f; size_t current_index; char * result; size_t result_len; current_index = 0; r = mailmime_quoted_printable_body_parse(mem, stat_info.st_size, ¤t_index, &result, &result_len); if (r == MAILIMF_NO_ERROR) { /* do the things */ mailmime_decoded_part_free(mem); status = EXIT_SUCCESS; } } munmap(mem, stat_info.st_size); } close(fd); } exit(status); }
#include <libetpan/libetpan.h> int mailmime_binary_body_parse(const char * message, size_t length, size_t * index, char ** result, size_t * result_len);
This function will parse a body part encoded using binary (no encoding).
message is a string encoded using binary.
length is the size of the given string.
index is a pointer to the start of the address in the given string, (* index) is modified to point at the end of the parsed data.
result. The result of the parse operation is stored in (* result) The result must be freed with mmap_string_unref().
Example 4-31. Parsing a binary encoded part
#include <libetpan/libetpan.h> #include <sys/stat.h> #include <sys/mman.h> int main(int argc, char ** argv) { int fd; int r; status = EXIT_FAILURE; fd = open("message.rfc2822", O_RDONLY); if (fd >= 0) { void * mem; struct stat stat_info; r = fstat(fd, &stat_info); if (r >= 0) { mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE); if (mem != MAP_FAILED) { struct mailimf_fields * f; size_t current_index; char * result; size_t result_len; current_index = 0; r = mailmime_binary_body_parse(mem, stat_info.st_size, ¤t_index, &result, &result_len); if (r == MAILIMF_NO_ERROR) { /* do the things */ mailmime_decoded_part_free(mem); status = EXIT_SUCCESS; } } munmap(mem, stat_info.st_size); } close(fd); } exit(status); }
#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 }; int mailmime_part_parse(const char * message, size_t length, size_t * index, int encoding, char ** result, size_t * result_len);
This function will parse a body part encoded using a given MIME encoding mechanism.
message is a string encoded using binary.
length is the size of the given string.
index is a pointer to the start of the address in the given string, (* index) is modified to point at the end of the parsed data.
encoding is a MIME encoding mechanism. The value can be MAILMIME_MECHANISM_7BIT, MAILMIME_MECHANISM_8BIT, MAILMIME_MECHANISM_BINARY, MAILMIME_MECHANISM_QUOTED_PRINTABLE, MAILMIME_MECHANISM_BASE64 or MAILMIME_MECHANISM_TOKEN (see the Section called mailmime_mechanism - MIME transfer encoding mechanism (Content-Transfer-Encoding)).
result. The result of the parse operation is stored in (* result) The result must be freed with mmap_string_unref().
Example 4-32. Parsing a MIME encoded part
#include <libetpan/libetpan.h> #include <sys/stat.h> #include <sys/mman.h> int main(int argc, char ** argv) { int fd; int r; status = EXIT_FAILURE; fd = open("message.rfc2822", O_RDONLY); if (fd >= 0) { void * mem; struct stat stat_info; r = fstat(fd, &stat_info); if (r >= 0) { mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE); if (mem != MAP_FAILED) { struct mailimf_fields * f; size_t current_index; char * result; size_t result_len; current_index = 0; r = mailmime_part_parse(mem, stat_info.st_size, ¤t_index, MAILMIME_MECHANISM_QUOTED_PRINTABLE, &result, &result_len); if (r == MAILIMF_NO_ERROR) { /* do the things */ mailmime_decoded_part_free(mem); status = EXIT_SUCCESS; } } munmap(mem, stat_info.st_size); } close(fd); } exit(status); }
#include <libetpan/libetpan.h> int mailmime_fields_write(FILE * f, int * col, struct mailmime_fields * fields); int mailmime_content_write(FILE * f, int * col, struct mailmime_content * content); int mailmime_content_type_write(FILE * f, int * col, struct mailmime_content * content);
mailmime_fields_write render the MIME header fields.
mailmime_content_write render the MIME content type header field.
mailmime_content_write render the content of the MIME content type header field.
col current column is given for wrapping purpose in (* col), the resulting columns will be returned..
f is the file descriptor. It can be stdout for example.
fields is the header fields (see the Section called mailmime_fields - header fields).
content is the header fields (see the Section called mailmime_content - MIME content type (Content-Type)).
Example 4-33. rendering MIME header fields
#include <libetpan/libetpan.h> int main(int argc, char ** argv) { struct mailmime_mime * mime_fields; int col; /* look at the example in mailmime_fields to see how to build a mailmime_fields */ mime_fields = build_mime_fields(); col = 0; mailmime_fields_write(stdout, &col, mime_fields); mailmime_fields_free(mime_fields); } int main(int argc, char ** argv) { struct mailmime_content * content; int col; /* look at the example in mailmime_content to see how to build a mailmime_fields */ content = build_mime_content(); col = 0; mailmime_content_write(stdout, &col, mime_fields); mailmime_content_free(content); } int main(int argc, char ** argv) { struct mailmime_content * content; int col; /* look at the example in mailmime_content to see how to build a mailmime_fields */ content = build_mime_content(); col = 0; mailmime_content_type_write(stdout, &col, mime_fields); mailmime_content_free(content); }
#include <libetpan/libetpan.h> int mailmime_write(FILE * f, int * col, struct mailmime * build_info);
This function will render a MIME message.
col current column is given for wrapping purpose in (* col), the resulting columns will be returned..
f is the file descriptor. It can be stdout for example.
build_info is the MIME message to render.
#include <libetpan/libetpan.h> int mailmime_quoted_printable_write(FILE * f, int * col, int istext, const char * text, size_t size); int mailmime_base64_write(FILE * f, int * col, const char * text, size_t size);
mailmime_quoted_printable_write() will render a string to quoted printable.
mailmime_base64_write() will render a string to base64.
col current column is given for wrapping purpose in (* col), the resulting columns will be returned..
f is the file descriptor. It can be stdout for example.
text is the string to render.
size is the size of the string to render.
Example 4-34. render base64 or quoted printable
#include <libetpan/libetpan.h> int main(int argc, char ** argv) { int col; col = 0; mailmime_quoted_printable_write(stdout, &col, "this is a test", 14); } #include <libetpan/libetpan.h> int main(int argc, char ** argv) { int col; col = 0; mailmime_base64_write(stdout, &col, "this is a test", 14); }
#include <libetpan/libetpan.h> int mailmime_data_write(FILE * f, int * col, struct mailmime_data * data, int istext);
mailmime_data_write will render MIME data.
col current column is given for wrapping purpose in (* col), the resulting columns will be returned..
f is the file descriptor. It can be stdout for example.
data is the data to render (see the Section called mailmime_data - Content of MIME part).
#include <libetpan/libetpan.h> enum { MAILMIME_DISPOSITION_TYPE_ERROR, MAILMIME_DISPOSITION_TYPE_INLINE, MAILMIME_DISPOSITION_TYPE_ATTACHMENT, MAILMIME_DISPOSITION_TYPE_EXTENSION }; struct mailmime_disposition * mailmime_disposition_new_filename(int type, char * filename); struct mailmime_disposition * mailmime_disposition_new_with_data(int type, char * filename, char * creation_date, char * modification_date, char * read_date, size_t size);
These functions will create a MIME content disposition information.
type a standard MIME disposition : MAILMIME_DISPOSITION_TYPE_INLINE or MAILMIME_DISPOSITION_TYPE_ATTACHMENT.
filename is the filename.
creation_date is the creation date.
modification_date is the modification date.
read_date is the last read date.
size is the size of the file.
This will return a MIME content disposition (see the Section called mailmime_disposition - MIME disposition information (Content-Disposition)).
Example 4-35. creating a MIME content disposition
#include <libetpan/libetpan.h> int main(int argc, char ** argv) { struct mailmime_disposition * disposition; disposition = mailmime_disposition_new_filename(MAILMIME_DISPOSITION_TYPE_ATTACHMENT, strdup("foo-bar.txt")); /* do the things */ mailmime_disposition_free(disposition); }
#include <libetpan/libetpan.h> struct mailmime_fields * mailmime_fields_new_empty(void); int mailmime_fields_add(struct mailmime_fields * fields, struct mailmime_field * field);
mailmime_fields_new_empty() will create a new empty MIME header fields list.
mailmime_fields_add() will add MIME header fields to the MIME header fields list.
fields. The MIME header field will be added to this MIME header fields list (see the Section called mailmime_fields - header fields).
field is the MIME header field to add (see the Section called mailmime_field - MIME header field).
Example 4-36. creating a MIME header fields list
#include <libetpan/libetpan.h> int main(int argc, char ** argv) { struct mailmime_fields * fields; struct mailmime_field * field; fields = mailmime_fields_new_empty(); field = build_mime_field(); /* do the things */ mailmime_fields_add(fields, field); mailmime_fields_free(fields); }
#include <libetpan/libetpan.h> struct mailmime_fields * mailmime_fields_new_with_data(struct mailmime_mechanism * encoding, char * id, char * description, struct mailmime_disposition * disposition, struct mailmime_language * language); struct mailmime_fields * mailmime_fields_new_with_version(struct mailmime_mechanism * encoding, char * id, char * description, struct mailmime_disposition * disposition, struct mailmime_language * language);
mailmime_fields_new_with_data() will create a MIME header fields list with all the given fields (NULL can be used for the value if the field must not be present). MIME-Version header field will not be added.
mailmime_fields_new_with_version() will create a MIME header fields list with all the given fields (NULL can be used for the value if the field must not be present). MIME-Version header field will be added.
Example 4-37. creating new fields
#include <libetpan/libetpan.h> int main(int argc, char ** argv) { struct mailmime_disposition * disposition; struct mailmime_fields * mime_fields; struct mailmime_mechanism * encoding; encoding = mailmime_mechanism_new(MAILMIME_MECHANISM_BASE64, NULL); disposition = mailmime_disposition_new_filename(MAILMIME_DISPOSITION_TYPE_ATTACHMENT, strdup("foo-bar.txt")); mime_fields = mailmime_fields_new_with_version(encoding, NULL, NULL, disposition, NULL); /* do the things */ mailmime_fields_free(mime_fields); }
#include <libetpan/libetpan.h> struct mailmime_content * mailmime_get_content_message(void); struct mailmime_content * mailmime_get_content_text(void); struct mailmime_content * mailmime_content_new_with_str(const char * str);
mailmime_get_content_message() will create a MIME content type message/rfc822.
mailmime_get_content_text() will create a MIME content type plain/text.
mailmime_get_content_new_with_str() will create a MIME content type given by the string plain/text.
str. This string will NOT be referenced by any structure. This string will only be parsed to create the structure.
Example 4-38. Creating a MIME content type
#include <libetpan/libetpan.h> int main(int argc, char ** argv) { struct mailmime_content * content; content = mailmime_get_content_message(); /* do the things */ mailmime_content_free(content); } int main(int argc, char ** argv) { struct mailmime_content * content; content = mailmime_get_content_text(); /* do the things */ mailmime_content_free(content); } int main(int argc, char ** argv) { struct mailmime_content * content; content = mailmime_get_content_new_with_str("multipart/mixed"); /* do the things */ mailmime_content_free(content); }
#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_data * mailmime_data_new_data(int encoding, int encoded, const char * data, size_t length); struct mailmime_data * mailmime_data_new_file(int encoding, int encoded, char * filename);
mailmime_data_new_data() will create a new MIME content, using a string in memory.
mailmime_data_new_file() will create a new MIME content, using a file.
encoding is the MIME encoding mechanism used to encode this part. The value can be MAILMIME_MECHANISM_7BIT, MAILMIME_MECHANISM_8BIT, MAILMIME_MECHANISM_BINARY, MAILMIME_MECHANISM_QUOTED_PRINTABLE or MAILMIME_MECHANISM_BASE64 (see the Section called mailmime_mechanism - MIME transfer encoding mechanism (Content-Transfer-Encoding)).
encoded is set to 1 if the part is already encoded with the mechanism given in encoding.
data is a pointer to the content of the part.
length is the length of the data.
filename is the name of the file.
Example 4-39. creating MIME content
#include <libetpan/libetpan.h> #define DATA_STR "my data" int main(int argc, char ** argv) { struct mailmime_data * data; data = mailmime_data_new_data(MAILMIME_MECHANISM_BASE64, 0, DATA_STR, sizeof(DATA_STR) - 1); /* do the things */ mailmime_data_free(data); } int main(int argc, char ** argv) { struct mailmime_data * data; data = mailmime_data_new_file(MAILMIME_MECHANISM_BASE64, 0, strdup("foo-bar.txt")); /* do the things */ mailmime_data_free(data); }
#include <libetpan/libetpan.h> struct mailmime * mailmime_new_message_data(struct mailmime * msg_mime); struct mailmime * mailmime_new_empty(struct mailmime_content * content, struct mailmime_fields * mime_fields); int mailmime_new_with_content(const char * content_type, struct mailmime_fields * mime_fields, struct mailmime ** result); struct mailmime * mailmime_multiple_new(const char * type);
mailmime_new_message_data() will create a new MIME message with the given subpart.
mailmime_new_empty() will create a new MIME part with the given content type and MIME fields but with no content.
mailmime_new_with_content() will create a new MIME part with a content type given by a string and a given MIME fields list.
mailmime_multiple_new() will create a new MIME multipart with a content type given by a string.
msg_mime is the sub part to add to the MIME message when creating it (see the Section called mailmime - MIME part).
content is the content type of the part to create (see the Section called mailmime_content - MIME content type (Content-Type)).
content_type is the content type of the part to create given by a string.
mime_fields is the list of MIME header fields (see the Section called mailmime_fields - header fields).
Example 4-40. creating a MIME part
#include <libetpan/libetpan.h> #define DATA_STR "my data" int main(int argc, char ** argv) { struct mailmime * mime; struct mailmime * single_part; mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_QUOTED_PRINTABLE); mailmime_new_with_content("plain/text", mime_fields, &single_part); mailmime_set_body_text(single_part, DATA_STR, sizeof(DATA_STR) - 1); mime = mailmime_new_message_data(single_part); /* do the things */ mailmime_free(mime); } int main(int argc, char ** argv) { struct mailmime * mime; struct mailmime * single_part; struct mailmime_content * content; mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_QUOTED_PRINTABLE); content = mailmime_get_content_text(); single_part = mailmime_new_empty(content, mime_fields); mailmime_set_body_text(single_part, DATA_STR, sizeof(DATA_STR) - 1); mime = mailmime_new_message_data(single_part); /* do the things */ mailmime_free(mime); } int main(int argc, char ** argv) { struct mailmime * mime; mime = mailmime_multiple_new("multipart/mixed"); /* do the things */ mailmime_free(mime); }
#include <libetpan/libetpan.h> int mailmime_set_preamble_file(struct mailmime * build_info, char * filename); int mailmime_set_epilogue_file(struct mailmime * build_info, char * filename); int mailmime_set_preamble_text(struct mailmime * build_info, char * data_str, size_t length); int mailmime_set_epilogue_text(struct mailmime * build_info, char * data_str, size_t length);
mailmime_set_preamble_file() will define the preamble of a multipart.
mailmime_set_preamble_text() will define the preamble of a multipart.
mailmime_set_epilogue_file() will define the epilogue of a multipart.
mailmime_set_preamble_text() will define the preamble of a multipart.
build_info is the MIME part to modify (see the Section called mailmime - MIME part).
data_str is the string to define as epilogue or prologue.
length is the length of the string to define as epilogue or prologue.
filename is the name of the file which content will be defined as epilogue or prologue.
Example 4-41. setting preamble and epilogue
#include <libetpan/libetpan.h> #define DATA_STR "test foo bar" int main(int argc, char ** argv) { struct mailmime * mime; mime = mailmime_multiple_new("multipart/mixed"); mailmime_set_preamble_file(mime, strdup("foo-bar.txt")); mailmime_set_epilogue_data(mime, DATA_STR, sizeof(DATA_STR) - 1); /* do the things */ mailmime_free(mime); }
#include <libetpan/libetpan.h> int mailmime_set_body_file(struct mailmime * build_info, char * filename); int mailmime_set_body_text(struct mailmime * build_info, char * data_str, size_t length);
mailmime_set_body_file() will define the body of a single part.
mailmime_set_body_text() will define the body of a single part.
build_info is the MIME part to modify (see the Section called mailmime - MIME part).
data_str is the string to define as the body of the part.
length is the length of the string to define as the body of the part.
filename is the name of the file which content will be defined as the body of the part.
Example 4-42. creating a MIME part
#include <libetpan/libetpan.h> #define DATA_STR "my data" int main(int argc, char ** argv) { struct mailmime * mime; mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_QUOTED_PRINTABLE); mailmime_new_with_content("plain/text", mime_fields, &mime); mailmime_set_body_text(mime, DATA_STR, sizeof(DATA_STR) - 1); /* do the things */ mailmime_free(mime); }
#include <libetpan/libetpan.h> int mailmime_add_part(struct mailmime * build_info, struct mailmime * part); void mailmime_remove_part(struct mailmime * mime); int mailmime_smart_add_part(struct mailmime * mime, struct mailmime * mime_sub); int mailmime_smart_remove_part(struct mailmime * mime);
mailmime_add_part() will add a sub MIME part.
mailmime_remove_part() will detach the given sub part from its parent.
mailmime_smart_add_part() will add a sub MIME part. If the parent part is a message and no child exist, the part is set as the child. If the parent part is a message and a child already exists, if the child is multipart, the part to add is added as child of this multipart, else a multipart is added and the part is added as child of the multipart.
mailmime_smart_remove_part() will detach the given sub part from its parent. The sub part will be freed.
build_info is the parent MIME part (see the Section called mailmime - MIME part).
part is the part to add (see the Section called mailmime - MIME part).
mime is the parent MIME part (see the Section called mailmime - MIME part).
mime_sub is the part to add or to detach (see the Section called mailmime - MIME part).
Example 4-43. modifying MIME structure
#include <libetpan/libetpan.h> int main(int argc, char ** argv) { struct mailmime * sub_mime; struct mailmime_fields * mime_fields; struct mailmime_content * content; content = mailmime_get_content_text(); mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_BASE64); sub_mime = mailmime_new_empty(content, mime_fields); mime = mailmime_new_message_data(NULL); mailmime_add_part(mime, sub_mime); /* do the things */ mailmime_free(mime); int main(int argc, char ** argv) { struct mailmime * sub_mime; struct mailmime * other_sub_mime; struct mailmime_fields * mime_fields; struct mailmime_content * content; content = mailmime_get_content_text(); mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_BASE64); sub_mime = mailmime_new_empty(content, mime_fields); content = mailmime_get_content_text(); mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_QUOTED_PRINTABLE); other_sub_mime = mailmime_new_empty(content, mime_fields); mime = mailmime_new_message_data(NULL); mailmime_smart_add_part(mime, sub_mime); mailmime_smart_add_part(mime, other_sub_mime); /* do the things */ mailmime_free(mime); int main(int argc, char ** argv) { struct mailmime * sub_mime; struct mailmime_fields * mime_fields; struct mailmime_content * content; content = mailmime_get_content_text(); mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_BASE64); sub_mime = mailmime_new_empty(content, mime_fields); mime = mailmime_new_message_data(NULL); mailmime_add_part(mime, sub_mime); mailmime_remove_part(sub_mime); /* do the things */ mailmime_free(sub_mime); mailmime_free(mime); int main(int argc, char ** argv) { struct mailmime * sub_mime; struct mailmime_fields * mime_fields; struct mailmime_content * content; content = mailmime_get_content_text(); mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_BASE64); sub_mime = mailmime_new_empty(content, mime_fields); mime = mailmime_new_message_data(NULL); mailmime_add_part(mime, sub_mime); mailmime_smart_remove_part(sub_mime); /* do the things */ mailmime_free(mime); }
#include <libetpan/libetpan.h> void mailmime_set_imf_fields(struct mailmime * build_info, struct mailimf_fields * fields);
mailmime_set_imf_fields() will set the fields of the given MIME message.
build_info is the MIME message to modify (see the Section called mailmime - MIME part).
fields is the header fields to set for the message (see the Section called mailimf_fields - list of header fields in Chapter 3).
Example 4-44. modifying MIME structure
#include <libetpan/libetpan.h> #define DATA_STR "test foo bar" int main(int argc, char ** argv) { struct mailmime * mime; struct mailmime_fields * mime_fields; struct mailimf_fields * imf_fields; mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_8BIT); mailmime_new_with_content("text/plain", mime_fields, &mime); mailmime_set_body_text(mime, DATA_STR, sizeof(DATA_STR) - 1); /* look at the example in mailimf_fields to see how to build a mailimf_fields */ imf_fields = build_fields(); mailmime_set_imf_fields(mime, imf_fields); /* do the things */ mailmime_free(mime); }
#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 }; enum { MAILMIME_DISPOSITION_TYPE_ERROR, MAILMIME_DISPOSITION_TYPE_INLINE, MAILMIME_DISPOSITION_TYPE_ATTACHMENT, MAILMIME_DISPOSITION_TYPE_EXTENSION }; struct mailmime_fields * mailmime_fields_new_encoding(int encoding_type); struct mailmime_fields * mailmime_fields_new_filename(int dsp_type, char * filename, int encoding_type);
mailmime_fields_new_encoding() will create a list of MIME header fields with only Content-Transfer-Encoding.
mailmime_fields_new_filename() will create a list of MIME header fields with Content-Transfer-Encoding and Content-Disposition.
The result will be a list of MIME header fields (see the Section called mailmime_fields - header fields).
encoding_type is the MIME encoding mechanism. The value can be MAILMIME_MECHANISM_7BIT, MAILMIME_MECHANISM_8BIT, MAILMIME_MECHANISM_BINARY, MAILMIME_MECHANISM_QUOTED_PRINTABLE or MAILMIME_MECHANISM_BASE64 (see the Section called mailmime_mechanism - MIME transfer encoding mechanism (Content-Transfer-Encoding)).
dsp_type is the disposition type. The value can be MAILMIME_DISPOSITION_TYPE_INLINE or MAILMIME_DISPOSITION_TYPE_ATTACHMENT (see the Section called mailmime_disposition_type - Type of MIME disposition).
filename is the filename for MIME content disposition.
Example 4-45. creating MIME fields with only Content-Transfer-Encoding
#include <libetpan/libetpan.h> int main(void) { struct mailmime_fields * fields; fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_BASE64); /* do the things */ mailmime_fields_free(fields); } int main(void) { struct mailmime_fields * fields; fields = mailmime_fields_new_filename(MAILMIME_DISPOSITION_TYPE_ATTACHMENT, strdup("foo-bar.txt"), MAILMIME_MECHANISM_BASE64); /* do the things */ mailmime_fields_free(fields); }
#include <libetpan/libetpan.h> int mailmime_transfer_encoding_get(struct mailmime_fields * fields);
mailmime_transfer_encoding_get() will return the standard MIME encoding mechanism.
fields is the list of MIME header fields.
An integer representing the MIME encoding mechanism will be returned (see the Section called mailmime_mechanism - MIME transfer encoding mechanism (Content-Transfer-Encoding)).
Example 4-46. extracting MIME encoding mechanism
#include <libetpan/libetpan.h> #include <sys/stat.h> #include <sys/mman.h> int main(int argc, char ** argv) { int fd; int r; status = EXIT_FAILURE; fd = open("message.rfc2822", O_RDONLY); if (fd >= 0) { void * mem; struct stat stat_info; r = fstat(fd, &stat_info); if (r >= 0) { mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE); if (mem != MAP_FAILED) { struct mailimf_fields * f; size_t current_index; current_index = 0; r = mailimf_fields_parse(mem, stat_info.st_size, ¤t_index, &f); if (r == MAILIMF_NO_ERROR) { struct mailmime_fields * mime_fields; r = mailmime_fields_parse(f, &mime_fields); if (r == MAILIMF_NO_ERROR) { int encoding; encoding = mailmime_transfer_encoding_get(mime_fields); /* do the things */ mailmime_fields_free(mime_fields); status = EXIT_SUCCESS; } mailimf_fields_free(f); } } munmap(mem, stat_info.st_size); } close(fd); } exit(status); }
#include <libetpan/libetpan.h> char * mailmime_content_charset_get(struct mailmime_content * content); char * mailmime_content_param_get(struct mailmime_content * content, char * name); char * mailmime_extract_boundary(struct mailmime_content * content_type);
mailmime_content_charset_get() will return the charset parameter of MIME content type.
mailmime_content_param_get() will return the value of a given parameter of MIME content type.
mailmime_extract_boundary() will return the charset parameter of MIME content type.
content is the MIME content type.
name is the name of the parameter to extract.
With mailmime_extract_boundary(), the returned value must be freed with free().
Example 4-47. extracting information from MIME content type
#include <libetpan/libetpan.h> #include <sys/stat.h> #include <sys/mman.h> int main(int argc, char ** argv) { int fd; int r; status = EXIT_FAILURE; fd = open("message.rfc2822", O_RDONLY); if (fd >= 0) { void * mem; struct stat stat_info; r = fstat(fd, &stat_info); if (r >= 0) { mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE); if (mem != MAP_FAILED) { struct mailimf_fields * f; size_t current_index; current_index = 0; r = mailimf_fields_parse(mem, stat_info.st_size, ¤t_index, &f); if (r == MAILIMF_NO_ERROR) { clistiter * cur; for(cur = clist_begin(f->fld_list) ; cur != NULL ; cur = clist_next(cur)) { struct mailmime_field * mime_field; struct mailimf_field * field; field = clist_content(cur); if (field->fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) { if (strcasecmp(field->fld_data.fld_optional_field->fld_name, "Content-Type") == 0) { struct mailmime_content * content_type; size_t current_index; current_index = 0; r = mailmime_content_parse(field->fld_data.fld_optional_field->fld_value, strlen(field->fld_data.fld_optional_field->fld_value), ¤t_index, &content_type); if (r == MAILIMF_NO_ERROR) { char * charset; char * name; char * boundary; charset = mailmime_content_charset_get(content_type); name = mailmime_content_param_get(content_type, "name"); boundary = mailmime_extract_boundary(content_type); /* do the things */ free(boundary); status = EXIT_SUCCESS; mailmime_content_free(content_type); } } } } mailimf_fields_free(f); } } munmap(mem, stat_info.st_size); } close(fd); } exit(status); }
This part will give the definition of some objects.
A message can have attachment such as images or other documents. The attachment are organized into a tree structure. Each node of this structure is a MIME part.
A storage is a "physical" localisation of your mailbox. This can be on a filesystem (local or remote disk, this is the case of MH, mbox and maildir), or this can be on a remote host (this is the case for POP3, IMAP or NNTP).
A storage, for the same user, can contain a given number of mailboxes, depending the storage capabilities, then, the storage driver capabilities. With etPan!, MH, IMAP and NNTP storages can have more than one mailbox. The mailboxes will be called folders. On storage where we only have one mailbox, the unique mailbox is the unique folder.
The session is the network connection or the entity to which the commands of the drivers are given.
Error codes returned as integers can be one of the following :
enum { MAIL_NO_ERROR = 0, MAIL_NO_ERROR_AUTHENTICATED, MAIL_NO_ERROR_NON_AUTHENTICATED, MAIL_ERROR_NOT_IMPLEMENTED, MAIL_ERROR_UNKNOWN, MAIL_ERROR_CONNECT, MAIL_ERROR_BAD_STATE, MAIL_ERROR_FILE, MAIL_ERROR_STREAM, MAIL_ERROR_LOGIN, MAIL_ERROR_CREATE, /* 10 */ MAIL_ERROR_DELETE, MAIL_ERROR_LOGOUT, MAIL_ERROR_NOOP, MAIL_ERROR_RENAME, MAIL_ERROR_CHECK, MAIL_ERROR_EXAMINE, MAIL_ERROR_SELECT, MAIL_ERROR_MEMORY, MAIL_ERROR_STATUS, MAIL_ERROR_SUBSCRIBE, /* 20 */ MAIL_ERROR_UNSUBSCRIBE, MAIL_ERROR_LIST, MAIL_ERROR_LSUB, MAIL_ERROR_APPEND, MAIL_ERROR_COPY, MAIL_ERROR_FETCH, MAIL_ERROR_STORE, MAIL_ERROR_SEARCH, MAIL_ERROR_DISKSPACE, MAIL_ERROR_MSG_NOT_FOUND, /* 30 */ MAIL_ERROR_PARSE, MAIL_ERROR_INVAL, MAIL_ERROR_PART_NOT_FOUND, MAIL_ERROR_REMOVE, MAIL_ERROR_FOLDER_NOT_FOUND, MAIL_ERROR_MOVE, MAIL_ERROR_STARTTLS, MAIL_ERROR_CACHE_MISS, MAIL_ERROR_NO_TLS, MAIL_ERROR_EXPUNGE, /* misc errors */ MAIL_ERROR_MISC, MAIL_ERROR_PROTOCOL, MAIL_ERROR_CAPABILITY, MAIL_ERROR_CLOSE, MAIL_ERROR_FATAL, MAIL_ERROR_READONLY, MAIL_ERROR_NO_APOP, MAIL_ERROR_COMMAND_NOT_SUPPORTED, MAIL_ERROR_NO_PERMISSION, MAIL_ERROR_PROGRAM_ERROR, MAIL_ERROR_SUBJECT_NOT_FOUND, MAIL_ERROR_CHAR_ENCODING_FAILED, MAIL_ERROR_SEND, MAIL_ERROR_COMMAND, };
#include <libetpan/libetpan.h> typedef struct mailstorage_driver mailstorage_driver; struct mailstorage_driver { char * sto_name; int (* sto_connect)(struct mailstorage * storage); int (* sto_get_folder_session)(struct mailstorage * storage, char * pathname, mailsession ** result); void (* sto_uninitialize)(struct mailstorage * storage); };
This is the driver for a storage.
sto_name is the name of the driver.
sto_connect() connects the storage to the remote access or to the path in the local filesystem.
sto_get_folder_session() can have two kinds of behaviour. Either it creates a new session and independant from the session used by the storage and select the given mailbox or it selects the given mailbox in the current session. It depends on the efficiency of the mail access.
XXX - in the future, this will be moved to the folder driver
sto_uninitialize() frees the data created with mailstorage constructor.
#include <libetpan/libetpan.h> struct mailstorage { char * sto_id; void * sto_data; mailsession * sto_session; mailstorage_driver * sto_driver; clist * sto_shared_folders; /* list of (struct mailfolder *) */ void * sto_user_data; };
sto_id is an identifier for the storage. This can be NULL.
sto_data is the internal data of the storage. This can only be changed by the driver.
sto_session is the session used by the storage. The session can be used to send commands.
sto_driver is the driver of the storage.
sto_shared_folders is the list of folders that share the session with the storage. This is used internally.
sto_user_data is a field for free use. The user can store any data in that field.
#include <libetpan/libetpan.h> struct mailstorage * mailstorage_new(char * sto_id); void mailstorage_free(struct mailstorage * storage);
mailstorage_new() initializes a storage structure with an identifier (sto_id) and with no driver.
mailstorage_free() free the memory used by a storage.
#include <libetpan/libetpan.h> int mailstorage_connect(struct mailstorage * storage); void mailstorage_disconnect(struct mailstorage * storage);
mailstorage_connect() connects the storage. This function can also be used to confirm that a storage connection is valid when the storage is already connected.
mailstorage_disconnect() disconnects the storage.
int imap_mailstorage_init(struct mailstorage * storage, char * imap_servername, uint16_t imap_port, char * imap_command, int imap_connection_type, int imap_auth_type, char * imap_login, char * imap_password, int imap_cached, char * imap_cache_directory);
Example 5-1. use of storage
int main(void) { struct mailstorage * storage; int r; storage = mailstorage_new(NULL); imap_mailstorage_init(storage, "imap.my-servers.org", 0, NULL, CONNECTION_TYPE_TRY_STARTTLS, IMAP_AUTH_TYPE_PLAIN, "my-login", "my-password", 1, "/home/login/.libetpan/cache"); r = mailstorage_connect(storage); if (r == MAIL_NO_ERROR) { mailstorage_disconnect(storage); } mailstorage_free(storage); }
#include <libetpan/libetpan.h> typedef struct mailfolder_driver mailfolder_driver; struct mailfolder_driver { int (* fld_get_session)(struct mailfolder * folder, mailsession ** result); int (* fld_noop)(struct mailfolder * folder); int (* fld_check)(struct mailfolder * folder); int (* fld_expunge)(struct mailfolder * folder); int (* fld_status)(struct mailfolder * folder, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen); int (* fld_append_message)(struct mailfolder * folder, char * message, size_t size); int (* fld_get_messages_list)(struct mailfolder * folder, struct mailmessage_list ** result); int (* fld_get_envelopes_list)(struct mailfolder * folder, struct mailmessage_list * result); int (* fld_get_message)(struct mailfolder * folder, uint32_t num, mailmessage ** result); int (* fld_get_message_by_uid)(struct mailfolder * folder, const char * uid, mailmessage ** result); }
XXX - this will be implemented in the future.
fld_get_session() will return the session this folder should use.
For other method, you should see the Section called Session driver.
#include <libetpan/libetpan.h> struct mailfolder { char * fld_pathname; char * fld_virtual_name; struct mailstorage * fld_storage; mailsession * fld_session; int fld_shared_session; clistiter * fld_pos; struct mailfolder * fld_parent; unsigned int fld_sibling_index; carray * fld_children; /* array of (struct mailfolder *) */ void * fld_user_data; };
fld_pathname is the pathname specific to the driver.
fld_virtual_name is the identifier of this folder. This can be NULL.
fld_storage is the storage used for this folder (see the Section called Storage).
fld_session is the session used for this folder.
fld_shared_session is set to 1 if the folder use the same session as the storage. This is used internally.
fld_pos is the position in the list of folders of the storage. This is used internally.
use of fld_parent, fld_sibling_index and fld_children is deprecated.
fld_user_data is a field for free use. The user can store any data in that field.
#include <libetpan/libetpan.h> struct mailfolder * mailfolder_new(struct mailstorage * fld_storage, char * fld_pathname, char * fld_virtual_name); void mailfolder_free(struct mailfolder * folder);
mailfolder_new() initializes a folder structure with an identifier (fld_virtual_name) with path name (fld_pathname). The folder will be owned by the given storage (fld_storage).
mailfolder_free() free the memory used by the folder.
#include <libetpan/libetpan.h> int mailfolder_connect(struct mailfolder * folder); void mailfolder_disconnect(struct mailfolder * folder);
mailfolder_connect() connects the folder. This function can also be used to confirm that a folder connection is valid when the folder is already connected. When doing operations with several folders, you have to be sure that this function has been called before making calls on folder.
mailfolder_disconnect() disconnects the folder.
#include <libetpan/libetpan.h> int mailfolder_noop(struct mailfolder * folder);
This function will only send noop to the mail access.
#include <libetpan/libetpan.h> int mailfolder_check(struct mailfolder * folder);
A call to this function will save to disk the internal state of the selected mailbox (such as flags).
#include <libetpan/libetpan.h> int mailfolder_expunge(struct mailfolder * folder);
A call to this function will delete all messages marked for deletion.
int mailfolder_status(struct mailfolder * folder, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen);
A call to this function will return some counts of messages in the mailbox.
int mailfolder_append_message(struct mailfolder * folder, char * message, size_t size);
This function will store a new message in the given folder. The message is given by a string in memory (message) and a size (size).
int mailfolder_get_messages_list(struct mailfolder * folder, struct mailmessage_list ** result);
This function will return the list of messages in the given folder (see the Section called Message list).
int mailfolder_get_envelopes_list(struct mailfolder * folder, struct mailmessage_list * result);
This function will fill the list of parsed header fields structure in the mailmessage structures of the given list of messages (result).
int mailfolder_get_message(struct mailfolder * folder, uint32_t num, mailmessage ** result);
This function will return the message identified by a message index (num) This will return a mailmessage structure in (* result) (see the Section called Message).
int mailfolder_get_message_by_uid(struct mailfolder * folder, const char * uid, mailmessage ** result);
This function will return the message identified by a unique identifier (uid) This will return a mailmessage structure in (* result) (see the Section called Message).
Example 5-2. use of folder
int main(void) { struct mailstorage * storage; int r; storage = mailstorage_new(NULL); imap_mailstorage_init(storage, "imap.my-servers.org", 0, NULL, CONNECTION_TYPE_TRY_STARTTLS, IMAP_AUTH_TYPE_PLAIN, "my-login", "my-password", 1, "/home/login/.libetpan/cache"); r = mailstorage_connect(storage); if (r == MAIL_NO_ERROR) { struct mailfolder * folder; folder = mailfolder_new(storage, "INBOX", NULL); r = mailfolder_connect(folder); if (r == MAIL_NO_ERROR) { struct mailmessage_list * msg_list; mailfolder_get_messages_list(folder, &msg_list); /* do the things */ mailmessage_list_free(msg_list); mailfolder_disconnect(folder); } mailstorage_disconnect(storage); } mailstorage_free(storage); }
#include <libetpan/libetpan.h> struct mailmessage_driver { char * msg_name; int (* msg_initialize)(mailmessage * msg_info); void (* msg_uninitialize)(mailmessage * msg_info); void (* msg_flush)(mailmessage * msg_info); void (* msg_check)(mailmessage * msg_info); void (* msg_fetch_result_free)(mailmessage * msg_info, char * msg); int (* msg_fetch)(mailmessage * msg_info, char ** result, size_t * result_len); int (* msg_fetch_header)(mailmessage * msg_info, char ** result, size_t * result_len); int (* msg_fetch_body)(mailmessage * msg_info, char ** result, size_t * result_len); int (* msg_fetch_size)(mailmessage * msg_info, size_t * result); int (* msg_get_bodystructure)(mailmessage * msg_info, struct mailmime ** result); int (* msg_fetch_section)(mailmessage * msg_info, struct mailmime * mime, char ** result, size_t * result_len); int (* msg_fetch_section_header)(mailmessage * msg_info, struct mailmime * mime, char ** result, size_t * result_len); int (* msg_fetch_section_mime)(mailmessage * msg_info, struct mailmime * mime, char ** result, size_t * result_len); int (* msg_fetch_section_body)(mailmessage * msg_info, struct mailmime * mime, char ** result, size_t * result_len); int (* msg_fetch_envelope)(mailmessage * msg_info, struct mailimf_fields ** result); int (* msg_get_flags)(mailmessage * msg_info, struct mail_flags ** result); };
msg_name is the name of the driver.
msg_initialize() will initialize the internal message state (field msg_data of mailmessage structure (see the Section called Message).
msg_uninitialize() will free the internal message state.
msg_flush() will release memory used by the MIME structure of the message.
msg_check() will store the flags of the message into the session, so that the message can be released without the flags are lost.
msg_fetch_result_free() will free a string returned by any fetch_XXX() function.
msg_fetch() will fetch a message.
msg_fetch_header() will fetch the header fields of a message.
msg_fetch_body() will fetch a message without its main header.
msg_fetch_size() will return the size of a message.
msg_get_bodystructure will retrieve the MIME structure of the message. The returned structure must NOT be freed.
msg_fetch_section() will fetch the content of the section of the message.
msg_fetch_section_header() will fetch the header of a section of the message if the content of the section is a message.
msg_fetch_section_mime() will fetch the MIME header of a section of the message.
msg_fetch_section_body() will fetch the body of a section (without the headers) of the message if the content of the section is a message.
msg_fetch_envelope() will return a given number of parsed header fields.
msg_get_flags() will return the flags of the message. The returned structure must NOT be freed.
#include <libetpan/libetpan.h> struct mailmessage { mailsession * msg_session; mailmessage_driver * msg_driver; uint32_t msg_index; char * msg_uid; size_t msg_size; struct mailimf_fields * msg_fields; struct mail_flags * msg_flags; int msg_resolved; struct mailimf_single_fields msg_single_fields; struct mailmime * msg_mime; /* internal data */ int msg_cached; void * msg_data; /* msg_folder field : used to reference the mailfolder, this is a workaround due to the problem with initial conception, where folder notion did not exist. */ void * msg_folder; /* user data */ void * msg_user_data; };
msg_session is the session related to the message (see the Section called Session).
msg_driver is the driver used for the message (see the Section called Message driver).
msg_index is an index to indentify the message.
msg_uid is the unique identifier of the message, valid accross disconnections.
msg_size is the size of the message.
msg_fields is the list of parsed header fields of the message. This can be NULL (see the Section called mailimf_fields - list of header fields in Chapter 3).
msg_flags is the flags of the message. This can be NULL (see the Section called Message flags).
msg_resolved will tell if the field msg_single_fields has been initialized.
msg_single_fields will be filled using msg_fields (see the Section called mailimf_single_fields - simplified fields in Chapter 3).
msg_mime is the MIME structure of the message. It is intialized at least when get_bodystructure() is called once.
msg_cached is 1 when the message was cached. This is used internally.
msg_data is the internal state of the message. The content depends on the driver.
msg_folder is used to reference the mailfolder, this is a workaround due to the problem with initial conception, where folder notion did not exist.
msg_user_data is a field for free use. The user can store any data in that field.
#include <libetpan/libetpan.h> mailmessage * mailmessage_new(void); void mailmessage_free(mailmessage * info);
mailmessage_new() will create a new message (without driver). This is used internally by drivers.
mailmessage_free() will free the memory used by the given message.
#include <libetpan/libetpan.h> int mailmessage_init(mailmessage * msg_info, mailsession * session, mailmessage_driver * driver, uint32_t index, size_t size);
mailmessage_init() will initialize a message with a driver.
msg_info is the message to initialize (see the Section called Message).
session is the session related to the message (see the Section called Session).
driver is the driver to use for the message (see the Section called Message driver).
index is the index of the message.
size is the size of the message.
#include <libetpan/libetpan.h> int mailmessage_flush(mailmessage * info);
This function will release the memory used by the MIME structure of the message.
#include <libetpan/libetpan.h> int mailmessage_check(mailmessage * info);
After you set some flags, if you want to notify them to the session before destroying the message, you can use this function.
#include <libetpan/libetpan.h> int mailmessage_fetch_result_free(mailmessage * msg_info, char * msg);
This function will free a string returned by any mailmessage_fetch_XXX() function.
#include <libetpan/libetpan.h> int mailmessage_fetch(mailmessage * msg_info, char ** result, size_t * result_len);
This function returns the content of the message (headers and text).
#include <libetpan/libetpan.h> int mailmessage_fetch_header(mailmessage * msg_info, char ** result, size_t * result_len);
This function returns the header of the message as a string.
#include <libetpan/libetpan.h> int mailmessage_fetch_body(mailmessage * msg_info, char ** result, size_t * result_len);
This function returns the content of the message (without headers).
#include <libetpan/libetpan.h> int mailmessage_fetch_size(mailmessage * msg_info, size_t * result);
This function returns the size of the message content.
#include <libetpan/libetpan.h> int mailmessage_get_bodystructure(mailmessage * msg_info, struct mailmime ** result);
This functions returns the MIME structure of the message. The returned information MUST not be freed by hand. It is freed by mailmessage_flush() or mailmessage_free() (see the Section called mailmime - MIME part in Chapter 4).
#include <libetpan/libetpan.h> int mailmessage_fetch_section(mailmessage * msg_info, struct mailmime * mime, char ** result, size_t * result_len);
This function returns the content of a MIME part.
#include <libetpan/libetpan.h> int mailmessage_fetch_section_header(mailmessage * msg_info, struct mailmime * mime, char ** result, size_t * result_len);
This function returns the header of the message contained in the given MIME part.
#include <libetpan/libetpan.h> int mailmessage_fetch_section_mime(mailmessage * msg_info, struct mailmime * mime, char ** result, size_t * result_len);
This function returns the MIME header of the given MIME part.
#include <libetpan/libetpan.h> int mailmessage_fetch_section_body(mailmessage * msg_info, struct mailmime * mime, char ** result, size_t * result_len);
This function returns the text part of the message contained in the given MIME part.
#include <libetpan/libetpan.h> int mailmessage_fetch_envelope(mailmessage * msg_info, struct mailimf_fields ** result);
#include <libetpan/libetpan.h> int mailmessage_get_flags(mailmessage * msg_info, struct mail_flags ** result);
This function returns the flags related to the message. The returned information MUST not be freed by hand. It is freed by mailmessage_free().
#include <libetpan/libetpan.h> void mailmessage_resolve_single_fields(mailmessage * msg_info);
This function will use the fields information to fill the single_fields structure in the mailmessage structure.
#include <libetpan/libetpan.h> struct mailmessage_list { carray * msg_tab; /* elements are (mailmessage *) */ }; struct mailmessage_list * mailmessage_list_new(carray * msg_tab); void mailmessage_list_free(struct mailmessage_list * env_list);
This is a list of messages.
msg_tab is an array containing the messages (see linkend="carray").
mailmessage_list_new() will initialize a list of messages, using a given array of messages.
mailmessage_list_free() will free the memory used by the list of messages. This will also free the messages.
#include <libetpan/libetpan.h> struct mailmessage_tree { struct mailmessage_tree * node_parent; char * node_msgid; time_t node_date; mailmessage * node_msg; carray * node_children; /* array of (struct mailmessage_tree *) */ /* private, used for threading */ int node_is_reply; char * node_base_subject; }; struct mailmessage_tree * mailmessage_tree_new(char * node_msgid, time_t node_date, mailmessage * node_msg); void mailmessage_tree_free(struct mailmessage_tree * tree); void mailmessage_tree_free_recursive(struct mailmessage_tree * tree);
This is a node of a tree of messages.
node_parent is the parent of this node.
node_msgid is the content of the field Message-ID of the message.
node_date is the date in UNIX format.
node_msg is the message of the node. The message should have the msg_fields field initialized.
node_children is the list of children of this node.
node_is_reply is set to 1 if the message is a reply.
node_base_subject is the base subject of the message (base subject is defined in definition of IMAP thread draft).
mailmessage_tree_new() will initialize a message node.
mailmessage_tree_free() will release memory used by the node. This will NOT free the message.
#include <libetpan/libetpan.h> enum { MAIL_FLAG_NEW = 1 << 0, MAIL_FLAG_SEEN = 1 << 1, MAIL_FLAG_FLAGGED = 1 << 2, MAIL_FLAG_DELETED = 1 << 3, MAIL_FLAG_ANSWERED = 1 << 4, MAIL_FLAG_FORWARDED = 1 << 5, MAIL_FLAG_CANCELLED = 1 << 6, }; struct mail_flags { uint32_t fl_flags; clist * fl_extension; /* elements are (char *) */ }; struct mail_flags * mail_flags_new(uint32_t fl_flags, clist * fl_ext); void mail_flags_free(struct mail_flags * flags); int mail_flags_add_extension(struct mail_flags * flags, char * ext_flag); int mail_flags_remove_extension(struct mail_flags * flags, char * ext_flag); int mail_flags_has_extension(struct mail_flags * flags, char * ext_flag);
This is the structure containing the message flags.
fl_flags will contain the standards flags. The value will be a combinaison (with or binary operation) of MAIL_FLAG_XXX values.
fl_extension will be a list (see the Section called List in Chapter 2) of strings representing the non-standard flags.
Example 5-3. use of message
#include <libetpan/libetpan.h> #define DEST_CHARSET "iso-8859-1" enum { NO_ERROR, ERROR_FILE, ERROR_MEMORY, ERROR_INVAL, ERROR_FETCH, }; /* returns TRUE is given MIME part is a text part */ int etpan_mime_is_text(struct mailmime * build_info) { if (build_info->mm_type == MAILMIME_SINGLE) { if (build_info->mm_content_type != NULL) { if (build_info->mm_content_type->ct_type->tp_type == MAILMIME_TYPE_DISCRETE_TYPE) { if (build_info->mm_content_type->ct_type->tp_data.tp_discrete_type->dt_type == MAILMIME_DISCRETE_TYPE_TEXT) return 1; } } else return 1; } return 0; } /* display content type */ int show_part_info(FILE * f, struct mailmime_single_fields * mime_fields, struct mailmime_content * content) { char * description; char * filename; int col; int r; description = mime_fields->fld_description; filename = mime_fields->fld_disposition_filename; col = 0; r = fprintf(f, " [ Part "); if (r < 0) goto err; if (content != NULL) { r = mailmime_content_type_write(f, &col, content); if (r != MAILIMF_NO_ERROR) goto err; } if (filename != NULL) { r = fprintf(f, " (%s)", filename); if (r < 0) goto err; } if (description != NULL) { r = fprintf(f, " : %s", description); if (r < 0) goto err; } r = fprintf(f, " ]\n\n"); if (r < 0) goto err; return NO_ERROR; err: return ERROR_FILE; } /* fetch message and decode if it is base64 or quoted-printable */ int etpan_fetch_message(mailmessage * msg_info, struct mailmime * mime_part, struct mailmime_single_fields * fields, char ** result, size_t * result_len) { char * data; size_t len; int r; int encoding; char * decoded; size_t decoded_len; size_t cur_token; int res; int encoded; encoded = 0; r = mailmessage_fetch_section(msg_info, mime_part, &data, &len); if (r != MAIL_NO_ERROR) { res = ERROR_FETCH; goto err; } encoded = 1; /* decode message */ if (encoded) { if (fields->fld_encoding != NULL) encoding = fields->fld_encoding->enc_type; else encoding = MAILMIME_MECHANISM_8BIT; } else { encoding = MAILMIME_MECHANISM_8BIT; } cur_token = 0; r = mailmime_part_parse(data, len, &cur_token, encoding, &decoded, &decoded_len); if (r != MAILIMF_NO_ERROR) { res = ERROR_FETCH; goto free; } mailmessage_fetch_result_free(msg_info, data); * result = decoded; * result_len = decoded_len; return NO_ERROR; free: mailmessage_fetch_result_free(msg_info, data); err: return res; } /* fetch fields */ struct mailimf_fields * fetch_fields(mailmessage * msg_info, struct mailmime * mime) { char * data; size_t len; int r; size_t cur_token; struct mailimf_fields * fields; r = mailmessage_fetch_section_header(msg_info, mime, &data, &len); if (r != MAIL_NO_ERROR) return NULL; cur_token = 0; r = mailimf_envelopes_fields_parse(data, len, &cur_token, &fields); if (r != MAILIMF_NO_ERROR) { mailmessage_fetch_result_free(msg_info, data); return NULL; } mailmessage_fetch_result_free(msg_info, data); return fields; } /* render message */ static int etpan_render_mime(FILE * f, mailmessage * msg_info, struct mailmime * mime) { int r; clistiter * cur; int col; int text; int show; struct mailmime_single_fields fields; int res; mailmime_single_fields_init(&fields, mime->mm_mime_fields, mime->mm_content_type); text = etpan_mime_is_text(mime); r = show_part_info(f, &fields, mime->mm_content_type); if (r != NO_ERROR) { res = r; goto err; } switch(mime->mm_type) { case MAILMIME_SINGLE: show = 0; if (text) show = 1; if (show) { char * data; size_t len; char * converted; size_t converted_len; char * source_charset; size_t write_len; /* viewable part */ r = etpan_fetch_message(msg_info, mime, &fields, &data, &len); if (r != NO_ERROR) { res = r; goto err; } source_charset = fields.fld_content_charset; if (source_charset == NULL) source_charset = DEST_CHARSET; r = charconv_buffer(source_charset, DEST_CHARSET, data, len, &converted, &converted_len); if (r != MAIL_CHARCONV_NO_ERROR) { r = fprintf(f, "[ error converting charset from %s to %s ]\n", source_charset, DEST_CHARSET); if (r < 0) { res = ERROR_FILE; goto err; } write_len = fwrite(data, 1, len, f); if (write_len != len) { mailmime_decoded_part_free(data); res = r; goto err; } } else { write_len = fwrite(converted, 1, converted_len, f); if (write_len != len) { charconv_buffer_free(converted); mailmime_decoded_part_free(data); res = r; goto err; } charconv_buffer_free(converted); } write_len = fwrite("\r\n\r\n", 1, 4, f); if (write_len < 4) { mailmime_decoded_part_free(data); res = ERROR_FILE; goto err; } mailmime_decoded_part_free(data); } else { /* not viewable part */ r = fprintf(f, " (not shown)\n\n"); if (r < 0) { res = ERROR_FILE; goto err; } } break; case MAILMIME_MULTIPLE: if (strcasecmp(mime->mm_content_type->ct_subtype, "alternative") == 0) { struct mailmime * prefered_body; int prefered_score; /* case of multiple/alternative */ /* we choose the better part, alternative preference : text/plain => score 3 text/xxx => score 2 other => score 1 */ prefered_body = NULL; prefered_score = 0; for(cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) { struct mailmime * submime; int score; score = 1; submime = clist_content(cur); if (etpan_mime_is_text(submime)) score = 2; if (submime->mm_content_type != NULL) { if (strcasecmp(submime->mm_content_type->ct_subtype, "plain") == 0) score = 3; } if (score > prefered_score) { prefered_score = score; prefered_body = submime; } } if (prefered_body != NULL) { r = etpan_render_mime(f, msg_info, prefered_body); if (r != NO_ERROR) { res = r; goto err; } } } else { for(cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) { r = etpan_render_mime(f, msg_info, clist_content(cur)); if (r != NO_ERROR) { res = r; goto err; } } } break; case MAILMIME_MESSAGE: if (mime->mm_data.mm_message.mm_fields != NULL) { struct mailimf_fields * fields; if (msg_info != NULL) { fields = fetch_fields(msg_info, mime); if (fields == NULL) { res = ERROR_FETCH; goto err; } col = 0; r = mailimf_fields_write(f, &col, fields); if (r != NO_ERROR) { mailimf_fields_free(fields); res = r; goto err; } mailimf_fields_free(fields); } else { col = 0; r = fields_write(f, &col, mime->mm_data.mm_message.mm_fields); if (r != NO_ERROR) { res = r; goto err; } } r = fprintf(f, "\r\n"); if (r < 0) { res = ERROR_FILE; goto err; } } if (mime->mm_data.mm_message.mm_msg_mime != NULL) { r = etpan_render_mime(f, msg_info, mime->mm_data.mm_message.mm_msg_mime); if (r != NO_ERROR) { res = r; goto err; } } break; } return NO_ERROR; err: return res; } int main(void) { struct mailstorage * storage; int r; storage = mailstorage_new(NULL); imap_mailstorage_init(storage, "imap.my-servers.org", 0, NULL, CONNECTION_TYPE_TRY_STARTTLS, IMAP_AUTH_TYPE_PLAIN, "my-login", "my-password", 1, "/home/login/.libetpan/cache"); r = mailstorage_connect(storage); if (r == MAIL_NO_ERROR) { struct mailfolder * folder; folder = mailfolder_new(storage, "INBOX", NULL); r = mailfolder_connect(folder); if (r == MAIL_NO_ERROR) { struct mailmessage_list * msg_list; mailmessage * msg; mailfolder_get_messages_list(folder, &msg_list); if (carray_count(msg_list->msg_tab) > 0) { struct mailmime * mime; msg = carray_get(msg_list->msg_tab, 0); mailmessage_get_bodystructure(msg, &mime); recursive_fetch(msg, mime); /* do the things */ mailmessage_flush(msg); } mailmessage_list_free(msg_list); mailfolder_disconnect(folder); } mailstorage_disconnect(storage); } mailstorage_free(storage); }
#include <libetpan/libetpan.h> struct mailsession_driver { char * sess_name; int (* sess_initialize)(mailsession * session); void (* sess_uninitialize)(mailsession * session); int (* sess_parameters)(mailsession * session, int id, void * value); int (* sess_connect_stream)(mailsession * session, mailstream * s); int (* sess_connect_path)(mailsession * session, char * path); int (* sess_starttls)(mailsession * session); int (* sess_login)(mailsession * session, char * userid, char * password); int (* sess_logout)(mailsession * session); int (* sess_noop)(mailsession * session); /* folders operations */ int (* sess_build_folder_name)(mailsession * session, char * mb, char * name, char ** result); int (* sess_create_folder)(mailsession * session, char * mb); int (* sess_delete_folder)(mailsession * session, char * mb); int (* sess_rename_folder)(mailsession * session, char * mb, char * new_name); int (* sess_check_folder)(mailsession * session); int (* sess_examine_folder)(mailsession * session, char * mb); int (* sess_select_folder)(mailsession * session, char * mb); int (* sess_expunge_folder)(mailsession * session); int (* sess_status_folder)(mailsession * session, char * mb, uint32_t * result_num, uint32_t * result_recent, uint32_t * result_unseen); int (* sess_messages_number)(mailsession * session, char * mb, uint32_t * result); int (* sess_recent_number)(mailsession * session, char * mb, uint32_t * result); int (* sess_unseen_number)(mailsession * session, char * mb, uint32_t * result); int (* sess_list_folders)(mailsession * session, char * mb, struct mail_list ** result); int (* sess_lsub_folders)(mailsession * session, char * mb, struct mail_list ** result); int (* sess_subscribe_folder)(mailsession * session, char * mb); int (* sess_unsubscribe_folder)(mailsession * session, char * mb); /* messages operations */ int (* sess_append_message)(mailsession * session, char * message, size_t size); int (* sess_copy_message)(mailsession * session, uint32_t num, char * mb); int (* sess_move_message)(mailsession * session, uint32_t num, char * mb); int (* sess_get_message)(mailsession * session, uint32_t num, mailmessage ** result); int (* sess_get_message_by_uid)(mailsession * session, const char * uid, mailmessage ** result); int (* sess_get_messages_list)(mailsession * session, struct mailmessage_list ** result); int (* sess_get_envelopes_list)(mailsession * session, struct mailmessage_list * env_list); int (* sess_remove_message)(mailsession * session, uint32_t num); };
This is a driver for a session.
sess_name is the name of the driver.
sess_initialize() is the function that will initializes a data structure (field sess_data in the session) specific to the driver. The field data (field sess_data in the session) is the state of the session, the internal data structure used by the driver. It is called when creating the mailsession structure with mailsession_new().
sess_uninitialize() frees the structure created with sess_initialize()
sess_parameters() implements functions specific to the given mail access.
sess_connect_stream() connects a stream to the session.
sess_connect_path() notify a main path to the session.
sess_starttls() changes the current stream to a TLS stream (see the Section called TLS stream in Chapter 2).
sess_login() notifies the user and the password to authenticate to the session.
sess_logout() exits the session and closes the stream.
sess_noop() does no operation on the session, but it can be used to poll for the status of the connection.
sess_build_folder_name() will return an allocated string with that contains the complete path of the folder to create. Use of this method is deprecated.
sess_create_folder() creates the folder that corresponds to the given name. Use of this method is deprecated.
sess_delete_folder() deletes the folder that corresponds to the given name. Use of this method is deprecated.
sess_rename_folder() change the name of the folder. Use of this method is deprecated.
sess_check_folder() makes a checkpoint of the session.
sess_examine_folder() selects a mailbox as readonly. Use of this method is deprecated.
sess_select_folder() selects a mailbox.
sess_expunge_folder() deletes all messages marked \Deleted.
sess_status_folder() queries the status of the folder (number of messages, number of recent messages, number of unseen messages).
sess_messages_number() queries the number of messages in the folder.
sess_recent_number() queries the number of recent messages in the folder.
sess_unseen_number() queries the number of unseen messages in the folder.
sess_list_folders() returns the list of all sub-mailboxes of the given mailbox. Use of this method is deprecated.
sess_lsub_folders() returns the list of subscribed sub-mailboxes of the given mailbox. Use of this method is deprecated.
sess_subscribe_folder() subscribes to the given mailbox. Use of this method is deprecated.
sess_unsubscribe_folder() unsubscribes to the given mailbox. Use of this method is deprecated.
sess_append_message() adds a RFC 2822 message to the current given mailbox.
sess_copy_message() copies a message whose number is given to a given mailbox. The mailbox must be accessible from the same session. Use of this method is deprecated.
sess_move_message() moves a message whose number is given to a given mailbox. The mailbox must be accessible from the same session. Use of this method is deprecated.
sess_get_messages_list() returns the list of message numbers of the current mailbox (see the Section called Message list).
sess_get_envelopes_list() fills the parsed fields in the mailmessage structures (see the Section called Message) of the mailmessage_list (see the Section called Message list).
sess_remove_message() removes the given message from the mailbox. The message is permanently deleted. Use of this method is deprecated.
sess_get_message() returns a mailmessage structure (see the Section called Message) that corresponds to the given message number. Use of this method is deprecated.
sess_get_message_by_uid() returns a mailmessage structure (see the Section called Message) that corresponds to the given message unique identifier.
mandatory functions are the following :
sess_connect_stream() or connect_path()
sess_logout()
sess_get_messages_list()
sess_get_envelopes_list()
we advise you to implement these functions :
sess_select_folder() (in case a session can access several folders).
sess_noop() (to check if the server is responding)
sess_check_folder() (to make a checkpoint of the session)
sess_status_folder(), sess_messages_number(), sess_recent_number(), sess_unseen_number() (to get stat of the folder)
sess_append_message() (but can't be done in the case of POP3 at least).
sess_login() in a case of an authenticated driver.
sess_starttls() in a case of a stream driver, if the procotol supports STARTTLS.
sess_get_message_by_uid() so that the application can remember the messages by UID and build its own list of messages.
Everything that is specific to the driver will be implemented in sess_parameters().
#include <libetpan/libetpan.h> struct mailsession { void * sess_data; mailsession_driver * sess_driver; }; mailsession * mailsession_new(mailsession_driver * sess_driver); void mailsession_free(mailsession * session);
This is a session. This is an abstraction used to access the storage, using the network or the filesystem.
sess_data is the state of the session. This is specific to the driver.
sess_driver is the driver of the session.
mailsession_new() will create a new session using the given driver (sess_driver).
mailsession_free() will release the memory used by the session.
#include <libetpan/libetpan.h> int mailsession_parameters(mailsession * session, int id, void * value);
This function make calls specific to the driver
#include <libetpan/libetpan.h> int mailsession_connect_stream(mailsession * session, mailstream * s);
There are drivers of two kinds : stream drivers (driver that connects to servers through TCP or other means of connection) and file drivers (driver that are based on filesystem) This function can only be used by stream drivers and this connects a stream to the session
#include <libetpan/libetpan.h> int mailsession_connect_path(mailsession * session, char * path);
This function can only be used by file drivers and selects the main path of the session.
#include <libetpan/libetpan.h> int mailsession_starttls(mailsession * session);
This switches the current connection to TLS (secure layer). This will only work with stream drivers.
#include <libetpan/libetpan.h> int mailsession_login(mailsession * session, char * userid, char * password);
This notifies the login and the password to authenticate to the session.
#include <libetpan/libetpan.h> int mailsession_logout(mailsession * session);
This function disconnects the session and closes the stream.
#include <libetpan/libetpan.h> int mailsession_noop(mailsession * session);
This function does no operation on the session, but it can be used to poll for the status of the connection.
#include <libetpan/libetpan.h> int mailsession_check_folder(mailsession * session);
This function makes a checkpoint of the session.
#include <libetpan/libetpan.h> int mailsession_select_folder(mailsession * session, char * mb);
This function selects a mailbox.
#include <libetpan/libetpan.h> int mailsession_expunge_folder(mailsession * session);
This function deletes all messages marked for deletion.
#include <libetpan/libetpan.h> int mailsession_status_folder(mailsession * session, char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen);
This function queries the status of the folder (number of messages, number of recent messages, number of unseen messages).
#include <libetpan/libetpan.h> int mailsession_messages_number(mailsession * session, char * mb, uint32_t * result);
This function queries the number of messages in the folder.
#include <libetpan/libetpan.h> int mailsession_recent_number(mailsession * session, char * mb, uint32_t * result);
This function queries the number of recent messages in the folder.
#include <libetpan/libetpan.h> int mailsession_unseen_number(mailsession * session, char * mb, uint32_t * result);
This function queries the number of unseen messages in the folder.
#include <libetpan/libetpan.h> int mailsession_append_message(mailsession * session, char * message, size_t size);
This adds a RFC 2822 message to the current mailbox.
#include <libetpan/libetpan.h> int mailsession_get_messages_list(mailsession * session, struct mailmessage_list ** result);
This function returns the list of messages of the current mailbox.
#include <libetpan/libetpan.h> int mailsession_get_envelopes_list(mailsession * session, struct mailmessage_list * result);
This function fills the parsed fields in the mailmessage structures (see the Section called Message) of the mailmessage_list (see the Section called Message list).
#include <libetpan/libetpan.h> int mailsession_get_message(mailsession * session, uint32_t num, mailmessage ** result);
This function returns a mailmessage (see the Section called Message) structure that corresponds to the given message number.
| Warning |
mailsession_get_message_by_uid() should be used instead. |
#include <libetpan/libetpan.h> int mailsession_get_message_by_uid(mailsession * session, const char * uid, mailmessage ** result);
This function returns a mailmessage structure that corresponds to the given message unique identifier. This is currently implemented only for cached drivers.
| Warning |
That deprecates the use of mailsession_get_message(). |