libetpan - fdik
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

15097 lines
419 KiB

<!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