summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan/doc/API.sgml
Side-by-side diff
Diffstat (limited to 'kmicromail/libetpan/doc/API.sgml') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/doc/API.sgml15097
1 files changed, 15097 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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdlib.h&gt;
+
+#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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdlib.h&gt;
+
+#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 &lt; 0)
+ goto free;
+
+ for(i = 0 ; i &lt; NEWSIZE ; i ++)
+ carray_set(a, i, &amp;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 &lt;libetpan/libetpan.h&gt;
+#include &lt;string.h&gt;
+
+#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 &lt; 0)
+ goto free;
+
+ carray_add(a, "foo-bar-2", NULL);
+ if (r &lt; 0)
+ goto free;
+
+ carray_add(a, "foo-bar-3", NULL);
+ if (r &lt; 0)
+ goto free;
+
+ for(i = 0 ; i &lt; 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 &lt;libetpan/libetpan.h&gt;
+
+#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 &lt; 0)
+ goto free;
+
+ carray_add(a, "foo-bar-2", NULL);
+ if (r &lt; 0)
+ goto free;
+
+ carray_add(a, "foo-bar-3", NULL);
+ if (r &lt; 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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+int main(void)
+{
+ clist * list;
+
+ list = clist_new();
+ if (list == NULL)
+ goto err;
+
+ r = clist_append(list, "foo-bar");
+ if (r &lt; 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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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, &amp;key, &amp;value, NULL);
+ if (r &lt; 0)
+ goto free_hash;
+
+ key.data = "bar";
+ key.len = strlen("bar");
+ value.data = str2;
+ value.data = strlen(str2) + 1;
+ if (r &lt; 0)
+ goto free_hash;
+
+ key.data = "foo";
+ key.len = strlen("foo");
+ r = chash_get(hash, &amp;key, &amp;value);
+ if (r &lt; 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, &amp;key, &amp;value);
+
+ /* it will never be possible to lookup "foo" */
+ key.data = "foo";
+ key.len = strlen("foo");
+ r = chash_get(hash, &amp;key, &amp;value);
+ if (r &lt; 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, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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-&gt;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-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;hoa@users.sourceforge.net&gt;
+ </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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+void display_mailbox(struct mailimf_mailbox * mb)
+{
+ if (mb-&gt;mb_display_name != NULL)
+ printf("display name: %s\n", mb-&gt;mb_display_name);
+ printf("address specifier : %s\n", mb-&gt;mb_addr_spec);
+}
+ </programlisting>
+ </example>
+ </sect2>
+
+ <!-- mailimf_address -->
+ <sect2 id="mailimf-address">
+ <title>mailimf_address - address</title>
+
+ <programlisting role="C">
+#include &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+void display_address(struct mailimf_address * a)
+{
+ clistiter * cur;
+
+ switch (a-&gt;ad_type) {
+ case MAILIMF_ADDRESS_GROUP:
+ display_mailimf_group(a-&gt;ad_data.ad_group);
+ break;
+
+ case MAILIMF_ADDRESS_MAILBOX:
+ display_mailimf_mailbox(a-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+void display_mailbox_list(struct mailimf_mailbox_list * mb_list)
+{
+ clistiter * cur;
+
+ for(cur = clist_begin(mb_list-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+void display_address_list(struct mailimf_address_list * addr_list)
+{
+ clistiter * cur;
+
+ for(cur = clist_begin(addr_list-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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: &lt;steve@morse.foo&gt;, &lt;neal@morse.foo&gt;,
+ &lt;yngwie@malmsteen.bar&gt;, &lt;michael@romeo.bar&gt;;
+ </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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+void display_group(struct mailimf_group * group)
+{
+ printf("name of the group: %s\n", a-&gt;group-&gt;display_name);
+ for(cur = clist_begin(a-&gt;group-&gt;mb_list-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+void display_date(struct mailimf_date_time * d)
+{
+ printf("%02i/%02i/%i %02i:%02i:%02i %+04i\n",
+ d-&gt;dt_day, d-&gt;dt_month, d-&gt;dt_year,
+ d-&gt;dt_hour, d-&gt;dt_min, d-&gt;dt_sec, d-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+void display_orig_date(struct mailimf_orig_date * orig_date)
+{
+ display_date_time(d-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+void display_from(struct mailimf_from * from)
+{
+ display_mailbox_list(from-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+void display_sender(struct mailimf_sender * sender)
+{
+ display_mailbox(sender-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+void display_reply_to(struct mailimf_reply_to * reply_to)
+{
+ display_address_list(reply_to-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+void display_to(struct mailimf_to * to)
+{
+ display_address_list(to-&gt;to_addr_list);
+}
+ </programlisting>
+ </example>
+ </sect2>
+
+ <!-- mailimf_cc -->
+ <sect2 id="mailimf-cc">
+ <title>mailimf_cc - parsed content of Cc</title>
+
+<programlisting>
+#include &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+void display_cc(struct mailimf_cc * cc)
+{
+ display_address_list(cc-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+void display_bcc(struct mailimf_bcc * bcc)
+{
+ if (bcc-&gt;addr_list == NULL) {
+ printf("hidden Bcc\n");
+ }
+ else {
+ display_address_list(bcc-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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: &lt;200312100009.43592@c01n-c01n.plop.P4N>&gt;
+ </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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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: &lt;etPan.3fd5fa29.4c3901c1.6b39@homer&gt;
+ </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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+void display_in_reply_to(struct mailimf_in_reply_to * in_reply_to)
+{
+ clistiter * cur;
+
+ for(cur = clist_begin(in_reply_to-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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: &lt;etPan.3fd5fa29.4c3901c1.6b39@homer&gt;
+ &lt;3FD5FA78.A1D98E7@oleane.net&gt;
+ &lt;etPan.3fd5fc69.2b349482.730e@homer&gt;
+ </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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+void display_references(struct mailimf_references * ref)
+{
+ clistiter * cur;
+
+ for(cur = clist_begin(ref-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+void display_keywords(struct mailimf_keywords * kw)
+{
+ clistiter * cur;
+
+ for(cur = clist_begin(kw-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+void display_return(struct mailimf_return * r)
+{
+ display_path(r-&gt;ret_path);
+}
+ </programlisting>
+ </example>
+ </sect2>
+
+ <!-- mailimf_path -->
+ <sect2 id="mailimf-path">
+ <title>mailimf_path - address in Return-Path field</title>
+
+ <programlisting role="C">
+#include &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+void display_path(struct mailimf_path * path)
+{
+ printf("%s\n", path-&gt;pt_addr_spec);
+}
+ </programlisting>
+ </example>
+ </sect2>
+
+ <!-- mailimf_optional_field -->
+ <sect2 id="mailimf-optional-field">
+ <title>mailimf_optional_field - non-standard header</title>
+
+ <programlisting>
+#include &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+void display_optional_field(struct mailimf_optional_field * opt)
+{
+ printf("%s: %s\n", opt-&gt;fld_name, opt-&gt;fld_value);
+}
+ </programlisting>
+ </example>
+ </sect2>
+
+ <!-- mailimf_field -->
+ <sect2 id="mailimf-field">
+ <title>mailimf_field - header field</title>
+
+ <programlisting role="C">
+#include &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+void display_field(struct mailimf_field * field)
+{
+ switch (field-&gt;type) {
+ case MAILIMF_FIELD_RETURN_PATH:
+ printf("Return-Path:\n");
+ display_return(field-&gt;fld_data.fld_return_path);
+ break;
+ case MAILIMF_FIELD_RESENT_DATE:
+ printf("Resent-Date:\n");
+ display_orig_date(field-&gt;fld_data.fld_orig_date);
+ break;
+ case MAILIMF_FIELD_RESENT_FROM:
+ printf("Resent-From:\n");
+ display_from(field-&gt;fld_data.fld_orig_date);
+ break;
+ case MAILIMF_FIELD_RESENT_SENDER:
+ printf("Resent-Sender:\n");
+ display_sender(field-&gt;fld_data.fld_resent_sender);
+ break;
+ case MAILIMF_FIELD_RESENT_TO:
+ printf("Resent-To:\n");
+ display_to(field-&gt;fld_data.fld_resent_to);
+ break;
+ case MAILIMF_FIELD_RESENT_CC:
+ printf("Resent-Cc:\n");
+ display_from(field-&gt;fld_data.fld_resent_cc);
+ break;
+ case MAILIMF_FIELD_RESENT_BCC:
+ printf("Resent-Bcc:\n");
+ display_from(field-&gt;fld_data.fld_resent_bcc);
+ break;
+ case MAILIMF_FIELD_RESENT_MSG_ID:
+ printf("Resent-Message-ID:\n");
+ display_message_id(field-&gt;fld_data.fld_resent_msg_id);
+ break;
+ case MAILIMF_FIELD_ORIG_DATE:
+ printf("Date:\n");
+ display_orig_date(field-&gt;fld_data.fld_orig_date);
+ break;
+ case MAILIMF_FIELD_FROM:
+ printf("From:\n");
+ display_from(field-&gt;fld_data.fld_from);
+ break;
+ case MAILIMF_FIELD_SENDER:
+ printf("Sender:\n");
+ display_sender(field-&gt;fld_data.fld_sender);
+ break;
+ case MAILIMF_FIELD_REPLY_TO:
+ printf("Reply-To:\n");
+ display_reply_to(field-&gt;fld_data.fld_reply_to);
+ break;
+ case MAILIMF_FIELD_TO:
+ printf("To:\n");
+ display_to(field-&gt;fld_data.fld_to);
+ break;
+ case MAILIMF_FIELD_CC:
+ printf("Cc:\n");
+ display_cc(field-&gt;fld_data.fld_cc);
+ break;
+ case MAILIMF_FIELD_BCC:
+ printf("Bcc:\n");
+ display_bcc(field-&gt;fld_data.fld_bcc);
+ break;
+ case MAILIMF_FIELD_MESSAGE_ID:
+ printf("Message-ID:\n");
+ display_message_id(field-&gt;fld_data.fld_message_id);
+ break;
+ case MAILIMF_FIELD_IN_REPLY_TO:
+ printf("In-Reply-To:\n");
+ display_in_reply_to(field-&gt;fld_data.fld_in_reply_to);
+ break;
+ case MAILIMF_FIELD_REFERENCES:
+ printf("References:\n");
+ display_references(field-&gt;fld_data.fld_references_to);
+ break;
+ case MAILIMF_FIELD_SUBJECT:
+ printf("Subject:\n");
+ display_subject(field-&gt;fld_data.fld_subject);
+ break;
+ case MAILIMF_FIELD_COMMENTS:
+ printf("Comments:\n");
+ display_comments(field-&gt;fld_data.fld_comments);
+ break;
+ case MAILIMF_FIELD_KEYWORDS:
+ printf("Keywords:\n");
+ display_keywords(field-&gt;fld_data.fld_keywords);
+ break;
+ case MAILIMF_FIELD_OPTIONAL_FIELD:
+ printf("[optional field]:\n");
+ display_optional_field(field-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+void display_fields(struct mailimf_fields * fields)
+{
+ clistiter * cur;
+
+ for(cur = clist_begin(field-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+void display_body(struct mailimf_body * b)
+{
+ char * text;
+
+ text = malloc(b-&gt;size + 1);
+ strncpy(text, b-&gt;bd_text, b-&gt;bd_size);
+ text[b-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;stdio.h&gt;
+
+void display_message(struct mailimf_message * msg)
+{
+ display_fields(msg-&gt;msg_fields);
+ printf("\n");
+ display_body(msg-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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(&amp;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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+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, &amp;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,
+ &amp;current_index, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+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, &amp;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,
+ &amp;current_index, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+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, &amp;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, &amp;current_index, &amp;f);
+ if (r == MAILIMF_NO_ERROR) {
+ r = mailimf_crlf_parse(mem, size, &amp;current_index);
+ /* ignore parse error of crlf */
+
+ r = mailimf_body_parse(mem, size, &amp;current_index, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+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, &amp;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,
+ &amp;current_index, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+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, &amp;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,
+ &amp;current_index, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+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, &amp;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,
+ &amp;current_index, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+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, &amp;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,
+ &amp;current_index, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+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, &amp;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,
+ &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+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, &amp;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,
+ &amp;current_index, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+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, &amp;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,
+ &amp;current_index, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+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, &amp;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,
+ &amp;current_index, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;foo@bar.org&gt;");
+
+ 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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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, &amp;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, &amp;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, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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-&gt;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-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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-&gt;ct_type);
+ printf("\n");
+ printf("subtype: %s\n", content_type-&gt;ct_subtype);
+ printf("\n");
+
+ for(cur = clist_begin(content_type-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+/* 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-&gt;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-&gt;dt_extension);
+ break;
+ }
+}
+ </programlisting>
+ </example>
+
+ </sect2>
+
+ <!-- mailmime_field -->
+ <sect2 id="mailmime-field">
+ <title>mailmime_field - MIME header field</title>
+
+ <programlisting role="C">
+#include &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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-&gt;fld_type) {
+ case MAILMIME_FIELD_TYPE:
+ printf("content-type:");
+ display_mime_content(field-&gt;fld_data.fld_content);
+ break;
+ case MAILMIME_FIELD_TRANSFER_ENCODING:
+ printf("content-transfer-encoding:");
+ display_mime_mechanism(field-&gt;fld_data.fld_encoding);
+ break;
+ case MAILMIME_FIELD_ID:
+ printf("content-id: %s\n", field-&gt;fld_data.fld_id);
+ break;
+ case MAILMIME_FIELD_DESCRIPTION:
+ printf("content-description: %s\n", field-&gt;fld_data.fld_description);
+ break;
+ case MAILMIME_FIELD_VERSION:
+ printf("mime-version: %i.%i\n",
+ field-&gt;version>> 16, field-&gt;fld_data.fld_version & 0xFFFF);
+ break;
+ case MAILMIME_FIELD_DISPOSITION:
+ printf("content-disposition:");
+ display_mime_disposition(field-&gt;fld_data.fld_disposition);
+ break;
+ case MAILMIME_FIELD_LANGUAGE:
+ printf("content-language:");
+ display_mime_language(field-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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-&gt;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-&gt;enc_token);
+ break;
+ }
+}
+ </programlisting>
+ </example>
+ </sect2>
+
+ <!-- mailmime_fields -->
+ <sect2 id="mailmime-fields">
+ <title>mailmime_fields - header fields</title>
+
+ <programlisting role="C">
+#include &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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-&gt;pa_name, param-&gt;pa_value);
+}
+ </programlisting>
+ </example>
+
+ </sect2>
+
+ <!-- mailmime_type -->
+ <sect2 id="mailmime-type">
+ <title>mailmime_type - MIME main type</title>
+
+ <programlisting role="C">
+#include &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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-&gt;tp_type) {
+ case MAILMIME_TYPE_DISCRETE_TYPE:
+ printf("discrete type:\n");
+ display_mime_discrete_type(type-&gt;tp_data.tp_discrete_type);
+ break;
+ case MAILMIME_TYPE_COMPOSITE_TYPE:
+ printf("composite type:\n");
+ display_mime_composite_type(type-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+/* 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-&gt;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-&gt;dt_encoded)
+ printf("already encoded\n");
+ else
+ printf("not encoded\n");
+
+ switch (data-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+/* 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-&gt;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-&gt;mm_mime_start, mime-&gt;mm_length);
+ printf("\n");
+
+ if (mime-&gt;mm_mime_fields != NULL) {
+ printf("MIME headers :\n");
+ display_mime_fields(mime->mm_mime_fields);
+ printf("\n");
+ }
+
+ printf("content type :\n");
+ display_content(mime-&gt;mm_content_type);
+ printf("\n");
+
+ switch (mime-&gt;mm_type) {
+ case MAILMIME_SINGLE:
+ display_mime_data(mime-&gt;mm_data.mm_single);
+ break;
+
+ case MAILMIME_MULTIPLE:
+ if (mime-&gt;mm_data.mm_multipart.mm_preamble) {
+ printf("preamble :\n");
+ display_mime_data(mime-&gt;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-&gt;mm_data.mm_multipart.mm_epilogue) {
+ printf("epilogue :\n");
+ display_mime_data(mime-&gt;mm_data.mm_multipart.mm_epilogue);
+ printf("\n");
+ }
+ break;
+
+ case MAILMIME_MESSAGE:
+ if (mime-&gt;mm_data.mm_message.mm_fields) {
+ printf("headers :\n");
+ display_field(mime-&gt;mm_data.mm_message.mm_msg_fields);
+ printf("\n");
+
+ if (mime-&gt;mm_data.mm_message.mm_msg_mime != NULL) {
+ printf("sub message %p :\n",
+ mime-&gt;mm_data.mm_message.mm_msg_mime);
+ display_mime(mime-&gt;mm_data.mm_message.mm_msg_mime);
+ printf("end of sub message %p\n",
+ mime-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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-&gt;dsp_type);
+ printf("\n");
+ printf("disposition parameters:\n");
+ for(cur = clist_begin(disposition-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+/* 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-&gt;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-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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-&gt;pa_type) {
+ case MAILMIME_DISPOSITION_PARM_FILENAME:
+ printf("filename: %s\n", param-&gt;pa_data.pa_filename);
+ break;
+ case MAILMIME_DISPOSITION_PARM_CREATION_DATE:
+ printf("creation date: %s\n", param-&gt;pa_data.pa_creation_date);
+ break;
+ case MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE:
+ printf("modification date: %s\n", param-&gt;pa_data.pa_modification_date);
+ break;
+ case MAILMIME_DISPOSITION_PARM_READ_DATE:
+ printf("read date: %s\n", param-&gt;pa_data.pa_read_date);
+ break;
+ case MAILMIME_DISPOSITION_PARM_SIZE:
+ printf("size: %lu\n", (unsigned long) param-&gt;pa_data.pa_size);
+ break;
+ case MAILMIME_DISPOSITION_PARM_PARAMETER:
+ printf("MIME disposition param:\n");
+ display_mime_parameter(param-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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-&gt;fld_content != NULL) {
+ printf("content type:\n");
+ display_mime_content(single_fields-&gt;fld_content);
+ printf("\n");
+ }
+ if (single_fields-&gt;fld_content_charset != NULL) {
+ printf("content type charset: %s\n",
+ single_fields-&gt;fld_content_charset);
+ printf("\n");
+ }
+ if (single_fields-&gt;fld_content_boundary != NULL) {
+ printf("content type boundary: %s\n",
+ single_fields-&gt;fld_content_boundary);
+ printf("\n");
+ }
+ if (single_fields-&gt;content_name != NULL) {
+ printf("content type name: %s\n", single_fields-&gt;content_name);
+ printf("\n");
+ }
+ if (single_fields-&gt;fld_encoding != NULL) {
+ printf("content transfer encoding:\n");
+ display_mime_mechanism(single_fields-&gt;fld_encoding);
+ printf("\n");
+ }
+ if (single_fields-&gt;fld_id != NULL) {
+ printf("content id: %s\n", single_fields-&gt;fld_id);
+ printf("\n");
+ }
+ if (single_fields-&gt;fld_description != NULL) {
+ printf("content description: %s\n", single_fields-&gt;fld_description);
+ printf("\n");
+ }
+ if (single_fields-&gt;fld_version != 0) {
+ printf("mime version: %i.%i\n",
+ single_fields-&gt;fld_version&gt;&gt; 16,
+ single_fields-&gt;fld_version & 0xFFFF);
+ printf("\n");
+ }
+ if (single_fields-&gt;fld_disposition != NULL) {
+ printf("content disposition:\n");
+ display_mime_disposition(single_fields-&gt;fld_disposition);
+ printf("\n");
+ }
+ if (single_fields-&gt;fld_disposition_filename != NULL) {
+ printf("content disposition filename: %s\n",
+ single_fields-&gt;fld_disposition_filename);
+ printf("\n");
+ }
+ if (single_fields-&gt;fld_disposition_creation_date != NULL) {
+ printf("content disposition creation date: %s\n",
+ single_fields-&gt;fld_disposition_creation_date);
+ printf("\n");
+ }
+ if (single_fields-&gt;fld_disposition_modification_date != NULL) {
+ printf("content disposition modification date: %s\n",
+ single_fields-&gt;fld_disposition_modification_date);
+ printf("\n");
+ }
+ if (single_fields-&gt;fld_disposition_read_date != NULL) {
+ printf("content disposition read date: %s\n",
+ single_fields-&gt;fld_disposition_read_date;
+ printf("\n");
+ }
+ if (single_fields-&gt;fld_disposition_size != (size_t) -1) {
+ printf("content disposition size : %i\n",
+ single_fields-&gt;fld_disposition_size);
+ printf("\n");
+ }
+ if (single_fields-&gt;language != NULL) {
+ printf("content language:\n");
+ display_mime_language(single_fields-&gt;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+int main(int argc, char ** argv)
+{
+ int fd;
+ int r;
+
+ status = EXIT_FAILURE;
+
+ fd = open("message.rfc2822", O_RDONLY);
+ if (fd &gt;= 0) {
+ void * mem;
+ struct stat stat_info;
+
+ r = fstat(fd, &amp;stat_info);
+ if (r &gt;= 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,
+ &amp;current_index, &amp;f);
+ if (r == MAILIMF_NO_ERROR) {
+ clistiter * cur;
+
+ for(cur = clist_begin(f-&gt;fld_list) ; cur != NULL ; cur =
+ clist_next(cur)) {
+ struct mailmime_field * mime_field;
+ struct mailimf_field * field;
+
+ field = clist_content(cur);
+
+ if (field-&gt;fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
+ if (strcasecmp(field-&gt;fld_data.fld_optional_field-&gt;fld_name,
+ "Content-Type") == 0) {
+ struct mailmime_content * content_type;
+ size_t current_index;
+
+ current_index = 0;
+ r = mailmime_content_parse(field-&gt;fld_data.fld_optional_field-&gt;fld_value,
+ strlen(field-&gt;fld_data.fld_optional_field-&gt;fld_value),
+ &amp;current_index, &amp;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 &gt;libetpan/libetpan.h&lt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+int main(int argc, char ** argv)
+{
+ int fd;
+ int r;
+
+ status = EXIT_FAILURE;
+
+ fd = open("message.rfc2822", O_RDONLY);
+ if (fd &gt;= 0) {
+ void * mem;
+ struct stat stat_info;
+
+ r = fstat(fd, &amp;stat_info);
+ if (r &gt;= 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,
+ &amp;current_index, &amp;f);
+ if (r == MAILIMF_NO_ERROR) {
+ clistiter * cur;
+
+ for(cur = clist_begin(f-&gt;fld_list) ; cur != NULL ; cur =
+ clist_next(cur)) {
+ struct mailmime_field * mime_field;
+ struct mailimf_field * field;
+
+ field = clist_content(cur);
+
+ if (field-&gt;fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
+ if (strcasecmp(field-&gt;fld_data.fld_optional_field-&gt;fld_name,
+ "Content-Description") == 0) {
+ char * description;
+ size_t current_index;
+
+ current_index = 0;
+ r = mailmime_description_parse(field-&gt;fld_data.fld_optional_field-&gt;fld_value,
+ strlen(field-&gt;fld_data.fld_optional_field-&gt;fld_value),
+ &amp;current_index, &amp;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 &gt;libetpan/libetpan.h&lt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+int main(int argc, char ** argv)
+{
+ int fd;
+ int r;
+
+ status = EXIT_FAILURE;
+
+ fd = open("message.rfc2822", O_RDONLY);
+ if (fd &gt;= 0) {
+ void * mem;
+ struct stat stat_info;
+
+ r = fstat(fd, &amp;stat_info);
+ if (r &gt;= 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,
+ &amp;current_index, &amp;f);
+ if (r == MAILIMF_NO_ERROR) {
+ clistiter * cur;
+
+ for(cur = clist_begin(f-&gt;fld_list) ; cur != NULL ; cur =
+ clist_next(cur)) {
+ struct mailmime_field * mime_field;
+ struct mailimf_field * field;
+
+ field = clist_content(cur);
+
+ if (field-&gt;fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
+ if (strcasecmp(field-&gt;fld_data.fld_optional_field-&gt;fld_name,
+ "Content-Transfer-Encoding") == 0) {
+ struct mailmime_content * encoding;
+ size_t current_index;
+
+ current_index = 0;
+ r = mailmime_encoding_parse(field-&gt;fld_data.fld_optional_field-&gt;fld_value,
+ strlen(field-&gt;fld_data.fld_optional_field-&gt;fld_value),
+ &amp;current_index, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+int main(int argc, char ** argv)
+{
+ int fd;
+ int r;
+
+ status = EXIT_FAILURE;
+
+ fd = open("message.rfc2822", O_RDONLY);
+ if (fd &gt;= 0) {
+ void * mem;
+ struct stat stat_info;
+
+ r = fstat(fd, &amp;stat_info);
+ if (r &gt;= 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,
+ &amp;current_index, &amp;f);
+ if (r == MAILIMF_NO_ERROR) {
+ clistiter * cur;
+
+ for(cur = clist_begin(f-&gt;fld_list) ; cur != NULL ; cur =
+ clist_next(cur)) {
+ struct mailmime_field * mime_field;
+ struct mailimf_field * field;
+
+ field = clist_content(cur);
+
+ if (field-&gt;fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
+ r = mailmime_field_parse(field-&gt;fld_data.fld_optional_field,
+ &amp;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 &gt;libetpan/libetpan.h&lt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+int main(int argc, char ** argv)
+{
+ int fd;
+ int r;
+
+ status = EXIT_FAILURE;
+
+ fd = open("message.rfc2822", O_RDONLY);
+ if (fd &gt;= 0) {
+ void * mem;
+ struct stat stat_info;
+
+ r = fstat(fd, &amp;stat_info);
+ if (r &gt;= 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,
+ &amp;current_index, &amp;f);
+ if (r == MAILIMF_NO_ERROR) {
+ clistiter * cur;
+
+ for(cur = clist_begin(f-&gt;fld_list) ; cur != NULL ; cur =
+ clist_next(cur)) {
+ struct mailmime_field * mime_field;
+ struct mailimf_field * field;
+
+ field = clist_content(cur);
+
+ if (field-&gt;fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
+ if (strcasecmp(field-&gt;fld_data.fld_optional_field-&gt;fld_name,
+ "Content-ID") == 0) {
+ char * id;
+ size_t current_index;
+
+ current_index = 0;
+ r = mailmime_id_parse(field-&gt;fld_data.fld_optional_field-&gt;fld_value,
+ strlen(field-&gt;fld_data.fld_optional_field-&gt;fld_value),
+ &amp;current_index, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+int main(int argc, char ** argv)
+{
+ int fd;
+ int r;
+
+ status = EXIT_FAILURE;
+
+ fd = open("message.rfc2822", O_RDONLY);
+ if (fd &gt;= 0) {
+ void * mem;
+ struct stat stat_info;
+
+ r = fstat(fd, &amp;stat_info);
+ if (r &gt;= 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,
+ &amp;current_index, &amp;f);
+ if (r == MAILIMF_NO_ERROR) {
+ struct mailmime_fields * mime_fields;
+
+ r = mailmime_fields_parse(f, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+int main(int argc, char ** argv)
+{
+ int fd;
+ int r;
+
+ status = EXIT_FAILURE;
+
+ fd = open("message.rfc2822", O_RDONLY);
+ if (fd &gt;= 0) {
+ void * mem;
+ struct stat stat_info;
+
+ r = fstat(fd, &amp;stat_info);
+ if (r &gt;= 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,
+ &amp;current_index, &amp;f);
+ if (r == MAILIMF_NO_ERROR) {
+ clistiter * cur;
+
+ for(cur = clist_begin(f-&gt;fld_list) ; cur != NULL ; cur =
+ clist_next(cur)) {
+ struct mailmime_field * mime_field;
+ struct mailimf_field * field;
+
+ field = clist_content(cur);
+
+ if (field-&gt;fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
+ if (strcasecmp(field-&gt;fld_data.fld_optional_field-&gt;fld_name,
+ "MIME-Version") == 0) {
+ uint32_t version;
+ size_t current_index;
+
+ current_index = 0;
+ r = mailmime_version_parse(field-&gt;fld_data.fld_optional_field-&gt;fld_value,
+ strlen(field-&gt;fld_data.fld_optional_field-&gt;fld_value),
+ &amp;current_index, &amp;version);
+ if (r == MAILIMF_NO_ERROR) {
+ printf("%i.%i\n", version &gt;&gt; 16, version &amp; 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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+#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,
+ &amp;current_index, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+int main(int argc, char ** argv)
+{
+ int fd;
+ int r;
+
+ status = EXIT_FAILURE;
+
+ fd = open("message.rfc2822", O_RDONLY);
+ if (fd &gt;= 0) {
+ void * mem;
+ struct stat stat_info;
+
+ r = fstat(fd, &amp;stat_info);
+ if (r &gt;= 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,
+ &amp;current_index, &amp;f);
+ if (r == MAILIMF_NO_ERROR) {
+ clistiter * cur;
+
+ for(cur = clist_begin(f-&gt;fld_list) ; cur != NULL ; cur =
+ clist_next(cur)) {
+ struct mailmime_field * mime_field;
+ struct mailimf_field * field;
+
+ field = clist_content(cur);
+
+ if (field-&gt;fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
+ if (strcasecmp(field-&gt;fld_data.fld_optional_field-&gt;fld_name,
+ "Content-Language") == 0) {
+ struct mailmime_language * lang;
+ size_t current_index;
+
+ current_index = 0;
+ r = mailmime_id_parse(field-&gt;fld_data.fld_optional_field-&gt;fld_value,
+ strlen(field-&gt;fld_data.fld_optional_field-&gt;fld_value),
+ &amp;current_index, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+int main(int argc, char ** argv)
+{
+ int fd;
+ int r;
+
+ status = EXIT_FAILURE;
+
+ fd = open("message.rfc2822", O_RDONLY);
+ if (fd &gt;= 0) {
+ void * mem;
+ struct stat stat_info;
+
+ r = fstat(fd, &amp;stat_info);
+ if (r &gt;= 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,
+ &amp;current_index, &amp;f);
+ if (r == MAILIMF_NO_ERROR) {
+ clistiter * cur;
+
+ for(cur = clist_begin(f-&gt;fld_list) ; cur != NULL ; cur =
+ clist_next(cur)) {
+ struct mailmime_field * mime_field;
+ struct mailimf_field * field;
+
+ field = clist_content(cur);
+
+ if (field-&gt;fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
+ if (strcasecmp(field-&gt;fld_data.fld_optional_field-&gt;fld_name,
+ "Content-Disposition") == 0) {
+ struct mailmime_disposition * dsp;
+ size_t current_index;
+
+ current_index = 0;
+ r = mailmime_id_parse(field-&gt;fld_data.fld_optional_field-&gt;fld_value,
+ strlen(field-&gt;fld_data.fld_optional_field-&gt;fld_value),
+ &amp;current_index, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+#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,
+ &amp;current_index, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+#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),
+ &amp;cur_token, "iso-8859-1", &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+int main(int argc, char ** argv)
+{
+ int fd;
+ int r;
+
+ status = EXIT_FAILURE;
+
+ fd = open("message.rfc2822", O_RDONLY);
+ if (fd &gt;= 0) {
+ void * mem;
+ struct stat stat_info;
+
+ r = fstat(fd, &amp;stat_info);
+ if (r &gt;= 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,
+ &amp;current_index, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+int main(int argc, char ** argv)
+{
+ int fd;
+ int r;
+
+ status = EXIT_FAILURE;
+
+ fd = open("message.rfc2822", O_RDONLY);
+ if (fd &gt;= 0) {
+ void * mem;
+ struct stat stat_info;
+
+ r = fstat(fd, &amp;stat_info);
+ if (r &gt;= 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,
+ &amp;current_index, &amp;result, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+int main(int argc, char ** argv)
+{
+ int fd;
+ int r;
+
+ status = EXIT_FAILURE;
+
+ fd = open("message.rfc2822", O_RDONLY);
+ if (fd &gt;= 0) {
+ void * mem;
+ struct stat stat_info;
+
+ r = fstat(fd, &amp;stat_info);
+ if (r &gt;= 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,
+ &amp;current_index, &amp;result, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+int main(int argc, char ** argv)
+{
+ int fd;
+ int r;
+
+ status = EXIT_FAILURE;
+
+ fd = open("message.rfc2822", O_RDONLY);
+ if (fd &gt;= 0) {
+ void * mem;
+ struct stat stat_info;
+
+ r = fstat(fd, &amp;stat_info);
+ if (r &gt;= 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,
+ &amp;current_index, &amp;result, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+int main(int argc, char ** argv)
+{
+ int fd;
+ int r;
+
+ status = EXIT_FAILURE;
+
+ fd = open("message.rfc2822", O_RDONLY);
+ if (fd &gt;= 0) {
+ void * mem;
+ struct stat stat_info;
+
+ r = fstat(fd, &amp;stat_info);
+ if (r &gt;= 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, &amp;current_index,
+ MAILMIME_MECHANISM_QUOTED_PRINTABLE, &amp;result, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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, &amp;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, &amp;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, &amp;col, mime_fields);
+
+ mailmime_content_free(content);
+}
+ </programlisting>
+ </example>
+ </sect2>
+
+ <!-- mailmime_write -->
+ <sect2 id="mailmime-write">
+ <title>mailmime_write</title>
+
+ <programlisting role="C">
+#include &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+int main(int argc, char ** argv)
+{
+ int col;
+
+ col = 0;
+ mailmime_quoted_printable_write(stdout, &amp;col,
+ "this is a test", 14);
+}
+
+#include &lt;libetpan/libetpan.h&gt;
+
+int main(int argc, char ** argv)
+{
+ int col;
+
+ col = 0;
+ mailmime_base64_write(stdout, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+#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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+#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, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+#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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+#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, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+#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, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+int main(int argc, char ** argv)
+{
+ int fd;
+ int r;
+
+ status = EXIT_FAILURE;
+
+ fd = open("message.rfc2822", O_RDONLY);
+ if (fd &gt;= 0) {
+ void * mem;
+ struct stat stat_info;
+
+ r = fstat(fd, &amp;stat_info);
+ if (r &gt;= 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,
+ &amp;current_index, &amp;f);
+ if (r == MAILIMF_NO_ERROR) {
+ struct mailmime_fields * mime_fields;
+
+ r = mailmime_fields_parse(f, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/mman.h&gt;
+
+int main(int argc, char ** argv)
+{
+ int fd;
+ int r;
+
+ status = EXIT_FAILURE;
+
+ fd = open("message.rfc2822", O_RDONLY);
+ if (fd &gt;= 0) {
+ void * mem;
+ struct stat stat_info;
+
+ r = fstat(fd, &amp;stat_info);
+ if (r &gt;= 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,
+ &amp;current_index, &amp;f);
+ if (r == MAILIMF_NO_ERROR) {
+ clistiter * cur;
+
+ for(cur = clist_begin(f-&gt;fld_list) ; cur != NULL ; cur =
+ clist_next(cur)) {
+ struct mailmime_field * mime_field;
+ struct mailimf_field * field;
+
+ field = clist_content(cur);
+
+ if (field-&gt;fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
+ if (strcasecmp(field-&gt;fld_data.fld_optional_field-&gt;fld_name,
+ "Content-Type") == 0) {
+ struct mailmime_content * content_type;
+ size_t current_index;
+
+ current_index = 0;
+ r = mailmime_content_parse(field-&gt;fld_data.fld_optional_field-&gt;fld_value,
+ strlen(field-&gt;fld_data.fld_optional_field-&gt;fld_value),
+ &amp;current_index, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+enum {
+ MAIL_FLAG_NEW = 1 &lt;&lt; 0,
+ MAIL_FLAG_SEEN = 1 &lt;&lt; 1,
+ MAIL_FLAG_FLAGGED = 1 &lt;&lt; 2,
+ MAIL_FLAG_DELETED = 1 &lt;&lt; 3,
+ MAIL_FLAG_ANSWERED = 1 &lt;&lt; 4,
+ MAIL_FLAG_FORWARDED = 1 &lt;&lt; 5,
+ MAIL_FLAG_CANCELLED = 1 &lt;&lt; 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 &lt;libetpan/libetpan.h&gt;
+
+#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-&gt;mm_type == MAILMIME_SINGLE) {
+ if (build_info-&gt;mm_content_type != NULL) {
+ if (build_info-&gt;mm_content_type-&gt;ct_type-&gt;tp_type ==
+ MAILMIME_TYPE_DISCRETE_TYPE) {
+ if (build_info-&gt;mm_content_type-&gt;ct_type-&gt;tp_data.tp_discrete_type-&gt;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-&gt;fld_description;
+ filename = mime_fields-&gt;fld_disposition_filename;
+
+ col = 0;
+
+ r = fprintf(f, " [ Part ");
+ if (r &lt; 0)
+ goto err;
+
+ if (content != NULL) {
+ r = mailmime_content_type_write(f, &amp;col, content);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+ }
+
+ if (filename != NULL) {
+ r = fprintf(f, " (%s)", filename);
+ if (r &lt; 0)
+ goto err;
+ }
+
+ if (description != NULL) {
+ r = fprintf(f, " : %s", description);
+ if (r &lt; 0)
+ goto err;
+ }
+
+ r = fprintf(f, " ]\n\n");
+ if (r &lt; 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, &amp;data, &amp;len);
+ if (r != MAIL_NO_ERROR) {
+ res = ERROR_FETCH;
+ goto err;
+ }
+
+ encoded = 1;
+
+ /* decode message */
+
+ if (encoded) {
+ if (fields-&gt;fld_encoding != NULL)
+ encoding = fields-&gt;fld_encoding-&gt;enc_type;
+ else
+ encoding = MAILMIME_MECHANISM_8BIT;
+ }
+ else {
+ encoding = MAILMIME_MECHANISM_8BIT;
+ }
+
+ cur_token = 0;
+ r = mailmime_part_parse(data, len, &amp;cur_token,
+ encoding, &amp;decoded, &amp;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,
+ &amp;data, &amp;len);
+ if (r != MAIL_NO_ERROR)
+ return NULL;
+
+ cur_token = 0;
+ r = mailimf_envelopes_fields_parse(data, len,
+ &amp;cur_token, &amp;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(&amp;fields, mime-&gt;mm_mime_fields,
+ mime-&gt;mm_content_type);
+
+ text = etpan_mime_is_text(mime);
+
+ r = show_part_info(f, &amp;fields, mime-&gt;mm_content_type);
+ if (r != NO_ERROR) {
+ res = r;
+ goto err;
+ }
+
+ switch(mime-&gt;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,
+ &amp;fields, &amp;data, &amp;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, &amp;converted, &amp;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 &lt; 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 &lt; 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 &lt; 0) {
+ res = ERROR_FILE;
+ goto err;
+ }
+ }
+
+ break;
+
+ case MAILMIME_MULTIPLE:
+
+ if (strcasecmp(mime-&gt;mm_content_type-&gt;ct_subtype,
+ "alternative") == 0) {
+ struct mailmime * prefered_body;
+ int prefered_score;
+
+ /* case of multiple/alternative */
+
+ /*
+ we choose the better part,
+ alternative preference :
+
+ text/plain =&gt; score 3
+ text/xxx =&gt; score 2
+ other =&gt; score 1
+ */
+
+ prefered_body = NULL;
+ prefered_score = 0;
+
+ for(cur = clist_begin(mime-&gt;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-&gt;mm_content_type != NULL) {
+ if (strcasecmp(submime-&gt;mm_content_type-&gt;ct_subtype,
+ "plain") == 0)
+ score = 3;
+ }
+
+ if (score &gt; 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-&gt;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-&gt;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, &amp;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, &amp;col, mime-&gt;mm_data.mm_message.mm_fields);
+ if (r != NO_ERROR) {
+ res = r;
+ goto err;
+ }
+ }
+
+ r = fprintf(f, "\r\n");
+ if (r &lt; 0) {
+ res = ERROR_FILE;
+ goto err;
+ }
+ }
+
+ if (mime-&gt;mm_data.mm_message.mm_msg_mime != NULL) {
+ r = etpan_render_mime(f, msg_info,
+ mime-&gt;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, &amp;msg_list);
+
+ if (carray_count(msg_list-&gt;msg_tab) &gt; 0) {
+ struct mailmime * mime;
+
+ msg = carray_get(msg_list-&gt;msg_tab, 0);
+
+ mailmessage_get_bodystructure(msg, &amp;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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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 &lt;libetpan/libetpan.h&gt;
+
+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>