5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2005 - 2006 Pekka Riikonen
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.
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.
20 /****h* silcutil/SILC MIME Interface
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.
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.
36 /****s* silcutil/SILCMIMEAPI/SilcMime
40 * typedef struct SilcMimeStruct *SilcMime;
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.
49 typedef struct SilcMimeStruct *SilcMime;
51 /****s* silcutil/SILCMIMEAPI/SilcMimeAssembler
55 * typedef struct SilcMimeAssemblerStruct *SilcMimeAssembler;
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.
64 typedef struct SilcMimeAssemblerStruct *SilcMimeAssembler;
66 /****f* silcutil/SILCMIMEAPI/silc_mime_alloc
70 * SilcMime silc_mime_alloc(void)
74 * Allocates SILC Mime message context.
77 SilcMime silc_mime_alloc(void);
79 /****f* silcutil/SILCMIMEAPI/silc_mime_free
83 * void silc_mime_alloc(SilcMime mime)
87 * Frees `mime' context.
90 void silc_mime_free(SilcMime mime);
92 /****f* silcutil/SILCMIMEAPI/silc_mime_assembler_alloc
96 * SilcMimeAssembler silc_mime_assembler_alloc(void);
100 * Allocates MIME fragment assembler.
103 SilcMimeAssembler silc_mime_assembler_alloc(void);
105 /****f* silcutil/SILCMIMEAPI/silc_mime_assembler_free
109 * void silc_mime_assembler_free(SilcMimeAssembler assembler)
113 * Frees `assembler' context.
116 void silc_mime_assembler_free(SilcMimeAssembler assembler);
118 /****f* silcutil/SILCMIMEAPI/silc_mime_decode
122 * SilcMime silc_mime_decode(SilcMime mime, const unsigned char *data,
123 * SilcUInt32 data_len);
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.
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");
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);
146 SilcMime silc_mime_decode(SilcMime mime, const unsigned char *data,
147 SilcUInt32 data_len);
149 /****f* silcutil/SILCMIMEAPI/silc_mime_encode
153 * unsigned char *silc_mime_encode(SilcMime mime, SilcUInt32 *encoded_len);
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
162 * If you want to create fragmented MIME message use the function
163 * silc_mime_encode_partial.
166 unsigned char *silc_mime_encode(SilcMime mime, SilcUInt32 *encoded_len);
168 /****f* silcutil/SILCMIMEAPI/silc_mime_assemble
172 * SilcMime silc_mime_assemble(SilcMimeAssembler assembler,
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'.
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)
196 SilcMime silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial);
198 /****f* silcutil/SILCMIMEAPI/silc_mime_encode_partial
202 * SilcDList silc_mime_encode_partial(SilcMime mime, int max_size);
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.
212 * To assemble the fragments into a complete MIME message the
213 * silc_mime_assemble can be used.
216 SilcDList silc_mime_encode_partial(SilcMime mime, int max_size);
218 /****f* silcutil/SILCMIMEAPI/silc_mime_partial_free
222 * void silc_mime_partial_free(SilcDList partials);
226 * This function must be called to free the list returned by the
227 * silc_mime_encode_partial function.
230 void silc_mime_partial_free(SilcDList partials);
232 /****f* silcutil/SILCMIMEAPI/silc_mime_add_field
236 * void silc_mime_add_field(SilcMime mime,
237 * const char *field, const char *value);
241 * Adds a field indicated by `field' to MIME message `mime'. The field
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");
251 void silc_mime_add_field(SilcMime mime, const char *field, const char *value);
253 /****f* silcutil/SILCMIMEAPI/silc_mime_get_field
257 * const char *silc_mime_get_field(SilcMime mime, const char *field);
261 * Returns the `field' value or NULL if such field does not exist in the
262 * MIME message `mime'.
265 const char *silc_mime_get_field(SilcMime mime, const char *field);
267 /****f* silcutil/SILCMIMEAPI/silc_mime_add_data
271 * void silc_mime_add_data(SilcMime mime, const unsigned char *data,
272 * SilcUInt32 data_len);
276 * Adds the actual MIME data to the `mime' message.
279 void silc_mime_add_data(SilcMime mime, const unsigned char *data,
280 SilcUInt32 data_len);
282 /****f* silcutil/SILCMIMEAPI/silc_mime_get_data
286 * const unsigned char *
287 * silc_mime_get_data(SilcMime mime, SilcUInt32 *data_len);
291 * Returns the MIME data from the `mime' message.
294 const unsigned char *silc_mime_get_data(SilcMime mime, SilcUInt32 *data_len);
296 /****f* silcutil/SILCMIMEAPI/silc_mime_steal_data
301 * silc_mime_steal_data(SilcMime mime, SilcUInt32 *data_len);
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
310 unsigned char *silc_mime_steal_data(SilcMime mime, SilcUInt32 *data_len);
312 /****f* silcutil/SILCMIMEAPI/silc_mime_is_partial
316 * SilcBool silc_mime_is_partial(SilcMime mime);
320 * Returns TRUE if the MIME message `mime' is a partial MIME fragment.
323 SilcBool silc_mime_is_partial(SilcMime mime);
325 /****f* silcutil/SILCMIMEAPI/silc_mime_set_multipart
329 * void silc_mime_set_multipart(SilcMime mime, const char *type,
330 * const char *boundary);
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.
339 void silc_mime_set_multipart(SilcMime mime, const char *type,
340 const char *boundary);
342 /****f* silcutil/SILCMIMEAPI/silc_mime_add_multipart
346 * SilcBool silc_mime_add_multipart(SilcMime mime, SilcMime part);
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.
357 * The silc_mime_set_multipart must be called for `mime' before parts
358 * can be added to it. Otherwise FALSE will be returned.
362 * part = silc_mime_alloc();
363 * silc_mime_add_field(part, "Content-Type", "image/jpeg");
364 * silc_mime_add_data(part, data, data_len);
366 * silc_mime_set_multipart(mime, "mixed", "boundary1");
367 * silc_mime_add_multipart(mime, part);
370 SilcBool silc_mime_add_multipart(SilcMime mime, SilcMime part);
372 /****f* silcutil/SILCMIMEAPI/silc_mime_is_multipart
376 * SilcBool silc_mime_is_multipart(SilcMime mime);
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.
384 SilcBool silc_mime_is_multipart(SilcMime mime);
386 /****f* silcutil/SILCMIMEAPI/silc_mime_get_multiparts
390 * SilcDList silc_mime_get_multiparts(SilcMime mime, const char **type);
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.
401 SilcDList silc_mime_get_multiparts(SilcMime mime, const char **type);
403 #include "silcmime_i.h"
405 #endif /* SILCMIME_H */