From e3b89230f065c48c84b48c88edb6eb088374c487 Mon Sep 17 00:00:00 2001 From: zautrix Date: Sat, 03 Jul 2004 16:33:12 +0000 Subject: Initial revision --- (limited to 'kmicromail/libetpan/doc') diff --git a/kmicromail/libetpan/doc/API.sgml b/kmicromail/libetpan/doc/API.sgml new file mode 100644 index 0000000..4516979 --- a/dev/null +++ b/kmicromail/libetpan/doc/API.sgml @@ -0,0 +1,15097 @@ + + + + + 2003-12-03 + libEtPan! API + + + Viet Hoa + DINH + + + + 2003 + DINH Viet Hoa + + + + + + + Introduction + + This document will describe the API of libEtPan! + + + + + + Tools and datatypes + + + libEtPan! include a collection of datatypes such as lists, + arrays, hash tables and tools such as buffered I/O. + + + + + Array + + +#include <libetpan/libetpan.h> + +typedef struct carray_s carray; + + + + carray is an array of pointers that will + resize automatically in case a new element is added. + + + + The carray is implemented with an array + (void **) that can be resized. An array has a + size: this is the number of elements that can be added before + the table is resized. It also has a count of elements: this is + the elements that exist in the array. + + + + carray_new and carray_free + + +carray * carray_new(unsigned int initsize); + +void carray_free(carray * array); + + + + carray_new() creates a new array with an + initial size. The array is not resized until the number of + element reach the initial size. It returns + NULL in case of failure. + + + + carray_free() releases memory used by the + given array. + + + + carray creation + +#include <libetpan/libetpan.h> +#include <stdlib.h> + +#define SIZE 50 + +int main(void) +{ + carray * a; + + a = carray_new(SIZE); + if (a == NULL) + exit(EXIT_FAILURE); + + /* do things here */ + + carray_free(a); + + exit(EXIT_SUCESS); +} + + + + + + carray_set_size + + +int carray_set_size(carray * array, uint32_t new_size); + + + + carray_set_size() sets the size of the + array. It returns 0 in case of success, + -1 in case of failure. + + + + preallocating carray + +#include <libetpan/libetpan.h> +#include <stdlib.h> + +#define SIZE 50 +#define NEWSIZE 200 + +int main(void) +{ + carray * a; + unsigned int i; + char p[500]; + + a = carray_new(SIZE); + if (a == NULL) + goto err; + + r = carray_set_size(NEWSIZE); + if (r < 0) + goto free; + + for(i = 0 ; i < NEWSIZE ; i ++) + carray_set(a, i, &p[i]); + + /* do things here */ + + carray_free(a); + + exit(EXIT_SUCESS); + + free: + carray_free(a); + err: + exit(EXIT_FAILURE); +} + + + + + + + carray_count, carray_add, carray_get and carray_set + + +int carray_count(carray); + +int carray_add(carray * array, void * data, unsigned int * index); + +void * carray_get(carray * array, unsigned int indx); + +void carray_set(carray * array, unsigned int indx, void * value); + + + + carray_count() returns the number of + elements in the carray. + Complexity is O(1). + + + + carray_add()adds an element at the end of + the array. The index of the element is + returns in (* index) if + index is not NULL. It + returns 0 in case of success, + -1 in case of failure. + Complexity is O(1). + + + + carray_get() returns the elements contained + at the given cell of the table. + Complexity is O(1). + + + + carray_set() replace the element at the + given index of table table with the given value. + Complexity is O(1). + + + + carray access + +#include <libetpan/libetpan.h> +#include <string.h> + +#define SIZE 50 + +int main(void) +{ + carray * a; + int r; + + a = carray_new(SIZE); + if (a == NULL) + goto err; + + r = carray_add(a, "foo-bar-1", NULL); + if (r < 0) + goto free; + + carray_add(a, "foo-bar-2", NULL); + if (r < 0) + goto free; + + carray_add(a, "foo-bar-3", NULL); + if (r < 0) + goto free; + + for(i = 0 ; i < carray_count(a) ; i ++) { + char * str; + + str = carray_get(a, i); + if (strcmp("foo-bar-2", str) == 0) + carray_set(a, i, "foo-bar-2-replacement"); + + printf("%s\n", str); + } + + carray_free(a); + + exit(EXIT_SUCESS); + + free: + carray_free(a); + err: + exit(EXIT_FAILURE); +} + + + + + + + + carray_delete + + +int carray_delete(carray * array, uint32_t indx); + +int carray_delete_slow(carray * array, uint32_t indx); + +int carray_delete_fast(carray * array, uint32_t indx); + + + + carray_delete() removes an element of the + table. Order will not be garanteed. The returned result can + be ignored. + Complexity is O(1). + + + + carray_delete_slow() removes an element of + the table. Order will be garanteed. The returned result can + be ignored. + Complexity is O(n). + + + + carray_delete_fast() the element will just + be replaced with NULL. Order will be kept + but the number of elements will remains the same. The + returned result can be ignored. + Complexity is O(1). + + + + deletion in carray + +#include <libetpan/libetpan.h> + +#define SIZE 50 + +carray * build_array(void) +{ + carray * a; + + a = carray_new(SIZE); + if (a == NULL) + goto err; + + r = carray_add(a, "foo-bar-1", NULL); + if (r < 0) + goto free; + + carray_add(a, "foo-bar-2", NULL); + if (r < 0) + goto free; + + carray_add(a, "foo-bar-3", NULL); + if (r < 0) + goto free; + + return a; + + free: + carray_free(a); + err: + exit(EXIT_FAILURE); +} + +void delete(carray * a) +{ + /* deleting foo-bar-1 */ + carray_delete(a, 0); + /* resulting size is 2, order of elements is undefined */ +} + +void delete_slow(carray * a) +{ + /* deleting foo-bar-1 */ + carray_delete_slow(a, 0); + /* resulting size is 2, order of elements is the same */ +} + +void delete_fast(carray * a) +{ + /* deleting foo-bar-1 */ + carray_delete_slow(a, 0); + /* + resulting size is 3, + order of elements is { NULL, foo-bar-2, foo-bar-3 } + */ +} + + + + + + + carray_data + + +void ** carray_data(carray); + + + + carray_datareturns the table used for + implementation : + (void **). + + + + + + + + + + List + + +#include <libetpan/libetpan.h> + +typedef struct clist_s clist; + +typedef clistcell clistiter; + + + + clist() is a list of cells. + Each cell of the list contains one element. This element is a + pointer. An iterator (clistiter) is a + pointer to an element of the list. With an iterator, we can + get the previous element of the list, the next element of the + list and the content of the element. + + + + clist_new and clist_free + + +clist * clist_new(void); + +void clist_free(clist *); + + + + clist_new() allocates a new empty list and + returns it. + + + + clist_free() frees the entire list with + its cells. + + + + clist creation + +#include <libetpan/libetpan.h> + +int main(void) +{ + clist * list; + + list = clist_new(); + if (list == NULL) + goto err; + + r = clist_append(list, "foo-bar"); + if (r < 0) + + clist_free(list); + + exit(EXIT_SUCCESS); + + free: + clist_free(list); + err: + exit(EXIT_FAILURE); +} + + + + + + clist_isempty and clist_count + + +int clist_isempty(clist *); + +int clist_count(clist *); + + + + clist_isempty() returns 1 if the list is + empty, else it is 0. + Complexity is O(1). + + + + clist_count() returns the number of + elements in the list. + Complexity is O(1). + + + + + running through clist + + +clistiter * clist_begin(clist *); + +clistiter * clist_end(clist *); + +clistiter * clist_next(clistiter *); + +clistiter * clist_previous(clistiter *); + +void * clist_content(clistiter *); + +void * clist_nth_data(clist * lst, int index); + +clistiter * clist_nth(clist * lst, int index); + + + + clist_begin() returns an iterator to the + first element of the list. + Complexity is O(1). + + + + clist_end() returns an iterator to the last + element of the list. + Complexity is O(1). + + + + clist_next() returns an iterator to the + next element of the list. + Complexity is O(1). + + + + clist_previous() returns an iterator to the + previous element of the list. + Complexity is O(1). + + + + clist_content() returns the element + contained in the cell pointed by the iterator in the list. + Complexity is O(1). + + + + clist_nth() returns an iterator on the + index-th element of the list. + Complexity is O(n). + + + + clist_nth_data() returns the index-th + element of the list. + Complexity is O(n). + + + + displaying content of clist + +#include <libetpan/libetpan.h> + +int main(void) +{ + clist * list; + clistiter * iter; + + list = build_string_list(); + if (list == NULL) + goto err; + + for(iter = clist_begin(list) ; iter != NULL ; iter = + clist_next(iter)) { + char * str; + + str = clist_content(iter); + printf("%s\n", str); + } + + clist_free(list); + + exit(EXIT_SUCCESS); + + free: + clist_free(list); + err: + exit(EXIT_FAILURE); +} + + + + + + + clist modification + + +int clist_prepend(clist *, void *); + +int clist_append(clist *, void *); + +int clist_insert_before(clist *, clistiter *, void *); + +int clist_insert_after(clist *, clistiter *, void *); + +clistiter * clist_delete(clist *, clistiter *); + + + + clist_prepend() adds an element at the + beginning of the list. Returns 0 on sucess, -1 on error. + Complexity is O(1). + + + + clist_append() adds an element at the end + of the list. Returns 0 on sucess, -1 on error. + Complexity is O(1). + + + + clist_insert_before() adds an element + before the element pointed by the given iterator in the + list. Returns 0 on sucess, -1 on error. + Complexity is O(1). + + + + clist_insert_after() adds an element after + the element pointed by the given iterator in the list. + Returns 0 on sucess, -1 on error. + Complexity is O(1). + + + + clist_delete() the elements pointed by + the given iterator in the list and returns an iterator to + the next element of the list. + Complexity is O(1). + + + + deleting elements in a clist + +#include <libetpan/libetpan.h> + +voir print_content(void * content, void * user_data) +{ + char * str; + + str = content; + + printf("%s\n", str); +} + +int main(void) +{ + clist * list; + clistiter * iter; + + list = build_string_list(); + if (list == NULL) + goto err; + + iter = = clist_begin(list); + while (iter != NULL) + char * str; + + str = clist_content(iter); + if (strcmp(str, "foo-bar") == 0) + iter = clist_delete(list, cur); + else + iter = clist_next(iter); + } + + clist_foreach(list, print_content, NULL); + printf("\n"); + + clist_free(list); + + exit(EXIT_SUCCESS); + + free: + clist_free(list); + err: + exit(EXIT_FAILURE); +} + + + + + + clist_foreach + + +typedef void (* clist_func)(void *, void *); + +void clist_foreach(clist * lst, clist_func func, void * data); + + + + clist_foreach() apply a fonction to each + element of the list. + Complexity is O(n). + + + + + clist_concat + + +void clist_concat(clist * dest, clist * src); + + + + clist_concat() adds all the elements of src + at the end of dest. Elements are added in the same + order. src is an empty list when the operation is finished. + Complexity is O(1). + + + + merging two clists + +#include <libetpan/libetpan.h> + +int main(void) +{ + clist * list; + clist * list_2; + clistiter * iter; + + list = build_string_list(); + if (list == NULL) + goto err; + + list_2 = build_string_list_2(); + if (list == NULL) + goto free_list; + + clist_concat(list, list_2); + clist_free(list_2); + + for(iter = clist_begin(list) ; iter != NULL ; iter = + clist_next(iter)) { + char * str; + + str = clist_content(iter); + printf("%s\n", str); + } + + clist_free(list); + + exit(EXIT_SUCCESS); + + free_list: + clist_free(list); + err: + exit(EXIT_FAILURE); +} + + + + + + + + + Hash table + + +#include <libetpan/libetpan.h> + +typedef struct chash chash; + +typedef struct chashcell chashiter; + +typedef struct { + char * data; + int len; +} chashdatum; + + + + chash is a hash table. + chashiter is a pointer to an element of the + hash table. + chashdatum is an element to be placed in + the hash table as a key or a value. It consists in + data and a corresponding length. + + + + chash_new and chash_free + +#define CHASH_COPYNONE 0 +#define CHASH_COPYKEY 1 +#define CHASH_COPYVALUE 2 +#define CHASH_COPYALL (CHASH_COPYKEY | CHASH_COPYVALUE) + +chash * chash_new(int size, int flags); + +void chash_free(chash * hash); + + + + chash_new() returns a new empty hash table + or NULL if this + failed. size is the initial size of the + table used for implementation. flags can + be a combinaison of CHASH_COPYKEY and + CHASH_COPYVALUE. + CHASH_COPYKEY enables copy of key, so + that the initial value used for chash_set() + + + + chash_free() releases memory used by the + hash table. + + + + + chash_set and chash_get + +int chash_set(chash * hash, + chashdatum * key, chashdatum * value, chashdatum * oldvalue); + +int chash_get(chash * hash, + chashdatum * key, chashdatum * result); + + + + chash_set() adds a new element into the + hash table. If a previous element had the same key, it is + returns into oldvalue if oldvalue is + different of NULL. + Medium complexity is O(1). + + + + returns -1 if it fails, 0 on success. + + + + chash_get()returns the corresponding value + of the given key. If there is no corresponding value, -1 is + returned. 0 on success. + Medium complexity is O(1). + + + + chash insert and lookup + +int main(void) +{ + chash * hash; + int r; + chashdatum key; + chashdatum value; + char * str1 = "my-data"; + char * str2 = "my-data"; + + hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYNONE); + + key.data = "foo"; + key.len = strlen("foo"); + value.data = str1; + value.data = strlen(str1) + 1; + /* + 1 is needed to get the terminal zero in the returned string */ + r = chash_set(hash, &key, &value, NULL); + if (r < 0) + goto free_hash; + + key.data = "bar"; + key.len = strlen("bar"); + value.data = str2; + value.data = strlen(str2) + 1; + if (r < 0) + goto free_hash; + + key.data = "foo"; + key.len = strlen("foo"); + r = chash_get(hash, &key, &value); + if (r < 0) { + printf("element not found\n"); + } + else { + char * str; + + str = value.data; + printf("found : %s", str); + } + + chash_free(hash); + + exit(EXIT_SUCCESS); + + free_hash: + chash_free(hash); + err: + exit(EXIT_FAILURE); +} + + + + + + chash_delete + +int chash_delete(chash * hash, + chashdatum * key, chashdatum * oldvalue); + + + + deletes the key/value pair given the corresponding key. + The value is returned in old_value. + If there is no corresponding value, -1 is returned. 0 on success. + Medium complexity is O(1). + + + + key deletion in a chash + +int main(void) +{ + chash * hash; + int r; + chashdatum key; + chashdatum value; + char * str1 = "my-data"; + char * str2 = "my-data"; + + hash = build_hash(); + + key.data = "foo"; + key.len = strlen("foo"); + chash_delete(hash, &key, &value); + + /* it will never be possible to lookup "foo" */ + key.data = "foo"; + key.len = strlen("foo"); + r = chash_get(hash, &key, &value); + if (r < 0) { + printf("element not found\n"); + } + else { + char * str; + + str = value.data; + printf("found : %s", str); + } + + chash_free(hash); + + exit(EXIT_SUCCESS); + + free_hash: + chash_free(hash); + err: + exit(EXIT_FAILURE); +} + + + + + + chash_resize + +int chash_resize(chash * hash, int size); + + + + chash_resize() changes the size of the + table used for implementation of the hash table. + returns 0 on success, -1 on failure. + + + + + running through the chash + +chashiter * chash_begin(chash * hash); + +chashiter * chash_next(chash * hash, chashiter * iter); + +void chash_key(chashiter * iter, chashdatum * result); + +void chash_value(chashiter iter, chashdatum * result); + + + + chash_begin() returns a pointer to the + first element of the hash table. Returns + NULL if there is no elements in the hash + table. + Complexity is O(n). + + + + chash_next() returns a pointer to the next + element of the hash table. Returns NULL + if there is no next element. + Complexity is O(n) but n calls to chash_next() also has + a complexity of O(n). + + + + chash_key() returns the key of the given + element of the hash table. + + + + chash_value returns the value of the + given element of the hash table. + + + + running through a chash + +int main(void) +{ + chash * hash; + int r; + chashiter * iter; + + hash = build_hash(); + + /* this will display all the values stored in the hash */ + for(iter = chash_begin(hash) ; iter != NULL ; iter = + chash_next(hash, iter)) { + chashdatum key; + chashdatum value; + char * str; + + chash_value(iter, &value); + str = value.data; + printf("%s\n", str); + } + + chash_free(hash); +} + + + + + + chash_size and chash_count + +int chash_size(chash * hash); + +int chash_count(chash * hash); + + + + chash_size() returns the size of the table + used for implementation of the hash table. + Complexity is O(1). + + + + chash_count() returns the number of + elements in the hash table. + Complexity is O(1). + + + + + + + Buffered I/O + + +#include <libetpan/libetpan.h> + +typedef struct _mailstream mailstream; + + + + streams are objects where we can read data from and write data + to. They are not seekable. That can be for example a pipe or a + network stream. + + + +mailstream * mailstream_new(mailstream_low * low, size_t buffer_size); + +int mailstream_close(mailstream * s); + + + + mailstream_new() creates a new stream + stream with the low-level (see ) + stream and a given buffer size. + + + + mailstream_close() closes the stream. + This function will be in charge to free the + mailstream_low structure. + + + + +ssize_t mailstream_write(mailstream * s, void * buf, size_t count); + +int mailstream_flush(mailstream * s); + +ssize_t mailstream_read(mailstream * s, void * buf, size_t count); + +ssize_t mailstream_feed_read_buffer(mailstream * s); + + + + mailstream_write() writes a buffer to the + given stream. This write operation will be buffered. + + + + mailstream_flush() will force a write of + all buffered data for a given stream. + + + + mailstream_read() reads data from the + stream to the given buffer. + + + + mailstream_feed_read_buffer() this function + will just fill the buffer for reading. + + + +mailstream_low * mailstream_get_low(mailstream * s); + +void mailstream_set_low(mailstream * s, mailstream_low * low); + + + + mailstream_get_low() returns the low-level + stream of the given stream. + + + + mailstream_set_low() changes the low-level + of the given stream. Useful, for + example, when a stream change from clear stream to SSL + stream. + + + +char * mailstream_read_line(mailstream * stream, MMAPString * line); + +char * mailstream_read_line_append(mailstream * stream, MMAPString * line); + +char * mailstream_read_line_remove_eol(mailstream * stream, MMAPString * line); + +char * mailstream_read_multiline(mailstream * s, size_t size, + MMAPString * stream_buffer, + MMAPString * multiline_buffer, + size_t progr_rate, + progress_function * progr_fun); + + + + mailstream_read_line() reads an entire line + from the buffer and store it into the + given string. returns NULL on error, the + corresponding array + of char is returned otherwise. + + + + mailstream_read_line_append() reads an entire + line from the buffer and appends it to the + given string. returns NULL on error, the + array of char corresponding to the entire buffer is returned + otherwise. + + + + mailstream_read_line_remove_eol() reads an + entire line from the buffer and store it into the + given string. All CR LF are removed. + returns NULL on error, the corresponding + array of char is returned otherwise. + + + + mailstream_read_multiline() reads a + multiline data (several lines, the data are ended with + a single period '.') + from the given stream and store it into the given + multiline buffer (multiline_buffer). progr_rate should be 0 + and progr_fun NULL (deprecated things). + stream_buffer is a buffer used for internal + work of the function. + size should be 0 (deprecated things). + + + +int mailstream_is_end_multiline(char * line); + + + + returns 1 if the line is an end of multiline data (a single + period '.', eventually with CR and/or LF). 0 is returned + otherwise. + + + +int mailstream_send_data(mailstream * s, char * message, + size_t size, + size_t progr_rate, + progress_function * progr_fun); + + + + sends multiline data to the given stream. + size is the size of the data. + progr_rate and progr_fun + are deprecated. progr_rate must be 0, + progr_fun must be NULL. + + + + socket stream + + +mailstream * mailstream_socket_open(int fd); + + + + mailstream_socket_open() will open a + clear-text socket. + + + + + TLS stream + + +mailstream * mailstream_ssl_open(int fd); + + + + mailstream_ssl_open() will open a + TLS/SSL socket. + + + + + + + non-buffered I/O + + +#include <libetpan/libetpan.h> + +struct mailstream_low_driver { + ssize_t (* mailstream_read)(mailstream_low *, void *, size_t); + ssize_t (* mailstream_write)(mailstream_low *, void *, size_t); + int (* mailstream_close)(mailstream_low *); + int (* mailstream_get_fd)(mailstream_low *); + void (* mailstream_free)(mailstream_low *); +}; + +typedef struct mailstream_low_driver mailstream_low_driver; + +struct _mailstream_low { + void * data; + mailstream_low_driver * driver; +}; + + + + mailstream_low is a non-buffered stream. + + + + The mailstream_low_driver is a set of + functions used to access the stream. + + + + + + mailstream_read/write/close() is the same + interface as read/write/close() + system calls, except that the file descriptor is replaced with the + mailstream_low structure. + + + + + mailstream_get_fd() returns the file + descriptor used for this non-buffered stream. + + + + + mailstream_free() is in charge to free + the internal structure of the mailstream_low and the + mailstream_low itself. + + + + + +mailstream_low * mailstream_low_new(void * data, + mailstream_low_driver * driver); + + + + mailstream_low_new() creates a low-level mailstream with the + given internal structure (data) and using the given set of + functions (driver). + + + +ssize_t mailstream_low_write(mailstream_low * s, void * buf, size_t count); + +ssize_t mailstream_low_read(mailstream_low * s, void * buf, size_t count); + +int mailstream_low_close(mailstream_low * s); + +int mailstream_low_get_fd(mailstream_low * s); + +void mailstream_low_free(mailstream_low * s); + + + + Each of these calls will call the corresponding function defined + in the driver. + + + + + + + + strings + + +#include <libetpan/libetpan.h> + +struct _MMAPString +{ + char * str; + size_t len; + size_t allocated_len; + int fd; + size_t mmapped_size; +}; + +typedef struct _MMAPString MMAPString; + + + + MMAPString is a string which size that can increase automatically. + + + + constructor and destructor + +MMAPString * mmap_string_new(const char * init); + +MMAPString * mmap_string_new_len(const char * init, size_t len); + +MMAPString * mmap_string_sized_new(size_t dfl_size); + +void mmap_string_free(MMAPString * string); + + + + mmap_string_new() allocates a new + string. init is the intial value of the string. + NULL will be returned on error. + + + + mmap_string_new_len() allocates a new + string. init is the intial value of the + string, len is the length of the initial string. + NULL will be returned on error. + + + + mmap_string_sized_new() allocates a new + string. dfl_size is the initial allocation of + the string. NULL will be returned on error. + + + + mmap_string_free() release the memory used + by the string. + + + + + string value modification + +MMAPString * mmap_string_assign(MMAPString * string, const char * rval); + +MMAPString * mmap_string_truncate(MMAPString *string, size_t len); + + + + mmap_string_assign() sets a new value for + the given string. + NULL will be returned on error. + + + + mmap_string_truncate() sets a length for + the string. + NULL will be returned on error. + + + +MMAPString * mmap_string_set_size (MMAPString * string, size_t len); + + + + sets the allocation of the string. + NULL will be returned on error. + + + + + insertion in string, deletion in string + +MMAPString * mmap_string_insert_len(MMAPString * string, size_t pos, + const char * val, size_t len); + +MMAPString * mmap_string_append(MMAPString * string, const char * val); + +MMAPString * mmap_string_append_len(MMAPString * string, + const char * val, size_t len); + +MMAPString * mmap_string_append_c(MMAPString * string, char c); + +MMAPString * mmap_string_prepend(MMAPString * string, const char * val); + +MMAPString * mmap_string_prepend_c(MMAPString * string, char c); + +MMAPString * mmap_string_prepend_len(MMAPString * string, const char * val, + size_t len); + +MMAPString * mmap_string_insert(MMAPString * string, size_t pos, + const char * val); + +MMAPString * mmap_string_insert_c(MMAPString *string, size_t pos, + char c); + +MMAPString * mmap_string_erase(MMAPString * string, size_t pos, + size_t len); + + + + For complexity here, n is the size of the given MMAPString, + and len is the size of the string to insert. + + + + mmap_string_insert_len() inserts the given + string value of given length in the string at the given + position. NULL will be returned on error. + Complexity is O(n + len). + + + + mmap_string_append() appends the given + string value at the end of the string. + NULL will be returned on error. + Complexity is O(len). + + + + mmap_string_append_len() appends the + given string value of given length at the end of the + string. NULL will be returned on error. + Complexity is O(len). + + + + mmap_string_append_c() appends the given + character at the end of the string. + NULL will be returned on error. + Complexity is O(1). + + + + mmap_string_prepend() insert the given + string value at the beginning of the string. + NULL will be returned on error. + Complexity is O(n + len). + + + + mmap_string_prepend_c() insert the given + character at the beginning of the string. + NULL will be returned on error. + Complexity is O(n). + + + + mmap_string_prepend_len() insert the given + string value of given length at the beginning of the string. + NULL will be returned on error. + Complexity is O(n + len). + + + + mmap_string_insert() inserts the given + string value in the string at the given position. + NULL will be returned on error. + Complexity is O(n + len). + + + + mmap_string_insert_c() inserts the given + character in the string at the given position. + NULL will be returned on error. + Complexity is O(n). + + + + mmap_string_erase() removes the given + count of characters (len) at the given position of the + string. NULL will be returned on error. + Complexity is O(n). + + + + + + referencing string + +int mmap_string_ref(MMAPString * string); + +int mmap_string_unref(char * str); + + + + MMAPString provides a mechanism that let you use MMAPString + like normal strings. You have first to use + mmap_string_ref(), so that you notify + that the string will be used as a normal string, then, you + use mmapstr->str to refer to the + string. When you have finished and you want to free a string + corresponding to a MMAPString, you will + use mmap_string_unref. + + + + mmap_string_ref() references the string + so that the array of characters can be used as a normal + string then released with + mmap_string_unref(). + The array of characters will be obtained with string->str. + returns -1 on error, 0 on success. + + + + + + + + Internet Message Format + + + libEtPan! implements Internet Message parser. Currently, format + is RFC 2822. + This module also allows to generate messages. + + + + + All allocation functions will take as argument allocated data + and will store these data in the structure they will allocate. + Data should be persistant during all the use of the structure + and will be freed by the free function of the structure + + + + allocation functions will return NULL on failure + + functions returning integer will be returning one of the + following error code: + MAILIMF_NO_ERROR, + MAILIMF_ERROR_PARSE, + MAILIMF_ERROR_MEMORY, + MAILIMF_ERROR_INVAL, + or MAILIMF_ERROR_FILE. + + + + + Quick start + + + You will need this module when you want to parse headers + of messages or when you want to build message headers + conformant to standards. + + + + Parse message headers + + You will use one of the four following functions, depending + on your needs : + + + + + mailimf_envelope_and_optional_fields_parse + (), + + + + + mailimf_envelope_fields_parse + (), + + + + + mailimf_optional_fields_parse + (), + + + + + mailimf_fields_parse + (). + + + + + + + Render the message headers + + Build your message headers, then use + mailimf_fields_write + () + to render the headers. + + + + + + Data types + + + mailimf_mailbox - mailbox + +#include <libetpan/libetpan.h> + +struct mailimf_mailbox { + char * mb_display_name; /* can be NULL */ + char * mb_addr_spec; /* != NULL */ +}; + +struct mailimf_mailbox * +mailimf_mailbox_new(char * mb_display_name, char * mb_addr_spec); + +void mailimf_mailbox_free(struct mailimf_mailbox * mailbox); + + + + This is an email mailbox with a display name. + + + + example of mailbox + +DINH Viet Hoa <hoa@users.sourceforge.net> + + + + + mailimf_mailbox_new creates and + initializes a data structure with a value. + Strings given as argument are referenced by the created + object and will be freed if the object is released. + + + + mailimf_mailbox_free frees memory used by + the structure and substructures will also be released. + + + + mailbox creation and display + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_mailbox * mb; + char * display_name; + char * address; + + display_name = strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="); + address = strdup("dinh.viet.hoa@free.fr"); + mb = mailimf_mailbox_new(str, address); + /* do the things */ + mailimf_mailbox_free(mb); + + return 0; +} + +/* display mailbox information */ + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_mailbox(struct mailimf_mailbox * mb) +{ + if (mb->mb_display_name != NULL) + printf("display name: %s\n", mb->mb_display_name); + printf("address specifier : %s\n", mb->mb_addr_spec); +} + + + + + + + mailimf_address - address + + +#include <libetpan/libetpan.h> + +struct mailimf_address { + int ad_type; + union { + struct mailimf_mailbox * ad_mailbox; /* can be NULL */ + struct mailimf_group * ad_group; /* can be NULL */ + } ad_data; +}; + +struct mailimf_address * +mailimf_address_new(int ad_type, struct mailimf_mailbox * ad_mailbox, + struct mailimf_group * ad_group); + +void mailimf_address_free(struct mailimf_address * address); + + + + This is a mailbox or a group of mailbox. + + + + + + ad_type can be MAILIMF_ADDRESS_MAILBOX or + MAILIMF_ADDRESS_GROUP. + + + + + ad_data.ad_mailbox is a mailbox if + ad_type is + MAILIMF_ADDRESS_MAILBOX + see ) + + + + + ad_data.group is a group if type is + MAILIMF_ADDRESS_GROUP. + see ) + + + + + + mailimf_address_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. + + + + mailimf_address_free frees memory used by + the structure and substructures will also be released. + + + + address creation and display + +/* creates an address of type mailbox */ + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_address * a_mb; + struct mailimf_mailbox * mb; + char * display_name; + char * address; + + display_name = strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="); + address = strdup("dinh.viet.hoa@free.fr"); + mb = mailimf_mailbox_new(str, address); + + a_mb = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL); + /* do the things */ + mailimf_address_free(a_mb); +} + +/* creates an address of type group */ + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_address * a_g; + struct mailimf_group * g; + char * display_name; + + display_name = strdup("undisclosed-recipient"); + g = mailimf_group_new(display_name, NULL); + + a_g = mailimf_address_new(MAILIMF_ADDRESS_GROUP, NULL, g); + /* do the things */ + mailimf_address_free(a_g); + + return 0; +} + +/* display the content of an address */ + +#include <libetpan/libetpan.h> + +void display_address(struct mailimf_address * a) +{ + clistiter * cur; + + switch (a->ad_type) { + case MAILIMF_ADDRESS_GROUP: + display_mailimf_group(a->ad_data.ad_group); + break; + + case MAILIMF_ADDRESS_MAILBOX: + display_mailimf_mailbox(a->ad_data.ad_mailbox); + break; + } +} + + + + + + + mailimf_mailbox_list - list of mailboxes + + +#include <libetpan/libetpan.h> + +struct mailimf_mailbox_list { + clist * mb_list; /* list of (struct mailimf_mailbox *), != NULL */ +}; + +struct mailimf_mailbox_list * +mailimf_mailbox_list_new(clist * mb_list); + +void mailimf_mailbox_list_free(struct mailimf_mailbox_list * mb_list); + + + + This is a list of mailboxes. + + + + mb_list is a list of mailboxes. This is a + clist which elements are of type + mailimf_mailbox (see ). + + + + mailimf_mailbox_list_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. + + + + mailimf_mailbox_list_free() frees memory used by the + structure and substructures will also be released. + + + + Creation and display of mailimf_mailbox_list + +/* creates a list of mailboxes with two mailboxes */ + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_group * g; + char * display_name; + struct mailimf_mailbox_list * mb_list; + clist * list; + + list = clist_new(); + mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="), + strdup("dinh.viet.hoa@free.fr")); + list = clist_append(mb); + mb = mailimf_mailbox_new(strdup("Christophe GIAUME"), + strdup("christophe@giaume.com")); + list = clist_append(mb); + + mb_list = mailimf_mailbox_list_new(list); + /* do the things */ + mailimf_mailbox_list_free(mb_list); + + return 0; +} + +/* display a list of mailboxes */ + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_mailbox_list(struct mailimf_mailbox_list * mb_list) +{ + clistiter * cur; + + for(cur = clist_begin(mb_list->mb_list) ; cur != NULL ; + cur = clist_next(cur)) { + struct mailimf_mailbox * mb; + + mb = clist_content(cur); + + display_mailbox(mb); + printf("\n"); + } +} + + + + + + + mailimf_address_list - list of addresses + + +#include <libetpan/libetpan.h> + +struct mailimf_address_list { + clist * ad_list; /* list of (struct mailimf_address *), != NULL */ +}; + +struct mailimf_address_list * +mailimf_address_list_new(clist * ad_list); + +void mailimf_address_list_free(struct mailimf_address_list * addr_list); + + + + This is a list of addresses. + + + + ad_list is a list of addresses. This is a + clist which elements are + of type mailimf_address (see ). + + + + mailimf_address_list_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. + + + + mailimf_address_list_free() frees memory + used by the structure and substructures will also be released. + + + + creation and display of list of addresses + +/* creates a list of addresses with two addresses */ + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_address_list * addr_list; + clist * list; + struct mailimf_mailbox * mb; + struct mailimf_address * addr; + + list = clist_new(); + mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="), + strdup("dinh.viet.hoa@free.fr")); + addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL); + list = clist_append(addr); + + mb = mailimf_mailbox_new(strdup("Christophe GIAUME"), + strdup("christophe@giaume.com")); + addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL); + list = clist_append(addr); + + addr_list = mailimf_address_list_new(list); + /* do the things */ + mailimf_address_list_free(mb_list); + + return 0; +} + +/* display a list of addresses */ + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_address_list(struct mailimf_address_list * addr_list) +{ + clistiter * cur; + + for(cur = clist_begin(addr_list->ad_list) ; cur != NULL ; + cur = clist_next(cur)) { + struct mailimf_address * addr; + + addr = clist_content(cur); + + display_address(addr); + printf("\n"); + } +} + + + + + + + mailimf_group - named group of mailboxes + +#include <libetpan/libetpan.h> + +struct mailimf_group { + char * grp_display_name; /* != NULL */ + struct mailimf_mailbox_list * grp_mb_list; /* can be NULL */ +}; + +struct mailimf_group * +mailimf_group_new(char * grp_display_name, + struct mailimf_mailbox_list * grp_mb_list); + +void mailimf_group_free(struct mailimf_group * group); + + + + This is a list of mailboxes tagged with a name. + + + + example of group + + they play music: <steve@morse.foo>, <neal@morse.foo>, + <yngwie@malmsteen.bar>, <michael@romeo.bar>; + + + + + grp_display_name is the name that will be + displayed for this group, + for example 'group_name' in + 'group_name: address1@domain1, + address2@domain2;'. + This must be allocated with malloc(). + grp_mb_list is a list of mailboxes + (see ). + + + + mailimf_group_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. + + + + mailimf_group_free() frees memory used by + the structure and substructures will also be released. + + + + creation and display of a group + +/* creates an empty group */ + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_group * g; + char * display_name; + + display_name = strdup("undisclosed-recipient"); + g = mailimf_group_new(display_name, NULL); + /* do the things */ + mailimf_group_free(g); +} + +/* creates a group with two mailboxes */ + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_group * g; + char * display_name; + struct mailimf_mailbox_list * mb_list; + struct mailimf_mailbox * mb; + clist * list; + + list = clist_new(); + mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="), + strdup("dinh.viet.hoa@free.fr")); + list = clist_append(mb); + mb = mailimf_mailbox_new(strdup("Christophe GIAUME"), + strdup("christophe@giaume.com")); + list = clist_append(mb); + + mb_list = mailimf_mailbox_list_new(list); + + display_name = strdup("my_group"); + g = mailimf_group_new(display_name, mb_list); + /* do the things */ + mailimf_group_free(g); + + return 0; +} + +/* display content of group */ + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_group(struct mailimf_group * group) +{ + printf("name of the group: %s\n", a->group->display_name); + for(cur = clist_begin(a->group->mb_list->list) ; cur != NULL ; + cur = clist_next(cur)) { + struct mailimf_mailbox * mb; + + mb = clist_content(cur); + display_mailbox(mb); + printf("\n"); + } +} + + + + + + + mailimf_date_time - date of a message + + +#include <libetpan/libetpan.h> + +struct mailimf_date_time { + int dt_day; + int dt_month; + int dt_year; + int dt_hour; + int dt_min; + int dt_sec; + int dt_zone; +}; + +struct mailimf_date_time * +mailimf_date_time_new(int dt_day, int dt_month, int dt_year, + int dt_hour, int dt_min, int dt_sec, int dt_zone); + +void mailimf_date_time_free(struct mailimf_date_time * date_time); + + + + This is the date and time of a message. + For example : + + + example of date + +Thu, 11 Dec 2003 00:15:02 +0100. + + + + + + + dt_day is the day of month (1 to 31) + + + + + dt_month (1 to 12) + + + + + dt_year (4 digits) + + + + + dt_hour (0 to 23) + + + + + dt_min (0 to 59) + + + + + dt_sec (0 to 59) + + + + + dt_zone (this is the decimal value that + we can read, for example: for + '-0200', the value is + -200). + + + + + + mailimf_date_time_new() creates and + initializes a date structure with a value. + + + + mailimf_date_time_free() frees memory used + by the structure. + + + + creation and display of date + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_date_time * d; + + d = mailimf_date_time_new(9, 5, 2003, 3, 01, 40, -0200); + /* do the things */ + mailimf_date_time_free(d); + + return 0; +} + +/* display the date */ + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_date(struct mailimf_date_time * d) +{ + printf("%02i/%02i/%i %02i:%02i:%02i %+04i\n", + d->dt_day, d->dt_month, d->dt_year, + d->dt_hour, d->dt_min, d->dt_sec, d->dt_zone); +} + + + + + + + mailimf_orig_date - parsed content of date header + + +#include <libetpan/libetpan.h> + +struct mailimf_orig_date { + struct mailimf_date_time * dt_date_time; /* != NULL */ +}; + +struct mailimf_orig_date * mailimf_orig_date_new(struct mailimf_date_time * + dt_date_time); + +void mailimf_orig_date_free(struct mailimf_orig_date * orig_date); + + + + This is the content of a header Date or + Resent-Date. + It encapsulates a mailimf_date_time + + + + dt_date_time is the parsed date + (see ). + + + + mailimf_orig_date_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. + + + + mailimf_orig_date_free() frees memory used + by the structure and substructures will also be released. + + + + creation and display of Date field + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_date_time * d; + struct mailimf_orig_date * date; + + d = mailimf_date_time_new(9, 5, 2003, 3, 01, 40, -0200); + date = mailimf_orig_date_new(d); + /* do the things */ + mailimf_orig_date_free(date); + + return 0; +} + +/* display date header */ + +#include <libetpan/libetpan.h> + +void display_orig_date(struct mailimf_orig_date * orig_date) +{ + display_date_time(d->dt_date_time); +} + + + + + + + mailimf_from - parsed content of From header + +#include <libetpan/libetpan.h> + +struct mailimf_from { + struct mailimf_mailbox_list * frm_mb_list; /* != NULL */ +}; + +struct mailimf_from * +mailimf_from_new(struct mailimf_mailbox_list * frm_mb_list); + +void mailimf_from_free(struct mailimf_from * from); + + + + This is the content of a header From or + Resent-From. + + + frm_mb_list is the parsed mailbox list + (see ). + + + + mailimf_from_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. + + + + mailimf_from_free() frees memory used by + the structure and substructures will also be released. + + + + creation and display of a From header + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + clist * list; + struct mailimf_mailbox * mb; + struct mailimf_mailbox_list * mb_list; + struct mailimf_from * from; + + list = clist_new(); + mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="), + strdup("dinh.viet.hoa@free.fr")); + clist_append(list, mb); + mb_list = mailimf_mailbox_list_new(list); + + from = mailimf_from_new(mb_list); + /* do the things */ + mailimf_from_free(from); + + return 0; +} + +/* display content of from header */ + +#include <libetpan/libetpan.h> + +void display_from(struct mailimf_from * from) +{ + display_mailbox_list(from->frm_mb_list); +} + + + + + + + mailimf_sender - parsed content of Sender header + + +#include <libetpan/libetpan.h> + +struct mailimf_sender { + struct mailimf_mailbox * snd_mb; /* != NULL */ +}; + +struct mailimf_sender * mailimf_sender_new(struct mailimf_mailbox * snd_mb); + +void mailimf_sender_free(struct mailimf_sender * sender); + + + + This is the content of a header Sender or + Resent-Sender. + + + + snd_mb is the parsed mailbox + (see ). + + + + mailimf_sender_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. + + + + mailimf_sender_free() This function frees + memory used by the structure and substructures + will also be released. + + + + creation and display of Sender field + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_mailbox * mb; + struct mailimf_sender * sender; + + mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="), + strdup("dinh.viet.hoa@free.fr")); + + sender = mailimf_sender_new(mb); + /* do the things */ + mailimf_sender_free(sender); + + return 0; +} + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_sender(struct mailimf_sender * sender) +{ + display_mailbox(sender->snd_mb); +} + + + + + + + mailimf_reply_to - parsed content of Reply-To header + + +#include <libetpan/libetpan.h> + +struct mailimf_reply_to { + struct mailimf_address_list * rt_addr_list; /* != NULL */ +}; + +struct mailimf_reply_to * +mailimf_reply_to_new(struct mailimf_address_list * rt_addr_list); + +void mailimf_reply_to_free(struct mailimf_reply_to * reply_to); + + + + This is the content of a header Reply-To. + + + + addr_list is the parsed address list + (see ). + + + + mailimf_reply_to_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. + + + + mailimf_reply_to_free() frees memory used + by the structure and substructures will also be released. + + + + creation and display of Reply-To field + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + clist * list; + struct mailimf_mailbox * mb; + struct mailimf_address * addr; + struct mailimf_address_list * addr_list; + struct mailimf_reply_to * reply_to; + + list = clist_new(); + + mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="), + strdup("dinh.viet.hoa@free.fr")); + addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL); + clist_append(list, addr); + + mb = mailimf_mailbox_new(strdup("Christophe GIAUME"), + strdup("christophe@giaume.com")); + addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL); + clist_append(list, addr); + + addr_list = mailimf_address_list_new(list); + + reply_to = mailimf_reply_to_new(addr_list); + /* do the things */ + mailimf_reply_to_free(reply_to); + + return 0; +} + +/* display Reply-To header */ + +#include <libetpan/libetpan.h> + +void display_reply_to(struct mailimf_reply_to * reply_to) +{ + display_address_list(reply_to->addr_list); +} + + + + + + + mailimf_to - parsed content of To header + + + struct mailimf_to { + struct mailimf_address_list * to_addr_list; /* != NULL */ +}; + +struct mailimf_to * mailimf_to_new(struct mailimf_address_list * to_addr_list); + +void mailimf_to_free(struct mailimf_to * to); + + + + This is the content of a header To or + Resent-To. + + + + to_addr_list is the parsed address list + (see ). + + + + mailimf_to_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. + + + + mailimf_to_free() frees memory used by the + structure and substructures will also be released. + + + + creation and display of To field + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + clist * list; + struct mailimf_mailbox * mb; + struct mailimf_address * addr; + struct mailimf_address_list * addr_list; + struct mailimf_to * to; + + list = clist_new(); + + mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="), + strdup("dinh.viet.hoa@free.fr")); + addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL); + clist_append(list, addr); + + mb = mailimf_mailbox_new(strdup("Christophe GIAUME"), + strdup("christophe@giaume.com")); + addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL); + clist_append(list, addr); + + addr_list = mailimf_address_list_new(list); + + to = mailimf_to_new(addr_list); + /* do the things */ + mailimf_to_free(to); + + return 0; +} + +/* display To header */ + +#include <libetpan/libetpan.h> + +void display_to(struct mailimf_to * to) +{ + display_address_list(to->to_addr_list); +} + + + + + + + mailimf_cc - parsed content of Cc + + +#include <libetpan/libetpan.h> + +struct mailimf_cc { + struct mailimf_address_list * cc_addr_list; /* != NULL */ +}; + +struct mailimf_cc * +mailimf_cc_new(struct mailimf_address_list * cc_addr_list); + +void mailimf_cc_free(struct mailimf_cc * cc); + + + + This is the content of a header Cc or + Resent-Cc. + + + + cc_addr_list is the parsed address list + (see ). + + + + mailimf_cc_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. + + + + mailimf_cc_free() This function frees + memory used by the structure and substructures will also be + released. + + + + creation and display of Cc field + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + clist * list; + struct mailimf_mailbox * mb; + struct mailimf_address * addr; + struct mailimf_address_list * addr_list; + struct mailimf_cc * cc; + + list = clist_new(); + + mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="), + strdup("dinh.viet.hoa@free.fr")); + addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL); + clist_append(list, addr); + + mb = mailimf_mailbox_new(strdup("Christophe GIAUME"), + strdup("christophe@giaume.com")); + addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL); + clist_append(list, addr); + + addr_list = mailimf_address_list_new(list); + + cc = mailimf_cc_new(addr_list); + /* do the things */ + mailimf_cc_free(cc); + + return 0; +} + +/* display content of Cc field */ + +#include <libetpan/libetpan.h> + +void display_cc(struct mailimf_cc * cc) +{ + display_address_list(cc->cc_addr_list); +} + + + + + + + + + mailimf_bcc - parsed content of Bcc field + + +#include <libetpan/libetpan.h> + +struct mailimf_bcc { + struct mailimf_address_list * bcc_addr_list; /* can be NULL */ +}; + +struct mailimf_bcc * +mailimf_bcc_new(struct mailimf_address_list * bcc_addr_list); + +void mailimf_bcc_free(struct mailimf_bcc * bcc); + + + + This is the content of a header Bcc or + Resent-Bcc. + + + + bcc_addr_list is the parsed address list + (see ). + + + + mailimf_bcc_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. + + + + mailimf_bcc_free() frees memory used by the + structure and substructures will also be released. + + + + creation and display of Bcc field + +/* create visible Bcc */ + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + clist * list; + struct mailimf_mailbox * mb; + struct mailimf_address * addr; + struct mailimf_address_list * addr_list; + struct mailimf_bcc * bcc; + + list = clist_new(); + + mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="), + strdup("dinh.viet.hoa@free.fr")); + addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL); + clist_append(list, addr); + + mb = mailimf_mailbox_new(strdup("Christophe GIAUME"), + strdup("christophe@giaume.com")); + addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL); + clist_append(list, addr); + + addr_list = mailimf_address_list_new(list); + + bcc = mailimf_bcc_new(addr_list); + /* do the things */ + mailimf_bcc_free(bcc); + + return 0; +} + +/* create unvisible Bcc */ + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_bcc * bcc; + + bcc = mailimf_bcc_new(NULL); + /* do the things */ + mailimf_bcc_free(bcc); + + return 0; +} + +/* display content of Bcc field */ + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_bcc(struct mailimf_bcc * bcc) +{ + if (bcc->addr_list == NULL) { + printf("hidden Bcc\n"); + } + else { + display_address_list(bcc->bcc_addr_list); + } +} + + + + + + + mailimf_message_id - parsed content of Message-ID header + + +#include <libetpan/libetpan.h> + +struct mailimf_message_id { + char * mid_value; /* != NULL */ +}; + +struct mailimf_message_id * mailimf_message_id_new(char * mid_value); + +void mailimf_message_id_free(struct mailimf_message_id * message_id); + + + + This is the content of a header Message-ID + or Resent-Message-ID. For example : + + + + example of Message-ID + +Message-ID: <200312100009.43592@c01n-c01n.plop.P4N>> + + + + + mid_value is the message identifier. + It is not enclosed by angle bracket. + + + + mailimf_message_id_new() This function + 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. + + + + The given string is allocated with + malloc() and is not enclosed by angle bracket. + + + + mailimf_message_id_free() frees memory + used by the structure and substructures will also be + released. + + + + creation and display of Message-ID field + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_message_id * msg_id; + char * id; + + id = strdup("1037197913.3dd26259752fa@imp.free.fr"); + msg_id = mailimf_message_id_new(id); + /* do the things */ + mailimf_message_id_free(msg_id); + + return 0; +} + +/* display message id */ + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_message_id(struct mailimf_message_id * msg_id) +{ + printf("%s\n", msg_id->mid_value); +} + + + + + + + mailimf_in_reply_to - parsed content of In-Reply-To + field + + +#include <libetpan/libetpan.h> + +struct mailimf_in_reply_to { + clist * mid_list; /* list of (char *), != NULL */ +}; + +struct mailimf_in_reply_to * mailimf_in_reply_to_new(clist * mid_list); + +void mailimf_in_reply_to_free(struct mailimf_in_reply_to * in_reply_to); + + + + content of a header In-Reply-To. + For example : + + + +In-Reply-To: <etPan.3fd5fa29.4c3901c1.6b39@homer> + + + + mid_list is a clist + in which elements are message identifiers. + their types are (char *) and they are + allocated with malloc(). + + + + mailimf_in_reply_to_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. + + + + mailimf_in_reply_to_free() frees memory + used by the structure and substructures will also be + released. + + + + creation and display of In-Reply-To field + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_in_reply_to * in_reply_to; + clist * msg_id_list; + + msg_id_list = clist_new(); + clist_append(msg_id_list, + strdup("etPan.3ebbcc18.4014197f.bc1@homer.invalid")); + + in_reply_to = mailimf_in_reply_to_new(msg_id_list); + /* do the things */ + mailimf_in_reply_to_free(in_reply_to); + + return 0; +} + +/* display the content of mailimf_in_reply_to */ + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_in_reply_to(struct mailimf_in_reply_to * in_reply_to) +{ + clistiter * cur; + + for(cur = clist_begin(in_reply_to->mid_list) ; cur != NULL ; + cur = clist_next(cur)) { + char * str; + + str = clist_content(cur); + + printf("%s\n", str); + } +} + + + + + + + mailimf_references - parsed content of References field + + +#include <libetpan/libetpan.h> + +struct mailimf_references { + clist * mid_list; /* list of (char *) */ + /* != NULL */ +}; + +struct mailimf_references * mailimf_references_new(clist * mid_list); + +void mailimf_references_free(struct mailimf_references * references); + + + + This is the content of a header References. + For example : + + +In-Reply-To: <etPan.3fd5fa29.4c3901c1.6b39@homer> + <3FD5FA78.A1D98E7@oleane.net> + <etPan.3fd5fc69.2b349482.730e@homer> + + + + mid_list is a clist + in which elements are message identifiers. + their types are (char *) and they are + allocated with malloc(). + + + + mailimf_references_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. + + + + mailimf_references_free() frees memory + used by the structure and substructures will also be + released. + + + + creation and display of References field + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_references * ref; + clist * msg_id_list; + + msg_id_list = clist_new(); + clist_append(msg_id_list, + strdup("200304280144.23633.wim.delvaux@adaptiveplanet.com")); + clist_append(msg_id_list, + strdup("200304301153.19688.wim.delvaux@adaptiveplanet.com")); + clist_append(msg_id_list, + strdup("etPan.3eb29de4.5fc4d652.3f83@homer")); + + ref = mailimf_references_new(msg_id_list); + /* do the things */ + mailimf_in_reply_to_free(ref); + + return 0; +} + +/* display references */ + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_references(struct mailimf_references * ref) +{ + clistiter * cur; + + for(cur = clist_begin(ref->mid_list) ; cur != NULL ; + cur = clist_next(cur)) { + char * msg_id; + + msg_id = clist_content(cur); + + printf("%s\n", msg_id); + } +} + + + + + + + mailimf_subject - parsed content of Subject field + + +#include <libetpan/libetpan.h> + +struct mailimf_subject { + char * sbj_value; /* != NULL */ +}; + +struct mailimf_subject * mailimf_subject_new(char * sbj_value); + +void mailimf_subject_free(struct mailimf_subject * subject); + + + + This is the content of a header Subject. + + + + sbj_value is the value of the field. + + + + mailimf_subject_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. + + + + mailimf_subject_free frees memory used by + the structure and substructures will also be released. + + + + creation and display of Subject field + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_subject * subject; + + subject = mailimf_subject_new(strdup("example of subject")); + /* do the things */ + mailimf_subject_free(subject); + + return 0; +} + +/* display subject header */ + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_subject(struct mailimf_subject * subject) +{ + printf("%s\n", subject->value); +} + + + + + + + mailimf_comments - parsed content of Comments field + + +#include <libetpan/libetpan.h> + +struct mailimf_comments { + char * cm_value; /* != NULL */ +}; + +struct mailimf_comments * mailimf_comments_new(char * cm_value); + +void mailimf_comments_free(struct mailimf_comments * comments); + + + + This is the content of a header Comments. + + + + cm_value is the value of the field. + + + + mailimf_comments_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. + + + + mailimf_comments_free() frees memory used + by the structure and substructures will also be released. + + + + creation and display of Comment field + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_comments * comments; + + comments = mailimf_comments_new(strdup("example of comment")); + /* do the things */ + mailimf_comments_free(comments); + + return 0; +} + +/* display the content of a comments */ + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_comments(struct mailimf_comments * comments) +{ + printf("%s\n", comments->cm_value); +} + + + + + + + mailimf_keywords - parsed content of Keywords field + + +#include <libetpan/libetpan.h> + +struct mailimf_keywords { + clist * kw_list; /* list of (char *), != NULL */ +}; + +struct mailimf_keywords * mailimf_keywords_new(clist * kw_list); + +void mailimf_keywords_free(struct mailimf_keywords * keywords); + + + + This is the content of a header Keywords. + + + + kw_list is the list of keywords. This is + a list of (char *) allocated with malloc(). + + + + mailimf_keywords_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. + + + + mailimf_keywords_free() frees memory used + by the structure and substructures will also be released. + + + + creation and display of Keywords field + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_keywords * keywords; + clist * list; + + list = clist_new(); + clist_append(list, strdup("sauerkraut")); + clist_append(list, strdup("potatoes")); + clist_append(list, strdup("cooking")); + + keywords = mailimf_keywords_new(list); + /* do the things */ + mailimf_keywords_free(keywords); + + return 0; +} + +/* display the content of mailimf_in_reply_to */ + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_keywords(struct mailimf_keywords * kw) +{ + clistiter * cur; + + for(cur = clist_begin(kw->kw_list) ; cur != NULL ; + cur = clist_next(cur)) { + char * str; + + str = clist_content(cur); + + printf("%s\n", str); + } +} + + + + + + + mailimf_return - parsed content of Return-Path field + + +#include <libetpan/libetpan.h> + +struct mailimf_return { + struct mailimf_path * ret_path; /* != NULL */ +}; + +struct mailimf_return * +mailimf_return_new(struct mailimf_path * ret_path); + +void mailimf_return_free(struct mailimf_return * return_path); + + + + This is the content of a header + Return-Path. + + + + ret_path is the parsed value of Return-Path + (see ). + + + + mailimf_return_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. + + + + mailimf_return_free() frees memory used + by the structure and substructures will also be released. + + + + creation and display of Return-Path field + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_path * path; + struct mailimf_return * r; + + path = mailimf_path_new(strdup("dinh.viet.hoa@free.fr")); + r = mailimf_return_new(path); + /* do the things */ + mailimf_return_free(r); + + return 0; +} + +/* display return path */ + +#include <libetpan/libetpan.h> + +void display_return(struct mailimf_return * r) +{ + display_path(r->ret_path); +} + + + + + + + mailimf_path - address in Return-Path field + + +#include <libetpan/libetpan.h> + +struct mailimf_path { + char * pt_addr_spec; /* can be NULL */ +}; + +struct mailimf_path * mailimf_path_new(char * pt_addr_spec); + +void mailimf_path_free(struct mailimf_path * path); + + + + This is the encapsulation of address specifier for + Return-Path content. + + + + pt_addr_spec is a mailbox destination. + + + + mailimf_path_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. + + + + The given string is allocated with + malloc(). This is a address + specifier. + + + + mailimf_path_free() frees memory used by + the structure and substructures will also be released. + + + + Creation and display of return path + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_path * path; + + path = mailimf_path_new(strdup("dinh.viet.hoa@free.fr")); + /* do the things */ + mailimf_path_free(r); + + return 0; +} + +/* display return path */ + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_path(struct mailimf_path * path) +{ + printf("%s\n", path->pt_addr_spec); +} + + + + + + + mailimf_optional_field - non-standard header + + +#include <libetpan/libetpan.h> + +struct mailimf_optional_field { + char * fld_name; /* != NULL */ + char * fld_value; /* != NULL */ +}; + +struct mailimf_optional_field * +mailimf_optional_field_new(char * fld_name, char * fld_value); + +void mailimf_optional_field_free(struct mailimf_optional_field * opt_field); + + + + This is a non-standard header or unparsed header. + + + + + + fld_name is the name of the header + field. + + + + + fld_value is the value of the header + field. + + + + + + mailimf_optional_field_new() This + function 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. + + + + field name and field value have to be allocated with + malloc(). + + + + mailimf_optional_field_free() This + function frees memory used by the structure and + substructures will also be released. + + + + creation and display of non-standard fields + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_optional_field * opt; + + opt = mailimf_optional_field_new(strdup("X-My-Field"), strdup("my value")); + /* do the things */ + mailimf_optional_field_free(opt); + + return 0; +} + +/* display the optional field */ + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_optional_field(struct mailimf_optional_field * opt) +{ + printf("%s: %s\n", opt->fld_name, opt->fld_value); +} + + + + + + + mailimf_field - header field + + +#include <libetpan/libetpan.h> + +enum { + MAILIMF_FIELD_NONE, /* on parse error */ + MAILIMF_FIELD_RETURN_PATH, /* Return-Path */ + MAILIMF_FIELD_RESENT_DATE, /* Resent-Date */ + MAILIMF_FIELD_RESENT_FROM, /* Resent-From */ + MAILIMF_FIELD_RESENT_SENDER, /* Resent-Sender */ + MAILIMF_FIELD_RESENT_TO, /* Resent-To */ + MAILIMF_FIELD_RESENT_CC, /* Resent-Cc */ + MAILIMF_FIELD_RESENT_BCC, /* Resent-Bcc */ + MAILIMF_FIELD_RESENT_MSG_ID, /* Resent-Message-ID */ + MAILIMF_FIELD_ORIG_DATE, /* Date */ + MAILIMF_FIELD_FROM, /* From */ + MAILIMF_FIELD_SENDER, /* Sender */ + MAILIMF_FIELD_REPLY_TO, /* Reply-To */ + MAILIMF_FIELD_TO, /* To */ + MAILIMF_FIELD_CC, /* Cc */ + MAILIMF_FIELD_BCC, /* Bcc */ + MAILIMF_FIELD_MESSAGE_ID, /* Message-ID */ + MAILIMF_FIELD_IN_REPLY_TO, /* In-Reply-To */ + MAILIMF_FIELD_REFERENCES, /* References */ + MAILIMF_FIELD_SUBJECT, /* Subject */ + MAILIMF_FIELD_COMMENTS, /* Comments */ + MAILIMF_FIELD_KEYWORDS, /* Keywords */ + MAILIMF_FIELD_OPTIONAL_FIELD, /* other field */ +}; + +struct mailimf_field { + int fld_type; + union { + struct mailimf_return * fld_return_path; /* can be NULL */ + struct mailimf_orig_date * fld_resent_date; /* can be NULL */ + struct mailimf_from * fld_resent_from; /* can be NULL */ + struct mailimf_sender * fld_resent_sender; /* can be NULL */ + struct mailimf_to * fld_resent_to; /* can be NULL */ + struct mailimf_cc * fld_resent_cc; /* can be NULL */ + struct mailimf_bcc * fld_resent_bcc; /* can be NULL */ + struct mailimf_message_id * fld_resent_msg_id; /* can be NULL */ + struct mailimf_orig_date * fld_orig_date; /* can be NULL */ + struct mailimf_from * fld_from; /* can be NULL */ + struct mailimf_sender * fld_sender; /* can be NULL */ + struct mailimf_reply_to * fld_reply_to; /* can be NULL */ + struct mailimf_to * fld_to; /* can be NULL */ + struct mailimf_cc * fld_cc; /* can be NULL */ + struct mailimf_bcc * fld_bcc; /* can be NULL */ + struct mailimf_message_id * fld_message_id; /* can be NULL */ + struct mailimf_in_reply_to * fld_in_reply_to; /* can be NULL */ + struct mailimf_references * fld_references; /* can be NULL */ + struct mailimf_subject * fld_subject; /* can be NULL */ + struct mailimf_comments * fld_comments; /* can be NULL */ + struct mailimf_keywords * fld_keywords; /* can be NULL */ + struct mailimf_optional_field * fld_optional_field; /* can be NULL */ + } fld_data; +}; + +struct mailimf_field * +mailimf_field_new(int fld_type, + struct mailimf_return * fld_return_path, + struct mailimf_orig_date * fld_resent_date, + struct mailimf_from * fld_resent_from, + struct mailimf_sender * fld_resent_sender, + struct mailimf_to * fld_resent_to, + struct mailimf_cc * fld_resent_cc, + struct mailimf_bcc * fld_resent_bcc, + struct mailimf_message_id * fld_resent_msg_id, + struct mailimf_orig_date * fld_orig_date, + struct mailimf_from * fld_from, + struct mailimf_sender * fld_sender, + struct mailimf_reply_to * fld_reply_to, + struct mailimf_to * fld_to, + struct mailimf_cc * fld_cc, + struct mailimf_bcc * fld_bcc, + struct mailimf_message_id * fld_message_id, + struct mailimf_in_reply_to * fld_in_reply_to, + struct mailimf_references * fld_references, + struct mailimf_subject * fld_subject, + struct mailimf_comments * fld_comments, + struct mailimf_keywords * fld_keywords, + struct mailimf_optional_field * fld_optional_field); + +void mailimf_field_free(struct mailimf_field * field); + + + + This is one header field of a message. + + + + + + type is the type of the field. This define the + type of the field. + Only the corresponding field should be, then, + filled. The value of this field can be one of : + MAILIMF_FIELD_RETURN_PATH, + MAILIMF_FIELD_RESENT_DATE, + MAILIMF_FIELD_RESENT_FROM, + MAILIMF_FIELD_RESENT_SENDER, + MAILIMF_FIELD_RESENT_TO, + MAILIMF_FIELD_RESENT_CC, + MAILIMF_FIELD_RESENT_BCC, + MAILIMF_FIELD_RESENT_MSG_ID, + MAILIMF_FIELD_ORIG_DATE, + MAILIMF_FIELD_FROM, + MAILIMF_FIELD_SENDER, + MAILIMF_FIELD_REPLY_TO, + MAILIMF_FIELD_TO, + MAILIMF_FIELD_CC, + MAILIMF_FIELD_BCC, + MAILIMF_FIELD_MESSAGE_ID, + MAILIMF_FIELD_IN_REPLY_TO, + MAILIMF_FIELD_REFERENCES, + MAILIMF_FIELD_SUBJECT, + MAILIMF_FIELD_COMMENTS, + MAILIMF_FIELD_KEYWORDS, + MAILIMF_FIELD_OPTIONAL_FIELD. + + + + + fld_data.fld_return_path is the + parsed content of the Return-Path field + if type is MAILIMF_FIELD_RETURN_PATH + (see ). + + + + + fld_data.fld_resent_date is the + parsed content of the Resent-Date field + if type is MAILIMF_FIELD_RESENT_DATE + (see ). + + + + + fld_data.fld_resent_from is the + parsed content of the Resent-From field + if type is MAILIMF_FIELD_RESENT_FROM + (see ). + + + + + fld_data.fld_resent_sender is the + parsed content of the Resent-Sender field + if type is MAILIMF_FIELD_RESENT_SENDER + (see ). + + + + + fld_data.fld_resent_to is the parsed + content of the Resent-To field + if type is MAILIMF_FIELD_RESENT_TO + (see ). + + + + + fld_data.fld_resent_cc is the parsed + content of the Resent-Cc field + if type is MAILIMF_FIELD_CC + (see ). + + + + + fld_data.fld_resent_bcc is the parsed + content of the Resent-Bcc field + if type is MAILIMF_FIELD_BCC + (see ). + + + + + fld_data.fld_resent_msg_id is the + parsed content of the Resent-Message-ID field + if type is MAILIMF_FIELD_RESENT_MSG_ID + (see ). + + + + + fld_data.fld_orig_date is the parsed + content of the Date field + if type is MAILIMF_FIELD_ORIG_DATE + (see ). + + + + + fld_data.fld_from is the parsed + content of the From field + if type is MAILIMF_FIELD_FROM + (see ). + + + + + fld_data.fld_sender is the parsed + content of the Sender field + if type is MAILIMF_FIELD_SENDER + (see ). + + + + + fld_data.fld_reply_to is the parsed + content of the Reply-To field + if type is MAILIMF_FIELD_REPLY_TO + (see ). + + + + + fld_data.fld_to is the parsed content + of the To field if type is + MAILIMF_FIELD_TO + (see ). + + + + + fld_data.fld_cc is the parsed content + of the Cc field if type is + MAILIMF_FIELD_CC + (see ). + + + + + fld_data.fld_bcc is the parsed + content of the Bcc field if type is + MAILIMF_FIELD_BCC + (see ). + + + + + fld_data.fld_message_id is the parsed + content of the Message-ID field + if type is MAILIMF_FIELD_MESSAGE_ID + (see ). + + + + + fld_data.fld_in_reply_to is the + parsed content of the In-Reply-To field + if type is MAILIMF_FIELD_IN_REPLY_TO + (see ). + + + + + fld_data.fld_references is the parsed + content of the References field + if type is MAILIMF_FIELD_REFERENCES + (see ). + + + + + fld_data.fld_subject is the content + of the Subject field + if type is MAILIMF_FIELD_SUBJECT + (see ). + + + + + fld_data.fld_comments is the content of the + Comments field + if type is MAILIMF_FIELD_COMMENTS + (see ). + + + + + fld_data.fld_keywords is the parsed + content of the Keywords field + if type is MAILIMF_FIELD_KEYWORDS + (see ). + + + + + fld_data.fld_optional_field is an + other field and is not parsed + if type is MAILIMF_FIELD_OPTIONAL_FIELD + (see ). + + + + + + mailimf_field_new() creates and + initializes a data structure with a value. + Structures given as argument are referenced by the created + object and will be freed if the object is released. + + + + mailimf_field_free() frees memory used by + the structure and substructures will also be released. + + + + creation and display of field + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_field * f; + struct mailimf_mailbox * mb; + struct mailimf_mailbox_list * mb_list; + struct mailimf_from * from; + + /* build header 'From' */ + + list = clist_new(); + mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="), + strdup("dinh.viet.hoa@free.fr")); + clist_append(list, mb); + mb_list = mailimf_mailbox_list_new(list); + + from = mailimf_from_new(mb_list); + + f = mailimf_field_new(MAILIMF_FIELD_FROM, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + from, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); + /* do the things */ + mailimf_field_free(f); + + return 0; +} + +/* display content of the header */ + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_field(struct mailimf_field * field) +{ + switch (field->type) { + case MAILIMF_FIELD_RETURN_PATH: + printf("Return-Path:\n"); + display_return(field->fld_data.fld_return_path); + break; + case MAILIMF_FIELD_RESENT_DATE: + printf("Resent-Date:\n"); + display_orig_date(field->fld_data.fld_orig_date); + break; + case MAILIMF_FIELD_RESENT_FROM: + printf("Resent-From:\n"); + display_from(field->fld_data.fld_orig_date); + break; + case MAILIMF_FIELD_RESENT_SENDER: + printf("Resent-Sender:\n"); + display_sender(field->fld_data.fld_resent_sender); + break; + case MAILIMF_FIELD_RESENT_TO: + printf("Resent-To:\n"); + display_to(field->fld_data.fld_resent_to); + break; + case MAILIMF_FIELD_RESENT_CC: + printf("Resent-Cc:\n"); + display_from(field->fld_data.fld_resent_cc); + break; + case MAILIMF_FIELD_RESENT_BCC: + printf("Resent-Bcc:\n"); + display_from(field->fld_data.fld_resent_bcc); + break; + case MAILIMF_FIELD_RESENT_MSG_ID: + printf("Resent-Message-ID:\n"); + display_message_id(field->fld_data.fld_resent_msg_id); + break; + case MAILIMF_FIELD_ORIG_DATE: + printf("Date:\n"); + display_orig_date(field->fld_data.fld_orig_date); + break; + case MAILIMF_FIELD_FROM: + printf("From:\n"); + display_from(field->fld_data.fld_from); + break; + case MAILIMF_FIELD_SENDER: + printf("Sender:\n"); + display_sender(field->fld_data.fld_sender); + break; + case MAILIMF_FIELD_REPLY_TO: + printf("Reply-To:\n"); + display_reply_to(field->fld_data.fld_reply_to); + break; + case MAILIMF_FIELD_TO: + printf("To:\n"); + display_to(field->fld_data.fld_to); + break; + case MAILIMF_FIELD_CC: + printf("Cc:\n"); + display_cc(field->fld_data.fld_cc); + break; + case MAILIMF_FIELD_BCC: + printf("Bcc:\n"); + display_bcc(field->fld_data.fld_bcc); + break; + case MAILIMF_FIELD_MESSAGE_ID: + printf("Message-ID:\n"); + display_message_id(field->fld_data.fld_message_id); + break; + case MAILIMF_FIELD_IN_REPLY_TO: + printf("In-Reply-To:\n"); + display_in_reply_to(field->fld_data.fld_in_reply_to); + break; + case MAILIMF_FIELD_REFERENCES: + printf("References:\n"); + display_references(field->fld_data.fld_references_to); + break; + case MAILIMF_FIELD_SUBJECT: + printf("Subject:\n"); + display_subject(field->fld_data.fld_subject); + break; + case MAILIMF_FIELD_COMMENTS: + printf("Comments:\n"); + display_comments(field->fld_data.fld_comments); + break; + case MAILIMF_FIELD_KEYWORDS: + printf("Keywords:\n"); + display_keywords(field->fld_data.fld_keywords); + break; + case MAILIMF_FIELD_OPTIONAL_FIELD: + printf("[optional field]:\n"); + display_optional_field(field->fld_data.fld_optional_field); + break; + } +} + + + + + + + mailimf_fields - list of header fields + + +#include <libetpan/libetpan.h> + +struct mailimf_fields { + clist * fld_list; /* list of (struct mailimf_field *), != NULL */ +}; + +struct mailimf_fields * mailimf_fields_new(clist * fld_list); + +void mailimf_fields_free(struct mailimf_fields * fields); + + + + This is the list of header fields of a message. + + + + fld_list is a list of header fields. This + is a clist which elements are + of type mailimf_field (see ). + + + + mailimf_fields_new() creates and + initializes a data structure with a value. + Structures given as argument are referenced by the created + object and will be freed if the object is released. + + + + mailimf_fields_free() frees memory used + by the structure and substructures will also be released. + + + + creation and display of header fields + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_fields * fields; + struct mailimf_field * f; + clist * list; + struct mailimf_from * from; + struct mailimf_to * to + struct mailimf_mailbox * mb; + struct mailimf_address * addr; + struct mailimf_mailbox_list * mb_list; + struct mailimf_address_list * addr_list; + clist * fields_list; + + /* build headers */ + + fields_list = clist_new(); + + /* build header 'From' */ + + list = clist_new(); + mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="), + strdup("dinh.viet.hoa@free.fr")); + clist_append(list, mb); + mb_list = mailimf_mailbox_list_new(list); + + from = mailimf_from_new(mb_list); + + f = mailimf_field_new(MAILIMF_FIELD_FROM, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + from, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); + + clist_append(fields_list, f); + + /* build header To */ + + list = clist_new(); + mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="), + strdup("dinh.viet.hoa@free.fr")); + addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL); + clist_append(list, addr); + addr_list = mailimf_address_list_new(list); + + to = mailimf_to_new(addr_list); + + f = mailimf_field_new(MAILIMF_FIELD_TO, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, to, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); + + clist_append(fields_list, f); + + fields = mailimf_fields_new(fields_list); + /* do the things */ + mailimf_fields_free(fields); + + return 0; +} + +/* display list of headers */ + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_fields(struct mailimf_fields * fields) +{ + clistiter * cur; + + for(cur = clist_begin(field->fld_list) ; cur != NULL ; + cur = clist_next(cur)) { + struct mailimf_field * f; + + f = clist_content(cur); + + display_field(f); + printf("\n"); + } +} + + + + + + + mailimf_body - message body without headers + + +#include <libetpan/libetpan.h> + +struct mailimf_body { + const char * bd_text; /* != NULL */ + size_t bd_size; +}; + +struct mailimf_body * mailimf_body_new(const char * bd_text, size_t bd_size); + +void mailimf_body_free(struct mailimf_body * body); + + + + This is the text content of a message (without headers). + + + + + + bd_text is the beginning of the + text part, it is a substring of an other string. + It is not necessarily zero terminated. + + + + + bd_size is the size of the text part + + + + + + + mailimf_body_new() creates and + initializes a data structure with a value. + Text given as argument will NOT be released. + + + + mailimf_body_free() frees memory used by + the structure. + + + + creation and display of message body + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_body * b; + + b = mailimf_body_new("this is the content of the message", 34); + /* do the things */ + mailimf_body_free(b); + + return 0; +} + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_body(struct mailimf_body * b) +{ + char * text; + + text = malloc(b->size + 1); + strncpy(text, b->bd_text, b->bd_size); + text[b->size] = 0; + + puts(text); + printf("\n"); + + free(text); + + return 0; +} + + + + + + + mailimf_message - parsed message + + +#include <libetpan/libetpan.h> + +struct mailimf_message { + struct mailimf_fields * msg_fields; /* != NULL */ + struct mailimf_body * msg_body; /* != NULL */ +}; + +struct mailimf_message * +mailimf_message_new(struct mailimf_fields * msg_fields, + struct mailimf_body * msg_body); + +void mailimf_message_free(struct mailimf_message * message); + + + + This is the message content (text and headers). + + + + + + msg_fields is the header fields of + the message + (see ). + + + + + msg_body is the text part of the message + (see ). + + + + + + mailimf_message_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. + + + + mailimf_message_free() frees memory used + by the structure and substructures will also be released. + + + + creation and display of message + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_body * b; + struct mailimf_message * m; + struct mailimf_fields * fields; + struct mailimf_fields * f; + clist * list; + struct mailimf_from * from; + struct mailimf_to * to + struct mailimf_mailbox * mb; + struct mailimf_address * addr; + struct mailimf_mailbox_list * mb_list; + struct mailimf_address_list * addr_list; + clist * fields_list; + + /* build text content */ + + b = mailimf_body_new("this is the content of the message", 34); + + /* build headers */ + + fields_list = clist_new(); + + /* build header 'From' */ + + list = clist_new(); + mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="), + strdup("dinh.viet.hoa@free.fr")); + clist_append(list, mb); + mb_list = mailimf_mailbox_list_new(list); + + from = mailimf_from_new(mb_list); + + f = mailimf_field_new(MAILIMF_FIELD_FROM, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + from, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); + + clist_append(fields_list, f); + + /* build header To */ + + list = clist_new(); + mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="), + strdup("dinh.viet.hoa@free.fr")); + addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL); + clist_append(list, addr); + addr_list = mailimf_address_list_new(list); + + to = mailimf_to_new(addr_list); + + f = mailimf_field_new(MAILIMF_FIELD_TO, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, to, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); + + clist_append(fields_list, f); + + fields = mailimf_fields_new(fields_list); + + /* build message */ + + m = mailimf_message_new(fields, b); + /* do the things */ + mailimf_message_free(m); + + return 0; +} + +/* display the message */ + +#include <libetpan/libetpan.h> +#include <stdio.h> + +void display_message(struct mailimf_message * msg) +{ + display_fields(msg->msg_fields); + printf("\n"); + display_body(msg->msg_body); + printf("\n"); +} + + + + + + + mailimf_single_fields - simplified fields + + +#include <libetpan/libetpan.h> + +struct mailimf_single_fields { + struct mailimf_orig_date * fld_orig_date; /* can be NULL */ + struct mailimf_from * fld_from; /* can be NULL */ + struct mailimf_sender * fld_sender; /* can be NULL */ + struct mailimf_reply_to * fld_reply_to; /* can be NULL */ + struct mailimf_to * fld_to; /* can be NULL */ + struct mailimf_cc * fld_cc; /* can be NULL */ + struct mailimf_bcc * fld_bcc; /* can be NULL */ + struct mailimf_message_id * fld_message_id; /* can be NULL */ + struct mailimf_in_reply_to * fld_in_reply_to; /* can be NULL */ + struct mailimf_references * fld_references; /* can be NULL */ + struct mailimf_subject * fld_subject; /* can be NULL */ + struct mailimf_comments * fld_comments; /* can be NULL */ + struct mailimf_keywords * fld_keywords; /* can be NULL */ +}; + +struct mailimf_single_fields * +mailimf_single_fields_new(struct mailimf_fields * fields); + +void mailimf_single_fields_free(struct mailimf_single_fields * + single_fields); + +void mailimf_single_fields_init(struct mailimf_single_fields * single_fields, + struct mailimf_fields * fields); + + + + Structure that contains some standard fields and allows access + to a given header without running through the list. + + + + mailimf_fields is the native structure that IMF module will use, + this module will provide an easier structure to use when + parsing fields. + mailimf_single_fields is an easier structure to get parsed fields, + rather than iteration over the list of fields + + + + + + fld_orig_date is the parsed "Date" + field + (see ). + + + + + fld_from is the parsed "From" field + (see ). + + + + + fld_sender is the parsed "Sender "field + (see ). + + + + + reply_to is the parsed "Reply-To" field + (see ). + + + + + fld_to is the parsed "To" field + (see ). + + + + + fld_cc is the parsed "Cc" field + (see ). + + + + + fld_bcc is the parsed "Bcc" field + (see ). + + + + + fld_message_id is the parsed + "Message-ID" field. + (see ). + + + + + fld_in_reply_to is the parsed + "In-Reply-To" field. + (see ). + + + + + fld_references is the parsed + "References" field. + (see ). + + + + + fld_subject is the parsed "Subject" field + (see ). + + + + + fld_comments is the parsed "Comments" field + (see ). + + + + + fld_keywords is the parsed "Keywords" field + (see ). + + + + + + mailimf_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. + + + + mailimf_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 (fields). The + interesting fields will be filled into + single_fields. + + + + using mailimf_single_fields + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_single_fields * single_fields; + struct mailimf_fields * fields; + struct mailimf_field * f; + clist * list; + struct mailimf_from * from; + struct mailimf_to * to + struct mailimf_mailbox * mb; + struct mailimf_address * addr; + struct mailimf_mailbox_list * mb_list; + struct mailimf_address_list * addr_list; + clist * fields_list; + + /* build headers */ + + fields_list = clist_new(); + + /* build header 'From' */ + + list = clist_new(); + mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="), + strdup("dinh.viet.hoa@free.fr")); + clist_append(list, mb); + mb_list = mailimf_mailbox_list_new(list); + + from = mailimf_from_new(mb_list); + + f = mailimf_field_new(MAILIMF_FIELD_FROM, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + from, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); + + clist_append(fields_list, f); + + /* build header To */ + + list = clist_new(); + mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="), + strdup("dinh.viet.hoa@free.fr")); + addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL); + clist_append(list, addr); + addr_list = mailimf_address_list_new(list); + + to = mailimf_to_new(addr_list); + + f = mailimf_field_new(MAILIMF_FIELD_TO, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, to, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); + + clist_append(fields_list, f); + + fields = mailimf_fields_new(fields_list); + + /* create the single fields */ + single_fields = mailimf_single_fields_new(fields); + /* do the things */ + mailimf_single_fields_free(single_fields); + mailimf_fields_free(fields); + + return 0; +} + + + + + using mailimf_single_fields without memory allocation + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_single_fields single_fields; + struct mailimf_fields * fields; + struct mailimf_field * f; + clist * list; + struct mailimf_from * from; + struct mailimf_to * to + struct mailimf_mailbox * mb; + struct mailimf_address * addr; + struct mailimf_mailbox_list * mb_list; + struct mailimf_address_list * addr_list; + clist * fields_list; + + /* build headers */ + + fields_list = clist_new(); + + /* build header 'From' */ + + list = clist_new(); + mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="), + strdup("dinh.viet.hoa@free.fr")); + clist_append(list, mb); + mb_list = mailimf_mailbox_list_new(list); + + from = mailimf_from_new(mb_list); + + f = mailimf_field_new(MAILIMF_FIELD_FROM, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + from, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); + + clist_append(fields_list, f); + + /* build header To */ + + list = clist_new(); + mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="), + strdup("dinh.viet.hoa@free.fr")); + addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL); + clist_append(list, addr); + addr_list = mailimf_address_list_new(list); + + to = mailimf_to_new(addr_list); + + f = mailimf_field_new(MAILIMF_FIELD_TO, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, to, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); + + clist_append(fields_list, f); + + fields = mailimf_fields_new(fields_list); + + /* fill the single fields */ + mailimf_fields_fields_init(&single_fields, fields); + /* do the things */ + mailimf_fields_free(fields); + + return 0; +} + + + + + + + + Parser functions + + + + mailimf_address_list_parse + +int +mailimf_address_list_parse(char * message, size_t length, + size_t * index, + struct mailimf_address_list ** result); + + + + mailimf_address_list_parse() parse a list + of addresses in RFC 2822 form. + + + + + + message this is a string containing + the list of addresses. + + + + + length this is the size of the given string + + + + + index this is a pointer to the + start of the list of + addresses 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 ). + + + + + + return MAILIMF_NO_ERROR on success, + MAILIMF_ERROR_XXX on error. + + + + parsing a list of addresses + +#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_address_list * addr_list; + size_t current_index; + + current_index = 0; + r = mailimf_address_list_parse(mem, stat_info.st_size, + &current_index, &addr_list); + if (r == MAILIMF_NO_ERROR) { + display_address_list(addr_list); + /* do the things */ + status = EXIT_SUCCESS; + mailimf_address_list_free(addr_list); + } + } + munmap(mem, stat_info.st_size); + } + + close(fd); + } + + exit(status); +} + + + + + + + mailimf_address_parse + + +#include <libetpan/libetpan.h> + +int +mailimf_address_parse(char * message, size_t length, + size_t * index, + struct mailimf_address ** result); + + + + mailimf_address_parse() parse an address + in RFC 2822 form. + + + + + + message this is a string containing the + address. + + + + + length this is the size of the given + string. + + + + + index index this 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 ). + + + + + + return MAILIMF_NO_ERROR on success, + MAILIMF_ERROR_XXX on error. + + + + parsing an address + +#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_address * addr; + size_t current_index; + + current_index = 0; + r = mailimf_address_parse(mem, stat_info.st_size, + &current_index, &addr); + if (r == MAILIMF_NO_ERROR) { + display_address(addr); + /* do the things */ + status = EXIT_SUCCESS; + mailimf_address_free(addr); + } + } + munmap(mem, stat_info.st_size); + } + + close(fd); + } + + exit(status); +} + + + + + + + + mailimf_body_parse + + +#include <libetpan/libetpan.h> + +int mailimf_body_parse(char * message, size_t length, + size_t * index, + struct mailimf_body ** result); + + + + mailimf_body_parse() parse text body of a + message. + + + + + + message this is a string containing + the message body part. + + + + + length this is the size of the given + string. + + + + + index this is a pointer to the start + of the message text part 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 ). + + + + + + return MAILIMF_NO_ERROR on success, + MAILIMF_ERROR_XXX on error. + + + + parsing a message body + +#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_body * b; + struct mailimf_fields * f; + size_t current_index; + size_t size; + + size = stat_info.st_size; + current_index = 0; + r = mailimf_fields_parse(mem, size, &current_index, &f); + if (r == MAILIMF_NO_ERROR) { + r = mailimf_crlf_parse(mem, size, &current_index); + /* ignore parse error of crlf */ + + r = mailimf_body_parse(mem, size, &current_index, &b); + if (r == MAILIMF_NO_ERROR) { + + display_body(b); + /* do the things */ + status = EXIT_SUCCESS; + mailimf_body_free(b); + } + mailimf_fields_free(f); + } + } + munmap(mem, stat_info.st_size); + } + + close(fd); + } + + exit(status); +} + + + + + + + + mailimf_envelope_and_optional_fields_parse + + +#include <libetpan/libetpan.h> + +int +mailimf_envelope_and_optional_fields_parse(char * message, size_t length, + size_t * index, + struct mailimf_fields ** result); + + + + mailimf_envelope_and_optional_fields_parse() + returns a list of most useful headers (parsed). The other + headers will be placed in the list in a non-parsed form. + + + + + + message this is a string containing the header. + + + + + length this is the size of the given string + + + + + index index this is a pointer to the + start of the header 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 ). + + + + + + return MAILIMF_NO_ERROR on success, + MAILIMF_ERROR_XXX on error. + + + + parsing commonly used fields and return other fields + in a non-parsed form + +#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_envelope_and_optional_fields_parse(mem, stat_info.st_size, + &current_index, &f); + if (r == MAILIMF_NO_ERROR) { + display_fields(m); + /* do the things */ + status = EXIT_SUCCESS; + mailimf_fields_free(f); + } + } + munmap(mem, stat_info.st_size); + } + + close(fd); + } + + exit(status); +} + + + + + + + + mailimf_envelope_fields_parse + + +#include <libetpan/libetpan.h> + +int mailimf_envelope_fields_parse(char * message, size_t length, + size_t * index, + struct mailimf_fields ** result); + + + + mailimf_envelope_fields_parse() return a + list of most useful headers (parsed). + + + + + + message this is a string containing the header + + + + + length this is the size of the given string + + + + + index index this is a pointer to the + start of the header 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 ). + + + + + + return MAILIMF_NO_ERROR on success, + MAILIMF_ERROR_XXX on error. + + + + parsing commonly used 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_envelope_fields_parse(mem, stat_info.st_size, + &current_index, &f); + if (r == MAILIMF_NO_ERROR) { + display_fields(m); + /* do the things */ + status = EXIT_SUCCESS; + mailimf_fields_free(f); + } + } + munmap(mem, stat_info.st_size); + } + + close(fd); + } + + exit(status); +} + + + + + + + + mailimf_optional_fields_parse + + +#include <libetpan/libetpan.h> + +int +mailimf_envelope_and_optional_fields_parse(char * message, size_t length, + size_t * index, + struct mailimf_fields ** result); + + + + mailimf_optional_fields_parse return a + list of non-parsed headers. + + + + + + message this is a string containing the header + + + + + length this is the size of the given string + + + + + index index this is a pointer to the + start of the header 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 ). + + + + + + return MAILIMF_NO_ERROR on success, + MAILIMF_ERROR_XXX on error. + + + + parsing optional 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_optional_fields_parse(mem, stat_info.st_size, + &current_index, &f); + if (r == MAILIMF_NO_ERROR) { + display_fields(m); + /* do the things */ + status = EXIT_SUCCESS; + mailimf_fields_free(f); + } + } + munmap(mem, stat_info.st_size); + } + + close(fd); + } + + exit(status); +} + + + + + + + mailimf_fields_parse + + +#include <libetpan/libetpan.h> + +int mailimf_fields_parse(char * message, size_t length, + size_t * index, + struct mailimf_fields ** result); + + + + mailimf_fields_parse() parse headers of a + message. + + + + + + message this is a string containing the header + + + + + length this is the size of the given string + + + + + index index this is a pointer to the + start of the header 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 ). + + + + + + return MAILIMF_NO_ERROR on success, + MAILIMF_ERROR_XXX on error. + + + + parsing 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, + &current_index, &f); + if (r == MAILIMF_NO_ERROR) { + display_fields(f); + /* do the things */ + status = EXIT_SUCCESS; + mailimf_fields_free(f); + } + } + munmap(mem, stat_info.st_size); + } + + close(fd); + } + + exit(status); +} + + + + + + + mailimf_ignore_field_parse + + +#include <libetpan/libetpan.h> + +int mailimf_ignore_field_parse(char * message, size_t length, + size_t * index); + + + + mailimf_ignore_field_parse() skip the + next header. + + + + + + message this is a string containing the header + + + + + length this is the size of the given string + + + + + index index this is a pointer to the + start of the field to skip in + the given string, (* index) is + modified to point at the end + of the parsed data + + + + + + return MAILIMF_NO_ERROR on success, + MAILIMF_ERROR_XXX on error. + + + + skipping 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) { + size_t current_index; + + current_index = 0; + r = mailimf_ignore_field_parse(mem, stat_info.st_size, + &current_index); + if (r == MAILIMF_NO_ERROR) { + /* do the things */ + status = EXIT_SUCCESS; + } + } + munmap(mem, stat_info.st_size); + } + + close(fd); + } + + exit(status); +} + + + + + + + mailimf_mailbox_list_parse + + +#include <libetpan/libetpan.h> + +int +mailimf_mailbox_list_parse(char * message, size_t length, + size_t * index, + struct mailimf_mailbox_list ** result); + + + + mailimf_mailbox_list_parse() parse a list + of mailboxes in RFC 2822 form. + + + + + + message this is a string containing the + list of mailboxes. + + + + + length this is the size of the given + string. + + + + + index index this is a pointer to the + start of the list of + mailboxes 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 ) + + + + + + return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on + error. + + + + parsing a list of mailboxes + +#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_mailbox_list * mb_list; + size_t current_index; + + current_index = 0; + r = mailimf_mailbox_list_parse(mem, stat_info.st_size, + &current_index, &mb_list); + if (r == MAILIMF_NO_ERROR) { + display_mailbox_list(mb_list); + /* do the things */ + status = EXIT_SUCCESS; + mailimf_mailbox_list_free(mb_list); + } + } + munmap(mem, stat_info.st_size); + } + + close(fd); + } + + exit(status); +} + + + + + + + + mailimf_mailbox_parse + + +#include <libetpan/libetpan.h> + +int mailimf_mailbox_parse(char * message, size_t length, + size_t * index, + struct mailimf_mailbox ** result); + + + + mailimf_mailbox_parse parse a mailbox in + RFC 2822 form. + + + + + + message this is a string containing the + mailbox. + + + + + length this is the size of the given + string. + + + + + index index this is a pointer to the + start of the mailbox 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 ) + + + + + + return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on + error. + + + + parsing a mailbox + +#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_mailbox_list * mb_list; + size_t current_index; + + current_index = 0; + r = mailimf_mailbox_parse(mem, stat_info.st_size, + &current_index, &mb_list); + if (r == MAILIMF_NO_ERROR) { + display_mailbox_list(mb_list); + /* do the things */ + status = EXIT_SUCCESS; + mailimf_mailbox_free(mb_list); + } + } + munmap(mem, stat_info.st_size); + } + + close(fd); + } + + exit(status); +} + + + + + + + + mailimf_message_parse + + +#include <libetpan/libetpan.h> + +int mailimf_message_parse(char * message, size_t length, + size_t * index, + struct mailimf_message ** result); + + + + mailimf_message_parse parse message + (headers and body). + + + + + + message this is a string containing + the message content. + + + + + param length this is the size of the given + string. + + + + + param index this is a pointer to the + start of the message in + the given string, (* index) is + modified to point at the end + of the parsed data. + + + + + param result the result of the parse + operation is stored in + (* result) + (see ). + + + + + + parsing a 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 mailimf_message * m; + size_t current_index; + + current_index = 0; + r = mailimf_message_parse(mem, stat_info.st_size, + &current_index, &m); + if (r == MAILIMF_NO_ERROR) { + display_message(m); + /* do the things */ + status = EXIT_SUCCESS; + mailimf_message_free(m); + } + } + munmap(mem, stat_info.st_size); + } + + close(fd); + } + + exit(status); +} + + + + + + + + + Creation functions + + mailimf_mailbox_list + +#include <libetpan/libetpan.h> + +struct mailimf_mailbox_list * +mailimf_mailbox_list_new_empty(); + +int mailimf_mailbox_list_add(struct mailimf_mailbox_list * mailbox_list, + struct mailimf_mailbox * mb); + +int mailimf_mailbox_list_add_parse(struct mailimf_mailbox_list * mailbox_list, + char * mb_str); + +int mailimf_mailbox_list_add_mb(struct mailimf_mailbox_list * mailbox_list, + char * display_name, char * address); + + + + + mailimf_mailbox_list_new_empty() creates a + new empty list of mailboxes. + + + + + mailimf_mailbox_list_add adds a mailbox + to the list of mailboxes. + + + + + mailimf_mailbox_list_add_parse adds a + mailbox given in form of a string to the list of mailboxes. + + + + + mailimf_mailbox_list_add_mb adds a + mailbox given in form of a couple : display name, mailbox + address. + + + + + + mailbox_list is the list of mailboxes. + + + + + mb is a mailbox + (see ). + + + + + mb_str is a mailbox given in the form + of a string. + + + + + display_name is the display name. + + + + + address is the mailbox address. + + + + + + creating a list of mailboxes + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_mailbox_list * mb_list; + struct mailimf_mailbox * mb; + + mb_list = mailimf_mailbox_list_new_empty(); + + mb = mailimf_mailbox_new(strdup("DINH Viet Hoa"), + strdup("dinh.viet.hoa@free.fr")); + mailimf_mailbox_list_add(mb_list, mb); + + mailimf_mailbox_list_add_parse(mb_list, "foo bar <foo@bar.org>"); + + mailimf_mailbox_list_add_mb(mb_list, strdup("bar foo"), strdup("bar@foo.com")); + + mailimf_mailbox_list_free(mb_list); +} + + + + + + mailimf_address_list + +#include <libetpan/libetpan.h> + +struct mailimf_address_list * mailimf_address_list_new_empty(); + +int mailimf_address_list_add(struct mailimf_address_list * address_list, + struct mailimf_address * addr); + +int mailimf_address_list_add_parse(struct mailimf_address_list * address_list, + char * addr_str); + +int mailimf_address_list_add_mb(struct mailimf_address_list * address_list, + char * display_name, char * address); + + + + + mailimf_address_list_new_empty() creates a + new empty list of addresses. + + + + + mailimf_address_list_add adds an address + to the list of addresses. + + + + + mailimf_address_list_add_parse adds an + address given in form of a string to the list of addresses. + + + + + mailimf_address_list_add_mb adds a + mailbox given in form of a couple : display name, mailbox + address. + + + + + + address_list is the list of mailboxes. + + + + + addr is an address. + (see ). + + + + + addr_str is an address given in the form of a + string. + + + + + display_name is the display name. + + + + + address is the mailbox address. + + + + + + + mailimf_fields + +#include <libetpan/libetpan.h> + +struct mailimf_fields * +mailimf_fields_new_empty(void); + +struct mailimf_field * mailimf_field_new_custom(char * name, char * value); + +int mailimf_fields_add(struct mailimf_fields * fields, + struct mailimf_field * field); + +int mailimf_fields_add_data(struct mailimf_fields * fields, + struct mailimf_date_time * date, + struct mailimf_mailbox_list * from, + struct mailimf_mailbox * sender, + struct mailimf_address_list * reply_to, + struct mailimf_address_list * to, + struct mailimf_address_list * cc, + struct mailimf_address_list * bcc, + char * msg_id, + clist * in_reply_to, + clist * references, + char * subject); + +struct mailimf_fields * +mailimf_fields_new_with_data_all(struct mailimf_date_time * date, + struct mailimf_mailbox_list * from, + struct mailimf_mailbox * sender, + struct mailimf_address_list * reply_to, + struct mailimf_address_list * to, + struct mailimf_address_list * cc, + struct mailimf_address_list * bcc, + char * message_id, + clist * in_reply_to, + clist * references, + char * subject); + +struct mailimf_fields * +mailimf_fields_new_with_data(struct mailimf_mailbox_list * from, + struct mailimf_mailbox * sender, + struct mailimf_address_list * reply_to, + struct mailimf_address_list * to, + struct mailimf_address_list * cc, + struct mailimf_address_list * bcc, + clist * in_reply_to, + clist * references, + char * subject); + +char * mailimf_get_message_id(void); + +struct mailimf_date_time * mailimf_get_current_date(void); + +int +mailimf_resent_fields_add_data(struct mailimf_fields * fields, + struct mailimf_date_time * resent_date, + struct mailimf_mailbox_list * resent_from, + struct mailimf_mailbox * resent_sender, + struct mailimf_address_list * resent_to, + struct mailimf_address_list * resent_cc, + struct mailimf_address_list * resent_bcc, + char * resent_msg_id); + +struct mailimf_fields * +mailimf_resent_fields_new_with_data_all(struct mailimf_date_time * + resent_date, struct mailimf_mailbox_list * resent_from, + struct mailimf_mailbox * resent_sender, + struct mailimf_address_list * resent_to, + struct mailimf_address_list * resent_cc, + struct mailimf_address_list * resent_bcc, + char * resent_msg_id); + +struct mailimf_fields * +mailimf_resent_fields_new_with_data(struct mailimf_mailbox_list * from, + struct mailimf_mailbox * resent_sender, + struct mailimf_address_list * resent_to, + struct mailimf_address_list * resent_cc, + struct mailimf_address_list * resent_bcc); + + + + + + from is the parsed content of the + From field + (see ). + + + + + sender is the parsed content of the + Sender field + (see ). + + + + + reply_to is the parsed content of the + Reply-To field + (see ). + + + + + to is the parsed content of the + To field + (see ). + + + + + cc is the parsed content of the + Cc field + (see ). + + + + + bcc is the parsed content of the + Bcc field + (see ). + + + + + message_id is the parsed content of + the Message-ID field + (see ). + + + + + in_reply_to is the parsed content of + the In-Reply-To field + (see ). + + + + + references is the parsed content of + the References field + (see ). + + + + + subject is the content of the + Subject field + (see ). + + + + + resent_date is the parsed content of + the Resent-Date field + (see ). + + + + + resent_from is the parsed content of + the Resent-From field + (see ). + + + + + resent_sender is the parsed content of the + Resent-Sender field + (see ). + + + + + resent_to is the parsed content of + the Resent-To field + (see ). + + + + + resent_cc is the parsed content of + the Resent-Cc field + (see ). + + + + + resent_bcc is the parsed content of the + Resent-Bcc field + (see ). + + + + + resent_msg_id is the parsed content of the + Resent-Message-ID field + (see ). + + + + + + + mailimf_fields_new_empty() creates a new + empty set of headers. + + + + + mailimf_field_new_custom() creates a new + custom header. + + + + + mailimf_fields_add() adds a header to the + set of headers. + + + + + mailimf_fields_add_data() adds some headers + to the set of headers. + + + + + mailimf_fields_new_with_data_all() creates + a set of headers with some headers (including Date and + Message-ID). + + + + + mailimf_fields_new_with_data() creates a + set of headers with some headers (Date and Message-ID will + be generated). + + + + + mailimf_get_message_id() generates a + Message-ID. The result must be freed using + free(). + + + + + mailimf_get_current_date() generates a + Date. The result must be freed using + mailimf_date_time_free. + + + + + mailimf_resent_fields_add_data() adds some + resent headers to the set of headers. + + + + + mailimf_resent_fields_new_with_data_all() + creates a set of headers with some resent headers (including + Resent-Date and Resent-Message-ID). + + + + + mailimf_resent_fields_new_with_data() + creates a set of headers with some resent headers + (Resent-Date and Resent-Message-ID will be generated) + + + + creation of header fields + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_fields * fields; + struct mailimf_field * field; + struct mailimf_date_time * date; + char * msg_id; + struct mailimf_mailbox_list * from; + struct mailimf_address_list * to; + + fields = mailimf_fields_new_empty(); + field = mailimf_field_new_custom(strdup("X-Mailer"), strdup("my-mailer")); + mailimf_fields_add(fields, field); + + from = mailimf_mailbox_list_new_empty(); + mailimf_mailbox_list_add_mb(from, strdup("DINH Viet Hoa"), strdup("dinh.viet.hoa@free.fr"); + date = mailimf_get_current_date(); + msg_id = mailimf_get_message_id(); + to = mailimf_address_list_new_empty(); + mailimf_address_list_add_mb(to, strdup("FOO Bar"), strdup("foo@bar.org"); + + mailimf_fields_add_data(fields, date, from, NULL, NULL, to, NULL, NULL, + msg_id, NULL, NULL, strdup("hello")); + + /* do the things */ + + mailimf_fields_free(fields); +} + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_fields * fields; + struct mailimf_mailbox_list * from; + struct mailimf_address_list * to; + struct mailimf_date_time * date; + char * msg_id; + + from = mailimf_mailbox_list_new_empty(); + mailimf_mailbox_list_add_mb(from, strdup("DINH Viet Hoa"), strdup("dinh.viet.hoa@free.fr"); + to = mailimf_address_list_new_empty(); + mailimf_address_list_add_mb(to, strdup("FOO Bar"), strdup("foo@bar.org"); + date = mailimf_get_current_date(); + msg_id = mailimf_get_message_id(); + + fields = mailimf_fields_new_with_all_data(date, from, NULL, NULL, to, NULL, NULL, + msg_id, NULL, NULL, strdup("hello")); + + /* do the things */ + + mailimf_fields_free(fields); +} + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailimf_fields * fields; + struct mailimf_mailbox_list * from; + struct mailimf_address_list * to; + + from = mailimf_mailbox_list_new_empty(); + mailimf_mailbox_list_add_mb(from, strdup("DINH Viet Hoa"), strdup("dinh.viet.hoa@free.fr"); + to = mailimf_address_list_new_empty(); + mailimf_address_list_add_mb(to, strdup("FOO Bar"), strdup("foo@bar.org"); + + fields = mailimf_fields_new_with_data(from, NULL, NULL, to, NULL, NULL, + NULL, NULL, strdup("hello")); + + /* do the things */ + + mailimf_fields_free(fields); +} + + + + + + + + Rendering of messages + + Header fields + +#include <libetpan/libetpan.h> + +int mailimf_fields_write(FILE * f, int * col, + struct mailimf_fields * fields); + +int mailimf_envelope_fields_write(FILE * f, int * col, + struct mailimf_fields * fields); + +int mailimf_field_write(FILE * f, int * col, + struct mailimf_field * 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 ). + + + + + field is a field + (see ). + + + + + + + mailimf_fields_write outputs the set of + header fields. + + + + + mailimf_envelope_fields_write outputs the + set of header fields except the optional fields. + + + + + mailimf_field_write outputs a header. + + + + rendering of fields + +int main(int argc, char ** argv) +{ + struct mailimf_fields * fields; + int col; + + /* look at the example in mailimf_fields to see how to + build a mailimf_fields */ + fields = build_imf_fields(); + + col = 0; + mailimf_fields_write(stdout, &col, fields); + + mailimf_fields_free(fields); +} + +int main(int argc, char ** argv) +{ + struct mailimf_fields * fields; + int col; + + /* look at the example in mailimf_fields to see how to + build a mailimf_fields */ + fields = build_imf_fields(); + + col = 0; + mailimf_envelope_fields_write(stdout, &col, fields); + + mailimf_fields_free(fields); +} + +int main(int argc, char ** argv) +{ + struct mailimf_field * field; + int col; + + field = mailimf_field_new_custom(strdup("X-Mailer"), strdup("my mailer")); + + col = 0; + mailimf_field_write(stdout, &col, field); + + mailimf_field_free(field); +} + + + + + + + + + + MIME + + + libEtPan! implements a MIME message parser (also known as + messages with attachments or + multipart messages). This also allows to generate MIME messages. + + + + + All allocation functions will take as argument allocated data + and will store these data in the structure they will allocate. + Data should be persistant during all the use of the structure + and will be freed by the free function of the structure + + + + allocation functions will return NULL on failure + + functions returning integer will be returning one of the + following error code: + MAILIMF_NO_ERROR, + MAILIMF_ERROR_PARSE, + MAILIMF_ERROR_MEMORY, + MAILIMF_ERROR_INVAL, + or MAILIMF_ERROR_FILE. + + + + + Quick start + + + You will need this module when you want to parse a MIME + message. + + + + Parse MIME message + + You will use the following function : + + + + + mailmime_parse + () + + + + + + + Render the MIME message + + Build your MIME message, then use + mailmime_write + () + to render a MIME message. + + + + + + Data types + + + mailmime_composite_type - Composite MIME type + + +#include <libetpan/libetpan.h> + +enum { + MAILMIME_COMPOSITE_TYPE_ERROR, + MAILMIME_COMPOSITE_TYPE_MESSAGE, + MAILMIME_COMPOSITE_TYPE_MULTIPART, + MAILMIME_COMPOSITE_TYPE_EXTENSION +}; + +struct mailmime_composite_type { + int ct_type; + char * ct_token; +}; + +struct mailmime_composite_type * +mailmime_composite_type_new(int ct_type, char * ct_token); + +void mailmime_composite_type_free(struct mailmime_composite_type * ct); + + + + This is a MIME composite type such as message or + multipart. + + + + ct_type can have one of the 3 following values : + MAILMIME_COMPOSITE_TYPE_MESSAGE when the + composite MIME type + is message, + MAILMIME_COMPOSITE_TYPE_MULTIPART when + the composite MIME type + is multipart, + MAILMIME_COMPOSITE_TYPE_EXTENSION for + other and ct_token is set + in this case. + MAILMIME_COMPOSITE_TYPE_ERROR is used + internally on parse error. + + + + mailmime_composite_type_new() creates and + initializes + a data structure with a value. + Structures given as argument are referenced by the created + object and will be freed if the object is released. + + + + mailmime_composite_type_free() frees + memory used by + the structure and substructures will also be released. + + + + create and display MIME composite type + +#include <libetpan/libetpan.h> + +int main(void) +{ + struct mailmime_composite_type * ct; + + ct = mailmime_composite_type_new(MAILMIME_COMPOSITE_TYPE_MULTIPART, NULL); + + /* do your things ... */ + + mailmime_composite_type_free(ct); + + exit(EXIT_SUCCESS); +} + +void display_composite_type() +{ + switch (ct->type) { + case MAILMIME_COMPOSITE_TYPE_MESSAGE: + printf("composite type is message\n"); + break; + case MAILMIME_COMPOSITE_TYPE_MULTIPART: + printf("composite type is multipart\n"); + break; + case MAILMIME_COMPOSITE_TYPE_EXTENSION: + printf("composite type: %s\n", ct->ct_token); + break; + } +} + + + + + + + + mailmime_content - MIME content type (Content-Type) + + +#include <libetpan/libetpan.h> + +struct mailmime_content { + struct mailmime_type * ct_type; + char * ct_subtype; + clist * ct_parameters; /* elements are (struct mailmime_parameter *) */ +}; + +struct mailmime_content * +mailmime_content_new(struct mailmime_type * ct_type, + char * ct_subtype, + clist * ct_parameters); + +void mailmime_content_free(struct mailmime_content * content); + + + + This is a MIME content type such as message/rfc822 or + text/plain. + + + + + + ct_type is the main MIME type, + for example text in + plain/text + (see ). + + + ct_subtype is the MIME subtype, + for example plain in + plain/text. + + + + + ct_parameters is the list of parameters for + the given MIME type. For example, for plain/text, + we can find charset=iso-8859-1, + format=flowed. Each element of the list + if of type struct mailmime_parameter * + (see ). + + + + + + mailmime_content_new() creates and initializes + a data structure with a value. + Structures given as argument are referenced by the created + object and will be freed if the object is released. + + + + mailmime_content_free() frees memory used by + the structure and substructures will also be released. + + + + Creation and display of MIME content type + +#include <libetpan/libetpan.h> + +int main(void) +{ + struct mailmime_content * content; + struct mailmime_type * type; + struct mailmime_discrete_type * dt; + struct mailmime_parameter * param; + clist * param_list; + + dt = mailmime_discrete_type_new(MAILMIME_DISCRETE_TYPE_TEXT, NULL); + type = mailmime_type_new(MAILMIME_TYPE_DISCRETE_TYPE, dt, NUL); + param_list = clist_new(); + param = mailmime_parameter_new(strdup("charset"), strdup("iso-8859-1")); + clist_append(param_list, param); + + content = mailmime_content_new(type, strdup("plain"), param_list); + + /* do your things */ + + exit(EXIT_SUCCESS); +} + +void display_mime_content(struct mailmime_content * content_type) +{ + clistiter * cur; + + printf("type:\n"); + display_type(content_type->ct_type); + printf("\n"); + printf("subtype: %s\n", content_type->ct_subtype); + printf("\n"); + + for(cur = clist_begin(content_type->ct_parameters) ; cur != NULL ; + cur = clist_next(cur)) { + struct mailmime_parameter * param; + + param = clist_content(cur); + display_mime_parameter(param); + printf("\n"); + } + printf("\n"); +} + + + + + + + + mailmime_discrete_type - MIME discrete type + + +#include <libetpan/libetpan.h> + +enum { + MAILMIME_DISCRETE_TYPE_ERROR, + MAILMIME_DISCRETE_TYPE_TEXT, + MAILMIME_DISCRETE_TYPE_IMAGE, + MAILMIME_DISCRETE_TYPE_AUDIO, + MAILMIME_DISCRETE_TYPE_VIDEO, + MAILMIME_DISCRETE_TYPE_APPLICATION, + MAILMIME_DISCRETE_TYPE_EXTENSION +}; + +struct mailmime_discrete_type { + int dt_type; + char * dt_extension; +}; + +struct mailmime_discrete_type * +mailmime_discrete_type_new(int dt_type, char * dt_extension); + +void mailmime_discrete_type_free(struct mailmime_discrete_type * + discrete_type); + + + + This is a MIME discrete type such as text or + image. This is also known as single part. This kind + of part does not have any child. + + + + dt_type is one of the given values : + MAILMIME_DISCRETE_TYPE_TEXT if part is text, + MAILMIME_DISCRETE_TYPE_IMAGE if part is an image, + MAILMIME_DISCRETE_TYPE_AUDIO if part is + audio data, + MAILMIME_DISCRETE_TYPE_VIDEO if part is video, + MAILMIME_DISCRETE_TYPE_APPLICATION if + part is application data or + MAILMIME_DISCRETE_TYPE_EXTENSION for other. + In the case of MAILMIME_DISCRETE_TYPE_EXTENSION, + dt_extension is filled in. + MAILMIME_DISCRETE_TYPE_ERROR is used internally. + + + + mailmime_discrete_type_new() creates and + initializes + a data structure with a value. + Structures given as argument are referenced by the created + object and will be freed if the object is released. + + + + mailmime_discrete_type_free() frees + memory used by + the structure and substructures will also be released. + + + + Creation and display of MIME discrete type + +#include <libetpan/libetpan.h> + +/* standard type */ + +int main(int argc, char ** argv) +{ + struct mailmime_discrete_type * discrete_type; + + discrete_type = mailmime_discrete_type_new(MAILMIME_DISCRETE_TYPE_TEXT, + NULL); + + /* do the things */ + + mailmime_discrete_type_free(discrete_type); +} + +/* extension */ + +int main(int argc, char ** argv) +{ + struct mailmime_discrete_type * discrete_type; + + discrete_type = mailmime_discrete_type_new(MAILMIME_DISCRETE_TYPE_EXTENSION, + strdup("my-type")); + + /* do the things */ + + mailmime_discrete_type_free(discrete_type); +} + +void display_mime_discrete_type(struct mailmime_discrete_type * discrete_type) +{ + switch (discrete_type->dt_type) { + case MAILMIME_DISCRETE_TYPE_TEXT: + printf("text\n"); + break; + case MAILMIME_DISCRETE_TYPE_IMAGE: + printf("image\n"); + break; + case MAILMIME_DISCRETE_TYPE_AUDIO: + printf("audio\n"); + break; + case MAILMIME_DISCRETE_TYPE_VIDEO: + printf("video\n"); + break; + case MAILMIME_DISCRETE_TYPE_APPLICATION: + printf("application\n"); + break; + case MAILMIME_DISCRETE_TYPE_EXTENSION: + printf("extension : %s\n", discrete_type->dt_extension); + break; + } +} + + + + + + + + mailmime_field - MIME header field + + +#include <libetpan/libetpan.h> + +enum { + MAILMIME_FIELD_NONE, + MAILMIME_FIELD_TYPE, + MAILMIME_FIELD_TRANSFER_ENCODING, + MAILMIME_FIELD_ID, + MAILMIME_FIELD_DESCRIPTION, + MAILMIME_FIELD_VERSION, + MAILMIME_FIELD_DISPOSITION, + MAILMIME_FIELD_LANGUAGE, +}; + +struct mailmime_field { + int fld_type; + union { + struct mailmime_content * fld_content; + struct mailmime_mechanism * fld_encoding; + char * fld_id; + char * fld_description; + uint32_t fld_version; + struct mailmime_disposition * fld_disposition; + struct mailmime_language * fld_language; + } fld_data; +}; + +struct mailmime_field * +mailmime_field_new(int fld_type, + struct mailmime_content * fld_content, + struct mailmime_mechanism * fld_encoding, + char * fld_id, + char * fld_description, + uint32_t fld_version, + struct mailmime_disposition * fld_disposition, + struct mailmime_language * fld_language); + +void mailmime_field_free(struct mailmime_field * field); + + + + This is a parsed MIME header field; + + + + + + fld_type is the type of MIME header field. The value can + be + MAILMIME_FIELD_TYPE + if field is Content-Type, + MAILMIME_FIELD_TRANSFER_ENCODING + if field is Content-Transfer-Encoding, + MAILMIME_FIELD_ID + if field is Content-ID, + MAILMIME_FIELD_DESCRIPTION + if field is Content-Description, + MAILMIME_FIELD_VERSION + if field is MIME-Version, + MAILMIME_FIELD_DISPOSITION + if field is Content-Disposition or + MAILMIME_FIELD_LANGUAGE + if field is Content-Language. + MAILMIME_FIELD_NONE is used internally. + + + + + fld_data.fld_content is set in case of + Content-Type. + (see ). + + + + + fld_data.fld_encoding is set in case of + Content-Transfer-Encoding. + (see ). + + + + + fld_data.fld_id is set in case of + Content-ID. This is a string. + + + + + fld_data.fld_description is set in case of + Content-Description. This is a string. + + + + + fld_data.fld_version is set in case of + MIME-Version. This is an integer built + using the following formula : + fld_version = major * 2^16 + minor. + Currenly MIME-Version is always 1.0, this means that + fld_version will always be 2^16 (in C language, + this is 1 << 16). + + + + + fld_data.fld_disposition is set in case of + Content-Disposition. + (see ). + + + + + fld_data.fld_language is set in case of + Content-Language. + (see ). + + + + + + mailmime_field_new() creates and initializes + a data structure with a value. + Structures given as argument are referenced by the created + object and will be freed if the object is released. + + + + mailmime_field_free() frees memory used by + the structure and substructures will also be released. + + + + Creation and display of MIME header field + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailmime_field * field; + struct mailmime_mechanism * encoding; + + encoding = mailmime_mechanism_new(MAILMIME_MECHANISM_BASE64, NULL); + + field = mailmime_field_new(MAILMIME_FIELD_TRANSFER_ENCODING, + NULL, encoding, NULL, NULL, 0, NULL, NULL); + + /* do the things */ + + mailmime_field_free(field); +} + +void display_mime_field(struct mailmime_field * field) +{ + switch (field->fld_type) { + case MAILMIME_FIELD_TYPE: + printf("content-type:"); + display_mime_content(field->fld_data.fld_content); + break; + case MAILMIME_FIELD_TRANSFER_ENCODING: + printf("content-transfer-encoding:"); + display_mime_mechanism(field->fld_data.fld_encoding); + break; + case MAILMIME_FIELD_ID: + printf("content-id: %s\n", field->fld_data.fld_id); + break; + case MAILMIME_FIELD_DESCRIPTION: + printf("content-description: %s\n", field->fld_data.fld_description); + break; + case MAILMIME_FIELD_VERSION: + printf("mime-version: %i.%i\n", + field->version>> 16, field->fld_data.fld_version & 0xFFFF); + break; + case MAILMIME_FIELD_DISPOSITION: + printf("content-disposition:"); + display_mime_disposition(field->fld_data.fld_disposition); + break; + case MAILMIME_FIELD_LANGUAGE: + printf("content-language:"); + display_mime_language(field->fld_data.fld_language); + break; + } +} + + + + + + + mailmime_mechanism - MIME transfer encoding mechanism (Content-Transfer-Encoding) + + +#include <libetpan/libetpan.h> + +enum { + MAILMIME_MECHANISM_ERROR, + MAILMIME_MECHANISM_7BIT, + MAILMIME_MECHANISM_8BIT, + MAILMIME_MECHANISM_BINARY, + MAILMIME_MECHANISM_QUOTED_PRINTABLE, + MAILMIME_MECHANISM_BASE64, + MAILMIME_MECHANISM_TOKEN +}; + +struct mailmime_mechanism { + int enc_type; + char * enc_token; +}; + +struct mailmime_mechanism * mailmime_mechanism_new(int enc_type, char * enc_token); + +void mailmime_mechanism_free(struct mailmime_mechanism * mechanism); + + + + This is a MIME transfer encoding mechanism description. + + + + enc_type is an encoding type. The value of this field + can be + MAILMIME_MECHANISM_7BIT + if mechanism is 7bit, + MAILMIME_MECHANISM_8BIT + if mechanism is 8bit, + MAILMIME_MECHANISM_BINARY + if mechanism is binary, + MAILMIME_MECHANISM_QUOTED_PRINTABLE + if mechanism is quoted-printable, + MAILMIME_MECHANISM_BASE64 + if mechanism is base64 or + MAILMIME_MECHANISM_TOKEN for other. + In case of MAILMIME_MECHANISM_TOKEN, + field enc_token is filled in. + MAILMIME_MECHANISM_ERROR is used internally. + + + + mailmime_mechanism_new() creates and initializes + a data structure with a value. + Structures given as argument are referenced by the created + object and will be freed if the object is released. + + + + mailmime_mechanism_free() frees memory used by + the structure and substructures will also be released. + + + + Creation and display of MIME transfer encoding mechanism + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailmime_mechanism * encoding; + + encoding = mailmime_mechanism_new(MAILMIME_MECHANISM_QUOTED_PRINTABLE, NULL); + + /* do the things */ + + mailmime_mechanism_free(encoding); +} + +int main(int argc, char ** argv) +{ + struct mailmime_mechanism * encoding; + + encoding = mailmime_mechanism_new(MAILMIME_MECHANISM_TOKEN, + strdup("uuencoding")); + + /* do the things */ + + mailmime_mechanism_free(encoding); +} + +void display_mime_mechanism(struct mailmime_mechanism * encoding) +{ + switch (encoding->enc_type) { + case MAILMIME_MECHANISM_7BIT: + printf("7bit\n"); + break; + case MAILMIME_MECHANISM_8BIT: + printf("8bit\n"); + break; + case MAILMIME_MECHANISM_BINARY: + printf("binary\n"); + break; + case MAILMIME_MECHANISM_QUOTED_PRINTABLE: + printf("quoted-printable\n"); + break; + case MAILMIME_MECHANISM_BASE64: + printf("base64\n"); + break; + case MAILMIME_MECHANISM_TOKEN: + printf("extension : %s\n", encoding->enc_token); + break; + } +} + + + + + + + mailmime_fields - header fields + + +#include <libetpan/libetpan.h> + +struct mailmime_fields { + clist * fld_list; /* list of (struct mailmime_field *) */ +}; + +struct mailmime_fields * mailmime_fields_new(clist * fld_list); + +void mailmime_fields_free(struct mailmime_fields * fields); + + + + This is the header fields of a MIME part. + + + + fld_list is the list of the header fields. + Each element of the list is a mailmime_field + (See ). + + + + mailmime_fields_new() creates and initializes + a data structure with a value. + Structures given as argument are referenced by the created + object and will be freed if the object is released. + + + + mailmime_fields_free() frees memory used by + the structure and substructures will also be released. + + + + Creation and display of MIME fields + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailmime_field * field; + struct mailmime_fields * fields; + clist * list; + struct mailmime_mechanism * encoding; + struct mailmime_disposition * disposition; + + list = clist_new(); + + encoding = mailmime_mechanism_new(MAILMIME_MECHANISM_BASE64, NULL); + field = mailmime_field_new(MAILMIME_FIELD_TRANSFER_ENCODING, + NULL, encoding, NULL, NULL, 0, NULL, NULL); + clist_append(list, field); + + field = mailmime_field_new(MAILMIME_FIELD_VERSION, + NULL, NULL, NULL, NULL, 1 << 16, NULL, NULL); + clist_append(list, field); + + /* look at the example in mailmime_disposition to see how to + build a mailmime_disposition */ + disposition = build_mime_disposition(); + field = mailmime_field_new(MAILMIME_FIELD_DISPOSITION, + NULL, NULL, NULL, NULL, 0, disposition, NULL); + clist_append(list, field); + + fields = mailmime_fields_new(list); + + /* do the things */ + + mailmime_fields_free(fields); +} + +void display_mime_fields(struct mailmime_fields * fields) +{ + clistiter * cur; + + for(cur = clist_begin(fields->fld_list ; cur != NULL ; + cur = clist_next(cur)) { + struct mailmime_field * field; + + field = clist_content(cur); + display_field(field); + } +} + + + + + + + mailmime_parameter - MIME type parameter + + +struct mailmime_parameter { + char * pa_name; + char * pa_value; +}; + + + + This is the MIME type parameter in + Content-Type MIME header + field. For example, this can be + charset="iso-8859-1". + + + + + + pa_name is the name of the parameter, + for example : charset. + + + + + pa_value is the value of the parameter, + for example : iso-8859-1. + + + + + + mailmime_parameter_new() creates and initializes + a data structure with a value. + Structures given as argument are referenced by the created + object and will be freed if the object is released. + + + + mailmime_parameter_free() frees memory used by + the structure and substructures will also be released. + + + + Creation and display of MIME type parameter + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailmime_parameter * param; + + param = mailmime_parameter_new(strdup("charset"), strdup("iso-8859-1")); + + /* do the things */ + + mailmime_parameter_free(param); +} + +void display_mime_parameter(struct mailmime_parameter * param) +{ + printf("%s = %s\n", param->pa_name, param->pa_value); +} + + + + + + + + mailmime_type - MIME main type + + +#include <libetpan/libetpan.h> + +enum { + MAILMIME_TYPE_ERROR, + MAILMIME_TYPE_DISCRETE_TYPE, + MAILMIME_TYPE_COMPOSITE_TYPE +}; + +struct mailmime_type { + int tp_type; + union { + struct mailmime_discrete_type * tp_discrete_type; + struct mailmime_composite_type * tp_composite_type; + } tp_data; +}; + +struct mailmime_type * +mailmime_type_new(int tp_type, + struct mailmime_discrete_type * tp_discrete_type, + struct mailmime_composite_type * tp_composite_type); + +void mailmime_type_free(struct mailmime_type * type); + + + + This is the MIME main type (no subtype, no parameter). + + + + + + tp_type. The value of this field + is either MAILMIME_TYPE_DISCRETE_TYPE for MIME discrete type, + or MAILMIME_TYPE_COMPOSITE_TYPE for MIME composite type. + MAILMIME_TYPE_ERROR is used internally. + + + + + tp_data.tp_discrete_type is set when tp_type + is MAILMIME_TYPE_DISCRETE_TYPE + (see ). + + + + + tp_data.tp_composite_type is set when tp_type + is MAILMIME_TYPE_COMPOSITE_TYPE + (see ). + + + + + + mailmime_discrete_type_new() creates and + initializes + a data structure with a value. + Structures given as argument are referenced by the created + object and will be freed if the object is released. + + + + mailmime_discrete_type_free() frees + memory used by + the structure and substructures will also be released. + + + + Creation and display of MIME main type + +#include <libetpan/libetpan.h> + +int main(int argc, char ** argv) +{ + struct mailmime_type * type; + struct mailmime_discrete_type * discrete_type; + + discrete_type = + mailmime_discrete_type_new(MAILMIME_DISCRETE_TYPE_TEXT, NULL); + type = mailmime_type_new(MAILMIME_TYPE_DISCRETE_TYPE, discrete_type, NULL); + + /* do the things */ + + mailmime_type_free(type); +} + +int main(int argc, char ** argv) +{ + struct mailmime_type * type; + struct mailmime_composite_type * composite_type; + + composite_type = + mailmime_composite_type_new(MAILMIME_COMPOSITE_TYPE_MULTIPART, NULL); + type = mailmime_type_new(MAILMIME_TYPE_COMPOSITE_TYPE, NULL, composite_type); + + /* do the things */ + + mailmime_type_free(type); +} + +void display_mime_type(struct mailmime_type * type) +{ + printf("mime type:\n"); + switch (type->tp_type) { + case MAILMIME_TYPE_DISCRETE_TYPE: + printf("discrete type:\n"); + display_mime_discrete_type(type->tp_data.tp_discrete_type); + break; + case MAILMIME_TYPE_COMPOSITE_TYPE: + printf("composite type:\n"); + display_mime_composite_type(type->tp_data.tp_composite_type); + break; + } + printf("\n"); +} + + + + + + + mailmime_language - Language of MIME part + + +#include <libetpan/libetpan.h> + +struct mailmime_language { + clist * lg_list; /* atom (char *) */ +}; + +struct mailmime_language * mailmime_language_new(clist * lg_list); + +void mailmime_language_free(struct mailmime_language * lang); + + + + This is the language used in the MIME part. + + + + lg_list is the list of codes of languages used + in the MIME part. This is a list of strings. + + + + mailmime_language_new() creates and + initializes + a data structure with a value. + Structures given as argument are referenced by the created + object and will be freed if the object is released. + + + + mailmime_language_free() frees + memory used by + the structure and substructures will also be released. + + + + 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"); +} + + + + + + + + mailmime_data - Content of MIME part + + +#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. + + + + 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; + } +} + + + + + + + mailmime - MIME part + + +#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. + + + + common + + + + + 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 ). + + + + + + + mm_content_type is the parsed + Content-Type field + (see ). + + + + + + + mm_body is the content of the MIME part + (excluding MIME header), when it is parsed from a string + in memory + (see ). + + + + + + + single 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 ). + + + + + + + multipart + + + + + 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 ). + + + + + + mm_data.mm_multipart.mm_epilogue + is the content of the epilogue of the multipart + (see ). + + + + + + mm_data.mm_multipart.mm_mp_list + is the list of sub parts + + + + + + + message part + + + + + 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 ). + + + + + + mm_data.mm_message.mm_msg_mime is + the subpart + of the message part. + + + + + + + constructor and destructor + + + 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. + + + + 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; + } +} + + + + + + + + + + mailmime_disposition - MIME disposition information (Content-Disposition) + + +#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 ). + + + + + + dsp_parms is the list of parameters + of Content-Disposition header field. + Each element is of type mailmime_disposition_parm + (see ). + + + + + + 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"); +} + + + + + + + + mailmime_disposition_type - Type of MIME disposition + + +#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. + + + + 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; + } +} + + + + + + + mailmime_disposition_parm - MIME disposition parameter + + +#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 ) + + + + + + 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; + } +} + + + + + + + mailmime_single_fields - MIME headers + + + +#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 ) 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 ). + + + + + 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 ). + + + + + 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 ). + + + + + 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 ). + + + + + 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. + + + + 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"); + } +} + + + + + + + + + Parser functions + + + + mailmime_content_parse + + +#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 ). + + + + + + 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, + &current_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), + &current_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); +} + + + + + + + mailmime_description_parse + + +#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(). + + + + + + 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, + &current_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), + &current_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); +} + + + + + + + + + mailmime_encoding_parse + + +#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 ). + + + + + + 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, + &current_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), + &current_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); +} + + + + + + + mailmime_field_parse + + +#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 ). + + + + result. The result of the parse + operation is stored in (* result) + (see ). + + + + + + 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, + &current_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); +} + + + + + + + + mailmime_id_parse + + +#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(). + + + + + + 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, + &current_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), + &current_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); +} + + + + + + + mailmime_fields_parse + + +#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 ). + + + + result. The result of the parse + operation is stored in (* result) + (see ). + + + + + + 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, + &current_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); +} + + + + + + + + mailmime_version_parse + + +#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 ). + + + + + + 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, + &current_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), + &current_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); +} + + + + + + + mailmime_parameter_parse + + +#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 ). + + + + + + 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, + &current_index, &param); + if (r == MAILIMF_NO_ERROR) { + display_mime_parameter(param); + /* do the things */ + mailmime_parameter_free(param); + status = EXIT_SUCCESS; + } + + exit(status); +} + + + + + + + mailmime_language_parse + + +#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 ). + + + + + + 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, + &current_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), + &current_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); +} + + + + + + + mailmime_disposition_parse + + +#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 ). + + + + + + 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, + &current_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), + &current_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); +} + + + + + + + mailmime_disposition_type_parse + + +#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 ). + + + + + + 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, + &current_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); +} + + + + + + + mailmime_encoded_phrase_parse + + +#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). + + + + + + 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); +} + + + + + + + + mailmime_parse + + +#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 ). + + + + + + 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, + &current_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); +} + + + + + + + mailmime_base64_body_parse + + +#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(). + + + + + + 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, + &current_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); +} + + + + + + + mailmime_quoted_printable_body_parse + + +#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(). + + + + + + 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, + &current_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); +} + + + + + + + mailmime_binary_body_parse + + +#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(). + + + + + + 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, + &current_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); +} + + + + + + + mailmime_part_parse + + +#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 ). + + + + + result. The result of the parse + operation is stored in (* result) + The result must be freed with + mmap_string_unref(). + + + + + + 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, &current_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); +} + + + + + + + + Rendering of MIME parts + + + + mailmime_fields_write, mailmime_content_write and + mailmime_content_type_write + + +#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 ). + + + + + content is the header fields + (see ). + + + + + + 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); +} + + + + + + + mailmime_write + + +#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. + + + + + + + + + mailmime_quoted_printable_write + and mailmime_base64_write + + +#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. + + + + + + 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); +} + + + + + + + mailmime_data_write + + +#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 ). + + + + + + + + + Creation functions + + + + mailmime_disposition_new_filename and + mailmime_disposition_new_with_data + + +#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 ). + + + + + + 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); +} + + + + + + + mailmime_fields_new_empty and mailmime_fields_add + + +#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 ). + + + + + field is the MIME header field to add + (see ). + + + + + + 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); +} + + + + + + + mailmime_fields_new_with_data and + mailmime_fields_new_with_version + + +#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. + + + + 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); +} + + + + + + + mailmime_get_content_message + + +#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. + + + + 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); +} + + + + + + + mailmime_data_new_data and mailmime_data_new_file + + +#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 ). + + + + + 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. + + + + + + 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); +} + + + + + + + mailmime_new_message_data, mailmime_new_empty and + mailmime_new_with_content + + +#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 ). + + + + + content is the content type of the part + to create + (see ). + + + + + 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 ). + + + + + + 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); +} + + + + + + + mailmime_set_preamble_file, mailmime_set_epilogue_file, + mailmime_set_preamble_text and mailmime_set_epilogue_text + + +#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 ). + + + + + 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. + + + + + + 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); +} + + + + + + + mailmime_set_body_file and mailmime_set_body_text + + +#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 ). + + + + + 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. + + + + + + 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); +} + + + + + + + + mailmime_add_part, mailmime_remove_part, + mailmime_smart_add_part and mailmime_smart_remove_part + + +#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 ). + + + + + part is the part to add + (see ). + + + + + mime is the parent MIME part + (see ). + + + + + mime_sub is the part to add or to + detach + (see ). + + + + + + 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); +} + + + + + + + mailmime_set_imf_fields + + +#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 ). + + + + + fields is the header fields to set + for the message + (see ). + + + + + + 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); +} + + + + + + + mailmime_fields_new_encoding and + mailmime_fields_new_filename + + +#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 ). + + + + + + 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 ). + + + + + dsp_type is the disposition type. + The value can be + MAILMIME_DISPOSITION_TYPE_INLINE or + MAILMIME_DISPOSITION_TYPE_ATTACHMENT + (see ). + + + + + filename is the filename for MIME + content disposition. + + + + + + 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); +} + + + + + + + + Helper functions + + + + mailmime_transfer_encoding_get + + +#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 ). + + + + + + 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, + &current_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); +} + + + + + + + + mailmime_content_charset_get and + mailmime_content_param_get + + +#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(). + + + + + + 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, + &current_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), + &current_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); +} + + + + + + + + + Storages, folders, messages + + + + Introduction + + + This part will give the definition of some objects. + + + + Message + + + A message is the common e-mail message or news message you + read or send. + + + + + MIME part + + + 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. + + + + + Mailbox + + + A mailbox will contain a given number of messages. + + + + + Storage + + + 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). + + + + + Folder + + + 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. + + + + + Session + + + The session is the network connection or the entity to which + the commands of the drivers are given. + + + + + + Error codes + + + 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, +}; + + + + + + Storage + + + Storage driver + + +#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. + + + + + + + Storage + + +#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. + + + + + + + mailstorage_new and mailstorage_free + + +#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. + + + + + mailstorage_connect and mailstorage_disconnect + + +#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. + + + + + IMAP 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 + + + 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); +} + + + + + + + + Folder + + + Folder driver + + +#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 . + + + + + + + Folder + + +#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 ). + + + + + + 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. + + + + + + + mailfolder_new and mail_folder_free + + +#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. + + + + + mailfolder_connect and mailfolder_disconnect + + +#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. + + + + + mailfolder_noop + + +#include <libetpan/libetpan.h> + +int mailfolder_noop(struct mailfolder * folder); + + + + This function will only send noop to the mail access. + + + + + mailfolder_check + + +#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). + + + + + mailfolder_expunge + + +#include <libetpan/libetpan.h> + +int mailfolder_expunge(struct mailfolder * folder); + + + + A call to this function will delete all messages marked for + deletion. + + + + + mailfolder_status + + +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. + + + + + mailfolder_append_message + + +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). + + + + + mailfolder_get_messages_list + + +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 ). + + + + + mailfolder_get_envelopes_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). + + + + + mailfolder_get_message + + +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 ). + + + + + mailfolder_get_message_by_uid + + +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 ). + + + + + Example + + + 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); +} + + + + + + + + + Message + + + Message driver + + +#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 ). + + + + + + 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. + + + + + + + Message + + +#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 ). + + + + + + msg_driver is the driver used for the + message + (see ). + + + + + + 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 ). + + + + + + msg_flags is the flags of the + message. This can be NULL + (see ). + + + + + + msg_resolved will tell if the field + msg_single_fields has been initialized. + + + + + + msg_single_fields will be filled + using msg_fields + (see ). + + + + + + 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. + + + + + + + mailmessage_new + + +#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. + + + + + mailmessage_init + + +#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 ). + + + + + + session is the session related to the + message + (see ). + + + + + + driver is the driver to use for the + message + (see ). + + + + + + index is the index of the message. + + + + + + size is the size of the message. + + + + + + + mailmessage_flush + + +#include <libetpan/libetpan.h> + +int mailmessage_flush(mailmessage * info); + + + + This function will release the memory used by the MIME + structure of the message. + + + + + mailmessage_check + + +#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. + + + + + mailmessage_fetch_result_free + + +#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. + + + + + mailmessage_fetch + + +#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). + + + + + mailmessage_fetch_header + + +#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. + + + + + + mailmessage_fetch_body + + +#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). + + + + + mailmessage_fetch_size + + +#include <libetpan/libetpan.h> + +int mailmessage_fetch_size(mailmessage * msg_info, + size_t * result); + + + + This function returns the size of the message content. + + + + + mailmessage_get_bodystructure + + +#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 ). + + + + + mailmessage_fetch_section + + +#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. + + + + + mailmessage_fetch_section_header + + +#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. + + + + + mailmessage_fetch_section_mime + + +#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. + + + + + mailmessage_fetch_section_body + + +#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. + + + + + mailmessage_fetch_envelope + + +#include <libetpan/libetpan.h> + +int mailmessage_fetch_envelope(mailmessage * msg_info, + struct mailimf_fields ** result); + + + + + mailmessage_get_flags + + +#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(). + + + + + mailmessage_resolve_single_fields + + +#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. + + + + + Message list + + +#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. + + + + + Message tree + + +#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. + + + + + Message flags + + +#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 + ) of strings representing the + non-standard flags. + + + + + + + Example + + + 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); +} + + + + + + + + Session + + + Session driver + + +#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 ). + + + + + + 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 ). + + + + + + sess_get_envelopes_list() fills the parsed + fields in the mailmessage structures + (see ) + of the mailmessage_list + (see ). + + + + + + 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 ) + that corresponds + to the given message number. + Use of this method is deprecated. + + + + + + sess_get_message_by_uid() returns a + mailmessage structure + (see ) + 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(). + + + + + + + Session + + +#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. + + + + + mailsession_parameters + + +#include <libetpan/libetpan.h> + +int mailsession_parameters(mailsession * session, + int id, void * value); + + + + This function make calls specific to the driver + + + + + mailsession_connect_stream + + +#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 + + + + + mailsession_connect_path + + +#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. + + + + + mailsession_starttls + + +#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. + + + + + mailsession_login + + +#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. + + + + + mailsession_logout + + +#include <libetpan/libetpan.h> + +int mailsession_logout(mailsession * session); + + + + This function disconnects the session and closes the stream. + + + + + mailsession_noop + + +#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. + + + + + mailsession_check_folder + + +#include <libetpan/libetpan.h> + +int mailsession_check_folder(mailsession * session); + + + + This function makes a checkpoint of the session. + + + + + mailsession_select_folder + + +#include <libetpan/libetpan.h> + +int mailsession_select_folder(mailsession * session, char * mb); + + + + This function selects a mailbox. + + + + + mailsession_expunge_folder + + +#include <libetpan/libetpan.h> + +int mailsession_expunge_folder(mailsession * session); + + + + This function deletes all messages marked for deletion. + + + + + mailsession_status_folder + + +#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). + + + + + mailsession_messages_number + + +#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. + + + + + mailsession_recent_number + + +#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. + + + + + mailsession_unseen_number + + +#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. + + + + + mailsession_append_message + + +#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. + + + + + mailsession_get_messages_list + + +#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. + + + + + mailsession_get_envelopes_list + + +#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 ) + of the mailmessage_list + (see ). + + + + + mailsession_get_message + + +#include <libetpan/libetpan.h> + +int mailsession_get_message(mailsession * session, + uint32_t num, mailmessage ** result); + + + + This function returns a mailmessage + (see ) structure that + corresponds to the given message number. + + + + + mailsession_get_message_by_uid() should + be used instead. + + + + + + mailsession_get_message_by_uid + + +#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. + + + + That deprecates the use of + mailsession_get_message(). + + + + + + + diff --git a/kmicromail/libetpan/doc/DOCUMENTATION b/kmicromail/libetpan/doc/DOCUMENTATION new file mode 100644 index 0000000..4f66519 --- a/dev/null +++ b/kmicromail/libetpan/doc/DOCUMENTATION @@ -0,0 +1,654 @@ +1/ Introduction +--------------- + +libEtPan! is mainly a library that will handle all kind of mailbox access. +For example: IMAPrev4, POP3, NNTP, mbox, MH. + +You have two kinds of mailbox access, either using low-level functions +with a different interface for each kind of access or using higher-level +functions, using a driver to wrap the higher-level API. + + +2/ Low-level +------------ + +2.1/ IMAP4rev1 - Internet Message Access Protocol - Version 4rev1 +----------------------------------------------------------------- + +Each command of the IMAP4rev1 Standard (RFC 2060) is implemented in +the IMAP4rev1 module. Directory imap/. + +2.1.1/ References + +- RFC 2060 - INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1 +- draft-crispin-imapv-15.txt + +Not yet implemented : + +- draft-crispin-imapv-20.txt + +2.1.2/ Dependencies + +- tools/ + +2.1.3/ Files descriptions + +description of header files : +mailimap.[ch] -- functions that implements each IMAP4rev1 command +mailimap_helper.[ch] -- helper interface for the previous functions +mailimap_types.[ch] -- definition of types and constructors for these + types +mailimap_types_helper.[ch] -- contains function definitions that will help + to create data necessary to use IMAP4rev1 module +mailimap_socket.[ch] -- provides a function to connect to an + IMAP4rev1 server over TCP +mailimap_ssl.[ch] -- provides a function to connect to an + IMAP4rev1 server over TLS layer + +2.1.4/ Interface + +Include for this module is mailimap.h and includes all other headers. + + +The interface of IMAP4rev1 is documented in the following files : + +mailimap.h +mailimap_types.h +mailimap_types_helper.h + + +2.2/ POP3 - Post Office Protocol - Version 3 +-------------------------------------------- + +Each command of the POP3 Standard (RFC 1939 and RFC 2449) is implemented +in the POP3 module. Directory pop3/. + +2.1.1/ References + +- RFC 1939 - Post Office Protocol - Version 3 +- RFC 2449 - POP3 Extension Mechanism (CAPA) + +Not yet implemented : + +- RFC 1734 - POP3 AUTHentication command + +2.1.2/ Dependencies + +- tools/ + +2.2.3/ Files descriptions + +mailpop3.[ch] -- functions that implements each POP3 command +mailpop3_helper.[ch] -- helper interface for the previous functions +mailpop3_socket.[ch] -- provides a function to connect to a + POP3 server over TCP +mailpop3_ssl.[ch] -- provides a function to connect to a + POP3 server over TLS layer + +2.2.4/ Interface + +Include for this module is mailpop3.h and includes all other headers. + +There is not yet documentation for POP3 module. + + +2.3/ NNTP - Network News Transfer Protocol +------------------------------------------ + +Each command of the NNTP Standard (RFC 977 and RFC 2980) is implemented +in the NNTP module. Directory nntp/. + +2.3.1/ References + +- RFC 977 - Network News Transfer Protocol +- RFC 2980 - Common NNTP Extensions + +Not yet implemented : + +- RFC 1036 - Standard for Interchange of USENET Messages +- son of RFC 1036 : FTP://zoo.toronto.edu/pub/news.txt.Z + +2.3.2/ Dependencies + +- tools/ + +2.3.3/ Files descriptions + +newsnntp.[ch] -- functions that implements each NNTP command +newsnntp_socket.[ch] -- provides a function to connect to a + NNTP server over TCP +newsnntp_ssl.[ch] -- provides a function to connect to a + POP3 server over TLS layer + +2.3.4/ Interface + +Include for this module is newsnntp.h and includes all other headers. + +There is not yet documentation for NNTP module. + + +2.4/ mbox +--------- + +The mbox module provides a set of functions to manipulate mbox mailboxes. +These functions make a safe lock on the mailbox they work with. +This module will assign to each message a unique message identifier +so that we can work with message numbers in mbox files without other +programs interfer. +Directory mbox/. + +2.4.1/ References + +- http://wp.netscape.com/eng/mozilla/2.0/relnotes/demo/content-length.html +- http://www.qmail.org/qmail-manual-html/man5/mbox.html + +2.4.2/ Dependencies + +- tools/ +- imf/ + +2.5.3/ Specific to libEtPan! + +- "X-LibEtPan-UID" header + +2.5.4/ Files descriptions + +mailmbox.[ch] -- functions to manipulate mbox mailboxes. +mailmbox_parse.[ch] -- this module is in charge of parsing the + mbox file content +mailmbox_types.[ch] -- definition of types and constructors for these + types + +2.4.5/ Interface + +Include for this module is mailmbox.h and includes all other headers. + +There is not yet documentation for mbox module. + + +2.5/ MH +------- + +The MH module provides a set of functions to manipulate MH mailboxes. +Directory mh/. + +2.5.1/ References + +- almost none + +2.5.2/ Dependencies + +- tools/ + +2.5.3/ Files descriptions + +mailmh.[ch] -- functions to manipulate MH mailboxes. + + +2.5.4/ Interface + +Include for this module is mailmh.h. + +There is not yet documentation for MH module. + + +2.6/ IMF - Internet Message Format +---------------------------------- + +The IMF module provides functions to parse data given in RFC 2822 +format (Internet Message Format). +Directory imf/. + +2.6.1/ References + +- RFC 2822 - Internet Message Format (Not entirely implemented) +- RFC 2076 - Common Internet Message Headers + +Not yet implemented : + +- RFC 2298 - An Extensible Message Format + for Message Disposition Notifications + +2.6.2/ Dependencies + +- tools/ + +2.6.3/ Files descriptions + +mailimf.[ch] -- functions to parse RFC 2822 messages. +mailimf_types.[ch] -- definition of types and constructors for these + types +mailimf_types_helper.[ch] -- contains function definitions that will help + to create data necessary to use IMF module. +mailimf_write.[ch] -- functions that output RFC 2822 messages or + sub-part of the messages in a (FILE *). + +2.6.4/ Interface + +Include for this module is mailimf.h and includes all other headers. + +The interface of IMAP4rev1 is documented in the following files : + +mailimf.h +mailimf_types.h +mailimf_types_helper.h +mailimf_write.h + + +2.7/ MIME - Multipurpose Internet Mail Extensions +------------------------------------------------- + +The MIME module provides functions to parse structure of MIME messages. +Directory mime/. + +2.7.1/ References + +- RFC 2045 - Multipurpose Internet Mail Extensions (MIME) Part One: Format of + Internet Message Bodies. +- RFC 2047 - MIME (Multipurpose Internet Mail Extensions) Part Three: Message + Header Extensions for Non-ASCII Text. +- RFC 2183 - Communicating Presentation Information in Internet Messages: + The Content-Disposition Header Field + +Not implemented : + +- RFC 2046 - Multipurpose Internet Mail Extensions (MIME) Part Two: Media + Types. + +2.7.2/ Dependencies + +- tools/ +- imf/ + +2.7.3/ Files descriptions + +mailmime.[ch] -- functions to parse the MIME fields (RFC 2045). +mailmime_content.[ch] -- functions to parse the MIME message. You get + the different parts and you can decode them. +mailmime_decode.[ch] -- functions to parse the MIME-encoded fields. +mailmime_disposition.[ch] -- functions to parse the Content-Disposition field + (RFC 2183) +mailmime_types.[ch] -- definition of types and constructors for these + types +mailmime_types_helper.[ch] -- contains function definitions that will help + to create data necessary to use MIME module. +mailmime_write.[ch] -- functions that output MIME messages or + sub-part of the messages in a (FILE *). + +2.7.4/ Interface + +Include for this module is mailmime.h and includes all other headers. + +There is not yet documentation for MIME module. + + +2.8/ SMTP - Simple Mail Transfer Protocol +----------------------------------------- + +Each command of the SMTP Standard (RFC 2821 and RFC 1891) is implemented +in the SMTP module. Directory smtp/. + +2.8.1/ References + +- RFC 2821 - Simple Mail Transfer Protocol (Not entirely implemented) +- RFC 1891 - SMTP Service Extension for Delivery Status Notifications + +2.8.2/ Depencencies + +- tools/ + +2.8.3/ Files descriptions + +mailsmtp.[ch] -- functions that implements each SMTP command +mailsmtp_helper.[ch] -- functions to get an easier use of SMTP module +mailsmtp_socket.[ch] -- provides a function to connect to a + SMTP server over TCP +mailsmtp_ssl.[ch] -- provides a function to connect to a + SMTP server over TLS layer +mailsmtp_types.h -- definition of types + +2.8.4/ Interface + +Include for this module is mailsmtp.h and includes all other headers. + +There is not yet documentation for MIME module. + + +2.9/ Miscellaneous + +2.9.1/ References + +- RFC 2234 - Augmented BNF for Syntax Specifications: ABNF +- RFC 2595 - Using TLS with IMAP, POP3 and ACAP + +2.9.2/ Tools + +tools/ directory contains some tools functions and useful data structures. + +alloc.h -- a wrapper on malloc() +carray.[ch] -- an array, that grows automatically when elements + are added. +charconv.[ch] -- character set converter. For example, it will + translate an iso-8859-1 string to an utf-8 string. +chash.[ch] -- a hash table which keys can be anything +cinthash.[ch] -- a hash table which keys are integers + (should be removed and replaced with chash) +clist.[ch] -- a double-linked list +connect.[ch] -- easy interface to connect a TCP server +hmac_md5.h +md5.[ch] +md5global.h -- MD5 calculation +mail.h -- some constants +maildb_helper.[ch] -- wrappers to DB 2.x 3.x or 4.x +maillock.[ch] -- safely lock a given file +mailstream.[ch] -- stream interface - buffered reading and writing + on files/socket/SSL connection +mailstream_helper.[ch] -- useful functions for stream + (for example: read a line) +mailstream_low.[ch] -- driver interface for a stream +mailstream_socket.[ch] -- stream driver for file descriptors (includes socket) +mailstream_ssl.[ch] -- stream driver for SSL connection +mailstream_types.h -- data structure definition +mapping.[ch] -- map parts of files in memory (no more used) +mmapstring.[ch] -- a string, that grows automatically when data + are added. + + +3/ Higher-level +--------------- + +The higher level will allow us to query folder informations or to get +messages information or content. + +There is four kinds of identities : +- storage +- folders +- session +- messages + +In the higher-level interface, you manipulate data types from IMF and +MIME module, plus additionnal data types of higher-level. + + +3.1/ Objects +------------ + +3.1.1/ Storage + +A storage (struct mail_storage) represents whether a server or +a main path, It can be an IMAP server, the root path of a MH or a mbox file. + + +3.1.2/ Folders + +A folder can be created from a storage. +Folders (struct mail_folder) are the mailboxes we can choose in the +server or as sub-folder of the main path. + +Folders for IMAP are the IMAP mailboxes, for MH this is one of the +folder of the MH storage, for mbox, there is only one folder, the +mbox file content; + + +3.1.3/ Session + +Storage and folders communicate with the lower-layer through the +mail session data structure. + +A mail session (struct mailsession) is a mail access to a server +or a mail access in the local file system. It allow us to send commands +to the mail access. + +A mail storage is using a mail session to communicate. +A folder folder also uses a mail session to get information or to send +information. It can be the same session or not, depdending of the +implementation. + + +3.1.4/ Messages + +From a session, we can get a message (struct mailmessage) to read. + + +3.2/ Drivers +------------ + +For a mail access, three drivers exist. +One for storage, one for session, one for message. +Note that the folder access rely only on session driver. + + +3.2.1/ storage driver interface + + mail_storage_driver is the driver structure for mail storage + + - name is the name of the driver + + - connect() connects the storage to the remote access or to + the path in the local filesystem. + + - get_folder() 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 driver. + + - free_data() frees the data created with mail_storage constructor. + + a constructor for each kind of access has to be implemented. + + +3.2.2/ session driver interface + + maildriver is the driver structure for mail sessions + + - name is the name of the driver + + - initialize() is the function that will initializes a data structure + specific to the driver, it returns a value that will be stored + in the field data of the session. + The field data of 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(). + + - uninitialize() frees the structure created with initialize() + + - parameters() implements functions specific to the given mail access + + - connect_stream() connects a stream to the session + + - connect_path() notify a main path to the session + + - starttls() changes the current stream to a TLS stream + + - login() notifies the user and the password to authenticate to the + session + + - logout() exits the session and closes the stream + + - noop() does no operation on the session, but it can be + used to poll for the status of the connection. + + - check_folder() makes a checkpoint of the session + + - select_folder() selects a mailbox + + - expunge_folder() deletes all messages marked \Deleted + + - status_folder() queries the status of the folder + (number of messages, number of recent messages, number of + unseen messages) + + - append_message() adds a RFC 2822 message to the current + given mailbox + + - get_messages_list() returns the list of message numbers + of the current mailbox. + + - get_envelopes_list() fills the parsed fields in the + mailmessage structures of the mail_envelopes_list. + + - remove_message() removes the given message from the mailbox. + The message is permanently deleted. + + - get_message returns a mailmessage structure that corresponds + to the given message number. + + +3.2.3/ message driver interface + + mailmessage_driver is the driver structure to get information from messages. + + - name is the name of the driver + + - initialize() is the function that will initializes a data structure + specific to the driver, it returns a value that will be stored + in the field data of the mailsession. + The field data of the session is the state of the session, + the internal data structure used by the driver. + It is called when initializing the mailmessage structure with + mailmessage_init(). + + - uninitialize() frees the structure created with initialize(). + It will be called by mailmessage_free(). + + - flush() will free from memory all temporary structures of the message + (for example, the MIME structure of the message). + + - fetch_result_free() will free all strings resulted by fetch() or + any fetch_xxx() functions that returns a string. + + - fetch() returns the content of the message (headers and text). + + - fetch_header() returns the content of the headers. + + - fetch_body() returns the message text (message content without headers) + + - fetch_size() returns the size of the message content. + + - get_bodystructure() returns the MIME structure of the message. + + - fetch_section() returns the content of a given MIME part + + - fetch_section_header() returns the header of the message + contained by the given MIME part. + + - fetch_section_mime() returns the MIME headers of the + given MIME part. + + - fetch_section_body() returns the text (if this is a message, this is the + message content without headers) of the given MIME part. + + - fetch_envelope() returns a mailimf_fields structure, with a list of + fields chosen by the driver. + + - get_flags() returns a the flags related to the message. + When you want to get flags of a message, you have to make sure to + call get_flags() at least once before using directly message->flags. + + +3.3/ Higher level interface +--------------------------- + +3.3.1/ Files descriptions + +generic_cache.[ch] -- functions that implements cache and + flags storing mechanism +imapdriver.[ch] -- IMAP driver for session +imapdriver_cached.[ch] -- IMAP driver for session, using cache, + IMAP already has flags. +imapdriver_cached_message.[ch] -- IMAP driver for message, using cache + IMAP already has flags. +imapdriver_message.[ch] -- IMAP driver for message +imapdriver_types.[ch] -- tools function for IMAP driver (types + conversion from IMAP module). +imapstorage.[ch] -- IMAP driver for storage +imfcache.[ch] -- implements cache for parsed fields +libetpan.h -- includes all necessary header files to + use libEtPan! +maildriver.[ch] -- wrappers to calls to the session driver +maildriver_tools.[ch] -- default implementation for drivers, + when the driver does not parse the + messages. +maildriver_types.[ch] -- data types declaration and constructors +maildriver_types_helper.[ch] -- easy data creation +mailmessage.[ch] -- wrappers to calls to the message driver +mailstorage.[ch] -- storage creation, calls to the storage + driver and implementation of folders. +mailstorage_tools.[ch] -- tools for storage (connection) +mailthread.[ch] -- threading: collection of the mails + into a treee +mboxdriver.[ch] -- mbox driver for session +mboxdriver_cached.[ch] -- mbox driver for session, using flags + and cache +mboxdriver_cached_message.[ch] -- mbox driver for message, using flags + and cache +mboxdriver_message.[ch] -- mbox driver for message +mboxdriver_tools.[ch] -- mbox driver common functions +mboxstorage.[ch] -- mbox driver for storage +mhdriver.[ch] -- MH driver for session +mhdriver_cached.[ch] -- MH driver for session, using flags + and cache +mhdriver_cached_message.[ch] -- MH driver for message, using flags + and cache. +mhdriver_message.[ch] -- MH driver for message +mhdriver_tools.[ch] -- MH driver common functions +mhstorage.[ch] -- MH driver for storage +nntpdriver.[ch] -- NNTP driver for session +nntpdriver_cached.[ch] -- NNTP driver for session, using flags + and cache +nntpdriver_cached_message.[ch] -- NNTP driver for message, using flags + and cache +nntpdriver_message.[ch] -- NNTP driver for message +nntpdriver_tools.[ch] -- NNTP driver common functions +nntpstorage.[ch] -- NNTP driver for storage +pop3driver.[ch] -- POP3 driver for session +pop3driver_cached.[ch] -- POP3 driver for session, using flags + and cache +pop3driver_cached_message.[ch] -- POP3 driver for message, using flags + and cache +pop3driver_message.[ch] -- POP3 driver for message +pop3driver_tools.[ch] -- POP3 driver common functions +pop3storage.[ch] -- POP3 driver for storage + + +3.3.2/ Interfaces + +Include for this module is libetpan.h and includes all other headers. + + +The interface of higher layer is documented in the following files : + +maildriver.h +maildriver_types.h +maildriver_types_helper.h +mailmessage.h +mailstorage.h +mailstorage_types.[h] +mailthread.h + + +4/ Architecture +--------------- + +(see layer.fig) + + +5/ Example of use +----------------- + +You can find some example in tests/ + + +6/ Constraints +-------------- + +- libEtPan! must run on a system where mmap() is available. + +- for mbox particularly, libEtPan! make assumption on the fact that a + file can be entirely mapped into memory. But if you don't read + mailboxes of 1 Go, it should be fine. + + + diff --git a/kmicromail/libetpan/doc/README.sgml b/kmicromail/libetpan/doc/README.sgml new file mode 100644 index 0000000..1ddbf96 --- a/dev/null +++ b/kmicromail/libetpan/doc/README.sgml @@ -0,0 +1,319 @@ + + + + + 2003-12-03 + libEtPan! + + + Viet Hoa + DINH + + + + 2003 + DINH Viet Hoa + + + + + + Introduction + + + + Description + + The purpose of this mail library is to provide a portable, + efficient middleware for different kinds of mail access + (IMAPrev4, POP3, NNTP, mbox, MH, Maildir). + + + + You have two kinds of mailbox access, either using low-level + functions with a different interface for each kind of access + or using higher-level functions, using a driver to wrap the + higher-level API. The API will be the same for each kind of + mail access using the higher-level API. + + + + + + Author + + Main author + + DINH Viet Hoa hoa@users.sourceforge.net + + + + Contributors + + + + + Wim Delvaux + + + + + Melvin Hadasht + + + + + David Woodhouse + + + + + Juergen Graf + + + + + Zsolt VARGA + + + + + Gael Roualland + + + + + + + + + + + Installation + + + Dependencies + + + + Dependencies for users + + + + + OpenSSL + (optional but recommended) + + + + + Berkeley + DB (optional but recommended) + + + + + POSIX Thread (required) + + + + + + + Dependencies for developers + + + + + + autoconf + + 2.13 + + + + + + automake + + 1.4 + + + + + + libtool + + 1.4.3 + + + + + + + + Existing packages + + + + + Before you try to compile it, you have to know that packages + exist for FreeBSD. (ports/mail/libetpan). + This is currently 0.29 for -stable, 0.30 for -current. + + + + + + + + Compilation + + + Generic installation instructions are in the + INSTALL file + You can pass the following extra options to configure : + + + + + FreeBSD + + + + make sure libiconv is installed from the ports collection (see + pkg_info). + + + + + issue configure with the following parameter: + +$ ./configure --with-libiconv-prefix=/usr/local + + + + + + + + + Mac OS X + + + + You have to configure using the following command line : + CPPFLAGS=-I/sw/include LDFLAGS=-L/sw/lib + ./configure + + + + + in tests/option-parser.c, change the inclusion + of getopt.h to + gnugetopt/getopt.h + + + + + in tests/Makefile, add + -I/sw/include for the + CFLAGS and + -L/sw/lib -lgnugetopt for the LDFLAGS. + + + + + + + + Linux + + + + + Since libEtPan! is making high usage of + mmap() even for + writing, when your mailboxes are on + NFS filesystem with + a Linux server, it is advised to use option + no_subtree_check in + /etc/exports. + This should avoid corruption of data. + + + The problem exist in Linux 2.4.22 and earlier versions. + + + + + + On RedHat systems, you have to configure using the + following command line : + ./configure --with-openssl=/usr/kerberos + + + + + On Debian systems, if the ./autogen + script fails on missing AM_ICONV, you + have to install gettext package. + + + + + + + + configure + + You can use the following options : + + + + + --enable-debug Compiles with + debugging turned on + + + + + --enable-optim Turns on some + optimizations flags for gcc + + + + + --without-openssl Disables OpenSSL (do + not look for it) + + + + + + Compile and install + + Download the package and do the following : + + +$ tar xzvf libetpan-XX.XX.tar.gz # to decompress the package + +$ cd libetpan-XX.XX + +$ ./configure --help # to get options of configure + +$ ./configure # you can specify your own options + +$ make # to compile the package + +$ su + +# make install + +# logout + + + + + diff --git a/kmicromail/libetpan/doc/depend.dot b/kmicromail/libetpan/doc/depend.dot new file mode 100644 index 0000000..b12990f --- a/dev/null +++ b/kmicromail/libetpan/doc/depend.dot @@ -0,0 +1,54 @@ +digraph "etPan! library" { + mime -> imf; + + "session/message" -> imf; + "session/message" -> mime; + + "storage/folder" -> "session/message"; +} + +digraph "imap driver" { + "imap driver" -> imap; + "imap driver" -> imf; + "imap driver" -> mime; + "imap driver" -> "session/message"; + + mime -> imf; +} + +digraph "mbox driver" { + "mbox driver" -> mbox; + "mbox driver" -> imf; + "mbox driver" -> mime; + "mbox driver" -> "session/message"; + "mbox" -> imf; + + mime -> imf; +} + +digraph "mh driver" { + "mh driver" -> mh; + "mh driver" -> imf; + "mh driver" -> mime; + "mh driver" -> "session/message"; + + mime -> imf; +} + +digraph "pop3 driver" { + "pop3 driver" -> pop3; + "pop3 driver" -> imf; + "pop3 driver" -> mime; + "pop3 driver" -> "session/message"; + + mime -> imf; +} + +digraph "nntp driver" { + "nntp driver" -> nntp; + "nntp driver" -> imf; + "nntp driver" -> mime; + "nntp driver" -> "session/message"; + + mime -> imf; +} diff --git a/kmicromail/libetpan/doc/layer.fig b/kmicromail/libetpan/doc/layer.fig new file mode 100644 index 0000000..ed41783 --- a/dev/null +++ b/kmicromail/libetpan/doc/layer.fig @@ -0,0 +1,39 @@ +#FIG 3.2 +Landscape +Center +Metric +A4 +100.00 +Single +-2 +1200 2 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 900 3150 12150 3150 12150 3825 900 3825 900 3150 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 900 3825 12150 3825 12150 4500 900 4500 900 3825 +2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 3150 3150 3150 3825 +2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 5400 3150 5400 3825 +2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 7650 3150 7650 3825 +2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 9900 3150 9900 3825 +2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 7 + 12150 3150 900 3150 900 2475 12825 2475 12825 4500 12150 4500 + 12150 3150 +2 3 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 7 + 900 2475 900 1800 13500 1800 13500 4500 12825 4500 12825 2475 + 900 2475 +2 3 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 8 + 900 4500 225 4500 225 1125 13500 1125 13500 1800 900 1800 + 900 4500 900 4500 +4 0 0 50 0 16 20 0.0000 4 210 1410 1305 3600 IMAP4rev1\001 +4 0 0 50 0 16 20 0.0000 4 210 450 10800 3600 MH\001 +4 0 0 50 0 16 20 0.0000 4 210 720 8370 3555 mbox\001 +4 0 0 50 0 16 20 0.0000 4 210 795 6120 3600 NNTP\001 +4 0 0 50 0 16 20 0.0000 4 210 765 3870 3600 POP3\001 +4 0 0 50 0 16 20 0.0000 4 270 1620 5670 2880 session layer\001 +4 0 0 50 0 16 20 0.0000 4 270 2730 5085 2250 storage / folders layer\001 +4 0 0 50 0 16 20 0.0000 4 210 1500 5760 4275 IMF / MIME\001 +4 0 0 50 0 16 20 0.0000 4 270 1395 5670 1575 application\001 -- cgit v0.9.0.2