From a52398a60f363640191ec3c17e98afdab5949e9a Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Sun, 20 Nov 2005 18:09:24 +0000 Subject: [PATCH] Removed callback from MIME assembler. Return multipart type in mime_get_multiparts. --- CHANGES | 8 ++++- lib/silcutil/silcmime.c | 45 ++++++++++++++++--------- lib/silcutil/silcmime.h | 53 +++++++++++------------------- lib/silcutil/tests/test_silcmime.c | 37 ++++++++------------- 4 files changed, 70 insertions(+), 73 deletions(-) diff --git a/CHANGES b/CHANGES index 25d7ebb3..2a05e088 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,10 @@ -Sat Nov 19 17:34:51 EET 2005 Pekka Riikonen +Sun Nov 20 19:13:35 EET 2005 Pekka Riikonen + + * Removed callback system from SilcMimeAssembler. Return + the multipart type in silc_mime_get_multiparts. Affected + files are lib/silcutil/silcmime.[ch]. + +Sat Nov 19 17:34:51 EET 2005 Pekka Riikonen * Added SilcMime API to lib/silcutil/silcmime.[ch]. The old silc_mime_parse is available but deprecated. diff --git a/lib/silcutil/silcmime.c b/lib/silcutil/silcmime.c index 5e2e4d96..1ecaf6f9 100644 --- a/lib/silcutil/silcmime.c +++ b/lib/silcutil/silcmime.c @@ -26,11 +26,10 @@ struct SilcMimeStruct { SilcUInt32 data_len; SilcDList multiparts; char *boundary; + char *multitype; }; struct SilcMimeAssemblerStruct { - SilcMimeComplete complete; - void *complete_context; SilcHashTable fragments; }; @@ -73,6 +72,7 @@ void silc_mime_free(SilcMime mime) silc_dlist_uninit(mime->multiparts); } silc_free(mime->boundary); + silc_free(mime->multitype); silc_free(mime->data); silc_free(mime); } @@ -84,8 +84,7 @@ static void silc_mime_assembler_dest(void *key, void *context, silc_hash_table_free(context); } -SilcMimeAssembler silc_mime_assembler_alloc(SilcMimeComplete complete, - void *complete_context) +SilcMimeAssembler silc_mime_assembler_alloc(void) { SilcMimeAssembler assembler; @@ -93,8 +92,6 @@ SilcMimeAssembler silc_mime_assembler_alloc(SilcMimeComplete complete, if (!assembler) return NULL; - assembler->complete = complete; - assembler->complete_context = complete_context; assembler->fragments = silc_hash_table_alloc(0, silc_hash_string, NULL, silc_hash_string_compare, NULL, @@ -189,6 +186,21 @@ SilcMime silc_mime_decode(const unsigned char *data, SilcUInt32 data_len) if (!mime->multiparts) goto err; + /* Get multipart type */ + value = strchr(field, '/'); + if (!value) + goto err; + value++; + if (strchr(field, '"')) + value++; + if (!strchr(field, ';')) + goto err; + memset(b, 0, sizeof(b)); + strncat(b, value, strchr(field, ';') - value); + if (strchr(b, '"')) + *strchr(b, '"') = '\0'; + mime->multitype = silc_memdup(b, strlen(b)); + /* Get boundary */ value = strrchr(field, '='); if (value && strlen(value) > 1) { @@ -372,7 +384,7 @@ static void silc_mime_assemble_dest(void *key, void *context, silc_mime_free(context); } -void silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial) +SilcMime silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial) { char *type, *id = NULL, *tmp; SilcHashTable f; @@ -437,7 +449,7 @@ void silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial) goto err; silc_hash_table_add(f, SILC_32_TO_PTR(number), partial); silc_hash_table_add(assembler->fragments, id, f); - return; + return NULL; } /* Try to get total number */ @@ -462,14 +474,14 @@ void silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial) /* If more fragments to come, add to hash table */ if (number != total) { silc_hash_table_add(f, SILC_32_TO_PTR(number), partial); - return; + return NULL; } silc_hash_table_add(f, SILC_32_TO_PTR(number), partial); /* Verify that we really have all the fragments */ if (silc_hash_table_count(f) < total) - return; + return NULL; /* Assemble the complete MIME message now. We get them in order from the hash table. */ @@ -503,21 +515,19 @@ void silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial) if (!complete) goto err; - if (assembler->complete) - assembler->complete(complete, assembler->complete_context); - /* Delete the hash table entry. Destructors will free memory */ silc_hash_table_del(assembler->fragments, (void *)id); - silc_free(id); silc_buffer_free(compbuf); - return; + + return complete; err: silc_free(id); if (compbuf) silc_buffer_free(compbuf); silc_mime_free(partial); + return NULL; } SilcDList silc_mime_encode_partial(SilcMime mime, int max_size) @@ -737,10 +747,13 @@ bool silc_mime_is_multipart(SilcMime mime) return mime->multiparts != NULL; } -SilcDList silc_mime_get_multiparts(SilcMime mime) +SilcDList silc_mime_get_multiparts(SilcMime mime, const char **type) { if (!mime) return NULL; + if (type) + *type = (const char *)mime->multitype; + return mime->multiparts; } diff --git a/lib/silcutil/silcmime.h b/lib/silcutil/silcmime.h index d8974c98..90684e17 100644 --- a/lib/silcutil/silcmime.h +++ b/lib/silcutil/silcmime.h @@ -60,21 +60,6 @@ typedef struct SilcMimeStruct *SilcMime; ***/ typedef struct SilcMimeAssemblerStruct *SilcMimeAssembler; -/****f* silcutil/SILCMIMEAPI/SilcMimeComplete - * - * SYNOPSIS - * - * typedef void (*SilcMimeComplete)(SilcMime mime, void *context); - * - * DESCRIPTION - * - * Callback function that is called by silc_mime_assemble function when - * all fragments has been received. The `mime' is the complete MIME - * message. It must be freed with silc_mime_free. - * - ***/ -typedef void (*SilcMimeComplete)(SilcMime mime, void *context); - /****f* silcutil/SILCMIMEAPI/silc_mime_alloc * * SYNOPSIS @@ -105,18 +90,14 @@ void silc_mime_free(SilcMime mime); * * SYNOPSIS * - * SilcMimeAssembler silc_mime_assembler_alloc(SilcMimeComplete complete, - * void *complete_context); + * SilcMimeAssembler silc_mime_assembler_alloc(void); * * DESCRIPTION * - * Allocates MIME fragment assembler. The `complete' callback will be - * whenever a MIME message has been assembled completely. It delivers - * the complete MIME message to the caller. + * Allocates MIME fragment assembler. * ***/ -SilcMimeAssembler silc_mime_assembler_alloc(SilcMimeComplete complete, - void *complete_context); +SilcMimeAssembler silc_mime_assembler_alloc(void); /****f* silcutil/SILCMIMEAPI/silc_mime_assembler_free * @@ -181,26 +162,31 @@ unsigned char *silc_mime_encode(SilcMime mime, SilcUInt32 *encoded_len); * * SYNOPSIS * - * void silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial); + * SilcMime silc_mime_assemble(SilcMimeAssembler assembler, + * SilcMime partial); * * DESCRIPTION * * Processes and attempts to assemble the received MIME fragment `partial'. * To check if a received MIME message is a fragment use the - * silc_mime_is_partial function. The callback that was given as argument - * to the function silc_mime_assembler_alloc will be called when all - * fragments has been received, to deliver the complete MIME message. - * Caller must not free the `partial'. + * silc_mime_is_partial function. Returns NULL if all fragments has not + * yet been received, or the newly allocated completed MIME message if + * all fragments were received. The caller must free the returned + * SilcMime context. The caller must not free the `partial'. * * EXAMPLE * * // Assemble received MIME fragment * mime = silc_mime_decode(data, data_len); - * if (silc_mime_is_partial(mime) == TRUE) - * silc_mime_assmeble(assembler, mime); + * if (silc_mime_is_partial(mime) == TRUE) { + * complete = silc_mime_assmeble(assembler, mime); + * if (complete == NULL) + * return; + * ... + * } * ***/ -void silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial); +SilcMime silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial); /****f* silcutil/SILCMIMEAPI/silc_mime_encode_partial * @@ -378,16 +364,17 @@ bool silc_mime_is_multipart(SilcMime mime); * * SYNOPSIS * - * SilcDList silc_mime_get_multiparts(SilcMime mime); + * SilcDList silc_mime_get_multiparts(SilcMime mime, const char **type); * * DESCRIPTION * * Returns list of the parts from the MIME message `mime'. Each entry * in the list is SilcMime context. The caller must not free the returned * list or the SilcMime contexts in the list. Returns NULL if no parts - * exists in the MIME message. + * exists in the MIME message. Returns the multipart type (like "mixed") + * into `type' pointer. * ***/ -SilcDList silc_mime_get_multiparts(SilcMime mime); +SilcDList silc_mime_get_multiparts(SilcMime mime, const char **type); #endif /* SILCMIME_H */ diff --git a/lib/silcutil/tests/test_silcmime.c b/lib/silcutil/tests/test_silcmime.c index 01e7fdd1..36d1fe31 100644 --- a/lib/silcutil/tests/test_silcmime.c +++ b/lib/silcutil/tests/test_silcmime.c @@ -3,26 +3,6 @@ #include "silcincludes.h" #include "silcmime.h" -struct foo { - int i; - struct foo *next; -}; - -static void ass_complete(SilcMime mime, void *context) -{ - unsigned char *enc; - SilcUInt32 enc_len; - - SILC_LOG_DEBUG(("Defragmentation completed")); - SILC_LOG_DEBUG(("Encoding MIME context")); - enc = silc_mime_encode(mime, &enc_len); - if (!enc) - SILC_LOG_DEBUG(("Error encoding")); - SILC_LOG_DEBUG(("Encoded MIME message: \n%s", enc)); - silc_free(enc); - silc_mime_free(mime); -} - int main(int argc, char **argv) { bool success = FALSE; @@ -34,6 +14,7 @@ int main(int argc, char **argv) SilcUInt32 enc_len; SilcDList frag; SilcBuffer buf; + const char *mtype; if (argc > 1 && !strcmp(argv[1], "-d")) { silc_log_debug(TRUE); @@ -173,9 +154,10 @@ int main(int argc, char **argv) SILC_LOG_DEBUG(("Re-encoded MIME message: \n%s", enc)); silc_free(enc); SILC_LOG_DEBUG(("Get multiparts")); - frag = silc_mime_get_multiparts(mime); + frag = silc_mime_get_multiparts(mime, &mtype); if (!frag) goto err; + SILC_LOG_DEBUG(("Multipart type '%s'", mtype)); silc_dlist_start(frag); while ((part = silc_dlist_get(frag)) != SILC_LIST_END) { SILC_LOG_DEBUG(("Encoding MIME part")); @@ -191,7 +173,7 @@ int main(int argc, char **argv) /* Fragmentation test */ SILC_LOG_DEBUG(("Allocating MIME assembler")); - ass = silc_mime_assembler_alloc(ass_complete, NULL); + ass = silc_mime_assembler_alloc(); if (!ass) goto err; SILC_LOG_DEBUG(("Allocating MIME message context")); @@ -231,7 +213,16 @@ int main(int argc, char **argv) part = silc_mime_decode(buf->data, buf->len); if (!silc_mime_is_partial(part)) goto err; - silc_mime_assemble(ass, part); + part = silc_mime_assemble(ass, part); + if (part) { + SILC_LOG_DEBUG(("Defragmentation completed")); + SILC_LOG_DEBUG(("Encoding MIME context")); + enc = silc_mime_encode(mime, &enc_len); + if (!enc) + SILC_LOG_DEBUG(("Error encoding")); + SILC_LOG_DEBUG(("Encoded MIME message: \n%s", enc)); + silc_free(enc); + } } silc_mime_partial_free(frag); silc_mime_assembler_free(ass); -- 2.24.0