in mime_get_multiparts.
-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.
SilcUInt32 data_len;
SilcDList multiparts;
char *boundary;
+ char *multitype;
};
struct SilcMimeAssemblerStruct {
- SilcMimeComplete complete;
- void *complete_context;
SilcHashTable fragments;
};
silc_dlist_uninit(mime->multiparts);
}
silc_free(mime->boundary);
+ silc_free(mime->multitype);
silc_free(mime->data);
silc_free(mime);
}
silc_hash_table_free(context);
}
-SilcMimeAssembler silc_mime_assembler_alloc(SilcMimeComplete complete,
- void *complete_context)
+SilcMimeAssembler silc_mime_assembler_alloc(void)
{
SilcMimeAssembler assembler;
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,
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) {
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;
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 */
/* 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. */
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)
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;
}
***/
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
*
* 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
*
*
* 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
*
*
* 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 */
#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;
SilcUInt32 enc_len;
SilcDList frag;
SilcBuffer buf;
+ const char *mtype;
if (argc > 1 && !strcmp(argv[1], "-d")) {
silc_log_debug(TRUE);
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"));
/* 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"));
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);