Added silc_mime_assembler_purge.
[silc.git] / lib / silcutil / silcmime.h
1 /*
2
3   silcmime.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2005 - 2007 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 /****h* silcutil/SILC MIME Interface
21  *
22  * DESCRIPTION
23  *
24  * Simple implementation of MIME.  Supports creation and parsing of simple
25  * MIME messages, multipart MIME messages, including nested multiparts, and
26  * MIME fragmentation and defragmentation.
27  *
28  * SILC Mime API is not thread-safe.  If the same MIME context must be
29  * used in multithreaded environment concurrency control must be employed.
30  *
31  ***/
32
33 #ifndef SILCMIME_H
34 #define SILCMIME_H
35
36 /****s* silcutil/SILCMIMEAPI/SilcMime
37  *
38  * NAME
39  *
40  *    typedef struct SilcMimeStruct *SilcMime;
41  *
42  * DESCRIPTION
43  *
44  *    This context is the actual MIME message and is allocated
45  *    by silc_mime_alloc and given as argument to all silc_mime_*
46  *    functions.  It is freed by the silc_mime_free function.
47  *
48  ***/
49 typedef struct SilcMimeStruct *SilcMime;
50
51 /****s* silcutil/SILCMIMEAPI/SilcMimeAssembler
52  *
53  * NAME
54  *
55  *    typedef struct SilcMimeAssemblerStruct *SilcMimeAssembler;
56  *
57  * DESCRIPTION
58  *
59  *    This context is a SILC MIME Assembler that is used to assemble partial
60  *    MIME messages (fgraments) into complete MIME messages.  It is allocated
61  *    by silc_mime_assembler_alloc and freed by silc_mime_assembler_free.
62  *
63  ***/
64 typedef struct SilcMimeAssemblerStruct *SilcMimeAssembler;
65
66 /****f* silcutil/SILCMIMEAPI/silc_mime_alloc
67  *
68  * SYNOPSIS
69  *
70  *    SilcMime silc_mime_alloc(void)
71  *
72  * DESCRIPTION
73  *
74  *    Allocates SILC Mime message context.
75  *
76  ***/
77 SilcMime silc_mime_alloc(void);
78
79 /****f* silcutil/SILCMIMEAPI/silc_mime_free
80  *
81  * SYNOPSIS
82  *
83  *    void silc_mime_alloc(SilcMime mime)
84  *
85  * DESCRIPTION
86  *
87  *    Frees `mime' context.
88  *
89  ***/
90 void silc_mime_free(SilcMime mime);
91
92 /****f* silcutil/SILCMIMEAPI/silc_mime_assembler_alloc
93  *
94  * SYNOPSIS
95  *
96  *    SilcMimeAssembler silc_mime_assembler_alloc(void);
97  *
98  * DESCRIPTION
99  *
100  *    Allocates MIME fragment assembler.
101  *
102  ***/
103 SilcMimeAssembler silc_mime_assembler_alloc(void);
104
105 /****f* silcutil/SILCMIMEAPI/silc_mime_assembler_free
106  *
107  * SYNOPSIS
108  *
109  *    void silc_mime_assembler_free(SilcMimeAssembler assembler)
110  *
111  * DESCRIPTION
112  *
113  *    Frees `assembler' context.
114  *
115  ***/
116 void silc_mime_assembler_free(SilcMimeAssembler assembler);
117
118 /****f* silcutil/SILCMIMEAPI/silc_mime_assembler_purge
119  *
120  * SYNOPSIS
121  *
122  *    void silc_mime_assembler_purge(SilcMimeAssembler assembler,
123  *                                   SilcUInt32 purge_minutes);
124  *
125  * DESCRIPTION
126  *
127  *    Purges the MIME fragment assembler from old fragments that have never
128  *    completed into a full MIME message.  This function may be called
129  *    periodically to purge MIME fragments.  The `purge_minutes' specify
130  *    how old fragments are purged.  If it is 0, fragments older than 5 minutes
131  *    are purged, by default.  The value is in minutes.
132  *
133  *    It is usefull to call this periodically to assure that memory is not
134  *    consumed needlessly by keeping old unfinished fragments in a long
135  *    running assembler.
136  *
137  ***/
138 void silc_mime_assembler_purge(SilcMimeAssembler assembler,
139                                SilcUInt32 purge_minutes);
140
141 /****f* silcutil/SILCMIMEAPI/silc_mime_decode
142  *
143  * SYNOPSIS
144  *
145  *    SilcMime silc_mime_decode(SilcMime mime, const unsigned char *data,
146  *                              SilcUInt32 data_len);
147  *
148  * DESCRIPTION
149  *
150  *    Decodes a MIME message and returns the parsed message into newly
151  *    allocated SilcMime context and returns it.  If `mime' is non-NULL
152  *    then the MIME message will be encoded into the pre-allocated `mime'
153  *    context and same context is returned.  If it is NULL then newly
154  *    allocated SilcMime context is returned.  On error NULL is returned.
155  *
156  * EXAMPLE
157  *
158  *    // Parse MIME message and get its content type
159  *    mime = silc_mime_decode(NULL, data, data_len);
160  *    type = silc_mime_get_field(mime, "Content-Type");
161  *    ...
162  *
163  *    // Assemble received MIME fragment
164  *    mime = silc_mime_decode(NULL, data, data_len);
165  *    if (silc_mime_is_partial(mime) == TRUE)
166  *      silc_mime_assmeble(assembler, mime);
167  *
168  ***/
169 SilcMime silc_mime_decode(SilcMime mime, const unsigned char *data,
170                           SilcUInt32 data_len);
171
172 /****f* silcutil/SILCMIMEAPI/silc_mime_encode
173  *
174  * SYNOPSIS
175  *
176  *    unsigned char *silc_mime_encode(SilcMime mime, SilcUInt32 *encoded_len);
177  *
178  * DESCRIPTION
179  *
180  *    Encodes the `mime' context into a raw MIME message (may be human
181  *    readable).  The caller must free the returned buffer.  If the `mime'
182  *    is multipart MIME message all parts will be automatically encoded
183  *    as well.
184  *
185  *    If you want to create fragmented MIME message use the function
186  *    silc_mime_encode_partial.
187  *
188  ***/
189 unsigned char *silc_mime_encode(SilcMime mime, SilcUInt32 *encoded_len);
190
191 /****f* silcutil/SILCMIMEAPI/silc_mime_assemble
192  *
193  * SYNOPSIS
194  *
195  *    SilcMime silc_mime_assemble(SilcMimeAssembler assembler,
196  *                                SilcMime partial);
197  *
198  * DESCRIPTION
199  *
200  *    Processes and attempts to assemble the received MIME fragment `partial'.
201  *    To check if a received MIME message is a fragment use the
202  *    silc_mime_is_partial function.  Returns NULL if all fragments have not
203  *    yet been received, or the newly allocated completed MIME message if
204  *    all fragments were received.  The caller must free the returned
205  *    SilcMime context.  The caller must not free the `partial'.
206  *
207  * EXAMPLE
208  *
209  *    // Assemble received MIME fragment
210  *    mime = silc_mime_decode(data, data_len);
211  *    if (silc_mime_is_partial(mime) == TRUE) {
212  *      complete = silc_mime_assmeble(assembler, mime);
213  *      if (complete == NULL)
214  *        return;
215  *      ...
216  *    }
217  *
218  ***/
219 SilcMime silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial);
220
221 /****f* silcutil/SILCMIMEAPI/silc_mime_encode_partial
222  *
223  * SYNOPSIS
224  *
225  *    SilcDList silc_mime_encode_partial(SilcMime mime, int max_size);
226  *
227  * DESCRIPTION
228  *
229  *    Same as silc_mime_encode except fragments the MIME message `mime'
230  *    if it is larger than `max_size' in bytes.  Returns the MIME fragments
231  *    in SilcDList where each entry is SilcBuffer context.  The caller must
232  *    free the returned list and all SilcBuffer entries in it by calling
233  *    silc_mime_partial_free function.
234  *
235  *    To assemble the fragments into a complete MIME message the
236  *    silc_mime_assemble can be used.
237  *
238  ***/
239 SilcDList silc_mime_encode_partial(SilcMime mime, int max_size);
240
241 /****f* silcutil/SILCMIMEAPI/silc_mime_partial_free
242  *
243  * SYNOPSIS
244  *
245  *    void silc_mime_partial_free(SilcDList partials);
246  *
247  * DESCRIPTION
248  *
249  *    This function must be called to free the list returned by the
250  *    silc_mime_encode_partial function.
251  *
252  ***/
253 void silc_mime_partial_free(SilcDList partials);
254
255 /****f* silcutil/SILCMIMEAPI/silc_mime_add_field
256  *
257  * SYNOPSIS
258  *
259  *    void silc_mime_add_field(SilcMime mime,
260  *                             const char *field, const char *value);
261  *
262  * DESCRIPTION
263  *
264  *    Adds a field indicated by `field' to MIME message `mime'.  The field
265  *    value is `value'.
266  *
267  * EXAMPLE
268  *
269  *    silc_mime_add_field(mime, "MIME-Version", "1.0");
270  *    silc_mime_add_field(mime, "Content-Type", "image/jpeg");
271  *    silc_mime_add_field(mime, "Content-Transfer-Encoding", "binary");
272  *
273  ***/
274 void silc_mime_add_field(SilcMime mime, const char *field, const char *value);
275
276 /****f* silcutil/SILCMIMEAPI/silc_mime_get_field
277  *
278  * SYNOPSIS
279  *
280  *    const char *silc_mime_get_field(SilcMime mime, const char *field);
281  *
282  * DESCRIPTION
283  *
284  *    Returns the `field' value or NULL if such field does not exist in the
285  *    MIME message `mime'.
286  *
287  ***/
288 const char *silc_mime_get_field(SilcMime mime, const char *field);
289
290 /****f* silcutil/SILCMIMEAPI/silc_mime_add_data
291  *
292  * SYNOPSIS
293  *
294  *    void silc_mime_add_data(SilcMime mime, const unsigned char *data,
295  *                            SilcUInt32 data_len);
296  *
297  * DESCRIPTION
298  *
299  *    Adds the actual MIME data to the `mime' message.
300  *
301  ***/
302 void silc_mime_add_data(SilcMime mime, const unsigned char *data,
303                         SilcUInt32 data_len);
304
305 /****f* silcutil/SILCMIMEAPI/silc_mime_get_data
306  *
307  * SYNOPSIS
308  *
309  *    const unsigned char *
310  *    silc_mime_get_data(SilcMime mime, SilcUInt32 *data_len);
311  *
312  * DESCRIPTION
313  *
314  *    Returns the MIME data from the `mime' message.
315  *
316  ***/
317 const unsigned char *silc_mime_get_data(SilcMime mime, SilcUInt32 *data_len);
318
319 /****f* silcutil/SILCMIMEAPI/silc_mime_steal_data
320  *
321  * SYNOPSIS
322  *
323  *    unsigned char *
324  *    silc_mime_steal_data(SilcMime mime, SilcUInt32 *data_len);
325  *
326  * DESCRIPTION
327  *
328  *    Returns the MIME data from the `mime' message.  The data will be
329  *    removed from the `mime' and the caller is responsible of freeing the
330  *    returned pointer.
331  *
332  ***/
333 unsigned char *silc_mime_steal_data(SilcMime mime, SilcUInt32 *data_len);
334
335 /****f* silcutil/SILCMIMEAPI/silc_mime_is_partial
336  *
337  * SYNOPSIS
338  *
339  *    SilcBool silc_mime_is_partial(SilcMime mime);
340  *
341  * DESCRIPTION
342  *
343  *    Returns TRUE if the MIME message `mime' is a partial MIME fragment.
344  *
345  ***/
346 SilcBool silc_mime_is_partial(SilcMime mime);
347
348 /****f* silcutil/SILCMIMEAPI/silc_mime_set_multipart
349  *
350  * SYNOPSIS
351  *
352  *    void silc_mime_set_multipart(SilcMime mime, const char *type,
353  *                                 const char *boundary);
354  *
355  * DESCRIPTION
356  *
357  *    Sets the `mime' to be a multipart MIME message.  The `type' specifies
358  *    the multipart type, usually "mixed", but can be something else too.
359  *    The `boundary' specifies the multipart boundary.
360  *
361  ***/
362 void silc_mime_set_multipart(SilcMime mime, const char *type,
363                              const char *boundary);
364
365 /****f* silcutil/SILCMIMEAPI/silc_mime_add_multipart
366  *
367  * SYNOPSIS
368  *
369  *    SilcBool silc_mime_add_multipart(SilcMime mime, SilcMime part);
370  *
371  * DESCRIPTION
372  *
373  *    Adds a multipart `part` to MIME message `mime'.  The `part' will be
374  *    freed automatically when silc_mime_free is called for `mime'.  Returns
375  *    TRUE if `part' was added to `mime' and FALSE if `mime' is not marked
376  *    as multipart MIME message.
377  *
378  * NOTES
379  *
380  *    The silc_mime_set_multipart must be called for `mime' before parts
381  *    can be added to it.  Otherwise FALSE will be returned.
382  *
383  * EXAMPLE
384  *
385  *    part = silc_mime_alloc();
386  *    silc_mime_add_field(part, "Content-Type", "image/jpeg");
387  *    silc_mime_add_data(part, data, data_len);
388  *
389  *    silc_mime_set_multipart(mime, "mixed", "boundary1");
390  *    silc_mime_add_multipart(mime, part);
391  *
392  ***/
393 SilcBool silc_mime_add_multipart(SilcMime mime, SilcMime part);
394
395 /****f* silcutil/SILCMIMEAPI/silc_mime_is_multipart
396  *
397  * SYNOPSIS
398  *
399  *    SilcBool silc_mime_is_multipart(SilcMime mime);
400  *
401  * DESCRIPTION
402  *
403  *    Returns TRUE if the MIME message `mime' is a multipart MIME message.
404  *    Its parts can be get by calling silc_mime_get_multiparts.
405  *
406  ***/
407 SilcBool silc_mime_is_multipart(SilcMime mime);
408
409 /****f* silcutil/SILCMIMEAPI/silc_mime_get_multiparts
410  *
411  * SYNOPSIS
412  *
413  *    SilcDList silc_mime_get_multiparts(SilcMime mime, const char **type);
414  *
415  * DESCRIPTION
416  *
417  *    Returns list of the parts from the MIME message `mime'.  Each entry
418  *    in the list is SilcMime context.  The caller must not free the returned
419  *    list or the SilcMime contexts in the list.  Returns NULL if no parts
420  *    exists in the MIME message.  Returns the multipart type (like "mixed")
421  *    into `type' pointer.
422  *
423  ***/
424 SilcDList silc_mime_get_multiparts(SilcMime mime, const char **type);
425
426 #include "silcmime_i.h"
427
428 #endif /* SILCMIME_H */