1 /* 2 3 silcmime.h 4 5 Author: Pekka Riikonen <priikone@silcnet.org> 6 7 Copyright (C) 2005 - 2006 Pekka Riikonen 8 9 The contents of this file are subject to one of the Licenses specified 10 in the COPYING file; You may not use this file except in compliance 11 with the License. 12 13 The software distributed under the License is distributed on an "AS IS" 14 basis, in the hope that it will be useful, but WITHOUT WARRANTY OF ANY 15 KIND, either expressed or implied. See the COPYING file for more 16 information. 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 */ 406