Merge branch 'topic/mm-fixes' of git://208.110.73.182/silc into silc.1.1.branch
[silc.git] / lib / silcutil / silcmime.h
1 /*
2
3   silcmime.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2005 - 2006 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_decode
119  *
120  * SYNOPSIS
121  *
122  *    SilcMime silc_mime_decode(SilcMime mime, const unsigned char *data,
123  *                              SilcUInt32 data_len);
124  *
125  * DESCRIPTION
126  *
127  *    Decodes a MIME message and returns the parsed message into newly
128  *    allocated SilcMime context and returns it.  If `mime' is non-NULL
129  *    then the MIME message will be encoded into the pre-allocated `mime'
130  *    context and same context is returned.  If it is NULL then newly
131  *    allocated SilcMime context is returned.  On error NULL is returned.
132  *
133  * EXAMPLE
134  *
135  *    // Parse MIME message and get its content type
136  *    mime = silc_mime_decode(NULL, data, data_len);
137  *    type = silc_mime_get_field(mime, "Content-Type");
138  *    ...
139  *
140  *    // Assemble received MIME fragment
141  *    mime = silc_mime_decode(NULL, data, data_len);
142  *    if (silc_mime_is_partial(mime) == TRUE)
143  *      silc_mime_assmeble(assembler, mime);
144  *
145  ***/
146 SilcMime silc_mime_decode(SilcMime mime, const unsigned char *data,
147                           SilcUInt32 data_len);
148
149 /****f* silcutil/SILCMIMEAPI/silc_mime_encode
150  *
151  * SYNOPSIS
152  *
153  *    unsigned char *silc_mime_encode(SilcMime mime, SilcUInt32 *encoded_len);
154  *
155  * DESCRIPTION
156  *
157  *    Encodes the `mime' context into a raw MIME message (may be human
158  *    readable).  The caller must free the returned buffer.  If the `mime'
159  *    is multipart MIME message all parts will be automatically encoded
160  *    as well.
161  *
162  *    If you want to create fragmented MIME message use the function
163  *    silc_mime_encode_partial.
164  *
165  ***/
166 unsigned char *silc_mime_encode(SilcMime mime, SilcUInt32 *encoded_len);
167
168 /****f* silcutil/SILCMIMEAPI/silc_mime_assemble
169  *
170  * SYNOPSIS
171  *
172  *    SilcMime silc_mime_assemble(SilcMimeAssembler assembler,
173  *                                SilcMime partial);
174  *
175  * DESCRIPTION
176  *
177  *    Processes and attempts to assemble the received MIME fragment `partial'.
178  *    To check if a received MIME message is a fragment use the
179  *    silc_mime_is_partial function.  Returns NULL if all fragments has not
180  *    yet been received, or the newly allocated completed MIME message if
181  *    all fragments were received.  The caller must free the returned
182  *    SilcMime context.  The caller must not free the `partial'.
183  *
184  * EXAMPLE
185  *
186  *    // Assemble received MIME fragment
187  *    mime = silc_mime_decode(data, data_len);
188  *    if (silc_mime_is_partial(mime) == TRUE) {
189  *      complete = silc_mime_assmeble(assembler, mime);
190  *      if (complete == NULL)
191  *        return;
192  *      ...
193  *    }
194  *
195  ***/
196 SilcMime silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial);
197
198 /****f* silcutil/SILCMIMEAPI/silc_mime_encode_partial
199  *
200  * SYNOPSIS
201  *
202  *    SilcDList silc_mime_encode_partial(SilcMime mime, int max_size);
203  *
204  * DESCRIPTION
205  *
206  *    Same as silc_mime_encode except fragments the MIME message `mime'
207  *    if it is larger than `max_size' in bytes.  Returns the MIME fragments
208  *    in SilcDList where each entry is SilcBuffer context.  The caller must
209  *    free the returned list and all SilcBuffer entries in it by calling
210  *    silc_mime_partial_free function.
211  *
212  *    To assemble the fragments into a complete MIME message the
213  *    silc_mime_assemble can be used.
214  *
215  ***/
216 SilcDList silc_mime_encode_partial(SilcMime mime, int max_size);
217
218 /****f* silcutil/SILCMIMEAPI/silc_mime_partial_free
219  *
220  * SYNOPSIS
221  *
222  *    void silc_mime_partial_free(SilcDList partials);
223  *
224  * DESCRIPTION
225  *
226  *    This function must be called to free the list returned by the
227  *    silc_mime_encode_partial function.
228  *
229  ***/
230 void silc_mime_partial_free(SilcDList partials);
231
232 /****f* silcutil/SILCMIMEAPI/silc_mime_add_field
233  *
234  * SYNOPSIS
235  *
236  *    void silc_mime_add_field(SilcMime mime,
237  *                             const char *field, const char *value);
238  *
239  * DESCRIPTION
240  *
241  *    Adds a field indicated by `field' to MIME message `mime'.  The field
242  *    value is `value'.
243  *
244  * EXAMPLE
245  *
246  *    silc_mime_add_field(mime, "MIME-Version", "1.0");
247  *    silc_mime_add_field(mime, "Content-Type", "image/jpeg");
248  *    silc_mime_add_field(mime, "Content-Transfer-Encoding", "binary");
249  *
250  ***/
251 void silc_mime_add_field(SilcMime mime, const char *field, const char *value);
252
253 /****f* silcutil/SILCMIMEAPI/silc_mime_get_field
254  *
255  * SYNOPSIS
256  *
257  *    const char *silc_mime_get_field(SilcMime mime, const char *field);
258  *
259  * DESCRIPTION
260  *
261  *    Returns the `field' value or NULL if such field does not exist in the
262  *    MIME message `mime'.
263  *
264  ***/
265 const char *silc_mime_get_field(SilcMime mime, const char *field);
266
267 /****f* silcutil/SILCMIMEAPI/silc_mime_add_data
268  *
269  * SYNOPSIS
270  *
271  *    void silc_mime_add_data(SilcMime mime, const unsigned char *data,
272  *                            SilcUInt32 data_len);
273  *
274  * DESCRIPTION
275  *
276  *    Adds the actual MIME data to the `mime' message.
277  *
278  ***/
279 void silc_mime_add_data(SilcMime mime, const unsigned char *data,
280                         SilcUInt32 data_len);
281
282 /****f* silcutil/SILCMIMEAPI/silc_mime_get_data
283  *
284  * SYNOPSIS
285  *
286  *    const unsigned char *
287  *    silc_mime_get_data(SilcMime mime, SilcUInt32 *data_len);
288  *
289  * DESCRIPTION
290  *
291  *    Returns the MIME data from the `mime' message.
292  *
293  ***/
294 const unsigned char *silc_mime_get_data(SilcMime mime, SilcUInt32 *data_len);
295
296 /****f* silcutil/SILCMIMEAPI/silc_mime_steal_data
297  *
298  * SYNOPSIS
299  *
300  *    unsigned char *
301  *    silc_mime_steal_data(SilcMime mime, SilcUInt32 *data_len);
302  *
303  * DESCRIPTION
304  *
305  *    Returns the MIME data from the `mime' message.  The data will be
306  *    removed from the `mime' and the caller is responsible of freeing the
307  *    returned pointer.
308  *
309  ***/
310 unsigned char *silc_mime_steal_data(SilcMime mime, SilcUInt32 *data_len);
311
312 /****f* silcutil/SILCMIMEAPI/silc_mime_is_partial
313  *
314  * SYNOPSIS
315  *
316  *    SilcBool silc_mime_is_partial(SilcMime mime);
317  *
318  * DESCRIPTION
319  *
320  *    Returns TRUE if the MIME message `mime' is a partial MIME fragment.
321  *
322  ***/
323 SilcBool silc_mime_is_partial(SilcMime mime);
324
325 /****f* silcutil/SILCMIMEAPI/silc_mime_set_multipart
326  *
327  * SYNOPSIS
328  *
329  *    void silc_mime_set_multipart(SilcMime mime, const char *type,
330  *                                 const char *boundary);
331  *
332  * DESCRIPTION
333  *
334  *    Sets the `mime' to be a multipart MIME message.  The `type' specifies
335  *    the multipart type, usually "mixed", but can be something else too.
336  *    The `boundary' specifies the multipart boundary.
337  *
338  ***/
339 void silc_mime_set_multipart(SilcMime mime, const char *type,
340                              const char *boundary);
341
342 /****f* silcutil/SILCMIMEAPI/silc_mime_add_multipart
343  *
344  * SYNOPSIS
345  *
346  *    SilcBool silc_mime_add_multipart(SilcMime mime, SilcMime part);
347  *
348  * DESCRIPTION
349  *
350  *    Adds a multipart `part` to MIME message `mime'.  The `part' will be
351  *    freed automatically when silc_mime_free is called for `mime'.  Returns
352  *    TRUE if `part' was added to `mime' and FALSE if `mime' is not marked
353  *    as multipart MIME message.
354  *
355  * NOTES
356  *
357  *    The silc_mime_set_multipart must be called for `mime' before parts
358  *    can be added to it.  Otherwise FALSE will be returned.
359  *
360  * EXAMPLE
361  *
362  *    part = silc_mime_alloc();
363  *    silc_mime_add_field(part, "Content-Type", "image/jpeg");
364  *    silc_mime_add_data(part, data, data_len);
365  *
366  *    silc_mime_set_multipart(mime, "mixed", "boundary1");
367  *    silc_mime_add_multipart(mime, part);
368  *
369  ***/
370 SilcBool silc_mime_add_multipart(SilcMime mime, SilcMime part);
371
372 /****f* silcutil/SILCMIMEAPI/silc_mime_is_multipart
373  *
374  * SYNOPSIS
375  *
376  *    SilcBool silc_mime_is_multipart(SilcMime mime);
377  *
378  * DESCRIPTION
379  *
380  *    Returns TRUE if the MIME message `mime' is a multipart MIME message.
381  *    Its parts can be get by calling silc_mime_get_multiparts.
382  *
383  ***/
384 SilcBool silc_mime_is_multipart(SilcMime mime);
385
386 /****f* silcutil/SILCMIMEAPI/silc_mime_get_multiparts
387  *
388  * SYNOPSIS
389  *
390  *    SilcDList silc_mime_get_multiparts(SilcMime mime, const char **type);
391  *
392  * DESCRIPTION
393  *
394  *    Returns list of the parts from the MIME message `mime'.  Each entry
395  *    in the list is SilcMime context.  The caller must not free the returned
396  *    list or the SilcMime contexts in the list.  Returns NULL if no parts
397  *    exists in the MIME message.  Returns the multipart type (like "mixed")
398  *    into `type' pointer.
399  *
400  ***/
401 SilcDList silc_mime_get_multiparts(SilcMime mime, const char **type);
402
403 #include "silcmime_i.h"
404
405 #endif /* SILCMIME_H */