Added SILC Thread Queue API
[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.  Returns NULL if system is out of
75  *    memory.
76  *
77  ***/
78 SilcMime silc_mime_alloc(void);
79
80 /****f* silcutil/SILCMIMEAPI/silc_mime_free
81  *
82  * SYNOPSIS
83  *
84  *    void silc_mime_alloc(SilcMime mime)
85  *
86  * DESCRIPTION
87  *
88  *    Frees `mime' context.
89  *
90  ***/
91 void silc_mime_free(SilcMime mime);
92
93 /****f* silcutil/SILCMIMEAPI/silc_mime_assembler_alloc
94  *
95  * SYNOPSIS
96  *
97  *    SilcMimeAssembler silc_mime_assembler_alloc(void);
98  *
99  * DESCRIPTION
100  *
101  *    Allocates MIME fragment assembler.  Returns NULL if system is out of
102  *    memory.
103  *
104  ***/
105 SilcMimeAssembler silc_mime_assembler_alloc(void);
106
107 /****f* silcutil/SILCMIMEAPI/silc_mime_assembler_free
108  *
109  * SYNOPSIS
110  *
111  *    void silc_mime_assembler_free(SilcMimeAssembler assembler)
112  *
113  * DESCRIPTION
114  *
115  *    Frees `assembler' context.
116  *
117  ***/
118 void silc_mime_assembler_free(SilcMimeAssembler assembler);
119
120 /****f* silcutil/SILCMIMEAPI/silc_mime_assembler_purge
121  *
122  * SYNOPSIS
123  *
124  *    void silc_mime_assembler_purge(SilcMimeAssembler assembler,
125  *                                   SilcUInt32 purge_minutes);
126  *
127  * DESCRIPTION
128  *
129  *    Purges the MIME fragment assembler from old fragments that have never
130  *    completed into a full MIME message.  This function may be called
131  *    periodically to purge MIME fragments.  The `purge_minutes' specify
132  *    how old fragments are purged.  If it is 0, fragments older than 5 minutes
133  *    are purged, by default.  The value is in minutes.
134  *
135  *    It is usefull to call this periodically to assure that memory is not
136  *    consumed needlessly by keeping old unfinished fragments in a long
137  *    running assembler.
138  *
139  ***/
140 void silc_mime_assembler_purge(SilcMimeAssembler assembler,
141                                SilcUInt32 purge_minutes);
142
143 /****f* silcutil/SILCMIMEAPI/silc_mime_decode
144  *
145  * SYNOPSIS
146  *
147  *    SilcMime silc_mime_decode(SilcMime mime, const unsigned char *data,
148  *                              SilcUInt32 data_len);
149  *
150  * DESCRIPTION
151  *
152  *    Decodes a MIME message and returns the parsed message into newly
153  *    allocated SilcMime context and returns it.  If `mime' is non-NULL
154  *    then the MIME message will be encoded into the pre-allocated `mime'
155  *    context and same context is returned.  If it is NULL then newly
156  *    allocated SilcMime context is returned.  On error NULL is returned.
157  *
158  * EXAMPLE
159  *
160  *    // Parse MIME message and get its content type
161  *    mime = silc_mime_decode(NULL, data, data_len);
162  *    type = silc_mime_get_field(mime, "Content-Type");
163  *    ...
164  *
165  *    // Assemble received MIME fragment
166  *    mime = silc_mime_decode(NULL, data, data_len);
167  *    if (silc_mime_is_partial(mime) == TRUE)
168  *      silc_mime_assmeble(assembler, mime);
169  *
170  ***/
171 SilcMime silc_mime_decode(SilcMime mime, const unsigned char *data,
172                           SilcUInt32 data_len);
173
174 /****f* silcutil/SILCMIMEAPI/silc_mime_encode
175  *
176  * SYNOPSIS
177  *
178  *    unsigned char *silc_mime_encode(SilcMime mime, SilcUInt32 *encoded_len);
179  *
180  * DESCRIPTION
181  *
182  *    Encodes the `mime' context into a raw MIME message (may be human
183  *    readable).  The caller must free the returned buffer.  If the `mime'
184  *    is multipart MIME message all parts will be automatically encoded
185  *    as well.
186  *
187  *    If you want to create fragmented MIME message use the function
188  *    silc_mime_encode_partial.
189  *
190  ***/
191 unsigned char *silc_mime_encode(SilcMime mime, SilcUInt32 *encoded_len);
192
193 /****f* silcutil/SILCMIMEAPI/silc_mime_assemble
194  *
195  * SYNOPSIS
196  *
197  *    SilcMime silc_mime_assemble(SilcMimeAssembler assembler,
198  *                                SilcMime partial);
199  *
200  * DESCRIPTION
201  *
202  *    Processes and attempts to assemble the received MIME fragment `partial'.
203  *    To check if a received MIME message is a fragment use the
204  *    silc_mime_is_partial function.  Returns NULL if all fragments have not
205  *    yet been received, or the newly allocated completed MIME message if
206  *    all fragments were received.  The caller must free the returned
207  *    SilcMime context.  The caller must not free the `partial'.
208  *
209  * EXAMPLE
210  *
211  *    // Assemble received MIME fragment
212  *    mime = silc_mime_decode(data, data_len);
213  *    if (silc_mime_is_partial(mime) == TRUE) {
214  *      complete = silc_mime_assmeble(assembler, mime);
215  *      if (complete == NULL)
216  *        return;
217  *      ...
218  *    }
219  *
220  ***/
221 SilcMime silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial);
222
223 /****f* silcutil/SILCMIMEAPI/silc_mime_encode_partial
224  *
225  * SYNOPSIS
226  *
227  *    SilcDList silc_mime_encode_partial(SilcMime mime, int max_size);
228  *
229  * DESCRIPTION
230  *
231  *    Same as silc_mime_encode except fragments the MIME message `mime'
232  *    if it is larger than `max_size' in bytes.  Returns the MIME fragments
233  *    in SilcDList where each entry is SilcBuffer context.  The caller must
234  *    free the returned list and all SilcBuffer entries in it by calling
235  *    silc_mime_partial_free function.
236  *
237  *    To assemble the fragments into a complete MIME message the
238  *    silc_mime_assemble can be used.
239  *
240  ***/
241 SilcDList silc_mime_encode_partial(SilcMime mime, int max_size);
242
243 /****f* silcutil/SILCMIMEAPI/silc_mime_partial_free
244  *
245  * SYNOPSIS
246  *
247  *    void silc_mime_partial_free(SilcDList partials);
248  *
249  * DESCRIPTION
250  *
251  *    This function must be called to free the list returned by the
252  *    silc_mime_encode_partial function.
253  *
254  ***/
255 void silc_mime_partial_free(SilcDList partials);
256
257 /****f* silcutil/SILCMIMEAPI/silc_mime_add_field
258  *
259  * SYNOPSIS
260  *
261  *    void silc_mime_add_field(SilcMime mime,
262  *                             const char *field, const char *value);
263  *
264  * DESCRIPTION
265  *
266  *    Adds a field indicated by `field' to MIME message `mime'.  The field
267  *    value is `value'.
268  *
269  * EXAMPLE
270  *
271  *    silc_mime_add_field(mime, "MIME-Version", "1.0");
272  *    silc_mime_add_field(mime, "Content-Type", "image/jpeg");
273  *    silc_mime_add_field(mime, "Content-Transfer-Encoding", "binary");
274  *
275  ***/
276 void silc_mime_add_field(SilcMime mime, const char *field, const char *value);
277
278 /****f* silcutil/SILCMIMEAPI/silc_mime_get_field
279  *
280  * SYNOPSIS
281  *
282  *    const char *silc_mime_get_field(SilcMime mime, const char *field);
283  *
284  * DESCRIPTION
285  *
286  *    Returns the `field' value or NULL if such field does not exist in the
287  *    MIME message `mime'.
288  *
289  ***/
290 const char *silc_mime_get_field(SilcMime mime, const char *field);
291
292 /****f* silcutil/SILCMIMEAPI/silc_mime_add_data
293  *
294  * SYNOPSIS
295  *
296  *    void silc_mime_add_data(SilcMime mime, const unsigned char *data,
297  *                            SilcUInt32 data_len);
298  *
299  * DESCRIPTION
300  *
301  *    Adds the actual MIME data to the `mime' message.
302  *
303  ***/
304 void silc_mime_add_data(SilcMime mime, const unsigned char *data,
305                         SilcUInt32 data_len);
306
307 /****f* silcutil/SILCMIMEAPI/silc_mime_get_data
308  *
309  * SYNOPSIS
310  *
311  *    const unsigned char *
312  *    silc_mime_get_data(SilcMime mime, SilcUInt32 *data_len);
313  *
314  * DESCRIPTION
315  *
316  *    Returns the MIME data from the `mime' message.
317  *
318  ***/
319 const unsigned char *silc_mime_get_data(SilcMime mime, SilcUInt32 *data_len);
320
321 /****f* silcutil/SILCMIMEAPI/silc_mime_steal_data
322  *
323  * SYNOPSIS
324  *
325  *    unsigned char *
326  *    silc_mime_steal_data(SilcMime mime, SilcUInt32 *data_len);
327  *
328  * DESCRIPTION
329  *
330  *    Returns the MIME data from the `mime' message.  The data will be
331  *    removed from the `mime' and the caller is responsible of freeing the
332  *    returned pointer.
333  *
334  ***/
335 unsigned char *silc_mime_steal_data(SilcMime mime, SilcUInt32 *data_len);
336
337 /****f* silcutil/SILCMIMEAPI/silc_mime_is_partial
338  *
339  * SYNOPSIS
340  *
341  *    SilcBool silc_mime_is_partial(SilcMime mime);
342  *
343  * DESCRIPTION
344  *
345  *    Returns TRUE if the MIME message `mime' is a partial MIME fragment.
346  *
347  ***/
348 SilcBool silc_mime_is_partial(SilcMime mime);
349
350 /****f* silcutil/SILCMIMEAPI/silc_mime_set_multipart
351  *
352  * SYNOPSIS
353  *
354  *    void silc_mime_set_multipart(SilcMime mime, const char *type,
355  *                                 const char *boundary);
356  *
357  * DESCRIPTION
358  *
359  *    Sets the `mime' to be a multipart MIME message.  The `type' specifies
360  *    the multipart type, usually "mixed", but can be something else too.
361  *    The `boundary' specifies the multipart boundary.
362  *
363  ***/
364 void silc_mime_set_multipart(SilcMime mime, const char *type,
365                              const char *boundary);
366
367 /****f* silcutil/SILCMIMEAPI/silc_mime_add_multipart
368  *
369  * SYNOPSIS
370  *
371  *    SilcBool silc_mime_add_multipart(SilcMime mime, SilcMime part);
372  *
373  * DESCRIPTION
374  *
375  *    Adds a multipart `part` to MIME message `mime'.  The `part' will be
376  *    freed automatically when silc_mime_free is called for `mime'.  Returns
377  *    TRUE if `part' was added to `mime' and FALSE if `mime' is not marked
378  *    as multipart MIME message.
379  *
380  * NOTES
381  *
382  *    The silc_mime_set_multipart must be called for `mime' before parts
383  *    can be added to it.  Otherwise FALSE will be returned.
384  *
385  * EXAMPLE
386  *
387  *    part = silc_mime_alloc();
388  *    silc_mime_add_field(part, "Content-Type", "image/jpeg");
389  *    silc_mime_add_data(part, data, data_len);
390  *
391  *    silc_mime_set_multipart(mime, "mixed", "boundary1");
392  *    silc_mime_add_multipart(mime, part);
393  *
394  ***/
395 SilcBool silc_mime_add_multipart(SilcMime mime, SilcMime part);
396
397 /****f* silcutil/SILCMIMEAPI/silc_mime_is_multipart
398  *
399  * SYNOPSIS
400  *
401  *    SilcBool silc_mime_is_multipart(SilcMime mime);
402  *
403  * DESCRIPTION
404  *
405  *    Returns TRUE if the MIME message `mime' is a multipart MIME message.
406  *    Its parts can be get by calling silc_mime_get_multiparts.
407  *
408  ***/
409 SilcBool silc_mime_is_multipart(SilcMime mime);
410
411 /****f* silcutil/SILCMIMEAPI/silc_mime_get_multiparts
412  *
413  * SYNOPSIS
414  *
415  *    SilcDList silc_mime_get_multiparts(SilcMime mime, const char **type);
416  *
417  * DESCRIPTION
418  *
419  *    Returns list of the parts from the MIME message `mime'.  Each entry
420  *    in the list is SilcMime context.  The caller must not free the returned
421  *    list or the SilcMime contexts in the list.  Returns NULL if no parts
422  *    exists in the MIME message.  Returns the multipart type (like "mixed")
423  *    into `type' pointer.
424  *
425  ***/
426 SilcDList silc_mime_get_multiparts(SilcMime mime, const char **type);
427
428 #include "silcmime_i.h"
429
430 #endif /* SILCMIME_H */