Removed callback from MIME assembler. Return multipart type
authorPekka Riikonen <priikone@silcnet.org>
Sun, 20 Nov 2005 18:09:24 +0000 (18:09 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sun, 20 Nov 2005 18:09:24 +0000 (18:09 +0000)
in mime_get_multiparts.

CHANGES
lib/silcutil/silcmime.c
lib/silcutil/silcmime.h
lib/silcutil/tests/test_silcmime.c

diff --git a/CHANGES b/CHANGES
index 25d7ebb3756c39cc941ebb2ec8b5883858e560a0..2a05e088c93bad0b6162fdd028b8db1144b0ddb4 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,10 @@
-Sat Nov 19 17:34:51 EET 2005  Pekka Riikonen <priikone@silcnet.org>
+Sun Nov 20 19:13:35 EET 2005 Pekka Riikonen <priikone@silcnet.org>
+
+       * 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 <priikone@silcnet.org>
 
        * Added SilcMime API to lib/silcutil/silcmime.[ch].  The old
          silc_mime_parse is available but deprecated.
index 5e2e4d966b67178ec4f6db563281515079d10ecc..1ecaf6f94ca148a98b1d38d3bcf1ee78853f8326 100644 (file)
@@ -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;
 }
index d8974c98d37ac8f2d245c11a7775d72aec40f01d..90684e17986e3f8fe9915d2542d4ec0b3b622bbe 100644 (file)
@@ -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 */
index 01e7fdd1b6827aa779ddf365e6b353802ac16d05..36d1fe31177b8fc0c263c6e6f8cf48489e677136 100644 (file)
@@ -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);