summaryrefslogtreecommitdiff
path: root/mailbox
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2007-06-28 08:03:44 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2007-06-28 08:03:44 +0000
commit1e32b2a35e78211b006f9c4efa20ab74b0087ac5 (patch)
tree792c406af2d03fbac27c20fcc9a426af0dcf087d /mailbox
parentff639efd3ee44de0e4904c2d8bb7d0de31b932a1 (diff)
downloadmailutils-1e32b2a35e78211b006f9c4efa20ab74b0087ac5.tar.gz
mailutils-1e32b2a35e78211b006f9c4efa20ab74b0087ac5.tar.bz2
( (mu_mailer_send_fragments): New function
Diffstat (limited to 'mailbox')
-rw-r--r--mailbox/mailer.c176
1 files changed, 172 insertions, 4 deletions
diff --git a/mailbox/mailer.c b/mailbox/mailer.c
index 28233dac8..cbb3938b2 100644
--- a/mailbox/mailer.c
+++ b/mailbox/mailer.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
+#include <unistd.h>
#include <errno.h>
#include <mailutils/address.h>
@@ -38,10 +39,13 @@
#include <mailutils/stream.h>
#include <mailutils/url.h>
#include <mailutils/header.h>
+#include <mailutils/body.h>
#include <mailutils/mailbox.h>
#include <mailutils/message.h>
#include <mailutils/argcv.h>
#include <mailutils/mutil.h>
+#include <mailutils/mime.h>
+#include <mu_umaxtostr.h>
#include <mailer0.h>
@@ -363,9 +367,137 @@ _set_from (mu_address_t *pfrom, mu_message_t msg, mu_address_t from,
return status;
}
+static int
+create_part (mu_mime_t mime, mu_stream_t istr,
+ size_t fragsize, size_t n, size_t nparts, char *msgid)
+{
+ int status = 0;
+ mu_message_t newmsg;
+ mu_header_t newhdr;
+ mu_body_t body;
+ mu_stream_t ostr;
+ char buffer[512], *str;
+ const char *nstr, *npartstr;
+
+ mu_message_create (&newmsg, NULL);
+ mu_message_get_header (newmsg, &newhdr);
+
+ nstr = mu_umaxtostr (0, n);
+ npartstr = mu_umaxtostr (1, nparts);
+ asprintf (&str,
+ "message/partial; id=\"%s\"; number=%s; total=%s",
+ msgid, nstr, npartstr);
+ mu_header_append (newhdr, MU_HEADER_CONTENT_TYPE, str);
+ free (str);
+ asprintf (&str, "part %s of %s", nstr, npartstr);
+ mu_header_append (newhdr, MU_HEADER_CONTENT_DESCRIPTION, str);
+ free (str);
+
+ mu_message_get_body (newmsg, &body);
+ mu_body_get_stream (body, &ostr);
+
+ mu_stream_seek (ostr, 0, SEEK_SET);
+
+ while (fragsize)
+ {
+ size_t rds = fragsize;
+ if (rds > sizeof buffer)
+ rds = sizeof buffer;
+
+ status = mu_stream_sequential_read (istr, buffer, rds, &rds);
+ if (status || rds == 0)
+ break;
+ status = mu_stream_sequential_write (ostr, buffer, rds);
+ if (status)
+ break;
+ fragsize -= rds;
+ }
+ if (status == 0)
+ {
+ mu_mime_add_part (mime, newmsg);
+ mu_message_unref (newmsg);
+ }
+ return status;
+}
+
+static void
+merge_headers (mu_message_t newmsg, mu_header_t hdr)
+{
+ size_t i, count;
+ mu_header_t newhdr;
+
+ mu_message_get_header (newmsg, &newhdr);
+ mu_header_get_field_count (hdr, &count);
+ for (i = 1; i <= count; i++)
+ {
+ const char *fn, *fv;
+
+ mu_header_sget_field_name (hdr, i, &fn);
+ mu_header_sget_field_value (hdr, i, &fv);
+ if (strcasecmp (fn, MU_HEADER_MESSAGE_ID) == 0)
+ continue;
+ else if (strcasecmp (fn, MU_HEADER_MIME_VERSION) == 0)
+ mu_header_append (newhdr, "X-Orig-" MU_HEADER_MIME_VERSION,
+ fv);
+ else if (strcasecmp (fn, MU_HEADER_CONTENT_TYPE) == 0)
+ mu_header_append (newhdr, "X-Orig-" MU_HEADER_CONTENT_TYPE,
+ fv);
+ else if (strcasecmp (fn, MU_HEADER_CONTENT_DESCRIPTION) == 0)
+ mu_header_append (newhdr, "X-Orig-" MU_HEADER_CONTENT_DESCRIPTION,
+ fv);
+ else
+ mu_header_append (newhdr, fn, fv);
+ }
+}
+
+
int
-mu_mailer_send_message (mu_mailer_t mailer, mu_message_t msg,
- mu_address_t from, mu_address_t to)
+send_fragments (mu_mailer_t mailer,
+ mu_header_t hdr,
+ mu_stream_t str,
+ size_t nparts, size_t fragsize,
+ struct timeval *delay,
+ mu_address_t from, mu_address_t to)
+{
+ int status;
+ size_t i;
+ char *msgid = NULL;
+
+ if (mu_header_aget_value (hdr, MU_HEADER_MESSAGE_ID, &msgid))
+ mu_rfc2822_msg_id (0, &msgid);
+
+ for (i = 1; i <= nparts; i++)
+ {
+ mu_message_t newmsg;
+ mu_mime_t mime;
+
+ mu_mime_create (&mime, NULL, 0);
+ status = create_part (mime, str, fragsize, i, nparts, msgid);
+ if (status)
+ break;
+
+ mu_mime_get_message (mime, &newmsg);
+ merge_headers (newmsg, hdr);
+
+ status = mailer->_send_message (mailer, newmsg, from, to);
+ mu_mime_destroy (&mime);
+ if (status)
+ break;
+ if (delay)
+ {
+ struct timeval t = *delay;
+ select (0, NULL, NULL, NULL, &t);
+ }
+ }
+ free (msgid);
+ return status;
+}
+
+int
+mu_mailer_send_fragments (mu_mailer_t mailer,
+ mu_message_t msg,
+ size_t fragsize, struct timeval *delay,
+ mu_address_t from, mu_address_t to)
{
int status;
mu_address_t sender_addr = NULL;
@@ -385,14 +517,50 @@ mu_mailer_send_message (mu_mailer_t mailer, mu_message_t msg,
&& (!to || (status = mu_mailer_check_to (to)) == 0))
{
save_fcc (msg);
- status = mailer->_send_message (mailer, msg, from, to);
+ if (fragsize == 0)
+ status = mailer->_send_message (mailer, msg, from, to);
+ else
+ {
+ mu_header_t hdr;
+ mu_body_t body;
+ size_t bsize;
+ size_t nparts;
+
+ /* Estimate the number of messages to be sent. */
+ mu_message_get_header (msg, &hdr);
+
+ mu_message_get_body (msg, &body);
+ mu_body_size (body, &bsize);
+
+ nparts = bsize + fragsize - 1;
+ if (nparts < bsize) /* overflow */
+ return EINVAL;
+ nparts /= fragsize;
+
+ if (nparts == 1)
+ status = mailer->_send_message (mailer, msg, from, to);
+ else
+ {
+ mu_stream_t str;
+ mu_body_get_stream (body, &str);
+
+ status = send_fragments (mailer, hdr, str, nparts, fragsize,
+ delay, from, to);
+ }
+ }
}
-
mu_address_destroy (&sender_addr);
return status;
}
int
+mu_mailer_send_message (mu_mailer_t mailer, mu_message_t msg,
+ mu_address_t from, mu_address_t to)
+{
+ return mu_mailer_send_fragments (mailer, msg, 0, NULL, from, to);
+}
+
+int
mu_mailer_set_stream (mu_mailer_t mailer, mu_stream_t stream)
{
if (mailer == NULL)

Return to:

Send suggestions and report system problems to the System administrator.