-rw-r--r-- | kmicromail/libetpan/doc/API.sgml | 15097 | ||||
-rw-r--r-- | kmicromail/libetpan/doc/DOCUMENTATION | 654 | ||||
-rw-r--r-- | kmicromail/libetpan/doc/README.sgml | 319 | ||||
-rw-r--r-- | kmicromail/libetpan/doc/depend.dot | 54 | ||||
-rw-r--r-- | kmicromail/libetpan/doc/layer.fig | 39 |
5 files changed, 16163 insertions, 0 deletions
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 @@ +<!doctype book PUBLIC "-//Davenport//DTD DocBook V3.0//EN"> + +<book id="libetpan-api"> + <bookinfo> + <date>2003-12-03</date> + <title>libEtPan! API</title> + <authorgroup> + <author> + <firstname>Viet Hoa</firstname> + <surname>DINH</surname> + </author> + </authorgroup> + <copyright> + <year>2003</year> + <holder>DINH Viet Hoa</holder> + </copyright> + </bookinfo> + <toc></toc> + + <!-- Introduction --> + <chapter> + <title>Introduction</title> + <para> + This document will describe the API of libEtPan! + </para> + </chapter> + + <!-- Tools --> + <chapter> + <title>Tools and datatypes</title> + + <para> + libEtPan! include a collection of datatypes such as lists, + arrays, hash tables and tools such as buffered I/O. + </para> + + <!-- Array --> + <sect1> + <title>Array</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +typedef struct carray_s carray; + </programlisting> + + <para> + <command>carray</command> is an array of pointers that will + resize automatically in case a new element is added. + </para> + + <para> + The <command>carray</command> is implemented with an array + <command>(void **)</command> 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. + </para> + + <sect2 id="carray-new"> + <title>carray_new and carray_free</title> + + <programlisting role="C"> +carray * carray_new(unsigned int initsize); + +void carray_free(carray * array); + </programlisting> + + <para> + <command>carray_new()</command> creates a new array with an + initial size. The array is not resized until the number of + element reach the initial size. It returns + <command>NULL</command> in case of failure. + </para> + + <para> + <command>carray_free()</command> releases memory used by the + given array. + </para> + + <example> + <title>carray creation</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <sect2 id="carray-set-size"> + <title>carray_set_size</title> + + <programlisting role="C"> +int carray_set_size(carray * array, uint32_t new_size); + </programlisting> + + <para> + <command>carray_set_size()</command> sets the size of the + array. It returns <command>0</command> in case of success, + <command>-1</command> in case of failure. + </para> + + <example> + <title>preallocating carray</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- carray_count, carray_add, carray_get and carray_set --> + <sect2 id="carray-count"> + <title>carray_count, carray_add, carray_get and carray_set</title> + + <programlisting role="C"> +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); + </programlisting> + + <para> + <command>carray_count()</command> returns the number of + elements in the <command>carray</command>. + Complexity is O(1). + </para> + + <para> + <command>carray_add()</command>adds an element at the end of + the array. The <command>index</command> of the element is + returns in <command>(* index)</command> if + <command>index</command> is not <command>NULL</command>. It + returns <command>0</command> in case of success, + <command>-1</command> in case of failure. + Complexity is O(1). + </para> + + <para> + <command>carray_get()</command> returns the elements contained + at the given cell of the table. + Complexity is O(1). + </para> + + <para> + <command>carray_set()</command> replace the element at the + given index of table table with the given value. + Complexity is O(1). + </para> + + <example> + <title>carray access</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + + </sect2> + + <!-- carray_delete --> + <sect2 id="carray-delete"> + <title>carray_delete</title> + + <programlisting role="C"> +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); + </programlisting> + + <para> + <command>carray_delete()</command> removes an element of the + table. Order will not be garanteed. The returned result can + be ignored. + Complexity is O(1). + </para> + + <para> + <command>carray_delete_slow()</command> removes an element of + the table. Order will be garanteed. The returned result can + be ignored. + Complexity is O(n). + </para> + + <para> + <command>carray_delete_fast()</command> the element will just + be replaced with <command>NULL</command>. Order will be kept + but the number of elements will remains the same. The + returned result can be ignored. + Complexity is O(1). + </para> + + <example> + <title>deletion in carray</title> + <programlisting role="C"> +#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 } + */ +} + </programlisting> + </example> + </sect2> + + <!-- carray_data --> + <sect2 id="carray-data"> + <title>carray_data</title> + + <programlisting role="C"> +void ** carray_data(carray); + </programlisting> + + <para> + <command>carray_data</command>returns the table used for + implementation : + <command>(void **)</command>. + </para> + + </sect2> + + + </sect1> + + <!-- List --> + <sect1 id="clist"> + <title>List</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +typedef struct clist_s clist; + +typedef clistcell clistiter; + </programlisting> + + <para> + <command>clist()</command> is a list of cells. + Each cell of the list contains one element. This element is a + pointer. An iterator (<command>clistiter</command>) 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. + </para> + + <sect2 id="clist-new"> + <title>clist_new and clist_free</title> + + <programlisting role="C"> +clist * clist_new(void); + +void clist_free(clist *); + </programlisting> + + <para> + <command>clist_new()</command> allocates a new empty list and + returns it. + </para> + + <para> + <command>clist_free()</command> frees the entire list with + its cells. + </para> + + <example> + <title>clist creation</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <sect2 id="clist-count"> + <title>clist_isempty and clist_count</title> + + <programlisting role="C"> +int clist_isempty(clist *); + +int clist_count(clist *); + </programlisting> + + <para> + <command>clist_isempty()</command> returns 1 if the list is + empty, else it is 0. + Complexity is O(1). + </para> + + <para> + <command>clist_count()</command> returns the number of + elements in the list. + Complexity is O(1). + </para> + </sect2> + + <sect2 id="clist-begin"> + <title>running through clist</title> + + <programlisting role="C"> +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); + </programlisting> + + <para> + <command>clist_begin()</command> returns an iterator to the + first element of the list. + Complexity is O(1). + </para> + + <para> + <command>clist_end()</command> returns an iterator to the last + element of the list. + Complexity is O(1). + </para> + + <para> + <command>clist_next()</command> returns an iterator to the + next element of the list. + Complexity is O(1). + </para> + + <para> + <command>clist_previous()</command> returns an iterator to the + previous element of the list. + Complexity is O(1). + </para> + + <para> + <command>clist_content()</command> returns the element + contained in the cell pointed by the iterator in the list. + Complexity is O(1). + </para> + + <para> + <command>clist_nth()</command> returns an iterator on the + <command>index</command>-th element of the list. + Complexity is O(n). + </para> + + <para> + <command>clist_nth_data()</command> returns the index-th + element of the list. + Complexity is O(n). + </para> + + <example> + <title>displaying content of clist</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + + <sect2 id="clist-append"> + <title>clist modification</title> + + <programlisting role="C"> +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 *); + </programlisting> + + <para> + <command>clist_prepend()</command> adds an element at the + beginning of the list. Returns 0 on sucess, -1 on error. + Complexity is O(1). + </para> + + <para> + <command>clist_append()</command> adds an element at the end + of the list. Returns 0 on sucess, -1 on error. + Complexity is O(1). + </para> + + <para> + <command>clist_insert_before()</command> 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). + </para> + + <para> + <command>clist_insert_after()</command> 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). + </para> + + <para> + <command>clist_delete()</command> 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). + </para> + + <example> + <title>deleting elements in a clist</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <sect2 id="clist-foreach"> + <title>clist_foreach</title> + + <programlisting role="C"> +typedef void (* clist_func)(void *, void *); + +void clist_foreach(clist * lst, clist_func func, void * data); + </programlisting> + + <para> + <command>clist_foreach()</command> apply a fonction to each + element of the list. + Complexity is O(n). + </para> + </sect2> + + <sect2 id="clist-concat"> + <title>clist_concat</title> + + <programlisting role="C"> +void clist_concat(clist * dest, clist * src); + </programlisting> + + <para> + <command>clist_concat()</command> 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). + </para> + + <example> + <title>merging two clists</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + + </sect2> + </sect1> + + <!-- Hash --> + <sect1> + <title>Hash table</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +typedef struct chash chash; + +typedef struct chashcell chashiter; + +typedef struct { + char * data; + int len; +} chashdatum; + </programlisting> + + <para> + <command>chash</command> is a hash table. + <command>chashiter</command> is a pointer to an element of the + hash table. + <command>chashdatum</command> is an element to be placed in + the hash table as a key or a value. It consists in + data and a corresponding length. + </para> + + <sect2 id="chash-new"> + <title>chash_new and chash_free</title> + <programlisting role="C"> +#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); + </programlisting> + + <para> + <command>chash_new()</command> returns a new empty hash table + or <command>NULL</command> if this + failed. <command>size</command> is the initial size of the + table used for implementation. <command>flags</command> can + be a combinaison of <command>CHASH_COPYKEY</command> and + <command>CHASH_COPYVALUE</command>. + <command>CHASH_COPYKEY</command> enables copy of key, so + that the initial value used for <command>chash_set()</command> + </para> + + <para> + <command>chash_free()</command> releases memory used by the + hash table. + </para> + </sect2> + + <sect2 id="chash-get"> + <title>chash_set and chash_get</title> + <programlisting role="C"> +int chash_set(chash * hash, + chashdatum * key, chashdatum * value, chashdatum * oldvalue); + +int chash_get(chash * hash, + chashdatum * key, chashdatum * result); + </programlisting> + + <para> + <command>chash_set()</command> adds a new element into the + hash table. If a previous element had the same key, it is + returns into oldvalue if <command>oldvalue</command> is + different of NULL. + Medium complexity is O(1). + </para> + + <para> + returns -1 if it fails, 0 on success. + </para> + + <para> + <command>chash_get()</command>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). + </para> + + <example> + <title>chash insert and lookup</title> + <programlisting role="C"> +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); +} + </programlisting> + </example> + </sect2> + + <sect2 id="chash-delete"> + <title>chash_delete</title> + <programlisting role="C"> +int chash_delete(chash * hash, + chashdatum * key, chashdatum * oldvalue); + </programlisting> + + <para> + 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). + </para> + + <example> + <title>key deletion in a chash</title> + <programlisting role="C"> +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); +} + </programlisting> + </example> + </sect2> + + <sect2 id="chash-resize"> + <title>chash_resize</title> + <programlisting role="C"> +int chash_resize(chash * hash, int size); + </programlisting> + + <para> + <command>chash_resize()</command> changes the size of the + table used for implementation of the hash table. + returns 0 on success, -1 on failure. + </para> + </sect2> + + <sect2 id="chash-begin"> + <title>running through the chash</title> + <programlisting role="C"> +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); + </programlisting> + + <para> + <command>chash_begin()</command> returns a pointer to the + first element of the hash table. Returns + <command>NULL</command> if there is no elements in the hash + table. + Complexity is O(n). + </para> + + <para> + <command>chash_next()</command> returns a pointer to the next + element of the hash table. Returns <command>NULL</command> + if there is no next element. + Complexity is O(n) but n calls to chash_next() also has + a complexity of O(n). + </para> + + <para> + <command>chash_key()</command> returns the key of the given + element of the hash table. + </para> + + <para> + <command>chash_value</command> returns the value of the + given element of the hash table. + </para> + + <example> + <title>running through a chash</title> + <programlisting role="C"> +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); +} + </programlisting> + </example> + </sect2> + + <sect2 id="chash-count"> + <title>chash_size and chash_count</title> + <programlisting role="C"> +int chash_size(chash * hash); + +int chash_count(chash * hash); + </programlisting> + + <para> + <command>chash_size()</command> returns the size of the table + used for implementation of the hash table. + Complexity is O(1). + </para> + + <para> + <command>chash_count()</command> returns the number of + elements in the hash table. + Complexity is O(1). + </para> + </sect2> + </sect1> + + <!-- mailstream --> + <sect1> + <title>Buffered I/O</title> + +<programlisting role="C"> +#include <libetpan/libetpan.h> + +typedef struct _mailstream mailstream; + </programlisting> + + <para> + 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. + </para> + + <programlisting role="C"> +mailstream * mailstream_new(mailstream_low * low, size_t buffer_size); + +int mailstream_close(mailstream * s); + </programlisting> + + <para> + <command>mailstream_new()</command> creates a new stream + stream with the low-level (see <xref linkend="mailstream-low">) + stream and a given buffer size. + </para> + + <para> + <command>mailstream_close()</command> closes the stream. + This function will be in charge to free the + <command>mailstream_low</command> structure. + </para> + + + <programlisting role="C"> +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); + </programlisting> + + <para> + <command>mailstream_write()</command> writes a buffer to the + given stream. This write operation will be buffered. + </para> + + <para> + <command>mailstream_flush()</command> will force a write of + all buffered data for a given stream. + </para> + + <para> + <command>mailstream_read()</command> reads data from the + stream to the given buffer. + </para> + + <para> + <command>mailstream_feed_read_buffer()</command> this function + will just fill the buffer for reading. + </para> + + <programlisting role="C"> +mailstream_low * mailstream_get_low(mailstream * s); + +void mailstream_set_low(mailstream * s, mailstream_low * low); + </programlisting> + + <para> + <command>mailstream_get_low()</command> returns the low-level + stream of the given stream. + </para> + + <para> + <command>mailstream_set_low()</command> changes the low-level + of the given stream. Useful, for + example, when a stream change from clear stream to SSL + stream. + </para> + + <programlisting role="C"> +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); + </programlisting> + + <para> + <command>mailstream_read_line()</command> reads an entire line + from the buffer and store it into the + given string. returns <command>NULL</command> on error, the + corresponding array + of <command>char</command> is returned otherwise. + </para> + + <para> + <command>mailstream_read_line_append()</command> reads an entire + line from the buffer and appends it to the + given string. returns <command>NULL</command> on error, the + array of char corresponding to the entire buffer is returned + otherwise. + </para> + + <para> + <command>mailstream_read_line_remove_eol()</command> reads an + entire line from the buffer and store it into the + given string. All CR LF are removed. + returns <command>NULL</command> on error, the corresponding + array of <command>char</command> is returned otherwise. + </para> + + <para> + <command>mailstream_read_multiline()</command> 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 <command>NULL</command> (deprecated things). + <command>stream_buffer</command> is a buffer used for internal + work of the function. + size should be 0 (deprecated things). + </para> + + <programlisting role="C"> +int mailstream_is_end_multiline(char * line); + </programlisting> + + <para> + returns 1 if the line is an end of multiline data (a single + period '.', eventually with CR and/or LF). 0 is returned + otherwise. + </para> + + <programlisting role="C"> +int mailstream_send_data(mailstream * s, char * message, + size_t size, + size_t progr_rate, + progress_function * progr_fun); + </programlisting> + + <para> + sends multiline data to the given stream. + <command>size</command> is the size of the data. + <command>progr_rate</command> and <command>progr_fun</command> + are deprecated. <command>progr_rate</command> must be 0, + <command>progr_fun</command> must be NULL. + </para> + + <sect2 id="mailstream-socket"> + <title>socket stream</title> + + <programlisting role="C"> +mailstream * mailstream_socket_open(int fd); + </programlisting> + + <para> + <command>mailstream_socket_open()</command> will open a + clear-text socket. + </para> + </sect2> + + <sect2 id="mailstream-ssl"> + <title>TLS stream</title> + + <programlisting role="C"> +mailstream * mailstream_ssl_open(int fd); + </programlisting> + + <para> + <command>mailstream_ssl_open()</command> will open a + TLS/SSL socket. + </para> + </sect2> + </sect1> + + <!-- mailstream_low --> + <sect1 id="mailstream-low"> + <title>non-buffered I/O</title> + + <programlisting role="C"> +#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; +}; + </programlisting> + + <para> + <command>mailstream_low</command> is a non-buffered stream. + </para> + + <para> + The <command>mailstream_low_driver</command> is a set of + functions used to access the stream. + </para> + + <itemizedlist> + <listitem> + <para> + <command>mailstream_read/write/close()</command> is the same + interface as <command>read/write/close()</command> + system calls, except that the file descriptor is replaced with the + <command>mailstream_low</command> structure. + </para> + </listitem> + <listitem> + <para> + <command>mailstream_get_fd()</command> returns the file + descriptor used for this non-buffered stream. + </para> + </listitem> + <listitem> + <para> + <command>mailstream_free()</command> is in charge to free + the internal structure of the mailstream_low and the + mailstream_low itself. + </para> + </listitem> + </itemizedlist> + + <programlisting role="C"> +mailstream_low * mailstream_low_new(void * data, + mailstream_low_driver * driver); + </programlisting> + + <para> + mailstream_low_new() creates a low-level mailstream with the + given internal structure (data) and using the given set of + functions (driver). + </para> + + <programlisting role="C"> +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); + </programlisting> + + <para> + Each of these calls will call the corresponding function defined + in the driver. + </para> + + </sect1> + + + <!-- MMAPString --> + <sect1> + <title>strings</title> + + <programlisting role="C"> +#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; + </programlisting> + + <para> + MMAPString is a string which size that can increase automatically. + </para> + + <sect2 id="mmap-string-new"> + <title>constructor and destructor</title> + <programlisting role="C"> +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); + </programlisting> + + <para> + <command>mmap_string_new()</command> allocates a new + string. init is the intial value of the string. + <command>NULL</command> will be returned on error. + </para> + + <para> + <command>mmap_string_new_len()</command> allocates a new + string. init is the intial value of the + string, len is the length of the initial string. + <command>NULL</command> will be returned on error. + </para> + + <para> + <command>mmap_string_sized_new()</command> allocates a new + string. dfl_size is the initial allocation of + the string. <command>NULL</command> will be returned on error. + </para> + + <para> + <command>mmap_string_free()</command> release the memory used + by the string. + </para> + </sect2> + + <sect2 id="mmap-string-assign"> + <title>string value modification</title> + <programlisting role="C"> +MMAPString * mmap_string_assign(MMAPString * string, const char * rval); + +MMAPString * mmap_string_truncate(MMAPString *string, size_t len); + </programlisting> + + <para> + <command>mmap_string_assign()</command> sets a new value for + the given string. + <command>NULL</command> will be returned on error. + </para> + + <para> + <command>mmap_string_truncate()</command> sets a length for + the string. + <command>NULL</command> will be returned on error. + </para> + + <programlisting role="C"> +MMAPString * mmap_string_set_size (MMAPString * string, size_t len); + </programlisting> + + <para> + sets the allocation of the string. + <command>NULL</command> will be returned on error. + </para> + </sect2> + + <sect2 id="mmap-string-append"> + <title>insertion in string, deletion in string</title> + <programlisting role="C"> +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); + </programlisting> + + <para> + For complexity here, n is the size of the given MMAPString, + and len is the size of the string to insert. + </para> + + <para> + <command>mmap_string_insert_len()</command> inserts the given + string value of given length in the string at the given + position. <command>NULL</command> will be returned on error. + Complexity is O(n + len). + </para> + + <para> + <command>mmap_string_append()</command> appends the given + string value at the end of the string. + <command>NULL</command> will be returned on error. + Complexity is O(len). + </para> + + <para> + <command>mmap_string_append_len()</command> appends the + given string value of given length at the end of the + string. <command>NULL</command> will be returned on error. + Complexity is O(len). + </para> + + <para> + <command>mmap_string_append_c()</command> appends the given + character at the end of the string. + <command>NULL</command> will be returned on error. + Complexity is O(1). + </para> + + <para> + <command>mmap_string_prepend()</command> insert the given + string value at the beginning of the string. + <command>NULL</command> will be returned on error. + Complexity is O(n + len). + </para> + + <para> + <command>mmap_string_prepend_c()</command> insert the given + character at the beginning of the string. + <command>NULL</command> will be returned on error. + Complexity is O(n). + </para> + + <para> + <command>mmap_string_prepend_len()</command> insert the given + string value of given length at the beginning of the string. + <command>NULL</command> will be returned on error. + Complexity is O(n + len). + </para> + + <para> + <command>mmap_string_insert()</command> inserts the given + string value in the string at the given position. + NULL will be returned on error. + Complexity is O(n + len). + </para> + + <para> + <command>mmap_string_insert_c()</command> inserts the given + character in the string at the given position. + NULL will be returned on error. + Complexity is O(n). + </para> + + <para> + <command>mmap_string_erase()</command> removes the given + count of characters (len) at the given position of the + string. <command>NULL</command> will be returned on error. + Complexity is O(n). + </para> + + </sect2> + + <sect2 id="mmap-string-ref"> + <title>referencing string</title> + <programlisting role="C"> +int mmap_string_ref(MMAPString * string); + +int mmap_string_unref(char * str); + </programlisting> + + <para> + MMAPString provides a mechanism that let you use MMAPString + like normal strings. You have first to use + <command>mmap_string_ref()</command>, so that you notify + that the string will be used as a normal string, then, you + use <command>mmapstr->str</command> to refer to the + string. When you have finished and you want to free a string + corresponding to a <command>MMAPString</command>, you will + use <command>mmap_string_unref</command>. + </para> + + <para> + <command>mmap_string_ref()</command> references the string + so that the array of characters can be used as a normal + string then released with + <command>mmap_string_unref()</command>. + The array of characters will be obtained with string->str. + returns -1 on error, 0 on success. + </para> + </sect2> + </sect1> + </chapter> + + <!-- IMF --> + <chapter id="imf"> + <title>Internet Message Format</title> + + <para> + libEtPan! implements Internet Message parser. Currently, format + is RFC 2822. + This module also allows to generate messages. + </para> + + <warning> + <para> + 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 + </para> + + <para> + allocation functions will return <command>NULL</command> on failure + + functions returning integer will be returning one of the + following error code: + <command>MAILIMF_NO_ERROR</command>, + <command>MAILIMF_ERROR_PARSE</command>, + <command>MAILIMF_ERROR_MEMORY</command>, + <command>MAILIMF_ERROR_INVAL</command>, + or <command>MAILIMF_ERROR_FILE</command>. + </para> + </warning> + + <sect1> + <title>Quick start</title> + + <para> + You will need this module when you want to parse headers + of messages or when you want to build message headers + conformant to standards. + </para> + + <sect2> + <title>Parse message headers</title> + <para> + You will use one of the four following functions, depending + on your needs : + </para> + <itemizedlist> + <listitem> + <para> + <command>mailimf_envelope_and_optional_fields_parse</command> + (<xref linkend="mailimf-envelope-and-optional-fields-parse">), + </para> + </listitem> + <listitem> + <para> + <command>mailimf_envelope_fields_parse</command> + (<xref linkend="mailimf-envelope-fields-parse">), + </para> + </listitem> + <listitem> + <para> + <command>mailimf_optional_fields_parse</command> + (<xref linkend="mailimf-optional-fields-parse">), + </para> + </listitem> + <listitem> + <para> + <command>mailimf_fields_parse</command> + (<xref linkend="mailimf-fields-parse">). + </para> + </listitem> + </itemizedlist> + </sect2> + + <sect2> + <title>Render the message headers</title> + <para> + Build your message headers, then use + <command>mailimf_fields_write</command> + (<xref linkend="mailimf-fields-write">) + to render the headers. + </para> + </sect2> + </sect1> + + <sect1> + <title>Data types</title> + <!-- mailimf_mailbox --> + <sect2 id="mailimf-mailbox"> + <title>mailimf_mailbox - mailbox</title> + <para> +#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); + </para> + + <para> + This is an email mailbox with a display name. + </para> + + <example> + <title>example of mailbox</title> + <programlisting> +DINH Viet Hoa <hoa@users.sourceforge.net> + </programlisting> + </example> + + <para> + <command>mailimf_mailbox_new</command> 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. + </para> + + <para> + <command>mailimf_mailbox_free</command> frees memory used by + the structure and substructures will also be released. + </para> + + <example> + <title>mailbox creation and display</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_address --> + <sect2 id="mailimf-address"> + <title>mailimf_address - address</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is a mailbox or a group of mailbox. + </para> + + <itemizedlist> + <listitem> + <para> + <command>ad_type</command> can be MAILIMF_ADDRESS_MAILBOX or + <command>MAILIMF_ADDRESS_GROUP</command>. + </para> + </listitem> + <listitem> + <para> + <command>ad_data.ad_mailbox</command> is a mailbox if + <command>ad_type</command> is + <command>MAILIMF_ADDRESS_MAILBOX</command> + see <xref linkend="mailimf-mailbox">) + </para> + </listitem> + <listitem> + <para> + <command>ad_data.group</command> is a group if type is + <command>MAILIMF_ADDRESS_GROUP</command>. + see <xref linkend="mailimf-group">) + </para> + </listitem> + </itemizedlist> + + <para> + <command>mailimf_address_new()</command> 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. + </para> + + <para> + <command>mailimf_address_free</command> frees memory used by + the structure and substructures will also be released. + </para> + + <example> + <title>address creation and display</title> + <programlisting role="C"> +/* 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; + } +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_mailbox_list --> + <sect2 id="mailimf-mailbox-list"> + <title>mailimf_mailbox_list - list of mailboxes</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is a list of mailboxes. + </para> + + <para> + <command>mb_list</command> is a list of mailboxes. This is a + <command>clist</command> which elements are of type + mailimf_mailbox (see <xref linkend="mailimf-mailbox">). + </para> + + <para> + <command>mailimf_mailbox_list_new()</command> 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. + </para> + + <para> + <command>mailimf_mailbox_list_free()</command> frees memory used by the + structure and substructures will also be released. + </para> + + <example> + <title>Creation and display of mailimf_mailbox_list</title> + <programlisting role="C"> +/* 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"); + } +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_address_list --> + <sect2 id="mailimf-address-list"> + <title>mailimf_address_list - list of addresses</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is a list of addresses. + </para> + + <para> + <command>ad_list</command> is a list of addresses. This is a + <command>clist</command> which elements are + of type mailimf_address (see <xref linkend="mailimf-address">). + </para> + + <para> + <command>mailimf_address_list_new()</command> 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. + </para> + + <para> + <command>mailimf_address_list_free()</command> frees memory + used by the structure and substructures will also be released. + </para> + + <example> + <title>creation and display of list of addresses</title> + <programlisting role="C"> +/* 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"); + } +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_group --> + <sect2 id="mailimf-group"> + <title>mailimf_group - named group of mailboxes</title> + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is a list of mailboxes tagged with a name. + </para> + + <example> + <title>example of group</title> + <programlisting> + they play music: <steve@morse.foo>, <neal@morse.foo>, + <yngwie@malmsteen.bar>, <michael@romeo.bar>; + </programlisting> + </example> + + <para> + <command>grp_display_name</command> is the name that will be + displayed for this group, + for example '<command>group_name</command>' in + '<command>group_name: address1@domain1, + address2@domain2;</command>'. + This must be allocated with malloc(). + <command>grp_mb_list</command> is a list of mailboxes + (see <xref linkend="mailimf-mailbox-list">). + </para> + + <para> + <command>mailimf_group_new()</command> 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. + </para> + + <para> + <command>mailimf_group_free()</command> frees memory used by + the structure and substructures will also be released. + </para> + + <example> + <title>creation and display of a group</title> + <programlisting role="C"> +/* 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"); + } +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_date_time --> + <sect2 id="mailimf-date-time"> + <title>mailimf_date_time - date of a message</title> + + <para> +#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); + </para> + + <para> + This is the date and time of a message. + For example : + </para> + <example> + <title>example of date</title> + <programlisting> +Thu, 11 Dec 2003 00:15:02 +0100. + </programlisting> + </example> + + <itemizedlist> + <listitem> + <para> + <command>dt_day</command> is the day of month (1 to 31) + </para> + </listitem> + <listitem> + <para> + <command>dt_month</command> (1 to 12) + </para> + </listitem> + <listitem> + <para> + <command>dt_year</command> (4 digits) + </para> + </listitem> + <listitem> + <para> + <command>dt_hour</command> (0 to 23) + </para> + </listitem> + <listitem> + <para> + <command>dt_min</command> (0 to 59) + </para> + </listitem> + <listitem> + <para> + <command>dt_sec</command> (0 to 59) + </para> + </listitem> + <listitem> + <para> + <command>dt_zone</command> (this is the decimal value that + we can read, for example: for + '<command>-0200</command>', the value is + <command>-200</command>). + </para> + </listitem> + </itemizedlist> + + <para> + <command>mailimf_date_time_new()</command> creates and + initializes a date structure with a value. + </para> + + <para> + <command>mailimf_date_time_free()</command> frees memory used + by the structure. + </para> + + <example> + <title>creation and display of date</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_orig_date --> + <sect2 id="mailimf-orig-date"> + <title>mailimf_orig_date - parsed content of date header</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is the content of a header <command>Date</command> or + <command>Resent-Date</command>. + It encapsulates a mailimf_date_time + </para> + + <para> + <command>dt_date_time</command> is the parsed date + (see <xref linkend="mailimf-date-time">). + </para> + + <para> + <command>mailimf_orig_date_new()</command> 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. + </para> + + <para> + <command>mailimf_orig_date_free()</command> frees memory used + by the structure and substructures will also be released. + </para> + + <example> + <title>creation and display of Date field</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_from --> + <sect2 id="mailimf-from"> + <title>mailimf_from - parsed content of From header</title> + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is the content of a header <command>From</command> or + <command>Resent-From</command>. + </para> + <para> + <command>frm_mb_list</command> is the parsed mailbox list + (see <xref linkend="mailimf-mailbox-list">). + </para> + + <para> + <command>mailimf_from_new()</command> 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. + </para> + + <para> + <command>mailimf_from_free()</command> frees memory used by + the structure and substructures will also be released. + </para> + + <example> + <title>creation and display of a From header</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_sender --> + <sect2 id="mailimf-sender"> + <title>mailimf_sender - parsed content of Sender header</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is the content of a header <command>Sender</command> or + <command>Resent-Sender</command>. + </para> + + <para> + <command>snd_mb</command> is the parsed mailbox + (see <xref linkend="mailimf-mailbox">). + </para> + + <para> + <command>mailimf_sender_new()</command> 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. + </para> + + <para> + <command>mailimf_sender_free()</command> This function frees + memory used by the structure and substructures + will also be released. + </para> + + <example> + <title>creation and display of Sender field</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_reply_to --> + <sect2 id="mailimf-reply-to"> + <title>mailimf_reply_to - parsed content of Reply-To header</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is the content of a header <command>Reply-To</command>. + </para> + + <para> + <command>addr_list</command> is the parsed address list + (see <xref linkend="mailimf-address-list">). + </para> + + <para> + <command>mailimf_reply_to_new()</command> 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. + </para> + + <para> + <command>mailimf_reply_to_free()</command> frees memory used + by the structure and substructures will also be released. + </para> + + <example> + <title>creation and display of Reply-To field</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_to --> + <sect2 id="mailimf-to"> + <title>mailimf_to - parsed content of To header</title> + + <programlisting role="C"> + 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); + </programlisting> + + <para> + This is the content of a header <command>To</command> or + <command>Resent-To</command>. + </para> + + <para> + <command>to_addr_list</command> is the parsed address list + (see <xref linkend="mailimf-address-list">). + </para> + + <para> + <command>mailimf_to_new()</command> 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. + </para> + + <para> + <command>mailimf_to_free()</command> frees memory used by the + structure and substructures will also be released. + </para> + + <example> + <title>creation and display of To field</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_cc --> + <sect2 id="mailimf-cc"> + <title>mailimf_cc - parsed content of Cc</title> + +<programlisting> +#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); +</programlisting> + + <para> + This is the content of a header <command>Cc</command> or + <command>Resent-Cc</command>. + </para> + + <para> + <command>cc_addr_list</command> is the parsed address list + (see <xref linkend="mailimf-address-list">). + </para> + + <para> + <command>mailimf_cc_new()</command> 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. + </para> + + <para> + <command>mailimf_cc_free()</command> This function frees + memory used by the structure and substructures will also be + released. + </para> + + <example> + <title>creation and display of Cc field</title> + <programlisting role="C"> +#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); +} + + </programlisting> + </example> + + </sect2> + + <!-- mailimf_bcc --> + <sect2 id="mailimf-bcc"> + <title>mailimf_bcc - parsed content of Bcc field</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is the content of a header <command>Bcc</command> or + <command>Resent-Bcc</command>. + </para> + + <para> + <command>bcc_addr_list</command> is the parsed address list + (see <xref linkend="mailimf-address-list">). + </para> + + <para> + <command>mailimf_bcc_new()</command> 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. + </para> + + <para> + <command>mailimf_bcc_free()</command> frees memory used by the + structure and substructures will also be released. + </para> + + <example> + <title>creation and display of Bcc field</title> + <programlisting role="C"> +/* 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); + } +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_message_id --> + <sect2 id="mailimf-message-id"> + <title>mailimf_message_id - parsed content of Message-ID header</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is the content of a header <command>Message-ID</command> + or <command>Resent-Message-ID</command>. For example : + </para> + + <example> + <title>example of Message-ID</title> + <programlisting> +Message-ID: <200312100009.43592@c01n-c01n.plop.P4N>> + </programlisting> + </example> + + <para> + <command>mid_value</command> is the message identifier. + It is not enclosed by angle bracket. + </para> + + <para> + <command>mailimf_message_id_new()</command> 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. + </para> + + <para> + The given string is allocated with + <command>malloc()</command> and is not enclosed by angle bracket. + </para> + + <para> + <command>mailimf_message_id_free()</command> frees memory + used by the structure and substructures will also be + released. + </para> + + <example> + <title>creation and display of Message-ID field</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_in_reply_to --> + <sect2 id="mailimf-in-reply-to"> + <title>mailimf_in_reply_to - parsed content of In-Reply-To + field</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + content of a header <command>In-Reply-To</command>. + For example : + </para> + + <programlisting> +In-Reply-To: <etPan.3fd5fa29.4c3901c1.6b39@homer> + </programlisting> + + <para> + <command>mid_list</command> is a <command>clist</command> + in which elements are message identifiers. + their types are <command>(char *)</command> and they are + allocated with <command>malloc()</command>. + </para> + + <para> + <command>mailimf_in_reply_to_new()</command> 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. + </para> + + <para> + <command>mailimf_in_reply_to_free()</command> frees memory + used by the structure and substructures will also be + released. + </para> + + <example> + <title>creation and display of In-Reply-To field</title> + <programlisting> +#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); + } +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_references --> + <sect2 id="mailimf-references"> + <title>mailimf_references - parsed content of References field</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is the content of a header <command>References</command>. + For example : + </para> + <programlisting> +In-Reply-To: <etPan.3fd5fa29.4c3901c1.6b39@homer> + <3FD5FA78.A1D98E7@oleane.net> + <etPan.3fd5fc69.2b349482.730e@homer> + </programlisting> + + <para> + <command>mid_list</command> is a <command>clist</command> + in which elements are message identifiers. + their types are <command>(char *)</command> and they are + allocated with <command>malloc()</command>. + </para> + + <para> + <command>mailimf_references_new()</command> 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. + </para> + + <para> + <command>mailimf_references_free()</command> frees memory + used by the structure and substructures will also be + released. + </para> + + <example> + <title>creation and display of References field</title> + <programlisting role="C"> +#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); + } +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_subject --> + <sect2 id="mailimf-subject"> + <title>mailimf_subject - parsed content of Subject field</title> + +<programlisting role="C"> +#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); +</programlisting> + + <para> + This is the content of a header <command>Subject</command>. + </para> + + <para> + <command>sbj_value</command> is the value of the field. + </para> + + <para> + <command>mailimf_subject_new()</command> 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. + </para> + + <para> + <command>mailimf_subject_free</command> frees memory used by + the structure and substructures will also be released. + </para> + + <example> + <title>creation and display of Subject field</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_comments --> + <sect2 id="mailimf-comments"> + <title>mailimf_comments - parsed content of Comments field</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is the content of a header <command>Comments</command>. + </para> + + <para> + <command>cm_value</command> is the value of the field. + </para> + + <para> + <command>mailimf_comments_new()</command> 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. + </para> + + <para> + <command>mailimf_comments_free()</command> frees memory used + by the structure and substructures will also be released. + </para> + + <example> + <title>creation and display of Comment field</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_keywords --> + <sect2 id="mailimf-keywords"> + <title>mailimf_keywords - parsed content of Keywords field</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is the content of a header <command>Keywords</command>. + </para> + + <para> + <command>kw_list</command> is the list of keywords. This is + a list of <command>(char *)</command> allocated with malloc(). + </para> + + <para> + <command>mailimf_keywords_new()</command> 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. + </para> + + <para> + <command>mailimf_keywords_free()</command> frees memory used + by the structure and substructures will also be released. + </para> + + <example> + <title>creation and display of Keywords field</title> + <programlisting role="C"> +#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); + } +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_return --> + <sect2 id="mailimf-return"> + <title>mailimf_return - parsed content of Return-Path field</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is the content of a header + <command>Return-Path</command>. + </para> + + <para> + <command>ret_path</command> is the parsed value of Return-Path + (see <xref linkend="mailimf-path">). + </para> + + <para> + <command>mailimf_return_new()</command> 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. + </para> + + <para> + <command>mailimf_return_free()</command> frees memory used + by the structure and substructures will also be released. + </para> + + <example> + <title>creation and display of Return-Path field</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_path --> + <sect2 id="mailimf-path"> + <title>mailimf_path - address in Return-Path field</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is the encapsulation of address specifier for + <command>Return-Path</command> content. + </para> + + <para> + <command>pt_addr_spec</command> is a mailbox destination. + </para> + + <para> + <command>mailimf_path_new()</command> 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. + </para> + + <para> + The given string is allocated with + <command>malloc()</command>. This is a address + specifier. + </para> + + <para> + <command>mailimf_path_free()</command> frees memory used by + the structure and substructures will also be released. + </para> + + <example> + <title>Creation and display of return path</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_optional_field --> + <sect2 id="mailimf-optional-field"> + <title>mailimf_optional_field - non-standard header</title> + + <programlisting> +#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); + </programlisting> + + <para> + This is a non-standard header or unparsed header. + </para> + + <itemizedlist> + <listitem> + <para> + <command>fld_name</command> is the name of the header + field. + </para> + </listitem> + <listitem> + <para> + <command>fld_value</command> is the value of the header + field. + </para> + </listitem> + </itemizedlist> + + <para> + <command>mailimf_optional_field_new()</command> 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. + </para> + + <para> + field name and field value have to be allocated with + <command>malloc()</command>. + </para> + + <para> + <command>mailimf_optional_field_free()</command> This + function frees memory used by the structure and + substructures will also be released. + </para> + + <example> + <title>creation and display of non-standard fields</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_field --> + <sect2 id="mailimf-field"> + <title>mailimf_field - header field</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is one header field of a message. + </para> + + <itemizedlist> + <listitem> + <para> + <command>type</command> 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 : + <command>MAILIMF_FIELD_RETURN_PATH</command>, + <command>MAILIMF_FIELD_RESENT_DATE</command>, + <command>MAILIMF_FIELD_RESENT_FROM</command>, + <command>MAILIMF_FIELD_RESENT_SENDER</command>, + <command>MAILIMF_FIELD_RESENT_TO</command>, + <command>MAILIMF_FIELD_RESENT_CC</command>, + <command>MAILIMF_FIELD_RESENT_BCC</command>, + <command>MAILIMF_FIELD_RESENT_MSG_ID</command>, + <command>MAILIMF_FIELD_ORIG_DATE</command>, + <command>MAILIMF_FIELD_FROM</command>, + <command>MAILIMF_FIELD_SENDER</command>, + <command>MAILIMF_FIELD_REPLY_TO</command>, + <command>MAILIMF_FIELD_TO</command>, + <command>MAILIMF_FIELD_CC</command>, + <command>MAILIMF_FIELD_BCC</command>, + <command>MAILIMF_FIELD_MESSAGE_ID</command>, + <command>MAILIMF_FIELD_IN_REPLY_TO</command>, + <command>MAILIMF_FIELD_REFERENCES</command>, + <command>MAILIMF_FIELD_SUBJECT</command>, + <command>MAILIMF_FIELD_COMMENTS</command>, + <command>MAILIMF_FIELD_KEYWORDS</command>, + <command>MAILIMF_FIELD_OPTIONAL_FIELD</command>. + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_return_path</command> is the + parsed content of the Return-Path field + if type is <command>MAILIMF_FIELD_RETURN_PATH</command> + (see <xref linkend="mailimf-return">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_resent_date</command> is the + parsed content of the Resent-Date field + if type is <command>MAILIMF_FIELD_RESENT_DATE</command> + (see <xref linkend="mailimf-orig-date">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_resent_from</command> is the + parsed content of the Resent-From field + if type is <command>MAILIMF_FIELD_RESENT_FROM</command> + (see <xref linkend="mailimf-from">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_resent_sender</command> is the + parsed content of the Resent-Sender field + if type is <command>MAILIMF_FIELD_RESENT_SENDER</command> + (see <xref linkend="mailimf-sender">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_resent_to</command> is the parsed + content of the Resent-To field + if type is <command>MAILIMF_FIELD_RESENT_TO</command> + (see <xref linkend="mailimf-to">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_resent_cc</command> is the parsed + content of the Resent-Cc field + if type is <command>MAILIMF_FIELD_CC</command> + (see <xref linkend="mailimf-cc">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_resent_bcc</command> is the parsed + content of the Resent-Bcc field + if type is <command>MAILIMF_FIELD_BCC</command> + (see <xref linkend="mailimf-bcc">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_resent_msg_id</command> is the + parsed content of the Resent-Message-ID field + if type is <command>MAILIMF_FIELD_RESENT_MSG_ID</command> + (see <xref linkend="mailimf-message-id">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_orig_date</command> is the parsed + content of the Date field + if type is <command>MAILIMF_FIELD_ORIG_DATE</command> + (see <xref linkend="mailimf-orig-date">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_from</command> is the parsed + content of the From field + if type is <command>MAILIMF_FIELD_FROM</command> + (see <xref linkend="mailimf-from">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_sender</command> is the parsed + content of the Sender field + if type is <command>MAILIMF_FIELD_SENDER</command> + (see <xref linkend="mailimf-sender">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_reply_to</command> is the parsed + content of the Reply-To field + if type is <command>MAILIMF_FIELD_REPLY_TO</command> + (see <xref linkend="mailimf-reply-to">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_to</command> is the parsed content + of the To field if type is + <command>MAILIMF_FIELD_TO</command> + (see <xref linkend="mailimf-to">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_cc</command> is the parsed content + of the Cc field if type is + <command>MAILIMF_FIELD_CC</command> + (see <xref linkend="mailimf-cc">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_bcc</command> is the parsed + content of the Bcc field if type is + <command>MAILIMF_FIELD_BCC</command> + (see <xref linkend="mailimf-bcc">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_message_id</command> is the parsed + content of the Message-ID field + if type is <command>MAILIMF_FIELD_MESSAGE_ID</command> + (see <xref linkend="mailimf-message-id">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_in_reply_to</command> is the + parsed content of the In-Reply-To field + if type is <command>MAILIMF_FIELD_IN_REPLY_TO</command> + (see <xref linkend="mailimf-in-reply-to">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_references</command> is the parsed + content of the References field + if type is <command>MAILIMF_FIELD_REFERENCES</command> + (see <xref linkend="mailimf-references">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_subject</command> is the content + of the Subject field + if type is <command>MAILIMF_FIELD_SUBJECT</command> + (see <xref linkend="mailimf-subject">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_comments</command> is the content of the + Comments field + if type is <command>MAILIMF_FIELD_COMMENTS</command> + (see <xref linkend="mailimf-comments">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_keywords</command> is the parsed + content of the Keywords field + if type is <command>MAILIMF_FIELD_KEYWORDS</command> + (see <xref linkend="mailimf-keywords">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_optional_field</command> is an + other field and is not parsed + if type is <command>MAILIMF_FIELD_OPTIONAL_FIELD</command> + (see <xref linkend="mailimf-optional-field">). + </para> + </listitem> + </itemizedlist> + + <para> + <command>mailimf_field_new()</command> 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. + </para> + + <para> + <command>mailimf_field_free()</command> frees memory used by + the structure and substructures will also be released. + </para> + + <example> + <title>creation and display of field</title> + <programlisting role="C"> +#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; + } +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_fields --> + <sect2 id="mailimf-fields"> + <title>mailimf_fields - list of header fields</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is the list of header fields of a message. + </para> + + <para> + <command>fld_list</command> is a list of header fields. This + is a <command>clist</command> which elements are + of type <command>mailimf_field</command> (see <xref + linkend="mailimf-field">). + </para> + + <para> + <command>mailimf_fields_new()</command> 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. + </para> + + <para> + <command>mailimf_fields_free()</command> frees memory used + by the structure and substructures will also be released. + </para> + + <example> + <title>creation and display of header fields</title> + <programlisting role="C"> +#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"); + } +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_body --> + <sect2 id="mailimf-body"> + <title>mailimf_body - message body without headers</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is the text content of a message (without headers). + </para> + <para> + <itemizedlist> + <listitem> + <para> + <command>bd_text</command> is the beginning of the + text part, it is a substring of an other string. + It is not necessarily zero terminated. + </para> + </listitem> + <listitem> + <para> + <command>bd_size</command> is the size of the text part + </para> + </listitem> + </itemizedlist> + </para> + + <para> + <command>mailimf_body_new()</command> creates and + initializes a data structure with a value. + Text given as argument will <emphasis>NOT</emphasis> be released. + </para> + + <para> + <command>mailimf_body_free()</command> frees memory used by + the structure. + </para> + + <example> + <title>creation and display of message body</title> + <programlisting role="C"> +#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; +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_message --> + <sect2 id="mailimf-message"> + <title>mailimf_message - parsed message</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is the message content (text and headers). + </para> + + <itemizedlist> + <listitem> + <para> + <command>msg_fields</command> is the header fields of + the message + (see <xref linkend="mailimf-fields">). + </para> + </listitem> + <listitem> + <para> + <command>msg_body</command> is the text part of the message + (see <xref linkend="mailimf-body">). + </para> + </listitem> + </itemizedlist> + + <para> + <command>mailimf_message_new()</command> 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. + </para> + + <para> + <command>mailimf_message_free()</command> frees memory used + by the structure and substructures will also be released. + </para> + + <example> + <title>creation and display of message</title> + <programlisting> +#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"); +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_single_fields --> + <sect2 id="mailimf-single-fields"> + <title>mailimf_single_fields - simplified fields</title> + +<programlisting role="C"> +#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); +</programlisting> + + <para> + Structure that contains some standard fields and allows access + to a given header without running through the list. + </para> + + <para> + 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 + </para> + + <itemizedlist> + <listitem> + <para> + <command>fld_orig_date</command> is the parsed "Date" + field + (see <xref linkend="mailimf-orig-date">). + </para> + </listitem> + <listitem> + <para> + <command>fld_from</command> is the parsed "From" field + (see <xref linkend="mailimf-from">). + </para> + </listitem> + <listitem> + <para> + <command>fld_sender</command> is the parsed "Sender "field + (see <xref linkend="mailimf-sender">). + </para> + </listitem> + <listitem> + <para> + <command>reply_to</command> is the parsed "Reply-To" field + (see <xref linkend="mailimf-reply-to">). + </para> + </listitem> + <listitem> + <para> + <command>fld_to</command> is the parsed "To" field + (see <xref linkend="mailimf-to">). + </para> + </listitem> + <listitem> + <para> + <command>fld_cc</command> is the parsed "Cc" field + (see <xref linkend="mailimf-cc">). + </para> + </listitem> + <listitem> + <para> + <command>fld_bcc</command> is the parsed "Bcc" field + (see <xref linkend="mailimf-bcc">). + </para> + </listitem> + <listitem> + <para> + <command>fld_message_id</command> is the parsed + "Message-ID" field. + (see <xref linkend="mailimf-message-id">). + </para> + </listitem> + <listitem> + <para> + <command>fld_in_reply_to</command> is the parsed + "In-Reply-To" field. + (see <xref linkend="mailimf-in-reply-to">). + </para> + </listitem> + <listitem> + <para> + <command>fld_references</command> is the parsed + "References" field. + (see <xref linkend="mailimf-references">). + </para> + </listitem> + <listitem> + <para> + <command>fld_subject</command> is the parsed "Subject" field + (see <xref linkend="mailimf-subject">). + </para> + </listitem> + <listitem> + <para> + <command>fld_comments</command> is the parsed "Comments" field + (see <xref linkend="mailimf-comments">). + </para> + </listitem> + <listitem> + <para> + <command>fld_keywords</command> is the parsed "Keywords" field + (see <xref linkend="mailimf-keywords">). + </para> + </listitem> + </itemizedlist> + + <para> + <command>mailimf_single_fields_new()</command> creates and + initializes a data structure with a value. + Structures given as argument are referenced by the created + object and will <emphasis>NOT</emphasis> be freed if the + object is released. + </para> + + <para> + <command>mailimf_single_fields_free()</command> frees memory + used by the structure and + substructures will <emphasis>NOT</emphasis> be + released. They should be released by the application. + </para> + + <para> + <command>mailimf_single_fields_init()</command> will + initialize fill the data structure, using + the given argument (<command>fields</command>). The + interesting fields will be filled into + <command>single_fields</command>. + </para> + + <example> + <title>using mailimf_single_fields</title> + <programlisting role="C"> +#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; +} + </programlisting> + </example> + + <example> + <title>using mailimf_single_fields without memory allocation</title> + <programlisting> +#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; +} + </programlisting> + </example> + </sect2> + </sect1> + + <!-- parser functions --> + <sect1> + <title>Parser functions</title> + + <!-- mailimf_address_list_parse --> + <sect2 id="mailimf-address-list-parse"> + <title>mailimf_address_list_parse</title> + <programlisting role="C"> +int +mailimf_address_list_parse(char * message, size_t length, + size_t * index, + struct mailimf_address_list ** result); + </programlisting> + + <para> + <command>mailimf_address_list_parse()</command> parse a list + of addresses in RFC 2822 form. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> this is a string containing + the list of addresses. + </para> + </listitem> + <listitem> + <para> + <command>length</command> this is the size of the given string + </para> + </listitem> + <listitem> + <para> + <command>index</command> this is a pointer to the + start of the list of + addresses in the given string, + <command>(* index)</command> is modified to point + at the end of the parsed data. + </para> + </listitem> + <listitem> + <para> + <command>result</command> the result of the parse + operation is stored in + <command>(* result)</command> + (see <xref linkend="mailimf-address-list">). + </para> + </listitem> + </itemizedlist> + + <para> + return <command>MAILIMF_NO_ERROR</command> on success, + <command>MAILIMF_ERROR_XXX</command> on error. + </para> + + <example> + <title>parsing a list of addresses</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_address_parse --> + <sect2 id="mailimf-address-parse"> + <title>mailimf_address_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int +mailimf_address_parse(char * message, size_t length, + size_t * index, + struct mailimf_address ** result); + </programlisting> + + <para> + <command>mailimf_address_parse()</command> parse an address + in RFC 2822 form. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> this is a string containing the + address. + </para> + </listitem> + <listitem> + <para> + <command>length</command> this is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> index this is a pointer to the + start of the address in the given string, <command>(* + index)</command> is modified to point at the end of the + parsed data. + </para> + </listitem> + <listitem> + <para> + <command>result</command> the result of the parse operation + is stored in <command>(* result)</command> + (see <xref linkend="mailimf-address">). + </para> + </listitem> + </itemizedlist> + + <para> + return <command>MAILIMF_NO_ERROR</command> on success, + <command>MAILIMF_ERROR_XXX</command> on error. + </para> + + <example> + <title>parsing an address</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + + </sect2> + + <!-- mailimf_body_parse --> + <sect2 id="mailimf-body-parse"> + <title>mailimf_body_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailimf_body_parse(char * message, size_t length, + size_t * index, + struct mailimf_body ** result); + </programlisting> + + <para> + <command>mailimf_body_parse()</command> parse text body of a + message. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> this is a string containing + the message body part. + </para> + </listitem> + <listitem> + <para> + <command>length</command> this is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> this is a pointer to the start + of the message text part in + the given string, <command>(* index)</command> is + modified to point at the end + of the parsed data. + </para> + </listitem> + <listitem> + <para> + <command>result</command> the result of the parse + operation is stored in + <command>(* result)</command> + (see <xref linkend="mailimf-body">). + </para> + </listitem> + </itemizedlist> + + <para> + return <command>MAILIMF_NO_ERROR</command> on success, + <command>MAILIMF_ERROR_XXX</command> on error. + </para> + + <example> + <title>parsing a message body</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + + </sect2> + + <!-- mailimf_envelope_and_optional_fields_parse --> + <sect2 id="mailimf-envelope-and-optional-fields-parse"> + <title>mailimf_envelope_and_optional_fields_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int +mailimf_envelope_and_optional_fields_parse(char * message, size_t length, + size_t * index, + struct mailimf_fields ** result); + </programlisting> + + <para> + <command>mailimf_envelope_and_optional_fields_parse()</command> + returns a list of most useful headers (parsed). The other + headers will be placed in the list in a non-parsed form. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> this is a string containing the header. + </para> + </listitem> + <listitem> + <para> + <command>length</command> this is the size of the given string + </para> + </listitem> + <listitem> + <para> + <command>index</command> index this is a pointer to the + start of the header in the given string, <command>(* + index)</command> is modified to point at the end + of the parsed data + </para> + </listitem> + <listitem> + <para> + <command>result</command> the result of the parse + operation is stored in <command>(* result)</command> + (see <xref linkend="mailimf-fields">). + </para> + </listitem> + </itemizedlist> + + <para> + return <command>MAILIMF_NO_ERROR</command> on success, + <command>MAILIMF_ERROR_XXX</command> on error. + </para> + + <example> + <title>parsing commonly used fields and return other fields + in a non-parsed form</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + + </sect2> + + <!-- mailimf_envelope_fields_parse --> + <sect2 id="mailimf-envelope-fields-parse"> + <title>mailimf_envelope_fields_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailimf_envelope_fields_parse(char * message, size_t length, + size_t * index, + struct mailimf_fields ** result); + </programlisting> + + <para> + <command>mailimf_envelope_fields_parse()</command> return a + list of most useful headers (parsed). + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> this is a string containing the header + </para> + </listitem> + <listitem> + <para> + <command>length</command> this is the size of the given string + </para> + </listitem> + <listitem> + <para> + <command>index</command> index this is a pointer to the + start of the header in + the given string, <command>(* index)</command> is + modified to point at the end + of the parsed data + </para> + </listitem> + <listitem> + <para> + <command>result</command> the result of the parse + operation is stored in + <command>(* result)</command> + (see <xref linkend="mailimf-fields">). + </para> + </listitem> + </itemizedlist> + + <para> + return <command>MAILIMF_NO_ERROR</command> on success, + <command>MAILIMF_ERROR_XXX</command> on error. + </para> + + <example> + <title>parsing commonly used fields</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + + </sect2> + + <!-- mailimf_optional_fields_parse --> + <sect2 id="mailimf-optional-fields-parse"> + <title>mailimf_optional_fields_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int +mailimf_envelope_and_optional_fields_parse(char * message, size_t length, + size_t * index, + struct mailimf_fields ** result); + </programlisting> + + <para> + <command>mailimf_optional_fields_parse</command> return a + list of non-parsed headers. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> this is a string containing the header + </para> + </listitem> + <listitem> + <para> + <command>length</command> this is the size of the given string + </para> + </listitem> + <listitem> + <para> + <command>index</command> index this is a pointer to the + start of the header in + the given string, <command>(* index)</command> is + modified to point at the end + of the parsed data + </para> + </listitem> + <listitem> + <para> + <command>result</command> the result of the parse + operation is stored in + <command>(* result)</command> + (see <xref linkend="mailimf-fields">). + </para> + </listitem> + </itemizedlist> + + <para> + return <command>MAILIMF_NO_ERROR</command> on success, + <command>MAILIMF_ERROR_XXX</command> on error. + </para> + + <example> + <title>parsing optional fields</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_fields_parse --> + <sect2 id="mailimf-fields-parse"> + <title>mailimf_fields_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailimf_fields_parse(char * message, size_t length, + size_t * index, + struct mailimf_fields ** result); + </programlisting> + + <para> + <command>mailimf_fields_parse()</command> parse headers of a + message. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> this is a string containing the header + </para> + </listitem> + <listitem> + <para> + <command>length</command> this is the size of the given string + </para> + </listitem> + <listitem> + <para> + <command>index</command> index this is a pointer to the + start of the header in + the given string, <command>(* index)</command> is + modified to point at the end + of the parsed data + </para> + </listitem> + <listitem> + <para> + <command>result</command> the result of the parse + operation is stored in + <command>(* result)</command> + (see <xref linkend="mailimf-fields">). + </para> + </listitem> + </itemizedlist> + + <para> + return <command>MAILIMF_NO_ERROR</command> on success, + <command>MAILIMF_ERROR_XXX</command> on error. + </para> + + <example> + <title>parsing header fields</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_ignore_field_parse --> + <sect2 id="mailimf-ignore-field-parse"> + <title>mailimf_ignore_field_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailimf_ignore_field_parse(char * message, size_t length, + size_t * index); + </programlisting> + + <para> + <command>mailimf_ignore_field_parse()</command> skip the + next header. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> this is a string containing the header + </para> + </listitem> + <listitem> + <para> + <command>length</command> this is the size of the given string + </para> + </listitem> + <listitem> + <para> + <command>index</command> index this is a pointer to the + start of the field to skip in + the given string, <command>(* index)</command> is + modified to point at the end + of the parsed data + </para> + </listitem> + </itemizedlist> + + <para> + return <command>MAILIMF_NO_ERROR</command> on success, + <command>MAILIMF_ERROR_XXX</command> on error. + </para> + + <example> + <title>skipping fields</title> + <programlisting> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailimf_mailbox_list_parse --> + <sect2 id="mailimf-mailbox-list-parse"> + <title>mailimf_mailbox_list_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int +mailimf_mailbox_list_parse(char * message, size_t length, + size_t * index, + struct mailimf_mailbox_list ** result); + </programlisting> + + <para> + <command>mailimf_mailbox_list_parse()</command> parse a list + of mailboxes in RFC 2822 form. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> this is a string containing the + list of mailboxes. + </para> + </listitem> + <listitem> + <para> + <command>length</command> this is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> index this is a pointer to the + start of the list of + mailboxes in the given string, + <command>(* index)</command> is modified to point + at the end of the parsed data. + </para> + </listitem> + <listitem> + <para> + <command>result</command> the result of the parse + operation is stored in + <command>(* result)</command>. + (see <xref linkend="mailimf-mailbox-list">) + </para> + </listitem> + </itemizedlist> + + <para> + return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on + error. + </para> + + <example> + <title>parsing a list of mailboxes</title> + <programlisting> +#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); +} + </programlisting> + </example> + + </sect2> + + <!-- mailimf_mailbox_parse --> + <sect2 id="mailimf-mailbox-parse"> + <title>mailimf_mailbox_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailimf_mailbox_parse(char * message, size_t length, + size_t * index, + struct mailimf_mailbox ** result); + </programlisting> + + <para> + <command>mailimf_mailbox_parse</command> parse a mailbox in + RFC 2822 form. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> this is a string containing the + mailbox. + </para> + </listitem> + <listitem> + <para> + <command>length</command> this is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> index this is a pointer to the + start of the mailbox in the given string, + <command>(* index)</command> is modified to point + at the end of the parsed data. + </para> + </listitem> + <listitem> + <para> + <command>result</command> the result of the parse + operation is stored in + <command>(* result)</command>. + (see <xref linkend="mailimf-mailbox">) + </para> + </listitem> + </itemizedlist> + + <para> + return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on + error. + </para> + + <example> + <title>parsing a mailbox</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + + </sect2> + + <!-- mailimf_message_parse --> + <sect2 id="mailimf-message-parse"> + <title>mailimf_message_parse</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailimf_message_parse(char * message, size_t length, + size_t * index, + struct mailimf_message ** result); + </programlisting> + + <para> + <command>mailimf_message_parse</command> parse message + (headers and body). + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> this is a string containing + the message content. + </para> + </listitem> + <listitem> + <para> + <command>param</command> length this is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>param</command> index this is a pointer to the + start of the message in + the given string, <command>(* index)</command> is + modified to point at the end + of the parsed data. + </para> + </listitem> + <listitem> + <para> + <command>param</command> result the result of the parse + operation is stored in + <command>(* result)</command> + (see <xref linkend="mailimf-message">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>parsing a message</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + + </sect2> + </sect1> + + <!-- helper functions --> + <sect1> + <title>Creation functions</title> + <sect2 id="mailimf-mailbox-list-add"> + <title>mailimf_mailbox_list</title> + <programlisting role="C"> +#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); + </programlisting> + + <!-- mailimf_mailbox_list_new_empty --> + <para> + <command>mailimf_mailbox_list_new_empty()</command> creates a + new empty list of mailboxes. + </para> + + <!-- mailimf_mailbox_list_add --> + <para> + <command>mailimf_mailbox_list_add</command> adds a mailbox + to the list of mailboxes. + </para> + + <!-- mailimf_mailbox_list_add_parse --> + <para> + <command>mailimf_mailbox_list_add_parse</command> adds a + mailbox given in form of a string to the list of mailboxes. + </para> + + <!-- mailimf_mailbox_list_add_mb --> + <para> + <command>mailimf_mailbox_list_add_mb</command> adds a + mailbox given in form of a couple : display name, mailbox + address. + </para> + + <itemizedlist> + <listitem> + <para> + <command>mailbox_list</command> is the list of mailboxes. + </para> + </listitem> + <listitem> + <para> + <command>mb</command> is a mailbox + (see <xref linkend="mailimf-mailbox">). + </para> + </listitem> + <listitem> + <para> + <command>mb_str</command> is a mailbox given in the form + of a string. + </para> + </listitem> + <listitem> + <para> + <command>display_name</command> is the display name. + </para> + </listitem> + <listitem> + <para> + <command>address</command> is the mailbox address. + </para> + </listitem> + </itemizedlist> + + <example> + <title>creating a list of mailboxes</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + + </sect2> + <sect2 id="mailimf-address-list-add"> + <title>mailimf_address_list</title> + <programlisting role="C"> +#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); + </programlisting> + + <!-- mailimf_address_list_new_empty --> + <para> + <command>mailimf_address_list_new_empty()</command> creates a + new empty list of addresses. + </para> + + <!-- mailimf_address_list_add --> + <para> + <command>mailimf_address_list_add</command> adds an address + to the list of addresses. + </para> + + <!-- mailimf_address_list_add_parse --> + <para> + <command>mailimf_address_list_add_parse</command> adds an + address given in form of a string to the list of addresses. + </para> + + <!-- mailimf_address_list_add_mb --> + <para> + <command>mailimf_address_list_add_mb</command> adds a + mailbox given in form of a couple : display name, mailbox + address. + </para> + + <itemizedlist> + <listitem> + <para> + <command>address_list</command> is the list of mailboxes. + </para> + </listitem> + <listitem> + <para> + <command>addr</command> is an address. + (see <xref linkend="mailimf-address">). + </para> + </listitem> + <listitem> + <para> + <command>addr_str</command> is an address given in the form of a + string. + </para> + </listitem> + <listitem> + <para> + <command>display_name</command> is the display name. + </para> + </listitem> + <listitem> + <para> + <command>address</command> is the mailbox address. + </para> + </listitem> + </itemizedlist> + + </sect2> + <sect2 id="mailimf-fields-add"> + <title>mailimf_fields</title> + <programlisting role="C"> +#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); + </programlisting> + + <itemizedlist> + <listitem> + <para> + <command>from</command> is the parsed content of the + From field + (see <xref linkend="mailimf-from">). + </para> + </listitem> + <listitem> + <para> + <command>sender</command> is the parsed content of the + Sender field + (see <xref linkend="mailimf-sender">). + </para> + </listitem> + <listitem> + <para> + <command>reply_to</command> is the parsed content of the + <command>Reply-To</command> field + (see <xref linkend="mailimf-reply-to">). + </para> + </listitem> + <listitem> + <para> + <command>to</command> is the parsed content of the + <command>To</command> field + (see <xref linkend="mailimf-to">). + </para> + </listitem> + <listitem> + <para> + <command>cc</command> is the parsed content of the + <command>Cc</command> field + (see <xref linkend="mailimf-cc">). + </para> + </listitem> + <listitem> + <para> + <command>bcc</command> is the parsed content of the + <command>Bcc</command> field + (see <xref linkend="mailimf-bcc">). + </para> + </listitem> + <listitem> + <para> + <command>message_id</command> is the parsed content of + the <command>Message-ID</command> field + (see <xref linkend="mailimf-message-id">). + </para> + </listitem> + <listitem> + <para> + <command>in_reply_to</command> is the parsed content of + the <command>In-Reply-To</command> field + (see <xref linkend="mailimf-in-reply-to">). + </para> + </listitem> + <listitem> + <para> + <command>references</command> is the parsed content of + the <command>References</command> field + (see <xref linkend="mailimf-references">). + </para> + </listitem> + <listitem> + <para> + <command>subject</command> is the content of the + <command>Subject</command> field + (see <xref linkend="mailimf-subject">). + </para> + </listitem> + <listitem> + <para> + <command>resent_date</command> is the parsed content of + the <command>Resent-Date</command> field + (see <xref linkend="mailimf-orig-date">). + </para> + </listitem> + <listitem> + <para> + <command>resent_from</command> is the parsed content of + the <command>Resent-From</command> field + (see <xref linkend="mailimf-from">). + </para> + </listitem> + <listitem> + <para> + <command>resent_sender</command> is the parsed content of the + <command>Resent-Sender</command> field + (see <xref linkend="mailimf-sender">). + </para> + </listitem> + <listitem> + <para> + <command>resent_to</command> is the parsed content of + the <command>Resent-To</command> field + (see <xref linkend="mailimf-to">). + </para> + </listitem> + <listitem> + <para> + <command>resent_cc</command> is the parsed content of + the <command>Resent-Cc</command> field + (see <xref linkend="mailimf-cc">). + </para> + </listitem> + <listitem> + <para> + <command>resent_bcc</command> is the parsed content of the + <command>Resent-Bcc</command> field + (see <xref linkend="mailimf-bcc">). + </para> + </listitem> + <listitem> + <para> + <command>resent_msg_id</command> is the parsed content of the + <command>Resent-Message-ID</command> field + (see <xref linkend="mailimf-message-id">). + </para> + </listitem> + </itemizedlist> + + <!-- mailimf_fields_new_empty --> + <para> + <command>mailimf_fields_new_empty()</command> creates a new + empty set of headers. + </para> + + <!-- mailimf_fields_new_custom --> + <para> + <command>mailimf_field_new_custom()</command> creates a new + custom header. + </para> + + <!-- mailimf_fields_add --> + <para> + <command>mailimf_fields_add()</command> adds a header to the + set of headers. + </para> + + <!-- mailimf_fields_add_data --> + <para> + <command>mailimf_fields_add_data()</command> adds some headers + to the set of headers. + </para> + + <!-- mailimf_fields_new_with_data_all --> + <para> + <command>mailimf_fields_new_with_data_all()</command> creates + a set of headers with some headers (including Date and + Message-ID). + </para> + + <!-- mailimf_fields_new_with_data --> + <para> + <command>mailimf_fields_new_with_data()</command> creates a + set of headers with some headers (Date and Message-ID will + be generated). + </para> + + <!-- mailimf_get_message_id --> + <para> + <command>mailimf_get_message_id()</command> generates a + Message-ID. The result must be freed using + <command>free()</command>. + </para> + + <!-- mailimf_get_current_date --> + <para> + <command>mailimf_get_current_date()</command> generates a + Date. The result must be freed using + <command>mailimf_date_time_free</command>. + </para> + + <!-- mailimf_resent_fields_add_data --> + <para> + <command>mailimf_resent_fields_add_data()</command> adds some + resent headers to the set of headers. + </para> + + <!-- mailimf_resent_fields_new_with_data_all --> + <para> + <command>mailimf_resent_fields_new_with_data_all()</command> + creates a set of headers with some resent headers (including + Resent-Date and Resent-Message-ID). + </para> + + <!-- mailimf_resent_fields_new_with_data --> + <para> + <command>mailimf_resent_fields_new_with_data()</command> + creates a set of headers with some resent headers + (Resent-Date and Resent-Message-ID will be generated) + </para> + + <example> + <title>creation of header fields</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + </sect1> + + <!-- rendering functions --> + <sect1> + <title>Rendering of messages</title> + <sect2 id="mailimf-fields-write"> + <title>Header fields</title> + <programlisting> +#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); + </programlisting> + + <itemizedlist> + <listitem> + <para> + <command>col</command> current column is given for wrapping + purpose in <command>(* col)</command>, + the resulting columns will be returned.. + </para> + </listitem> + <listitem> + <para> + <command>f</command> is the file descriptor. It can be + stdout for example. + </para> + </listitem> + <listitem> + <para> + <command>fields</command> is the header fields + (see <xref linkend="mailimf-fields">). + </para> + </listitem> + <listitem> + <para> + <command>field</command> is a field + (see <xref linkend="mailimf-field">). + </para> + </listitem> + </itemizedlist> + + <!-- mailimf_fields_write --> + <para> + <command>mailimf_fields_write</command> outputs the set of + header fields. + </para> + + <!-- mailimf_envelope_fields_write --> + <para> + <command>mailimf_envelope_fields_write</command> outputs the + set of header fields except the optional fields. + </para> + + <!-- mailimf_field_write --> + <para> + <command>mailimf_field_write</command> outputs a header. + </para> + + <example> + <title>rendering of fields</title> + <programlisting role="C"> +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); +} + </programlisting> + </example> + </sect2> + </sect1> + </chapter> + + + <!-- MIME --> + <chapter> + <title>MIME</title> + + <para> + libEtPan! implements a MIME message parser (also known as + messages with attachments or + multipart messages). This also allows to generate MIME messages. + </para> + + <warning> + <para> + 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 + </para> + + <para> + allocation functions will return <command>NULL</command> on failure + + functions returning integer will be returning one of the + following error code: + <command>MAILIMF_NO_ERROR</command>, + <command>MAILIMF_ERROR_PARSE</command>, + <command>MAILIMF_ERROR_MEMORY</command>, + <command>MAILIMF_ERROR_INVAL</command>, + or <command>MAILIMF_ERROR_FILE</command>. + </para> + </warning> + + <sect1> + <title>Quick start</title> + + <para> + You will need this module when you want to parse a MIME + message. + </para> + + <sect2> + <title>Parse MIME message</title> + <para> + You will use the following function : + </para> + <itemizedlist> + <listitem> + <para> + <command>mailmime_parse</command> + (<xref linkend="mailimf-envelope-and-optional-fields-parse">) + </para> + </listitem> + </itemizedlist> + </sect2> + + <sect2> + <title>Render the MIME message</title> + <para> + Build your MIME message, then use + <command>mailmime_write</command> + (<xref linkend="mailmime-write">) + to render a MIME message. + </sect2> + </sect1> + + <!-- Data types--> + <sect1> + <title>Data types</title> + <!-- mailmime_composite_type --> + <sect2 id="mailmime-composite-type"> + <title>mailmime_composite_type - Composite MIME type</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is a MIME composite type such as <command>message</command> or + <command>multipart</command>. + </para> + + <para> + <command>ct_type</command> can have one of the 3 following values : + <command>MAILMIME_COMPOSITE_TYPE_MESSAGE</command> when the + composite MIME type + is <command>message</command>, + <command>MAILMIME_COMPOSITE_TYPE_MULTIPART</command> when + the composite MIME type + is <command> multipart</command>, + <command>MAILMIME_COMPOSITE_TYPE_EXTENSION</command> for + other and <command>ct_token</command> is set + in this case. + <command>MAILMIME_COMPOSITE_TYPE_ERROR</command> is used + internally on parse error. + </para> + + <para> + <command>mailmime_composite_type_new()</command> 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. + </para> + + <para> + <command>mailmime_composite_type_free()</command> frees + memory used by + the structure and substructures will also be released. + </para> + + <example> + <title>create and display MIME composite type</title> + <programlisting role="C"> +#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; + } +} + </programlisting> + </example> + + </sect2> + + <!-- mailmime_content --> + <sect2 id="mailmime-content"> + <title>mailmime_content - MIME content type (Content-Type)</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is a MIME content type such as <command>message/rfc822</command> or + <command>text/plain</command>. + </para> + + <itemizedlist> + <listitem> + <para> + <command>ct_type</command> is the main MIME type, + for example <command>text</command> in + <command>plain/text</command> + (see <xref linkend="mailmime-type">). + </para> + <para> + <command>ct_subtype</command> is the MIME subtype, + for example <command>plain</command> in + <command>plain/text</command>. + </para> + </listitem> + <listitem> + <para> + <command>ct_parameters</command> is the list of parameters for + the given MIME type. For example, for <command>plain/text</command>, + we can find <command>charset=iso-8859-1</command>, + <command>format=flowed</command>. Each element of the list + if of type <command>struct mailmime_parameter *</command> + (see <xref linkend="mailmime-parameter">). + </para> + </listitem> + </itemizedlist> + + <para> + <command>mailmime_content_new()</command> 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. + </para> + + <para> + <command>mailmime_content_free()</command> frees memory used by + the structure and substructures will also be released. + </para> + + <example> + <title>Creation and display of MIME content type</title> + <programlisting role="C"> +#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"); +} + </programlisting> + </example> + + </sect2> + + <!-- mailmime_discrete_type --> + <sect2 id="mailmime-discrete-type"> + <title>mailmime_discrete_type - MIME discrete type</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is a MIME discrete type such as <command>text</command> or + <command>image</command>. This is also known as single part. This kind + of part does not have any child. + </para> + + <para> + <command>dt_type</command> is one of the given values : + <command>MAILMIME_DISCRETE_TYPE_TEXT</command> if part is text, + <command>MAILMIME_DISCRETE_TYPE_IMAGE</command> if part is an image, + <command>MAILMIME_DISCRETE_TYPE_AUDIO</command> if part is + audio data, + <command>MAILMIME_DISCRETE_TYPE_VIDEO</command> if part is video, + <command>MAILMIME_DISCRETE_TYPE_APPLICATION</command> if + part is application data or + <command>MAILMIME_DISCRETE_TYPE_EXTENSION</command> for other. + In the case of <command>MAILMIME_DISCRETE_TYPE_EXTENSION</command>, + <command>dt_extension</command> is filled in. + <command>MAILMIME_DISCRETE_TYPE_ERROR</command> is used internally. + </para> + + <para> + <command>mailmime_discrete_type_new()</command> 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. + </para> + + <para> + <command>mailmime_discrete_type_free()</command> frees + memory used by + the structure and substructures will also be released. + </para> + + <example> + <title>Creation and display of MIME discrete type</title> + <programlisting role="C"> +#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; + } +} + </programlisting> + </example> + + </sect2> + + <!-- mailmime_field --> + <sect2 id="mailmime-field"> + <title>mailmime_field - MIME header field</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is a parsed MIME header field; + </para> + + <itemizedlist> + <listitem> + <para> + <command>fld_type</command> is the type of MIME header field. The value can + be + <command>MAILMIME_FIELD_TYPE</command> + if field is <command>Content-Type</command>, + <command>MAILMIME_FIELD_TRANSFER_ENCODING</command> + if field is <command>Content-Transfer-Encoding</command>, + <command>MAILMIME_FIELD_ID</command> + if field is <command>Content-ID</command>, + <command>MAILMIME_FIELD_DESCRIPTION</command> + if field is <command>Content-Description</command>, + <command>MAILMIME_FIELD_VERSION</command> + if field is <command>MIME-Version</command>, + <command>MAILMIME_FIELD_DISPOSITION</command> + if field is <command>Content-Disposition</command> or + <command>MAILMIME_FIELD_LANGUAGE</command> + if field is <command>Content-Language</command>. + <command>MAILMIME_FIELD_NONE</command> is used internally. + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_content</command> is set in case of + <command>Content-Type</command>. + (see <xref linkend="mailmime-content">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_encoding</command> is set in case of + <command>Content-Transfer-Encoding</command>. + (see <xref linkend="mailmime-mechanism">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_id</command> is set in case of + <command>Content-ID</command>. This is a string. + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_description</command> is set in case of + <command>Content-Description</command>. This is a string. + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_version</command> is set in case of + <command>MIME-Version</command>. This is an integer built + using the following formula : + <command>fld_version = major * 2^16 + minor</command>. + Currenly MIME-Version is always <command>1.0</command>, this means that + fld_version will always be <command>2^16</command> (in C language, + this is <command>1 << 16</command>). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_disposition</command> is set in case of + <command>Content-Disposition</command>. + (see <xref linkend="mailmime-disposition">). + </para> + </listitem> + <listitem> + <para> + <command>fld_data.fld_language</command> is set in case of + <command>Content-Language</command>. + (see <xref linkend="mailmime-language">). + </para> + </listitem> + </itemizedlist> + + <para> + <command>mailmime_field_new()</command> 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. + </para> + + <para> + <command>mailmime_field_free()</command> frees memory used by + the structure and substructures will also be released. + </para> + + <example> + <title>Creation and display of MIME header field</title> + <programlisting role="C"> +#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; + } +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_mechanism --> + <sect2 id="mailmime-mechanism"> + <title>mailmime_mechanism - MIME transfer encoding mechanism (Content-Transfer-Encoding)</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is a MIME transfer encoding mechanism description. + </para> + + <para> + <command>enc_type</command> is an encoding type. The value of this field + can be + <command>MAILMIME_MECHANISM_7BIT</command> + if mechanism is <command>7bit</command>, + <command>MAILMIME_MECHANISM_8BIT</command> + if mechanism is <command>8bit</command>, + <command>MAILMIME_MECHANISM_BINARY</command> + if mechanism is <command>binary</command>, + <command>MAILMIME_MECHANISM_QUOTED_PRINTABLE</command> + if mechanism is <command>quoted-printable</command>, + <command>MAILMIME_MECHANISM_BASE64</command> + if mechanism is <command>base64</command> or + <command>MAILMIME_MECHANISM_TOKEN</command> for other. + In case of <command>MAILMIME_MECHANISM_TOKEN</command>, + field <command>enc_token</command> is filled in. + <command>MAILMIME_MECHANISM_ERROR</command> is used internally. + </para> + + <para> + <command>mailmime_mechanism_new()</command> 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. + </para> + + <para> + <command>mailmime_mechanism_free()</command> frees memory used by + the structure and substructures will also be released. + </para> + + <example> + <title>Creation and display of MIME transfer encoding mechanism</title> + <programlisting role="C"> +#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; + } +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_fields --> + <sect2 id="mailmime-fields"> + <title>mailmime_fields - header fields</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is the header fields of a MIME part. + </para> + + <para> + <command>fld_list</command> is the list of the header fields. + Each element of the list is a <command>mailmime_field</command> + (See <xref linkend="mailmime-field">). + </para> + + <para> + <command>mailmime_fields_new()</command> 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. + </para> + + <para> + <command>mailmime_fields_free()</command> frees memory used by + the structure and substructures will also be released. + </para> + + <example> + <title>Creation and display of MIME fields</title> + <programlisting role="C"> +#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); + } +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_parameter --> + <sect2 id="mailmime-parameter"> + <title>mailmime_parameter - MIME type parameter</title> + + <programlisting role="C"> +struct mailmime_parameter { + char * pa_name; + char * pa_value; +}; + </programlisting> + + <para> + This is the MIME type parameter in + <command>Content-Type</command> MIME header + field. For example, this can be + <command>charset="iso-8859-1"</command>. + </para> + + <itemizedlist> + <listitem> + <para> + <command>pa_name</command> is the name of the parameter, + for example : <command>charset</command>. + </para> + </listitem> + <listitem> + <para> + <command>pa_value</command> is the value of the parameter, + for example : <command>iso-8859-1</command>. + </para> + </listitem> + </itemizedlist> + + <para> + <command>mailmime_parameter_new()</command> 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. + </para> + + <para> + <command>mailmime_parameter_free()</command> frees memory used by + the structure and substructures will also be released. + </para> + + <example> + <title>Creation and display of MIME type parameter</title> + <programlisting role="C"> +#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); +} + </programlisting> + </example> + + </sect2> + + <!-- mailmime_type --> + <sect2 id="mailmime-type"> + <title>mailmime_type - MIME main type</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is the MIME main type (no subtype, no parameter). + </para> + + <itemizedlist> + <listitem> + <para> + <command>tp_type</command>. The value of this field + is either <command>MAILMIME_TYPE_DISCRETE_TYPE</command> for MIME discrete type, + or <command>MAILMIME_TYPE_COMPOSITE_TYPE</command> for MIME composite type. + <command>MAILMIME_TYPE_ERROR</command> is used internally. + </para> + </listitem> + <listitem> + <para> + <command>tp_data.tp_discrete_type</command> is set when <command>tp_type</command> + is <command>MAILMIME_TYPE_DISCRETE_TYPE</command> + (see <xref linkend="mailmime-discrete-type">). + </para> + </listitem> + <listitem> + <para> + <command>tp_data.tp_composite_type</command> is set when <command>tp_type</command> + is <command>MAILMIME_TYPE_COMPOSITE_TYPE</command> + (see <xref linkend="mailmime-composite-type">). + </para> + </listitem> + </itemizedlist> + + <para> + <command>mailmime_discrete_type_new()</command> 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. + </para> + + <para> + <command>mailmime_discrete_type_free()</command> frees + memory used by + the structure and substructures will also be released. + </para> + + <example> + <title>Creation and display of MIME main type</title> + <programlisting role="C"> +#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"); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_discrete_type --> + <sect2 id="mailmime-language"> + <title>mailmime_language - Language of MIME part</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is the language used in the MIME part. + </para> + + <para> + <command>lg_list</command> is the list of codes of languages used + in the MIME part. This is a list of strings. + </para> + + <para> + <command>mailmime_language_new()</command> 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. + </para> + + <para> + <command>mailmime_language_free()</command> frees + memory used by + the structure and substructures will also be released. + </para> + + <example> + <title>Creation and display of language of MIME part</title> + <programlisting role="C"> +#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"); +} + </programlisting> + </example> + + </sect2> + + <!-- mailmime_data --> + <sect2 id="mailmime-data"> + <title>mailmime_data - Content of MIME part</title> + + <programlisting role="C"> +#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_ </programlisting> + + <para> + This is the content of MIME part, content of + preamble or content of epilogue. + </para> + + <para> + <command>dt_type</command> can be + <command>MAILMIME_DATA_TEXT</command> if + the content is a string in memory, + <command>MAILMIME_DATA_FILE</command> if the + content is in a file, + </para> + + <para> + <command>dt_encoding</command> is the encoding mechanism + of the part. The value of this field can be + <command>MAILMIME_MECHANISM_7BIT</command> if mechanism is + <command>7bit</command>, + <command>MAILMIME_MECHANISM_8BIT</command> if mechanism is + <command>8bit</command>, + <command>MAILMIME_MECHANISM_BINARY</command> if mechanism is + <command>binary</command>, + <command>MAILMIME_MECHANISM_QUOTED_PRINTABLE</command> if + mechanism is <command>quoted-printable</command>, + <command>MAILMIME_MECHANISM_BASE64</command> if mechanism is + <command>base64</command> or + <command>MAILMIME_MECHANISM_TOKEN</command> for other. If + <command>MAILMIME_MECHANISM_TOKEN</command>, the part will + be considered as binary. + <command>MAILMIME_MECHANISM_ERROR</command> is used internally. + </para> + + <para> + <command>dt_encoded</command> is set to 1 if the part is + already encoded with the mechanism given in + <command>dt_encoding</command>. It is set to 0 if the part + is already decoded or if it is necessary to encode that part + before rendering it. + </para> + + <para> + <command>dt_data.dt_text.dt_data</command> is a pointer to the + content of the part and <command>dt_data.dt_text.dt_length</command> + is the length of the data if <command>dt_type</command> is + <command>MAILMIME_DATA_TEXT</command>. + </para> + + <para> + <command>dt_data.dt_filename</command> is the name of the file if + <command>dt_type</command> is <command>MAILMIME_DATA_FILE</command>. + </para> + + <para> + <command>mailmime_data_new()</command> 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. + </para> + + <para> + <command>mailmime_data_free()</command> frees + memory used by + the structure and substructures will also be released. + </para> + + <example> + <title>Creation and display of MIME part content</title> + + <programlisting role="C"> +#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; + } +} + </programlisting> + </example> + </sect2> + + <!-- mailmime --> + <sect2 id="mailmime"> + <title>mailmime - MIME part</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This describes the MIME structure of a message or a subpart + of a message. + </para> + + <sect3> + <title>common</title> + + <itemizedlist> + <listitem> + <para> + <command>mm_parent_type</command>. MIME part type can be + single part, multipart or message part. This describes the MIME part + type of the parent. The value can be + <command>MAILMIME_NONE</command> if there is no parent part, + <command>MAILMIME_SINGLE</command> if parent is a single part, + <command>MAILMIME_MULTIPLE</command> if parent is a multipart, + <command>MAILMIME_MESSAGE</command> if parent is a mesage part. + </para> + </listitem> + + <listitem> + <para> + <command>mm_parent</command> is the parent MIME structure. + </para> + </listitem> + + <listitem> + <para> + <command>mm_multipart_pos</command>. 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 + <command>clisiter *</command>. + </para> + </listitem> + + <listitem> + <para> + <command>mm_type</command>. This describes the MIME part type + of this part. The value can be + <command>MAILMIME_SINGLE</command> if this is a single part, + <command>MAILMIME_MULTIPLE</command> if this is a multipart, + <command>MAILMIME_MESSAGE</command> if this is a mesage part. + </para> + </listitem> + + <listitem> + <para> + <command>mm_mime_start</command>. 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. + </para> + </listitem> + + + <listitem> + <para> + <command>mm_length</command>. This gives the length of the MIME part, + including the MIME header fields. + </para> + </listitem> + + <listitem> + <para> + <command>mm_mime_fields</command> is the list of parsed MIME headers + of this part. <command>Content-Type</command> must be excluded and stored + in <command>mm_content_type</command> instead + (see <xref linkend="mailmime-fields">). + </para> + </listitem> + + + <listitem> + <para> + <command>mm_content_type</command> is the parsed + <command>Content-Type</command> field + (see <xref linkend="mailmime-content">). + </para> + </listitem> + + + <listitem> + <para> + <command>mm_body</command> is the content of the MIME part + (excluding MIME header), when it is parsed from a string + in memory + (see <xref linkend="mailmime-data">). + </para> + </listitem> + </itemizedlist> + </sect3> + + <sect3> + <title>single part</title> + + <itemizedlist> + <listitem> + <para> + When the part is a single part (<command>mm_type</command> + is <command>MAILMIME_SINGLE</command>). The following fields + are valid. + </para> + </listitem> + + <listitem> + <para> + <command>mm_data.mm_single</command> 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 <command>mm_body</command> when it is set + (see <xref linkend="mailmime-data">). + </para> + </listitem> + </itemizedlist> + </sect3> + + <sect3> + <title>multipart</title> + + <itemizedlist> + <listitem> + <para> + When the part is a multipart (<command>mm_type</command> + is <command>MAILMIME_MULTIPLE</command>). The following fields + are valid. + </para> + </listitem> + + <listitem> + <para> + <command>mm_data.mm_multipart.mm_preamble</command> + is the content of the preamble of the multipart + (see <xref linkend="mailmime-data">). + </para> + </listitem> + + <listitem> + <para> + <command>mm_data.mm_multipart.mm_epilogue</command> + is the content of the epilogue of the multipart + (see <xref linkend="mailmime-data">). + </para> + </listitem> + + <listitem> + <para> + <command>mm_data.mm_multipart.mm_mp_list</command> + is the list of sub parts + </para> + </listitem> + </itemizedlist> + </sect3> + + <sect3> + <title>message part</title> + + <itemizedlist> + <listitem> + <para> + When the part is a message (<command>mm_type</command> + is <command>MAILMIME_MESSAGE</command>). The following fields + are valid. + </para> + </listitem> + + <listitem> + <para> + <command>mm_data.mm_message.mm_fields</command> is the list of + the header fields of the message + (see <xref linkend="mailimf-fields">). + </para> + </listitem> + + <listitem> + <para> + <command>mm_data.mm_message.mm_msg_mime</command> is + the subpart + of the message part. + </para> + </listitem> + </itemizedlist> + </sect3> + + <sect3> + <title>constructor and destructor</title> + + <para> + <command>mailmime_new()</command> 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. + </para> + + <para> + <command>mailmime_free()</command> frees + memory used by + the structure and substructures will also be released. + </para> + + <example> + <title>Creation and display of MIME part</title> + + <programlisting role="C"> +#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; + } +} + </programlisting> + </example> + + </sect3> + + </sect2> + + <!-- mailmime_disposition --> + <sect2 id="mailmime-disposition"> + <title>mailmime_disposition - MIME disposition information (Content-Disposition)</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +struct mailmime_disposition { + struct mailmime_disposition_type * dsp_type; + clist * dsp_parms; /* struct mailmime_disposition_parm */ +}; + </programlisting> + + <para> + This is the parsed <command>Content-Disposition</command> + header field. + </para> + + <itemizedlist> + <listitem> + <para> + <command>dsp_type</command> is the type of disposition + (see <xref linkend="mailmime-disposition-type">). + </para> + </listitem> + + <listitem> + <para> + <command>dsp_parms</command> is the list of parameters + of <command>Content-Disposition</command> header field. + Each element is of type <command>mailmime_disposition_parm</command> + (see <xref linkend="mailmime-disposition-parm">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>Creation and display of MIME disposition information</title> + <programlisting role="C"> +#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"); +} + + </programlisting> + </example> + </sect2> + + <!-- mailmime_disposition_type --> + <sect2 id="mailmime-disposition-type"> + <title>mailmime_disposition_type - Type of MIME disposition</title> + + <programlisting role="C"> +#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; +}; + </programlisting> + + <para> + This is the type of MIME disposition. + Parsed <command>Content-Disposition</command> field without + parameters. + </para> + + <para> + <command>dsp_type</command> is the type of disposition. + The value can be + <command>MAILMIME_DISPOSITION_TYPE_INLINE</command> + if MIME disposition is inline, + <command>MAILMIME_DISPOSITION_TYPE_ATTACHMENT</command> + if MIME disposition is attachment, + <command>MAILMIME_DISPOSITION_TYPE_EXTENSION</command> + for other. In this case, <command>dsp_extension</command> must be + set. + <command>MAILMIME_DISPOSITION_TYPE_ERROR</command> is used internally. + </para> + + <example> + <title>Creation and display of MIME disposition type</title> + <programlisting role="C"> +#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; + } +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_disposition_parm --> + <sect2 id="mailmime-disposition-parm"> + <title>mailmime_disposition_parm - MIME disposition parameter</title> + + <programlisting role="C"> +#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; +}; + </programlisting> + + <para> + This is a parameter of MIME disposition information. For + example, this can be + <command>filename="foo.jpg"</command>. + </para> + + <itemizedlist> + <listitem> + <para> + <command>pa_type</command> is the type of + disposition. The value can be + <command>MAILMIME_DISPOSITION_PARM_FILENAME</command> + for a filename parameter, + <command>MAILMIME_DISPOSITION_PARM_CREATION_DATE</command> + for a creation date parameter, + <command>MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE</command> + for a modification date parameter, + <command>MAILMIME_DISPOSITION_PARM_READ_DATE</command> + for a last read date parameter, + <command>MAILMIME_DISPOSITION_PARM_SIZE</command> + for a file size parameter or + <command>MAILMIME_DISPOSITION_PARM_PARAMETER</command> + for other parameters. + </para> + </listitem> + + <listitem> + <para> + <command>pa_data.pa_filename</command> is the filename + parameter when <command>pa_type</command> is + <command>MAILMIME_DISPOSITION_PARM_FILENAME</command> + This is a string containing the name of the + file. + </para> + </listitem> + <listitem> + <para> + <command>pa_data.pa_creation_date</command> is the + creation date parameter when <command>pa_type</command> is + <command>MAILMIME_DISPOSITION_PARM_CREATION_DATE</command>. + This is a string containing the formatted creation date. + </para> + </listitem> + + <listitem> + <para> + <command>pa_data.pa_modification_date</command> is the + modification date parameter when <command>pa_type</command> is + <command>MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE</command>. + This is a string containing the formatted modification date. + </para> + </listitem> + + <listitem> + <para> + <command>pa_data.pa_read_date</command> is the + last read date parameter when <command>pa_type</command> is + <command>MAILMIME_DISPOSITION_PARM_READ_DATE</command>. + This is a string containing the formatted last read date. + </para> + </listitem> + + <listitem> + <para> + <command>pa_data.pa_size</command> is the size + parameter when <command>pa_type</command> is + <command>MAILMIME_DISPOSITION_PARM_SIZE</command>. + This gives the size of the file. + </para> + </listitem> + + <listitem> + <para> + <command>pa_data.pa_parameter</command> is the + name and the value of the parameter when + <command>pa_type</command> is + <command>MAILMIME_DISPOSITION_PARM_PARAMETER</command> + (see <xref linkend="mailmime-parameter">) + </para> + </listitem> + </itemizedlist> + + <example> + <title>Creation and display of MIME disposition + parameter</title> + + <programlisting role="C"> +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; + } +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_single_fields --> + <sect2 id="mailmime-single-fields"> + <title>mailmime_single_fields - MIME headers</title> + + + <programlisting role="C"> +#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); + </programlisting> + + <para> + <command>mailmime_fields</command> (see <xref + linkend="mailmime-fields">) is the native structure + that MIME module will use, this module will provide an easier + structure to use when + parsing fields. <command>mailmime_single_fields</command> is + an easier structure to get parsed fields, rather than + iteration over the list of fields. + </para> + + <itemizedlist> + <listitem> + <para> + <command>fld_content</command> is the MIME content type + (see <xref linkend="mailmime-content">). + </para> + </listitem> + <listitem> + <para> + <command>fld_content_charset</command> is the value + of the MIME type parameter <command>charset</command>. + </para> + </listitem> + <listitem> + <para> + <command>fld_content_boundary</command> is the value + of the MIME type parameter <command>boundary</command>. + </para> + </listitem> + <listitem> + <para> + <command>fld_content_name</command> is the value + of the MIME type parameter <command>name</command>. + </para> + </listitem> + <listitem> + <para> + <command>fld_encoding</command> is the MIME encoding + mechanism used + (see <xref linkend="mailmime-mechanism">). + </para> + </listitem> + <listitem> + <para> + <command>fld_id</command> is the content of the field + <command>Content-ID</command>. + </para> + </listitem> + <listitem> + <para> + <command>fld_description</command> is the content of the field + <command>Content-Description</command>. + </para> + </listitem> + <listitem> + <para> + <command>fld_version</command> is the version of MIME + in use. + </para> + </listitem> + <listitem> + <para> + <command>fld_disposition</command> is the MIME + disposition information + (see <xref linkend="mailmime-disposition">). + </para> + </listitem> + <listitem> + <para> + <command>fld_disposition_filename</command> is + the <command>filename</command> parameter of the + MIME disposition information. + </para> + </listitem> + <listitem> + <para> + <command>fld_disposition_creation_date</command> is + the <command>creation-date</command> parameter of the + MIME disposition information. + </para> + </listitem> + <listitem> + <para> + <command>fld_disposition_modification_date</command> is + the <command>modification-date</command> parameter of the + MIME disposition information. + </para> + </listitem> + <listitem> + <para> + <command>fld_disposition_read_date</command> is + the <command>read-date</command> parameter of the + MIME disposition information. + </para> + </listitem> + <listitem> + <para> + <command>fld_disposition_size</command> is + the <command>size</command> parameter of the + MIME disposition information. + </para> + </listitem> + <listitem> + <para> + <command>fld_language</command> is the language + of the MIME part + (see <xref linkend="mailmime-language">). + </para> + </listitem> + <listitem> + <para> + <command>single_fields</command> is the structure to fill. + </para> + </listitem> + <listitem> + <para> + <command>fld_fields</command> is the MIME fields list to + use to fill the <command>single_fields</command>. + </para> + </listitem> + </itemizedlist> + + <para> + <command>mailmime_single_fields_new()</command> creates and + initializes a data structure with a + value. Structures given as argument are referenced by the created + object and will <emphasis>NOT</emphasis> be freed if the + object is released. + </para> + + <para> + <command>mailmime_single_fields_free()</command> frees + memory used by the structure and + substructures will <emphasis>NOT</emphasis> be + released. They should be released by + the application. + </para> + + <para> + <command>mailimf_single_fields_init()</command> will + initialize fill the data structure, using + the given argument (<command>fld_fields</command> and + <command>fld_content</command>). The interesting fields will + be filled into single_fields. + </para> + + <example> + <title>Creation and display of single fields</title> + + <programlisting role="C"> +#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"); + } +} + </programlisting> + </example> + </sect2> + + </sect1> + + <!-- Parser functions --> + <sect1> + <title>Parser functions</title> + + <!-- mailmime_content_parse --> + <sect2 id="mailmime-content-parse"> + <title>mailmime_content_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmime_content_parse(const char * message, size_t length, + size_t * index, + struct mailmime_content ** result); + </programlisting> + + <para> + This function will parse the content of a + <command>Content-Type</command> header field. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> is a string containing + the MIME content type. + </para> + </listitem> + <listitem> + <para> + <command>length</command> is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> is a pointer to the start of + the address in the given string, <command>(* + index)</command> is modified to point at the end of the + parsed data. + </para> + </listitem> + <listitem> + <para> + <command>result</command>. The result of the parse + operation is stored in <command>(* result)</command> + (see <xref linkend="mailmime-content">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>Parsing MIME content type</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_description_parse --> + <sect2 id="mailmime-description-parse"> + <title>mailmime_description_parse</title> + + <programlisting role="C"> +#include >libetpan/libetpan.h< + +int mailmime_description_parse(const char * message, size_t length, + size_t * index, + char ** result); + </programlisting> + + <para> + This will parse the content of + <command>Content-Description</command> MIME header field. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> is a string containing + the MIME content description. + </para> + </listitem> + <listitem> + <para> + <command>length</command> is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> is a pointer to the start of + the address in the given string, <command>(* + index)</command> is modified to point at the end of the + parsed data. + </para> + </listitem> + <listitem> + <para> + <command>result</command>. The result of the parse + operation is stored in <command>(* result)</command>. + The result string must be freed with + <command>free()</command>. + </para> + </listitem> + </itemizedlist> + + <example> + <title>Parsing MIME description</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + + + </sect2> + + <!-- mailmime_encoding_parse --> + <sect2 id="mailmime-encoding-parse"> + <title>mailmime_encoding_parse</title> + + <programlisting role="C"> +#include >libetpan/libetpan.h< + +int mailmime_encoding_parse(const char * message, size_t length, + size_t * index, + struct mailmime_mechanism ** result); + </programlisting> + + <para> + This function will parse the content of + <command>Content-Transfer-Encoding</command> header field. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> is a string containing + the MIME encoding mechanism. + </para> + </listitem> + <listitem> + <para> + <command>length</command> is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> is a pointer to the start of + the address in the given string, <command>(* + index)</command> is modified to point at the end of the + parsed data. + </para> + </listitem> + <listitem> + <para> + <command>result</command>. The result of the parse + operation is stored in <command>(* result)</command> + (see <xref linkend="mailmime-mechanism">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>parsing MIME encoding mechanism</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_field_parse --> + <sect2 id="mailmime-field-parse"> + <title>mailmime_field_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int +mailmime_field_parse(struct mailimf_optional_field * field, + struct mailmime_field ** result); + </programlisting> + + <para> + This function will parse a MIME header field. + </para> + + <itemizedlist> + <listitem> + <para> + <command>field</command> is a non-parsed field + (see <xref linkend="mailimf-optional-field">). + </para> + + <para> + <command>result</command>. The result of the parse + operation is stored in <command>(* result)</command> + (see <xref linkend="mailmime-field">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>parsing MIME header field</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + + </sect2> + + <!-- mailmime_id_parse --> + <sect2 id="mailmime-id-parse"> + <title>mailmime_id_parse</title> + + <programlisting role="C"> +#include >libetpan/libetpan.h< + +int mailmime_id_parse(const char * message, size_t length, + size_t * index, char ** result); + </programlisting> + + <para> + This will parse the content of + <command>Content-ID</command> MIME header field. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> is a string containing + the MIME content identifier. + </para> + </listitem> + <listitem> + <para> + <command>length</command> is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> is a pointer to the start of + the address in the given string, <command>(* + index)</command> is modified to point at the end of the + parsed data. + </para> + </listitem> + <listitem> + <para> + <command>result</command>. The result of the parse + operation is stored in <command>(* result)</command>. + The result string must be freed with + <command>free()</command>. + </para> + </listitem> + </itemizedlist> + + <example> + <title>Parsing MIME content identifier</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_fields_parse --> + <sect2 id="mailmime-fields-parse"> + <title>mailmime_fields_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int +mailmime_fields_parse(struct mailimf_fields * fields, + struct mailmime_fields ** result); + </programlisting> + + <para> + This function will parse a MIME header fields. + </para> + + <itemizedlist> + <listitem> + <para> + <command>fields</command> is a list of RFC 2822 fields + (see <xref linkend="mailimf-fields">). + </para> + + <para> + <command>result</command>. The result of the parse + operation is stored in <command>(* result)</command> + (see <xref linkend="mailmime-fields">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>parsing MIME header fields</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + + </sect2> + + <!-- mailmime_version_parse --> + <sect2 id="mailmime-version-parse"> + <title>mailmime_version_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmime_version_parse(const char * message, size_t length, + size_t * index, + uint32_t * result); + </programlisting> + + <para> + This will parse the content of + <command>MIME-Version</command> MIME header field. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> is a string containing + the MIME version. + </para> + </listitem> + <listitem> + <para> + <command>length</command> is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> is a pointer to the start of + the address in the given string, <command>(* + index)</command> is modified to point at the end of the + parsed data. + </para> + </listitem> + <listitem> + <para> + <command>result</command>. The result of the parse + operation is stored in <command>(* result)</command> + (see <xref linkend="mailmime-field">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>parsing MIME version</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_parameter_parse --> + <sect2 id="mailmime-parameter-parse"> + <title>mailmime_parameter_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmime_parameter_parse(const char * message, size_t length, + size_t * index, + struct mailmime_parameter ** result); + </programlisting> + + <para> + This will parse a MIME parameter (parameter of + <command>Content-Type</command> or parameter of + <command>Content-Disposition</command>). + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> is a string containing + the MIME parameter. + </para> + </listitem> + <listitem> + <para> + <command>length</command> is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> is a pointer to the start of + the address in the given string, <command>(* + index)</command> is modified to point at the end of the + parsed data. + </para> + </listitem> + <listitem> + <para> + <command>result</command>. The result of the parse + operation is stored in <command>(* result)</command> + (see <xref linkend="mailmime-parameter">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>parsing a MIME parameter</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_language_parse --> + <sect2 id="mailmime-language-parse"> + <title>mailmime_language_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmime_language_parse(const char * message, size_t length, + size_t * index, + struct mailmime_language ** result); + </programlisting> + + <para> + This function will parse the content of a + <command>Content-Language</command> header. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> is a string containing + the MIME content language. + </para> + </listitem> + <listitem> + <para> + <command>length</command> is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> is a pointer to the start of + the address in the given string, <command>(* + index)</command> is modified to point at the end of the + parsed data. + </para> + </listitem> + <listitem> + <para> + <command>result</command>. The result of the parse + operation is stored in <command>(* result)</command> + (see <xref linkend="mailmime-language">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>Parsing the MIME content langage</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_disposition_parse --> + <sect2 id="mailmime-disposition-parse"> + <title>mailmime_disposition_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmime_disposition_parse(const char * message, size_t length, + size_t * index, + struct mailmime_disposition ** result); + </programlisting> + + <para> + This function will parse the content of a + <command>Content-Disposition</command> MIME header field. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> is a string containing + the MIME content disposition. + </para> + </listitem> + <listitem> + <para> + <command>length</command> is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> is a pointer to the start of + the address in the given string, <command>(* + index)</command> is modified to point at the end of the + parsed data. + </para> + </listitem> + <listitem> + <para> + <command>result</command>. The result of the parse + operation is stored in <command>(* result)</command> + (see <xref linkend="mailmime-disposition">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>Parsing the MIME content disposition</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_disposition_type_parse --> + <sect2 id="mailmime-disposition-type-parse"> + <title>mailmime_disposition_type_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int +mailmime_disposition_type_parse(const char * message, size_t length, + size_t * index, + struct mailmime_disposition_type ** + result); + </programlisting> + + <para> + This function will parse the type of MIME content + disposition. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> is a string containing + the MIME content disposition type. + </para> + </listitem> + <listitem> + <para> + <command>length</command> is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> is a pointer to the start of + the address in the given string, <command>(* + index)</command> is modified to point at the end of the + parsed data. + </para> + </listitem> + <listitem> + <para> + <command>result</command>. The result of the parse + operation is stored in <command>(* result)</command> + (see <xref linkend="mailmime-disposition-type">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>parsing a MIME content disposition type</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_encoded_phrase_parse --> + <sect2 id="mailmime-encoded-phrase-parse"> + <title>mailmime_encoded_phrase_parse</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This function will decode a MIME encoded header string, + encoded with RFC 2047. + </para> + + <itemizedlist> + <listitem> + <para> + <command>default_fromcode</command> is the default + code to use for parts of string that are not marked + with charset. + </para> + </listitem> + <listitem> + <para> + <command>message</command> is the string to decode. + </para> + </listitem> + <listitem> + <para> + <command>length</command> is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> is a pointer to the start of + the address in the given string, <command>(* + index)</command> is modified to point at the end of the + parsed data. + </para> + </listitem> + <listitem> + <para> + <command>tocode</command> is the destination charset + for decoding. + </para> + </listitem> + <listitem> + <para> + <command>result</command>. The result of the parse + operation is stored in <command>(* result)</command>. + </para> + </listitem> + </itemizedlist> + + <example> + <title>decoding a MIME encoded header string</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + + </sect2> + + <!-- mailmime_parse --> + <sect2 id="mailmime-parse"> + <title>mailmime_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmime_parse(const char * message, size_t length, + size_t * index, struct mailmime ** result); + </programlisting> + + <para> + This will parse a MIME message. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> is a string containing + the MIME message. + </para> + </listitem> + <listitem> + <para> + <command>length</command> is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> is a pointer to the start of + the address in the given string, <command>(* + index)</command> is modified to point at the end of the + parsed data. + </para> + </listitem> + <listitem> + <para> + <command>result</command>. The result of the parse + operation is stored in <command>(* result)</command> + (see <xref linkend="mailmime">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>parsing a MIME message</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_base64_body_parse --> + <sect2 id="mailmime-base64-body-parse"> + <title>mailmime_base64_body_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmime_base64_body_parse(const char * message, size_t length, + size_t * index, char ** result, + size_t * result_len); + </programlisting> + + <para> + This function will parse a body part encoded using base64. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> is a string encoded using + base64. + </para> + </listitem> + <listitem> + <para> + <command>length</command> is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> is a pointer to the start of + the address in the given string, <command>(* + index)</command> is modified to point at the end of the + parsed data. + </para> + </listitem> + <listitem> + <para> + <command>result</command>. The result of the parse + operation is stored in <command>(* result)</command> + The result must be freed with + <command>mmap_string_unref()</command>. + </para> + </listitem> + </itemizedlist> + + <example> + <title>Parsing a base64 encoded part</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_quoted_printable_body_parse --> + <sect2 id="mailmime-quoted-printable-body-parse"> + <title>mailmime_quoted_printable_body_parse</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This function will parse a body part encoded using quoted + printable. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> is a string encoded using + quoted printable. + </para> + </listitem> + <listitem> + <para> + <command>length</command> is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> is a pointer to the start of + the address in the given string, <command>(* + index)</command> is modified to point at the end of the + parsed data. + </para> + </listitem> + <listitem> + <para> + <command>result</command>. The result of the parse + operation is stored in <command>(* result)</command> + The result must be freed with + <command>mmap_string_unref()</command>. + </para> + </listitem> + </itemizedlist> + + <example> + <title>Parsing a quoted printable encoded part</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_binary_body_parse --> + <sect2 id="mailmime-binary-body-parse"> + <title>mailmime_binary_body_parse</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmime_binary_body_parse(const char * message, size_t length, + size_t * index, char ** result, + size_t * result_len); + </programlisting> + + <para> + This function will parse a body part encoded using binary + (no encoding). + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> is a string encoded using + binary. + </para> + </listitem> + <listitem> + <para> + <command>length</command> is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> is a pointer to the start of + the address in the given string, <command>(* + index)</command> is modified to point at the end of the + parsed data. + </para> + </listitem> + <listitem> + <para> + <command>result</command>. The result of the parse + operation is stored in <command>(* result)</command> + The result must be freed with + <command>mmap_string_unref()</command>. + </para> + </listitem> + </itemizedlist> + + <example> + <title>Parsing a binary encoded part</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_part_parse --> + <sect2 id="mailmime-part-parse"> + <title>mailmime_part_parse</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This function will parse a body part encoded using a + given MIME encoding mechanism. + </para> + + <itemizedlist> + <listitem> + <para> + <command>message</command> is a string encoded using + binary. + </para> + </listitem> + <listitem> + <para> + <command>length</command> is the size of the given + string. + </para> + </listitem> + <listitem> + <para> + <command>index</command> is a pointer to the start of + the address in the given string, <command>(* + index)</command> is modified to point at the end of the + parsed data. + </para> + </listitem> + <listitem> + <para> + <command>encoding</command> is a MIME encoding + mechanism. The value can be + <command>MAILMIME_MECHANISM_7BIT</command>, + <command>MAILMIME_MECHANISM_8BIT</command>, + <command>MAILMIME_MECHANISM_BINARY</command>, + <command>MAILMIME_MECHANISM_QUOTED_PRINTABLE</command>, + <command>MAILMIME_MECHANISM_BASE64</command> or + <command>MAILMIME_MECHANISM_TOKEN</command> + (see <xref linkend="mailmime-mechanism">). + </para> + </listitem> + <listitem> + <para> + <command>result</command>. The result of the parse + operation is stored in <command>(* result)</command> + The result must be freed with + <command>mmap_string_unref()</command>. + </para> + </listitem> + </itemizedlist> + + <example> + <title>Parsing a MIME encoded part</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + </sect1> + + <sect1> + <title>Rendering of MIME parts</title> + + <!-- mailmime_fields_write --> + <sect2 id="mailmime-fields-write"> + <title>mailmime_fields_write, mailmime_content_write and + mailmime_content_type_write</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + <command>mailmime_fields_write</command> render the MIME + header fields. + </para> + + <para> + <command>mailmime_content_write</command> render the MIME + content type header field. + </para> + + <para> + <command>mailmime_content_write</command> render the + content of the MIME content type header field. + </para> + + <itemizedlist> + <listitem> + <para> + <command>col</command> current column is given for wrapping + purpose in <command>(* col)</command>, + the resulting columns will be returned.. + </para> + </listitem> + <listitem> + <para> + <command>f</command> is the file descriptor. It can be + stdout for example. + </para> + </listitem> + <listitem> + <para> + <command>fields</command> is the header fields + (see <xref linkend="mailmime-fields">). + </para> + </listitem> + <listitem> + <para> + <command>content</command> is the header fields + (see <xref linkend="mailmime-content">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>rendering MIME header fields</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_write --> + <sect2 id="mailmime-write"> + <title>mailmime_write</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmime_write(FILE * f, int * col, + struct mailmime * build_info); + </programlisting> + + <para> + This function will render a MIME message. + </para> + + <itemizedlist> + <listitem> + <para> + <command>col</command> current column is given for wrapping + purpose in <command>(* col)</command>, + the resulting columns will be returned.. + </para> + </listitem> + <listitem> + <para> + <command>f</command> is the file descriptor. It can be + stdout for example. + </para> + </listitem> + <listitem> + <para> + <command>build_info</command> is the MIME message to + render. + </para> + </listitem> + </itemizedlist> + + </sect2> + + <!-- mailmime_quoted_printable_write --> + <sect2 id="mailmime-quoted-printable-write"> + <title>mailmime_quoted_printable_write + and mailmime_base64_write</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + <command>mailmime_quoted_printable_write()</command> will + render a string to quoted printable. + </para> + + <para> + <command>mailmime_base64_write()</command> will + render a string to base64. + </para> + + <itemizedlist> + <listitem> + <para> + <command>col</command> current column is given for wrapping + purpose in <command>(* col)</command>, + the resulting columns will be returned.. + </para> + </listitem> + <listitem> + <para> + <command>f</command> is the file descriptor. It can be + stdout for example. + </para> + </listitem> + <listitem> + <para> + <command>text</command> is the string to render. + </para> + </listitem> + <listitem> + <para> + <command>size</command> is the size of the string to + render. + </para> + </listitem> + </itemizedlist> + + <example> + <title>render base64 or quoted printable</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_data_write --> + <sect2 id="mailmime-data-write"> + <title>mailmime_data_write</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmime_data_write(FILE * f, int * col, + struct mailmime_data * data, + int istext); + </programlisting> + + <para> + <command>mailmime_data_write</command> will + render MIME data. + </para> + + <itemizedlist> + <listitem> + <para> + <command>col</command> current column is given for wrapping + purpose in <command>(* col)</command>, + the resulting columns will be returned.. + </para> + </listitem> + <listitem> + <para> + <command>f</command> is the file descriptor. It can be + stdout for example. + </para> + </listitem> + <listitem> + <para> + <command>data</command> is the data to render + (see <xref linkend="mailmime-data">). + </para> + </listitem> + </itemizedlist> + </sect2> + </sect1> + + <!-- Creation functions --> + <sect1> + <title>Creation functions</title> + + <!-- mailmime_disposition_new_filename --> + <sect2 id="mailmime-disposition-new-filename"> + <title>mailmime_disposition_new_filename and + mailmime_disposition_new_with_data</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + These functions will create a MIME content disposition + information. + </para> + + <itemizedlist> + <listitem> + <para> + <command>type</command> a standard MIME disposition : + <command>MAILMIME_DISPOSITION_TYPE_INLINE</command> or + <command>MAILMIME_DISPOSITION_TYPE_ATTACHMENT</command>. + </para> + <para> + <command>filename</command> is the filename. + </para> + <para> + <command>creation_date</command> is the creation date. + </para> + <para> + <command>modification_date</command> is the modification + date. + </para> + <para> + <command>read_date</command> is the last read date. + </para> + <para> + <command>size</command> is the size of the file. + </para> + </listitem> + <listitem> + <para> + This will return a MIME content disposition + (see <xref linkend="mailmime-disposition">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>creating a MIME content disposition</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_fields_new_empty --> + <sect2 id="mailmime-fields-new-empty"> + <title>mailmime_fields_new_empty and mailmime_fields_add</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +struct mailmime_fields * mailmime_fields_new_empty(void); + +int mailmime_fields_add(struct mailmime_fields * fields, + struct mailmime_field * field); + </programlisting> + + <para> + <command>mailmime_fields_new_empty()</command> will + create a new empty MIME header fields list. + </para> + + <para> + <command>mailmime_fields_add()</command> will add + MIME header fields to the MIME header fields list. + </para> + + <itemizedlist> + <listitem> + <para> + <command>fields</command>. The MIME header field will + be added to this MIME header fields list + (see <xref linkend="mailmime-fields">). + </para> + </listitem> + <listitem> + <para> + <command>field</command> is the MIME header field to add + (see <xref linkend="mailmime-field">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>creating a MIME header fields list</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_fields_new_with_data --> + <sect2 id="mailmime-fields-new-with-data"> + <title>mailmime_fields_new_with_data and + mailmime_fields_new_with_version</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + <command>mailmime_fields_new_with_data()</command> will + create a MIME header fields list with all the given fields + (<command>NULL</command> can be used for the value if the + field must not be present). + <command>MIME-Version</command> header field will + <emphasis>not</emphasis> be added. + </para> + + <para> + <command>mailmime_fields_new_with_version()</command> will + create a MIME header fields list with all the given fields + (<command>NULL</command> can be used for the value if the + field must not be present). + <command>MIME-Version</command> header field will be added. + </para> + + <example> + <title>creating new fields</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_get_content_message --> + <sect2 id="mailmime-get-content-message"> + <title>mailmime_get_content_message</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + <command>mailmime_get_content_message()</command> will + create a MIME content type + <command>message/rfc822</command>. + </para> + + <para> + <command>mailmime_get_content_text()</command> will + create a MIME content type + <command>plain/text</command>. + </para> + + <para> + <command>mailmime_get_content_new_with_str()</command> will + create a MIME content type given by the string + <command>plain/text</command>. + </para> + + <para> + <command>str</command>. This string will + <command>NOT</command> be referenced by any structure. + This string will only be parsed to create the structure. + </para> + + <example> + <title>Creating a MIME content type</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_data_new_data --> + <sect2 id="mailmime-data-new-data"> + <title>mailmime_data_new_data and mailmime_data_new_file</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + <command>mailmime_data_new_data()</command> will create a + new MIME content, using a string in memory. + </para> + + <para> + <command>mailmime_data_new_file()</command> will create a + new MIME content, using a file. + </para> + + <itemizedlist> + <listitem> + <para> + <command>encoding</command> is the MIME encoding + mechanism used to encode this part. The value can be + <command>MAILMIME_MECHANISM_7BIT</command>, + <command>MAILMIME_MECHANISM_8BIT</command>, + <command>MAILMIME_MECHANISM_BINARY</command>, + <command>MAILMIME_MECHANISM_QUOTED_PRINTABLE</command> or + <command>MAILMIME_MECHANISM_BASE64</command> + (see <xref linkend="mailmime-mechanism">). + </para> + </listitem> + <listitem> + <para> + <command>encoded</command> is set to 1 if the part is + already encoded with the mechanism given in + <command>encoding</command>. + </para> + </listitem> + <listitem> + <para> + <command>data</command> is a pointer to the + content of the part. + </para> + </listitem> + <listitem> + <para> + <command>length</command> is the length of the data. + </para> + </listitem> + <listitem> + <para> + <command>filename</command> is the name of the file. + </para> + </listitem> + </itemizedlist> + + <example> + <title>creating MIME content</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_new_message_data --> + <sect2 id="mailmime-new-message-data"> + <title>mailmime_new_message_data, mailmime_new_empty and + mailmime_new_with_content</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + <command>mailmime_new_message_data()</command> will create a + new MIME message with the given subpart. + </para> + + <para> + <command>mailmime_new_empty()</command> will create a + new MIME part with the given content type and MIME fields + but with no content. + </para> + + <para> + <command>mailmime_new_with_content()</command> will create a + new MIME part with a content type given by a string and a + given MIME fields list. + </para> + + <para> + <command>mailmime_multiple_new()</command> will create a + new MIME multipart with a content type given by a string. + </para> + + <itemizedlist> + <listitem> + <para> + <command>msg_mime</command> is the sub part to add to the + MIME message when creating it + (see <xref linkend="mailmime">). + </para> + </listitem> + <listitem> + <para> + <command>content</command> is the content type of the part + to create + (see <xref linkend="mailmime-content">). + </para> + </listitem> + <listitem> + <para> + <command>content_type</command> is the content type of + the part to create given by a string. + </para> + </listitem> + <listitem> + <para> + <command>mime_fields</command> is the list of MIME + header fields + (see <xref linkend="mailmime-fields">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>creating a MIME part</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_set_preamble_file --> + <sect2 id="mailmime-set-preamble-file"> + <title>mailmime_set_preamble_file, mailmime_set_epilogue_file, + mailmime_set_preamble_text and mailmime_set_epilogue_text</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + <command>mailmime_set_preamble_file()</command> will define + the preamble of a multipart. + </para> + + <para> + <command>mailmime_set_preamble_text()</command> will define + the preamble of a multipart. + </para> + + <para> + <command>mailmime_set_epilogue_file()</command> will define + the epilogue of a multipart. + </para> + + <para> + <command>mailmime_set_preamble_text()</command> will define + the preamble of a multipart. + </para> + + <itemizedlist> + <listitem> + <para> + <command>build_info</command> is the MIME part to modify + (see <xref linkend="mailmime">). + </para> + </listitem> + <listitem> + <para> + <command>data_str</command> is the string to define + as epilogue or prologue. + </para> + </listitem> + <listitem> + <para> + <command>length</command> is the length of the string to + define as epilogue or prologue. + </para> + </listitem> + <listitem> + <para> + <command>filename</command> is the name of the file + which content will be defined as epilogue or prologue. + </para> + </listitem> + </itemizedlist> + + <example> + <title>setting preamble and epilogue</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_set_body_file --> + <sect2 id="mailmime-set-body-file"> + <title>mailmime_set_body_file and mailmime_set_body_text</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + <command>mailmime_set_body_file()</command> will define + the body of a single part. + </para> + + <para> + <command>mailmime_set_body_text()</command> will define + the body of a single part. + </para> + + <itemizedlist> + <listitem> + <para> + <command>build_info</command> is the MIME part to modify + (see <xref linkend="mailmime">). + </para> + </listitem> + <listitem> + <para> + <command>data_str</command> is the string to define + as the body of the part. + </para> + </listitem> + <listitem> + <para> + <command>length</command> is the length of the string to + define as the body of the part. + </para> + </listitem> + <listitem> + <para> + <command>filename</command> is the name of the file + which content will be defined as the body of the part. + </para> + </listitem> + </itemizedlist> + + <example> + <title>creating a MIME part</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + + </sect2> + + <!-- mailmime_add_part --> + <sect2 id="mailmime-add-part"> + <title>mailmime_add_part, mailmime_remove_part, + mailmime_smart_add_part and mailmime_smart_remove_part</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + <command>mailmime_add_part()</command> will add a sub MIME + part. + </para> + + <para> + <command>mailmime_remove_part()</command> will detach the + given sub part from its parent. + </para> + + <para> + <command>mailmime_smart_add_part()</command> 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. + </para> + + <para> + <command>mailmime_smart_remove_part()</command> will detach + the given sub part from its parent. The sub part will be + freed. + </para> + + <itemizedlist> + <listitem> + <para> + <command>build_info</command> is the parent MIME part + (see <xref linkend="mailmime">). + </para> + </listitem> + <listitem> + <para> + <command>part</command> is the part to add + (see <xref linkend="mailmime">). + </para> + </listitem> + <listitem> + <para> + <command>mime</command> is the parent MIME part + (see <xref linkend="mailmime">). + </para> + </listitem> + <listitem> + <para> + <command>mime_sub</command> is the part to add or to + detach + (see <xref linkend="mailmime">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>modifying MIME structure</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_set_imf_fields --> + <sect2 id="mailmime-set-imf-fields"> + <title>mailmime_set_imf_fields</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +void mailmime_set_imf_fields(struct mailmime * build_info, + struct mailimf_fields * fields); + </programlisting> + + <para> + <command>mailmime_set_imf_fields()</command> will set the + fields of the given MIME message. + </para> + + <itemizedlist> + <listitem> + <para> + <command>build_info</command> is the MIME message to + modify + (see <xref linkend="mailmime">). + </para> + </listitem> + <listitem> + <para> + <command>fields</command> is the header fields to set + for the message + (see <xref linkend="mailimf-fields">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>modifying MIME structure</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + + <!-- mailmime_fields_new_encoding --> + <sect2 id="mailmime-fields-new-encoding"> + <title>mailmime_fields_new_encoding and + mailmime_fields_new_filename</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + <command>mailmime_fields_new_encoding()</command> will + create a list of MIME header fields with only + <command>Content-Transfer-Encoding</command>. + </para> + + <para> + <command>mailmime_fields_new_filename()</command> will + create a list of MIME header fields with + <command>Content-Transfer-Encoding</command> and + <command>Content-Disposition</command>. + </para> + + <para> + The result will be a list of MIME header fields + (see <xref linkend="mailmime-fields">). + </para> + + <itemizedlist> + <listitem> + <para> + <command>encoding_type</command> is the MIME encoding + mechanism. The value can be + <command>MAILMIME_MECHANISM_7BIT</command>, + <command>MAILMIME_MECHANISM_8BIT</command>, + <command>MAILMIME_MECHANISM_BINARY</command>, + <command>MAILMIME_MECHANISM_QUOTED_PRINTABLE</command> or + <command>MAILMIME_MECHANISM_BASE64</command> + (see <xref linkend="mailmime-mechanism">). + </para> + </listitem> + <listitem> + <para> + <command>dsp_type</command> is the disposition type. + The value can be + <command>MAILMIME_DISPOSITION_TYPE_INLINE</command> or + <command>MAILMIME_DISPOSITION_TYPE_ATTACHMENT</command> + (see <xref linkend="mailmime-disposition-type">). + </para> + </listitem> + <listitem> + <para> + <command>filename</command> is the filename for MIME + content disposition. + </para> + </listitem> + </itemizedlist> + + <example> + <title>creating MIME fields with only Content-Transfer-Encoding</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + </sect1> + + <!-- Helper functions --> + <sect1> + <title>Helper functions</title> + + <!-- mailmime_transfer_encoding_get --> + <sect2 id="mailmime-transfer-encoding-get"> + <title>mailmime_transfer_encoding_get</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmime_transfer_encoding_get(struct mailmime_fields * fields); + </programlisting> + + <para> + <command>mailmime_transfer_encoding_get()</command> will + return the standard MIME encoding mechanism. + </para> + + <itemizedlist> + <listitem> + <para> + <command>fields</command> is the list of MIME header + fields. + </para> + </listitem> + <listitem> + <para> + An integer representing the MIME encoding mechanism will + be returned + (see <xref linkend="mailmime-mechanism">). + </para> + </listitem> + </itemizedlist> + + <example> + <title>extracting MIME encoding mechanism</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + + </sect2> + + <!-- mailmime_content_charset_get --> + <sect2 id="mailmime-content-charset-get"> + <title>mailmime_content_charset_get and + mailmime_content_param_get</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + <command>mailmime_content_charset_get()</command> will + return the <command>charset</command> parameter of + MIME content type. + </para> + + <para> + <command>mailmime_content_param_get()</command> will + return the value of a given parameter of + MIME content type. + </para> + + <para> + <command>mailmime_extract_boundary()</command> will + return the <command>charset</command> parameter of + MIME content type. + </para> + + <itemizedlist> + <listitem> + <para> + <command>content</command> is the MIME content type. + </para> + </listitem> + <listitem> + <para> + <command>name</command> is the name of the parameter to + extract. + </para> + </listitem> + <listitem> + <para> + With <command>mailmime_extract_boundary()</command>, the + returned value must be freed with + <command>free()</command>. + </para> + </listitem> + </itemizedlist> + + <example> + <title>extracting information from MIME content type</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + </sect1> + </chapter> + + <!-- Storages, folders, messages --> + <chapter> + <title>Storages, folders, messages</title> + + <!-- Introduction --> + <sect1> + <title>Introduction</title> + + <para> + This part will give the definition of some objects. + </para> + + <sect2> + <title>Message</title> + + <para> + A message is the common e-mail message or news message you + read or send. + </para> + </sect2> + + <sect2> + <title>MIME part</title> + + <para> + 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. + </para> + </sect2> + + <sect2> + <title>Mailbox</title> + + <para> + A mailbox will contain a given number of messages. + </para> + </sect2> + + <sect2> + <title>Storage</title> + + <para> + 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). + </para> + </sect2> + + <sect2> + <title>Folder</title> + + <para> + 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. + </para> + </sect2> + + <sect2> + <title>Session</title> + + <para> + The session is the network connection or the entity to which + the commands of the drivers are given. + </para> + </sect2> + </sect1> + + <sect1> + <title>Error codes</title> + + <para> + Error codes returned as integers can be one of the following : + </para> + + <programlisting role="C"> +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, +}; + </programlisting> + </sect1> + + <!-- Storage --> + <sect1> + <title>Storage</title> + + <sect2 id="mailstorage-driver"> + <title>Storage driver</title> + + <programlisting role="C"> +#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); +}; + </programlisting> + + <para> + This is the driver for a storage. + </para> + + <itemizedlist> + <listitem> + <para> + <command>sto_name</command> is the name of the driver. + </para> + </listitem> + <listitem> + <para> + <command>sto_connect()</command> connects the storage to + the remote access or to the path in the local filesystem. + </para> + </listitem> + <listitem> + <para> + <command>sto_get_folder_session()</command> 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. + </para> + <para> + <emphasis>XXX - in the future, this will be moved to the + folder driver</emphasis> + </para> + </listitem> + <listitem> + <para> + <command>sto_uninitialize()</command> frees the data + created with mailstorage constructor. + </para> + </listitem> + </itemizedlist> + </sect2> + + <sect2 id="mailstorage"> + <title>Storage</title> + + <programlisting role="C"> +#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; +}; + </programlisting> + + <itemizedlist> + <listitem> + <para> + <command>sto_id</command> is an identifier for the + storage. This can be <command>NULL</command>. + </para> + </listitem> + <listitem> + <para> + <command>sto_data</command> is the internal data + of the storage. This can only be changed by the driver. + </para> + </listitem> + <listitem> + <para> + <command>sto_session</command> is the session used by + the storage. The session can be used to send commands. + </para> + </listitem> + <listitem> + <para> + <command>sto_driver</command> is the driver of the + storage. + </para> + </listitem> + <listitem> + <para> + <command>sto_shared_folders</command> is the list of + folders that share the session with the storage. + This is used internally. + </para> + </listitem> + <listitem> + <para> + <command>sto_user_data</command> is a field for free + use. The user can store any data in that field. + </para> + </listitem> + </itemizedlist> + </sect2> + + <sect2 id="mailstorage-new"> + <title>mailstorage_new and mailstorage_free</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +struct mailstorage * mailstorage_new(char * sto_id); + +void mailstorage_free(struct mailstorage * storage); + </programlisting> + + <para> + <command>mailstorage_new()</command> initializes a storage + structure with an identifier (<command>sto_id</command>) and + with no driver. + </para> + + <para> + <command>mailstorage_free()</command> free the memory used + by a storage. + </para> + </sect2> + + <sect2 id="mailstorage-connect"> + <title>mailstorage_connect and mailstorage_disconnect</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailstorage_connect(struct mailstorage * storage); + +void mailstorage_disconnect(struct mailstorage * storage); + </programlisting> + + <para> + <command>mailstorage_connect()</command> connects the storage. + This function can also be used to confirm that a storage + connection is valid when the storage is already connected. + </para> + + <para> + <command>mailstorage_disconnect()</command> disconnects the + storage. + </para> + </sect2> + + <sect2> + <title>IMAP storage</title> + + <programlisting role="C"> +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); + </programlisting> + </sect2> + + <sect2> + <title>Example</title> + + <example> + <title>use of storage</title> + + <programlisting role="C"> +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); +} + </programlisting> + </example> + </sect2> + </sect1> + + <!-- Folder --> + <sect1> + <title>Folder</title> + + <sect2 id="mailfolder-driver"> + <title>Folder driver</title> + + <programlisting role="C"> +#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); +} + </programlisting> + + <para> + XXX - this will be implemented in the future. + </para> + + <itemizedlist> + <listitem> + <para> + <command>fld_get_session()</command> will return the session + this folder should use. + </para> + </listitem> + <listitem> + <para> + For other method, you should see <xref + linkend="mailsession-driver">. + </para> + </listitem> + </itemizedlist> + </sect2> + + <sect2> + <title>Folder</title> + + <programlisting role="C"> +#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; +}; + </programlisting> + + <itemizedlist> + <listitem> + <para> + <command>fld_pathname</command> is the pathname specific to + the driver. + </para> + </listitem> + + <listitem> + <para> + <command>fld_virtual_name</command> is the identifier of + this folder. This can be <command>NULL</command>. + </para> + </listitem> + + <listitem> + <para> + <command>fld_storage</command> is the storage used for this + folder (see <xref linkend="mailstorage">). + </para> + </listitem> + + <listitem> + <para> + <command>fld_session</command> is the session used for this + folder. + </para> + </listitem> + + <listitem> + <para> + <command>fld_shared_session</command> is set to 1 if the + folder use the same session as the storage. This is used + internally. + </para> + </listitem> + + <listitem> + <para> + <command>fld_pos</command> is the + position in the list of folders of the storage. + This is used internally. + </para> + </listitem> + + <listitem> + <para> + use of <command>fld_parent</command>, + <command>fld_sibling_index</command> and + <command>fld_children</command> is deprecated. + </para> + </listitem> + + <listitem> + <para> + <command>fld_user_data</command> is a field for free + use. The user can store any data in that field. + </para> + </listitem> + </itemizedlist> + </sect2> + + <sect2 id="mailfolder-new"> + <title>mailfolder_new and mail_folder_free</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + <command>mailfolder_new()</command> initializes a folder + structure with an identifier + (<command>fld_virtual_name</command>) with path name + (<command>fld_pathname</command>). The folder will be owned + by the given storage (<command>fld_storage</command>). + </para> + + <para> + <command>mailfolder_free()</command> free the memory used + by the folder. + </para> + </sect2> + + <sect2 id="mailfolder-connect"> + <title>mailfolder_connect and mailfolder_disconnect</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailfolder_connect(struct mailfolder * folder); + +void mailfolder_disconnect(struct mailfolder * folder); + </programlisting> + + <para> + <command>mailfolder_connect()</command> 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. + </para> + + <para> + <command>mailfolder_disconnect()</command> disconnects the + folder. + </para> + </sect2> + + <sect2 id="mailfolder-noop"> + <title>mailfolder_noop</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailfolder_noop(struct mailfolder * folder); + </programlisting> + + <para> + This function will only send noop to the mail access. + </para> + </sect2> + + <sect2 id="mailfolder-check"> + <title>mailfolder_check</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailfolder_check(struct mailfolder * folder); + </programlisting> + + <para> + A call to this function will save to disk the internal state + of the selected mailbox (such as flags). + </para> + </sect2> + + <sect2 id="mailfolder-expunge"> + <title>mailfolder_expunge</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailfolder_expunge(struct mailfolder * folder); + </programlisting> + + <para> + A call to this function will delete all messages marked for + deletion. + </para> + </sect2> + + <sect2 id="mailfolder-status"> + <title>mailfolder_status</title> + + <programlisting role="C"> +int mailfolder_status(struct mailfolder * folder, + uint32_t * result_messages, uint32_t * result_recent, + uint32_t * result_unseen); + </programlisting> + + <para> + A call to this function will return some counts of messages + in the mailbox. + </para> + </sect2> + + <sect2 id="mailfolder-append-message"> + <title>mailfolder_append_message</title> + + <programlisting role="C"> +int mailfolder_append_message(struct mailfolder * folder, + char * message, size_t size); + </programlisting> + + <para> + This function will store a new message in the given folder. + The message is given by a string in memory + (<command>message</command>) and a size + (<command>size</command>). + </para> + </sect2> + + <sect2 id="mailfolder-get-messages-list"> + <title>mailfolder_get_messages_list</title> + + <programlisting role="C"> +int mailfolder_get_messages_list(struct mailfolder * folder, + struct mailmessage_list ** result); + </programlisting> + + <para> + This function will return the list of messages in the given + folder (see <xref linkend="mailmessage-list">). + </para> + </sect2> + + <sect2 id="mailfolder-get-envelopes-list"> + <title>mailfolder_get_envelopes_list</title> + + <programlisting role="C"> +int mailfolder_get_envelopes_list(struct mailfolder * folder, + struct mailmessage_list * result); + </programlisting> + + <para> + This function will fill the list of parsed header fields + structure in the <command>mailmessage</command> structures + of the given list of messages (<command>result</command>). + </para> + </sect2> + + <sect2 id="mailfolder-get-message"> + <title>mailfolder_get_message</title> + + <programlisting role="C"> +int mailfolder_get_message(struct mailfolder * folder, + uint32_t num, mailmessage ** result); + </programlisting> + + <para> + This function will return the message identified by a + message index (<command>num</command>) + This will return a <command>mailmessage</command> structure + in <command>(* result)</command> (see <xref + linkend="mailmessage">). + </para> + </sect2> + + <sect2 id="mailfolder-get-message-by-uid"> + <title>mailfolder_get_message_by_uid</title> + + <programlisting role="C"> +int mailfolder_get_message_by_uid(struct mailfolder * folder, + const char * uid, mailmessage ** result); + </programlisting> + + <para> + This function will return the message identified by a + unique identifier (<command>uid</command>) + This will return a <command>mailmessage</command> structure + in <command>(* result)</command> (see <xref + linkend="mailmessage">). + </para> + </sect2> + + <sect2> + <title>Example</title> + + <example> + <title>use of folder</title> + + <programlisting role="C"> +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); +} + </programlisting> + </example> + </sect2> + + </sect1> + + <!-- Message --> + <sect1> + <title>Message</title> + + <sect2 id="mailmessage-driver"> + <title>Message driver</title> + + <programlisting role="C"> +#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); +}; + </programlisting> + + <itemizedlist> + <listitem> + <para> + <command>msg_name</command> is the name of the driver. + </para> + </listitem> + + <listitem> + <para> + <command>msg_initialize()</command> will initialize the + internal message state (field + <command>msg_data</command> of + <command>mailmessage</command> structure (see <xref + linkend="mailmessage">). + </para> + </listitem> + + <listitem> + <para> + <command>msg_uninitialize()</command> will free the + internal message state. + </para> + </listitem> + + <listitem> + <para> + <command>msg_flush()</command> will release memory used + by the MIME structure of the message. + </para> + </listitem> + + <listitem> + <para> + <command>msg_check()</command> will store the flags of + the message into the session, so that the message can be + released without the flags are lost. + </para> + </listitem> + + <listitem> + <para> + <command>msg_fetch_result_free()</command> will free a + string returned by any fetch_XXX() function. + </para> + </listitem> + + <listitem> + <para> + <command>msg_fetch()</command> will fetch a message. + </para> + </listitem> + + <listitem> + <para> + <command>msg_fetch_header()</command> will fetch the + header fields of a message. + </para> + </listitem> + + <listitem> + <para> + <command>msg_fetch_body()</command> will fetch a message + without its main header. + </para> + </listitem> + + <listitem> + <para> + <command>msg_fetch_size()</command> will return the size + of a message. + </para> + </listitem> + + <listitem> + <para> + <command>msg_get_bodystructure</command> will retrieve + the MIME structure of the message. The returned + structure must <emphasis>NOT</emphasis> be freed. + </para> + </listitem> + + <listitem> + <para> + <command>msg_fetch_section()</command> will fetch the + content of the section of the message. + </para> + </listitem> + + <listitem> + <para> + <command>msg_fetch_section_header()</command> will fetch + the header of a section of the message if the content of + the section is a message. + </para> + </listitem> + + <listitem> + <para> + <command>msg_fetch_section_mime()</command> will fetch + the MIME header of a section of the message. + </para> + </listitem> + + <listitem> + <para> + <command>msg_fetch_section_body()</command> will fetch + the body of a section (without the headers) of the + message if the content of the section is a message. + </para> + </listitem> + + <listitem> + <para> + <command>msg_fetch_envelope()</command> will return + a given number of parsed header fields. + </para> + </listitem> + + <listitem> + <para> + <command>msg_get_flags()</command> will return the + flags of the message. + The returned structure must <emphasis>NOT</emphasis> be + freed. + </para> + </listitem> + </itemizedlist> + </sect2> + + <sect2 id="mailmessage"> + <title>Message</title> + + <programlisting role="C"> +#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; +}; + </programlisting> + + <itemizedlist> + <listitem> + <para> + <command>msg_session</command> is the session related to + the message + (see <xref linkend="mailsession">). + </para> + </listitem> + + <listitem> + <para> + <command>msg_driver</command> is the driver used for the + message + (see <xref linkend="mailmessage-driver">). + </para> + </listitem> + + <listitem> + <para> + <command>msg_index</command> is an index to indentify + the message. + </para> + </listitem> + + <listitem> + <para> + <command>msg_uid</command> is the unique identifier of + the message, valid accross disconnections. + </para> + </listitem> + + <listitem> + <para> + <command>msg_size</command> is the size of the message. + </para> + </listitem> + + <listitem> + <para> + <command>msg_fields</command> is the list of parsed + header fields of the message. This can be + <command>NULL</command> + (see <xref linkend="mailimf-fields">). + </para> + </listitem> + + <listitem> + <para> + <command>msg_flags</command> is the flags of the + message. This can be <command>NULL</command> + (see <xref linkend="mail-flags">). + </para> + </listitem> + + <listitem> + <para> + <command>msg_resolved</command> will tell if the field + <command>msg_single_fields</command> has been initialized. + </para> + </listitem> + + <listitem> + <para> + <command>msg_single_fields</command> will be filled + using <command>msg_fields</command> + (see <xref linkend="mailimf-single-fields">). + </para> + </listitem> + + <listitem> + <para> + <command>msg_mime</command> is the MIME structure of the + message. It is intialized at least when + <command>get_bodystructure()</command> is called once. + </para> + </listitem> + + <listitem> + <para> + <command>msg_cached</command> is 1 when the message was + cached. This is used internally. + </para> + </listitem> + + <listitem> + <para> + <command>msg_data</command> is the internal state of the + message. The content depends on the driver. + </para> + </listitem> + + <listitem> + <para> + <command>msg_folder</command> is used to reference the + mailfolder, this is a workaround due to the problem with + initial conception, where folder notion did not exist. + </para> + </listitem> + + <listitem> + <para> + <command>msg_user_data</command> is a field for free + use. The user can store any data in that field. + </para> + </listitem> + </itemizedlist> + </sect2> + + <sect2 id="mailmessage-new"> + <title>mailmessage_new</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +mailmessage * mailmessage_new(void); + +void mailmessage_free(mailmessage * info); + </programlisting> + + <para> + <command>mailmessage_new()</command> will create a new + message (without driver). This is used internally by + drivers. + </para> + + <para> + <command>mailmessage_free()</command> will free the memory + used by the given message. + </para> + </sect2> + + <sect2 id="mailmessage-init"> + <title>mailmessage_init</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmessage_init(mailmessage * msg_info, + mailsession * session, + mailmessage_driver * driver, + uint32_t index, size_t size); + </programlisting> + + <para> + <command>mailmessage_init()</command> will initialize a + message with a driver. + </para> + + <itemizedlist> + <listitem> + <para> + <command>msg_info</command> is the message to initialize + (see <xref linkend="mailmessage">). + </para> + </listitem> + + <listitem> + <para> + <command>session</command> is the session related to the + message + (see <xref linkend="mailsession">). + </para> + </listitem> + + <listitem> + <para> + <command>driver</command> is the driver to use for the + message + (see <xref linkend="mailmessage-driver">). + </para> + </listitem> + + <listitem> + <para> + <command>index</command> is the index of the message. + </para> + </listitem> + + <listitem> + <para> + <command>size</command> is the size of the message. + </para> + </listitem> + </itemizedlist> + </sect2> + + <sect2 id="mailmessage-flush"> + <title>mailmessage_flush</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmessage_flush(mailmessage * info); + </programlisting> + + <para> + This function will release the memory used by the MIME + structure of the message. + </para> + </sect2> + + <sect2 id="mailmessage-check"> + <title>mailmessage_check</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmessage_check(mailmessage * info); + </programlisting> + + <para> + After you set some flags, if you want to notify them to the + session before destroying the message, you can use this function. + </para> + </sect2> + + <sect2 id="mailmessage-fetch-result-free"> + <title>mailmessage_fetch_result_free</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmessage_fetch_result_free(mailmessage * msg_info, + char * msg); + </programlisting> + + <para> + This function will free a string returned by any + mailmessage_fetch_XXX() function. + </para> + </sect2> + + <sect2 id="mailmessage-fetch"> + <title>mailmessage_fetch</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmessage_fetch(mailmessage * msg_info, + char ** result, + size_t * result_len); + </programlisting> + + <para> + This function returns the content of the message (headers + and text). + </para> + </sect2> + + <sect2 id="mailmessage-fetch-header"> + <title>mailmessage_fetch_header</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmessage_fetch_header(mailmessage * msg_info, + char ** result, + size_t * result_len); + </programlisting> + + <para> + This function returns the header of the message as a string. + </para> + + </sect2> + + <sect2 id="mailmessage-fetch-body"> + <title>mailmessage_fetch_body</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmessage_fetch_body(mailmessage * msg_info, + char ** result, size_t * result_len); + </programlisting> + + <para> + This function returns the content of the message (without + headers). + </para> + </sect2> + + <sect2 id="mailmessage-fetch-size"> + <title>mailmessage_fetch_size</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmessage_fetch_size(mailmessage * msg_info, + size_t * result); + </programlisting> + + <para> + This function returns the size of the message content. + </para> + </sect2> + + <sect2 id="mailmessage-get-bodystructure"> + <title>mailmessage_get_bodystructure</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmessage_get_bodystructure(mailmessage * msg_info, + struct mailmime ** result); + </programlisting> + + <para> + This functions returns the MIME structure of the message. + The returned information <emphasis>MUST</emphasis> not be + freed by hand. It is freed by + <command>mailmessage_flush()</command> or + <command>mailmessage_free()</command> + (see <xref linkend="mailmime">). + </para> + </sect2> + + <sect2 id="mailmessage-fetch-section"> + <title>mailmessage_fetch_section</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmessage_fetch_section(mailmessage * msg_info, + struct mailmime * mime, + char ** result, size_t * result_len); + </programlisting> + + <para> + This function returns the content of a MIME part. + </para> + </sect2> + + <sect2 id="mailmessage-fetch-section-header"> + <title>mailmessage_fetch_section_header</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmessage_fetch_section_header(mailmessage * msg_info, + struct mailmime * mime, + char ** result, + size_t * result_len); + </programlisting> + + <para> + This function returns the header of the message contained + in the given MIME part. + </para> + </sect2> + + <sect2 id="mailmessage-fetch-section-mime"> + <title>mailmessage_fetch_section_mime</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmessage_fetch_section_mime(mailmessage * msg_info, + struct mailmime * mime, + char ** result, + size_t * result_len); + </programlisting> + + <para> + This function returns the MIME header of the given MIME + part. + </para> + </sect2> + + <sect2 id="mailmessage-fetch-section-body"> + <title>mailmessage_fetch_section_body</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmessage_fetch_section_body(mailmessage * msg_info, + struct mailmime * mime, + char ** result, + size_t * result_len); + </programlisting> + + <para> + This function returns the text part of the message contained + in the given MIME part. + </para> + </sect2> + + <sect2 id="mailmessage-fetch-envelope"> + <title>mailmessage_fetch_envelope</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmessage_fetch_envelope(mailmessage * msg_info, + struct mailimf_fields ** result); + </programlisting> + </sect2> + + <sect2 id="mailmessage-get-flags"> + <title>mailmessage_get_flags</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +int mailmessage_get_flags(mailmessage * msg_info, + struct mail_flags ** result); + </programlisting> + + <para> + This function returns the flags related to the message. + The returned information MUST not be freed by hand. It is freed by + <command>mailmessage_free()</command>. + </para> + </sect2> + + <sect2 id="mailmessage-resolve-single-fields"> + <title>mailmessage_resolve_single_fields</title> + + <programlisting role="C"> +#include <libetpan/libetpan.h> + +void mailmessage_resolve_single_fields(mailmessage * msg_info); + </programlisting> + + <para> + This function will use the fields information to fill + the single_fields structure in the mailmessage structure. + </para> + </sect2> + + <sect2 id="mailmessage-list"> + <title>Message list</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is a list of messages. + </para> + + <para> + <command>msg_tab</command> is an array containing the + messages (see linkend="carray"). + </para> + + <para> + <command>mailmessage_list_new()</command> will initialize a + list of messages, using a given array of messages. + </para> + + <para> + <command>mailmessage_list_free()</command> will free the + memory used by the list of messages. This will also free the + messages. + </para> + </sect2> + + <sect2 id="mailmessage-tree"> + <title>Message tree</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is a node of a tree of messages. + </para> + + <itemizedlist> + <listitem> + <para> + <command>node_parent</command> is the parent of this + node. + </para> + </listitem> + + <listitem> + <para> + <command>node_msgid</command> is the content of the + field <command>Message-ID</command> of the message. + </para> + </listitem> + + <listitem> + <para> + <command>node_date</command> is the date in UNIX + format. + </para> + </listitem> + + <listitem> + <para> + <command>node_msg</command> is the message of the node. + The message should have the <command>msg_fields</command> + field initialized. + </para> + </listitem> + + <listitem> + <para> + <command>node_children</command> is the list of + children of this node. + </para> + </listitem> + + <listitem> + <para> + <command>node_is_reply</command> is set to 1 if the + message is a reply. + </para> + </listitem> + + <listitem> + <para> + <command>node_base_subject</command> is the base subject + of the message (base subject is defined in definition of + IMAP thread draft). + </para> + </listitem> + </itemizedlist> + + <para> + <command>mailmessage_tree_new()</command> will initialize a + message node. + </para> + + <para> + <command>mailmessage_tree_free()</command> will release + memory used by the node. This will <emphasis>NOT</emphasis> + free the message. + </para> + </sect2> + + <sect2 id="mail-flags"> + <title>Message flags</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is the structure containing the message flags. + </para> + + <itemizedlist> + <listitem> + <para> + <command>fl_flags</command> will contain the standards + flags. The value will be a combinaison (with or binary + operation) of <command>MAIL_FLAG_XXX</command> values. + </para> + </listitem> + <listitem> + <para> + <command>fl_extension</command> will be a list (see + <xref linkend="clist">) of strings representing the + non-standard flags. + </para> + </listitem> + </itemizedlist> + </sect2> + + <sect2> + <title>Example</title> + + <example> + <title>use of message</title> + + <programlisting role="C"> +#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); +} + </programlisting> + </example> + </sect2> + </sect1> + + <!-- Session --> + <sect1> + <title>Session</title> + + <sect2 id="mailsession-driver"> + <title>Session driver</title> + + <programlisting role="C"> +#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); +}; + </programlisting> + + <para> + This is a driver for a session. + </para> + + <itemizedlist> + <listitem> + <para> + <command>sess_name</command> is the name of the driver. + </para> + </listitem> + + <listitem> + <para> + <command>sess_initialize()</command> is the function + that will initializes a data structure (field + <command>sess_data</command> in the session) specific to + the driver. + The field data (field <command>sess_data</command> in + the session) is the state of the session, + the internal data structure used by the driver. + It is called when creating the + <command>mailsession</command> structure with + <command>mailsession_new()</command>. + </para> + </listitem> + + <listitem> + <para> + <command>sess_uninitialize()</command> frees the structure + created with <command>sess_initialize()</command> + </para> + </listitem> + + <listitem> + <para> + <command>sess_parameters()</command> implements + functions specific to the given mail access. + </para> + </listitem> + + <listitem> + <para> + <command>sess_connect_stream()</command> connects a + stream to the session. + </para> + </listitem> + + <listitem> + <para> + <command>sess_connect_path()</command> notify a main + path to the session. + </para> + </listitem> + + <listitem> + <para> + <command>sess_starttls()</command> changes the current + stream to a TLS stream + (see <xref linkend="mailstream-ssl">). + </para> + </listitem> + + <listitem> + <para> + <command>sess_login()</command> notifies the user and + the password to authenticate to the session. + </para> + </listitem> + + <listitem> + <para> + <command>sess_logout()</command> exits the session and + closes the stream. + </para> + </listitem> + + <listitem> + <para> + <command>sess_noop()</command> does no operation on the + session, but it can be used to poll for the status of + the connection. + </para> + </listitem> + + <listitem> + <para> + <command>sess_build_folder_name()</command> will return an + allocated string with that contains the complete path of + the folder to create. + <emphasis>Use of this method is deprecated</emphasis>. + </para> + </listitem> + + <listitem> + <para> + <command>sess_create_folder()</command> creates the + folder that corresponds to the given name. + <emphasis>Use of this method is deprecated</emphasis>. + </para> + </listitem> + + <listitem> + <para> + <command>sess_delete_folder()</command> deletes the folder + that corresponds to the given name. + <emphasis>Use of this method is deprecated</emphasis>. + </para> + </listitem> + + <listitem> + <para> + <command>sess_rename_folder()</command> change the name + of the folder. + <emphasis>Use of this method is deprecated</emphasis>. + </para> + </listitem> + + <listitem> + <para> + <command>sess_check_folder()</command> makes a + checkpoint of the session. + </para> + </listitem> + + <listitem> + <para> + <command>sess_examine_folder()</command> selects a mailbox as + readonly. + <emphasis>Use of this method is deprecated</emphasis>. + </para> + </listitem> + + <listitem> + <para> + <command>sess_select_folder()</command> selects a mailbox. + </para> + </listitem> + + <listitem> + <para> + <command>sess_expunge_folder()</command> deletes all + messages marked \Deleted. + </para> + </listitem> + + <listitem> + <para> + <command>sess_status_folder()</command> queries the + status of the folder (number of messages, number of + recent messages, number of unseen messages). + </para> + </listitem> + + <listitem> + <para> + <command>sess_messages_number()</command> queries the + number of messages in the folder. + </para> + </listitem> + + <listitem> + <para> + <command>sess_recent_number()</command> queries the + number of recent messages in the folder. + </para> + </listitem> + + <listitem> + <para> + <command>sess_unseen_number()</command> queries the number of + unseen messages in the folder. + </para> + </listitem> + + <listitem> + <para> + <command>sess_list_folders()</command> returns the list of + all sub-mailboxes of the given mailbox. + <emphasis>Use of this method is deprecated</emphasis>. + </para> + </listitem> + + <listitem> + <para> + <command>sess_lsub_folders()</command> returns the list of + subscribed sub-mailboxes of the given mailbox. + <emphasis>Use of this method is deprecated</emphasis>. + </para> + </listitem> + + <listitem> + <para> + <command>sess_subscribe_folder()</command> subscribes to + the given mailbox. + <emphasis>Use of this method is deprecated</emphasis>. + </para> + </listitem> + + <listitem> + <para> + <command>sess_unsubscribe_folder()</command> unsubscribes to + the given mailbox. + <emphasis>Use of this method is deprecated</emphasis>. + </para> + </listitem> + + <listitem> + <para> + <command>sess_append_message()</command> adds a RFC 2822 + message to the current given mailbox. + </para> + </listitem> + + <listitem> + <para> + <command>sess_copy_message()</command> copies a message + whose number is given to a given mailbox. The mailbox + must be accessible from the same session. + <emphasis>Use of this method is deprecated</emphasis>. + </listitem> + + <listitem> + <para> + <command>sess_move_message()</command> moves a message whose + number is given to + a given mailbox. The mailbox must be accessible from the + same session. + <emphasis>Use of this method is deprecated</emphasis>. + </para> + </listitem> + + <listitem> + <para> + <command>sess_get_messages_list()</command> returns the list + of message numbers + of the current mailbox + (see <xref linkend="mailmessage-list">). + </para> + </listitem> + + <listitem> + <para> + <command>sess_get_envelopes_list()</command> fills the parsed + fields in the <command>mailmessage</command> structures + (see <xref linkend="mailmessage">) + of the <command>mailmessage_list</command> + (see <xref linkend="mailmessage-list">). + </para> + </listitem> + + <listitem> + <para> + <command>sess_remove_message()</command> removes the given + message from the mailbox. + The message is permanently deleted. + <emphasis>Use of this method is deprecated</emphasis>. + </para> + </listitem> + + <listitem> + <para> + <command>sess_get_message()</command> returns a + mailmessage structure + (see <xref linkend="mailmessage">) + that corresponds + to the given message number. + <emphasis>Use of this method is deprecated</emphasis>. + </para> + </listitem> + + <listitem> + <para> + <command>sess_get_message_by_uid()</command> returns a + mailmessage structure + (see <xref linkend="mailmessage">) + that corresponds + to the given message unique identifier. + </para> + </listitem> + </itemizedlist> + + <para> + mandatory functions are the following : + </para> + + <itemizedlist> + <listitem> + <para> + <command>sess_connect_stream()</command> or + <command>connect_path()</command> + </para> + </listitem> + + <listitem> + <para> + <command>sess_logout()</command> + </para> + </listitem> + + <listitem> + <para> + <command>sess_get_messages_list()</command> + </para> + </listitem> + + <listitem> + <para> + <command>sess_get_envelopes_list()</command> + </para> + </listitem> + </itemizedlist> + + <para> + we advise you to implement these functions : + </para> + + <itemizedlist> + <listitem> + <para> + <command>sess_select_folder()</command> (in case a session + can access several folders). + </para> + </listitem> + + <listitem> + <para> + <command>sess_noop()</command> (to check if the server is + responding) + </para> + </listitem> + + <listitem> + <para> + <command>sess_check_folder()</command> (to make a checkpoint + of the session) + </para> + </listitem> + + <listitem> + <para> + <command>sess_status_folder()</command>, + <command>sess_messages_number()</command>, + <command>sess_recent_number()</command>, + <command>sess_unseen_number()</command> + (to get stat of the folder) + </para> + </listitem> + + <listitem> + <para> + <command>sess_append_message()</command> (but can't be done + in the case of POP3 at least). + </para> + </listitem> + + <listitem> + <para> + <command>sess_login()</command> in a case of an + authenticated driver. + </para> + </listitem> + + <listitem> + <para> + <command>sess_starttls()</command> in a case of a stream + driver, if the procotol supports STARTTLS. + </para> + </listitem> + + <listitem> + <para> + <command>sess_get_message_by_uid()</command> so that the + application can remember the messages + by UID and build its own list of messages. + </para> + </listitem> + + <listitem> + <para> + Everything that is specific to the driver will be + implemented in <command>sess_parameters()</command>. + </para> + </listitem> + </itemizedlist> + </sect2> + + <sect2 id="mailsession"> + <title>Session</title> + + <programlisting role="C"> +#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); + </programlisting> + + <para> + This is a session. This is an abstraction used to access the + storage, using the network or the filesystem. + </para> + + <itemizedlist> + <listitem> + <para> + <command>sess_data</command> is the state of the + session. This is specific to the driver. + </para> + </listitem> + <listitem> + <para> + <command>sess_driver</command> is the driver of the + session. + </para> + </listitem> + </itemizedlist> + + <para> + <command>mailsession_new()</command> will create a new session + using the given driver (<command>sess_driver</command>). + </para> + + <para> + <command>mailsession_free()</command> will release the memory + used by the session. + </para> + </sect2> + + <sect2> + <title>mailsession_parameters</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_parameters(mailsession * session, + int id, void * value); + </programlisting> + + <para> + This function make calls specific to the driver + </para> + </sect2> + + <sect2> + <title>mailsession_connect_stream</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_connect_stream(mailsession * session, mailstream * s); + </programlisting> + + <para> + 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 + </para> + </sect2> + + <sect2> + <title>mailsession_connect_path</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_connect_path(mailsession * session, char * path); + </programlisting> + + <para> + This function can only be used by file drivers and + selects the main path of the session. + </para> + </sect2> + + <sect2> + <title>mailsession_starttls</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_starttls(mailsession * session); + </programlisting> + + <para> + This switches the current connection to TLS (secure layer). + This will only work with stream drivers. + </para> + </sect2> + + <sect2> + <title>mailsession_login</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_login(mailsession * session, + char * userid, char * password); + </programlisting> + + <para> + This notifies the login and the password to authenticate + to the session. + </para> + </sect2> + + <sect2> + <title>mailsession_logout</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_logout(mailsession * session); + </programlisting> + + <para> + This function disconnects the session and closes the stream. + </para> + </sect2> + + <sect2> + <title>mailsession_noop</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_noop(mailsession * session); + </programlisting> + + <para> + This function does no operation on the session, but it can be + used to poll for the status of the connection. + </para> + </sect2> + + <sect2> + <title>mailsession_check_folder</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_check_folder(mailsession * session); + </programlisting> + + <para> + This function makes a checkpoint of the session. + </para> + </sect2> + + <sect2> + <title>mailsession_select_folder</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_select_folder(mailsession * session, char * mb); + </programlisting> + + <para> + This function selects a mailbox. + </para> + </sect2> + + <sect2> + <title>mailsession_expunge_folder</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_expunge_folder(mailsession * session); + </programlisting> + + <para> + This function deletes all messages marked for deletion. + </para> + </sect2> + + <sect2> + <title>mailsession_status_folder</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_status_folder(mailsession * session, char * mb, + uint32_t * result_messages, uint32_t * result_recent, + uint32_t * result_unseen); + </programlisting> + + <para> + This function queries the status of the folder + (number of messages, number of recent messages, number of + unseen messages). + </para> + </sect2> + + <sect2> + <title>mailsession_messages_number</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_messages_number(mailsession * session, char * mb, + uint32_t * result); + </programlisting> + + <para> + This function queries the number of messages in the folder. + </para> + </sect2> + + <sect2> + <title>mailsession_recent_number</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_recent_number(mailsession * session, + char * mb, uint32_t * result); + </programlisting> + + <para> + This function queries the number of recent messages in the + folder. + </para> + </sect2> + + <sect2> + <title>mailsession_unseen_number</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_unseen_number(mailsession * session, char * mb, + uint32_t * result); + </programlisting> + + <para> + This function queries the number of unseen messages in the + folder. + </para> + </sect2> + + <sect2> + <title>mailsession_append_message</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_append_message(mailsession * session, + char * message, size_t size); + </programlisting> + + <para> + This adds a RFC 2822 message to the current mailbox. + </para> + </sect2> + + <sect2> + <title>mailsession_get_messages_list</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_get_messages_list(mailsession * session, + struct mailmessage_list ** result); + </programlisting> + + <para> + This function returns the list of messages + of the current mailbox. + </para> + </sect2> + + <sect2> + <title>mailsession_get_envelopes_list</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_get_envelopes_list(mailsession * session, + struct mailmessage_list * result); + </programlisting> + + <para> + This function fills the parsed fields in the + <command>mailmessage</command> structures + (see <xref linkend="mailmessage">) + of the mailmessage_list + (see <xref linkend="mailmessage-list">). + </para> + </sect2> + + <sect2> + <title>mailsession_get_message</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_get_message(mailsession * session, + uint32_t num, mailmessage ** result); + </programlisting> + + <para> + This function returns a <command>mailmessage</command> + (see <xref linkend="mailmessage">) structure that + corresponds to the given message number. + </para> + + <warning> + <para> + <command>mailsession_get_message_by_uid()</command> should + be used instead. + </para> + </warning> + </sect2> + + <sect2> + <title>mailsession_get_message_by_uid</title> + + <programlisting> +#include <libetpan/libetpan.h> + +int mailsession_get_message_by_uid(mailsession * session, + const char * uid, mailmessage ** result); + </programlisting> + + <para> + This function returns a mailmessage structure + that corresponds to the given message unique identifier. + This is currently implemented only for cached drivers. + </para> + <warning> + <para> + That deprecates the use of + <command>mailsession_get_message()</command>. + </para> + </warning> + </sect2> + </sect1> + </chapter> + +</book> 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 @@ +<!doctype book PUBLIC "-//Davenport//DTD DocBook V3.0//EN"> + +<book id="libetpan-readme"> + <bookinfo> + <date>2003-12-03</date> + <title>libEtPan!</title> + <authorgroup> + <author> + <firstname>Viet Hoa</firstname> + <surname>DINH</surname> + </author> + </authorgroup> + <copyright> + <year>2003</year> + <holder>DINH Viet Hoa</holder> + </copyright> + </bookinfo> + <toc></toc> + + <chapter id="introduction"> + <title>Introduction</title> + + <!-- description --> + <sect1 id="description"> + <title>Description</title> + <para> + 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). + </para> + + <para> + 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. + </para> + </sect1> + + <!-- authors --> + <sect1 id="author"> + <title>Author</title> + <sect2 id="main-auth"> + <title>Main author</title> + <para> + DINH Viet Hoa <email>hoa@users.sourceforge.net</email> + </para> + </sect2> + <sect2 id="contrib"> + <title>Contributors</title> + <para> + <itemizedlist> + <listitem> + <para> + Wim Delvaux <!-- wim.delvaux.adaptiveplanet.com --> + </para> + </listitem> + <listitem> + <para> + Melvin Hadasht <!-- melvin.hadasht@free.fr --> + </para> + </listitem> + <listitem> + <para> + David Woodhouse <!-- dwmw2@infradead.org --> + </para> + </listitem> + <listitem> + <para> + Juergen Graf <!-- libetpan@codeguy.org --> + </para> + </listitem> + <listitem> + <para> + Zsolt VARGA <!-- redax@redax.hu --> + </para> + </listitem> + <listitem> + <para> + Gael Roualland <!-- gael.roualland@dial.oleane.com --> + </para> + </listitem> + </itemizedlist> + </para> + </sect2> + </sect1> + </chapter> + + <!-- installation --> + <chapter id="installation"> + <title>Installation</title> + + <sect1 id="dependencies"> + <title>Dependencies</title> + + <!-- dependencies for users --> + <sect2 id="depend-users"> + <title>Dependencies for users</title> + + <itemizedlist> + <listitem> + <para> + <ulink url="http://www.openssl.org">OpenSSL</ulink> + (optional but recommended) + </para> + </listitem> + <listitem> + <para> + <ulink url="http://www.sleepycat.com">Berkeley + DB</ulink> (optional but recommended) + </para> + </listitem> + <listitem> + <para> + POSIX Thread (required) + </para> + </listitem> + </itemizedlist> + </sect2> + <!-- dependencies for developers --> + <sect2 id="depend-developers"> + <title>Dependencies for developers</title> + + <itemizedlist> + <listitem> + <para> + <ulink url="http://www.gnu.org/software/autoconf"> + autoconf + </ulink> + 2.13 + </para> + </listitem> + <listitem> + <para> + <ulink url="http://www.gnu.org/software/automake"> + automake + </ulink> + 1.4 + </para> + </listitem> + <listitem> + <para> + <ulink + url="http://www.gnu.org/software/libtool/libtool.html"> + libtool + </ulink> + 1.4.3 + </para> + </listitem> + </itemizedlist> + </sect2> + </sect1> + <!-- packages --> + <sect1 id="packages"> + <title>Existing packages</title> + + <itemizedlist> + <listitem> + <para> + 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. + </para> + </listitem> + </itemizedlist> + </sect1> + + <!-- compilation --> + <sect1 id="compilation"> + <title>Compilation</title> + + <para> + Generic installation instructions are in the + <filename>INSTALL</filename> file + You can pass the following extra options to configure : + </para> + + <!-- FreeBSD --> + <sect2 id="freebsd"> + <title>FreeBSD</title> + <itemizedlist> + <listitem> + <para> + make sure libiconv is installed from the ports collection (see + <command>pkg_info</command>). + </para> + </listitem> + <listitem> + <para> + issue configure with the following parameter: + <screen> +<prompt>$</prompt> <userinput>./configure --with-libiconv-prefix=/usr/local</userinput> + </screen> + </para> + </listitem> + </itemizedlist> + </sect2> + + <!-- MacOS X --> + <sect2 id="macosx"> + <title>Mac OS X</title> + <itemizedlist> + <listitem> + <para> + You have to configure using the following command line : + <command>CPPFLAGS=-I/sw/include LDFLAGS=-L/sw/lib + ./configure</command> + </para> + </listitem> + <listitem> + <para> + in tests/option-parser.c, change the inclusion + of <filename>getopt.h</filename> to + <filename>gnugetopt/getopt.h</filename> + </para> + </listitem> + <listitem> + <para> + in <filename>tests/Makefile</filename>, add + <command>-I/sw/include</command> for the + <command>CFLAGS</command> and + -L/sw/lib -lgnugetopt for the LDFLAGS. + </para> + </listitem> + </itemizedlist> + </sect2> + + <!-- Linux --> + <sect2 id="linux"> + <title>Linux</title> + <itemizedlist> + <listitem> + <warning> + <para> + Since libEtPan! is making high usage of + <command>mmap()</command> even for + writing, when your mailboxes are on + <command>NFS</command> filesystem with + a Linux server, it is advised to use option + <command>no_subtree_check</command> in + <filename>/etc/exports</filename>. + This should avoid corruption of data. + </para> + <para> + The problem exist in Linux 2.4.22 and earlier versions. + </para> + </warning> + </listitem> + <listitem> + <para> + On RedHat systems, you have to configure using the + following command line : + <command>./configure --with-openssl=/usr/kerberos</command> + </para> + </listitem> + <listitem> + <para> + On Debian systems, if the <command>./autogen</command> + script fails on missing <command>AM_ICONV</command>, you + have to install <command>gettext</command> package. + </para> + </listitem> + </itemizedlist> + </sect2> + + <!-- configure --> + <sect2 id="configure"> + <title>configure</title> + <para> + You can use the following options : + </para> + <itemizedlist> + <listitem> + <para> + <command>--enable-debug</command> Compiles with + debugging turned on + </para> + </listitem> + <listitem> + <para> + <command>--enable-optim</command> Turns on some + optimizations flags for gcc + </para> + </listitem> + <listitem> + <para> + <command>--without-openssl</command> Disables OpenSSL (do + not look for it) + </para> + </listitem> + </itemizedlist> + </sect2> + <sect2 id="install"> + <title>Compile and install</title> + <para> + Download the package and do the following : + </para> + <programlisting> +$ 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 + </programlisting> + </sect2> + </sect1> + </chapter> +</book> 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 |