/* Check whether an alias from ADDRESSES is part of To: or Cc: headers of the originating mail. Return non-zero if so and store a pointer to the matching address to *MY_ADDRESS. */ static int match_addresses (mu_header_t hdr, mu_sieve_value_t *addresses, char **my_address) { int match = 0; const char *str; struct addr_data ad; ad.my_address = NULL; if (mu_header_sget_value (hdr, MU_HEADER_TO, &str) == 0) { if (!mu_address_create (&ad.addr, str)) { match += mu_sieve_vlist_do (addresses, _compare, &ad); mu_address_destroy (&ad.addr); } } if (!match && mu_header_sget_value (hdr, MU_HEADER_CC, &str) == 0) { if (!mu_address_create (&ad.addr, str)) { match += mu_sieve_vlist_do (addresses, _compare, &ad); mu_address_destroy (&ad.addr); } } *my_address = ad.my_address; return match; }
int mu_message_save_attachment (mu_message_t msg, const char *filename, mu_mime_io_buffer_t info) { mu_stream_t istream; int ret; mu_header_t hdr; const char *fname = NULL; char *partname = NULL; if (msg == NULL) return EINVAL; if ((ret = _attachment_setup (&info, msg, &istream)) != 0) return ret; if (ret == 0 && (ret = mu_message_get_header (msg, &hdr)) == 0) { if (filename == NULL) { ret = mu_message_aget_decoded_attachment_name (msg, info->charset, &partname, NULL); if (partname) fname = partname; } else fname = filename; if (fname && (ret = mu_file_stream_create (&info->fstream, fname, MU_STREAM_WRITE | MU_STREAM_CREAT)) == 0) { const char *content_encoding; if (mu_header_sget_value (hdr, MU_HEADER_CONTENT_TRANSFER_ENCODING, &content_encoding)) content_encoding = "7bit"; ret = mu_filter_create (&info->stream, istream, content_encoding, MU_FILTER_DECODE, MU_STREAM_READ); } } if (info->stream && istream) ret = mu_stream_copy (info->fstream, info->stream, 0, NULL); if (ret != EAGAIN && info) { mu_stream_close (info->fstream); mu_stream_destroy (&info->stream); mu_stream_destroy (&info->fstream); } mu_stream_destroy (&istream); _attachment_free (info, ret); /* FIXME: or 0? */ /* Free fname if we allocated it. */ if (partname) free (partname); return ret; }
int mu_message_unencapsulate (mu_message_t msg, mu_message_t *newmsg, mu_mime_io_buffer_t info) { int ret = 0; mu_header_t hdr; mu_stream_t istream; if (msg == NULL) return EINVAL; if (newmsg == NULL) return MU_ERR_OUT_PTR_NULL; if (info == NULL /* FIXME: not needed? */ && (ret = mu_message_get_header (msg, &hdr)) == 0) { const char *s; if (!(mu_header_sget_value (hdr, MU_HEADER_CONTENT_TYPE, &s) == 0 && mu_c_strncasecmp (s, MESSAGE_RFC822_STR, sizeof (MESSAGE_RFC822_STR) - 1) == 0)) return EINVAL; } if ((ret = _attachment_setup (&info, msg, &istream)) != 0) return ret; ret = mu_stream_to_message (istream, &info->msg); mu_stream_unref (istream); if (ret == 0) *newmsg = info->msg; _attachment_free (info, ret && ret != EAGAIN); return ret; }
static int _mh_prop_getval (struct _mu_property *prop, const char *key, const char **pval) { mu_header_t header = prop->_prop_data; if (!header) return MU_ERR_NOENT; return mu_header_sget_value (header, key, pval); }
/* Return T if letter precedence is 'bulk' or 'junk' */ static int bulk_precedence_p (mu_header_t hdr) { int rc = 0; const char *str; if (mu_header_sget_value (hdr, MU_HEADER_PRECEDENCE, &str) == 0) { rc = mu_c_strcasecmp (str, "bulk") == 0 || mu_c_strcasecmp (str, "junk") == 0; } return rc; }
int moderator_message_get_part (mu_sieve_machine_t mach, mu_message_t msg, size_t index, mu_message_t *pmsg) { int rc; mu_message_t tmp; mu_header_t hdr = NULL; const char *value; if ((rc = mu_message_get_part (msg, index, &tmp))) { mu_sieve_error (mach, _("cannot get message part #%lu: %s"), (unsigned long) index, mu_strerror (rc)); return 1; } mu_message_get_header (tmp, &hdr); if (mu_header_sget_value (hdr, MU_HEADER_CONTENT_TYPE, &value) == 0 && memcmp (value, "message/rfc822", 14) == 0) { mu_stream_t str; mu_body_t body; mu_message_get_body (tmp, &body); mu_body_get_streamref (body, &str); rc = mu_stream_to_message (str, pmsg); mu_stream_destroy (&str); if (rc) { mu_sieve_error (mach, _("cannot convert MIME part stream to message: %s"), mu_strerror (rc)); return 1; } } else if (value) { mu_sieve_error (mach, _("expected message type message/rfc822, but found %s"), value); return 1; } else { mu_sieve_error (mach, _("no Content-Type header found")); return 1; } return 0; }
static int copy_header (mu_sieve_machine_t mach, mu_header_t to_hdr, char *to, mu_header_t from_hdr, char *from) { int rc; const char *value = NULL; if ((rc = mu_header_sget_value (from_hdr, from, &value))) { mu_sieve_error (mach, _("cannot get `%s:' header: %s"), from, mu_strerror (rc)); return rc; } rc = mu_header_set_value (to_hdr, to, value, 0); return rc; }
int mu_header_sget_firstof (mu_header_t hdr, char **names, const char **pval, int *pidx) { int status; const char *s = NULL; int i; for (i = 0; names[i]; i++) { status = mu_header_sget_value (hdr, names[i], &s); if (status == 0 && *s != 0) { if (pval) *pval = s; if (pidx) *pidx = i; return 0; } } return MU_ERR_NOENT; }
int main (int argc, char **argv) { mu_mailbox_t mbox = NULL; size_t i; size_t count = 0; char *mailbox_name; int debug = 0; for (i = 1; i < argc; i++) { if (strcmp (argv[i], "-d") == 0) debug = 1; else if (strcmp (argv[i], "-p") == 0) print_attachments = 1; else if (strcmp (argv[i], "-i") == 0) { if (++i == argc) { mu_error ("-i requires argument"); exit (1); } indent_level = strtoul (argv[i], NULL, 0); } else if (strcmp (argv[i], "-c") == 0) { if (++i == argc) { mu_error ("-c requires argument"); exit (1); } charset = argv[i]; } else break; } mailbox_name = argv[i]; /* Registration. */ mu_registrar_record (mu_imap_record); mu_registrar_record (mu_pop_record); mu_registrar_record (mu_mbox_record); mu_registrar_set_default_record (mu_mbox_record); MU_ASSERT (mu_mailbox_create_default (&mbox, mailbox_name)); /* Debugging trace. */ if (debug) { mu_debug_set_category_level (MU_DEBCAT_MAILBOX, MU_DEBUG_LEVEL_UPTO (MU_DEBUG_PROT)); } /* Open the mailbox for reading only. */ MU_ASSERT (mu_mailbox_open (mbox, MU_STREAM_READ)); /* Iterate through the entire message set. */ MU_ASSERT (mu_mailbox_messages_count (mbox, &count)); for (i = 1; i <= count; ++i) { mu_message_t msg; mu_header_t hdr; size_t nparts; size_t msize, nlines; MU_ASSERT (mu_mailbox_get_message (mbox, i, &msg)); MU_ASSERT (mu_message_size (msg, &msize)); MU_ASSERT (mu_message_lines (msg, &nlines)); MU_ASSERT (mu_message_get_header (msg, &hdr)); if (mu_header_sget_value (hdr, MU_HEADER_FROM, &from)) from = ""; if (mu_header_sget_value (hdr, MU_HEADER_SUBJECT, &subject)) subject = ""; printf ("Message: %lu\n", (unsigned long) i); printf ("From: %s\n", from); printf ("Subject: %s\n", subject); MU_ASSERT (mu_message_get_num_parts (msg, &nparts)); printf ("Number of parts in message - %lu\n", (unsigned long) nparts); printf ("Total message size - %lu/%lu\n", (unsigned long) msize, (unsigned long) nlines); message_display_parts (msg, 0); } mu_mailbox_close (mbox); mu_mailbox_destroy (&mbox); return 0; }
void message_display_parts (mu_message_t msg, int indent) { int ret, j; size_t nparts; mu_message_t part; mu_header_t hdr; mu_stream_t str; mu_body_t body; int ismulti; size_t nbytes; /* How many parts does the message has? */ if ((ret = mu_message_get_num_parts (msg, &nparts)) != 0) { fprintf (stderr, "mu_message_get_num_parts - %s\n", mu_strerror (ret)); exit (2); } /* Iterate through all the parts. Treat type "message/rfc822" differently, since it is a message of its own that can have other subparts(recursive). */ for (j = 1; j <= nparts; j++) { int status; const char *hvalue; char *type = NULL; const char *encoding = ""; MU_ASSERT (mu_message_get_part (msg, j, &part)); MU_ASSERT (mu_message_get_header (part, &hdr)); status = mu_header_sget_value (hdr, MU_HEADER_CONTENT_TYPE, &hvalue); if (status == MU_ERR_NOENT) /* nothing */; else if (status != 0) mu_error ("Cannot get header value: %s", mu_strerror (status)); else { status = mu_mimehdr_aget_disp (hvalue, &type); if (status) mu_error ("Cannot extract content type field: %s", mu_strerror (status)); } printf ("%*.*sType of part %d = %s\n", indent, indent, "", j, type ? type : ""); print_message_part_sizes (part, indent); if (mu_header_sget_value (hdr, MU_HEADER_CONTENT_TRANSFER_ENCODING, &encoding)) encoding = ""; ismulti = 0; if ((type && mu_c_strcasecmp (type, "message/rfc822") == 0) || (mu_message_is_multipart (part, &ismulti) == 0 && ismulti)) { if (!ismulti) MU_ASSERT (mu_message_unencapsulate (part, &part, NULL)); MU_ASSERT (mu_message_get_header (part, &hdr)); if (mu_header_sget_value (hdr, MU_HEADER_FROM, &from)) from = ""; if (mu_header_sget_value (hdr, MU_HEADER_SUBJECT, &subject)) subject = ""; printf ("%*.*sEncapsulated message : %s\t%s\n", indent, indent, "", from, subject); printf ("%*.*sBegin\n", indent, indent, ""); message_display_parts (part, indent + indent_level); mu_message_destroy (&part, NULL); } else if (!type || (mu_c_strcasecmp (type, "text/plain") == 0) || (mu_c_strcasecmp (type, "text/html")) == 0) { printf ("%*.*sText Message\n", indent, indent, ""); printf ("%*.*sBegin\n", indent, indent, ""); mu_message_get_body (part, &body); mu_body_get_streamref (body, &str); /* Make sure the original body stream is not closed when str gets destroyed */ mu_filter_create (&str, str, encoding, MU_FILTER_DECODE, MU_STREAM_READ); while (mu_stream_readline (str, buf, sizeof (buf), &nbytes) == 0 && nbytes) { printf ("%*.*s%s", indent, indent, "", buf); } mu_stream_destroy (&str); } else { /* Save the attachements. */ char *fname = NULL; mu_message_aget_decoded_attachment_name (part, charset, &fname, NULL); if (fname == NULL) fname = mu_tempname (NULL); printf ("%*.*sAttachment - saving [%s]\n", indent, indent, "", fname); printf ("%*.*sBegin\n", indent, indent, ""); if (charset) { mu_mime_io_buffer_t info; mu_mime_io_buffer_create (&info); mu_mime_io_buffer_set_charset (info, charset); MU_ASSERT (mu_message_save_attachment (part, NULL, info)); mu_mime_io_buffer_destroy (&info); } else MU_ASSERT (mu_message_save_attachment (part, fname, NULL)); if (print_attachments) print_file (fname, indent); free (fname); } printf ("\n%*.*sEnd\n", indent, indent, ""); free (type); } }
int mutool_send (int argc, char **argv) { int index; char *infile; mu_stream_t instr; mu_message_t msg; size_t count; mu_url_t urlhint, url; mu_mailer_t mailer; MU_ASSERT (mu_address_create_null (&rcpt_addr)); mu_register_all_mailer_formats (); if (argp_parse (&send_argp, argc, argv, 0, &index, NULL)) return 1; argc -= index; argv += index; if (argc < 1) { mu_error (_("not enough arguments")); return 1; } infile = argv[1]; if (infile) MU_ASSERT (mu_file_stream_create (&instr, infile, MU_STREAM_READ|MU_STREAM_SEEK)); else MU_ASSERT (mu_stdio_stream_create (&instr, MU_STDIN_FD, MU_STREAM_READ|MU_STREAM_SEEK)); MU_ASSERT (mu_stream_to_message (instr, &msg)); mu_stream_unref (instr); mu_address_get_count (rcpt_addr, &count); if (count == 0) read_recipients = 1; if (read_recipients) { int rc; mu_header_t header; const char *value; MU_ASSERT (mu_message_get_header (msg, &header)); rc = mu_header_sget_value (header, MU_HEADER_TO, &value); if (rc == 0) send_address_add (&rcpt_addr, value); else if (rc != MU_ERR_NOENT) { mu_diag_funcall (MU_DIAG_ERROR, "mu_header_sget_value", MU_HEADER_TO, rc); exit (1); } rc = mu_header_sget_value (header, MU_HEADER_CC, &value); if (rc == 0) send_address_add (&rcpt_addr, value); else if (rc != MU_ERR_NOENT) { mu_diag_funcall (MU_DIAG_ERROR, "mu_header_sget_value", MU_HEADER_CC, rc); exit (1); } rc = mu_header_sget_value (header, MU_HEADER_BCC, &value); if (rc == 0) send_address_add (&rcpt_addr, value); else if (rc != MU_ERR_NOENT) { mu_diag_funcall (MU_DIAG_ERROR, "mu_header_sget_value", MU_HEADER_BCC, rc); exit (1); } } mu_address_get_count (rcpt_addr, &count); if (count == 0) { mu_error (_("no recipients")); exit (1); } MU_ASSERT (mu_url_create (&urlhint, "smtp://")); MU_ASSERT (mu_url_create_hint (&url, argv[0], MU_URL_PARSE_DEFAULT, urlhint)); mu_url_invalidate (url); MU_ASSERT (mu_mailer_create_from_url (&mailer, url)); MU_ASSERT (mu_mailer_open (mailer, MU_STREAM_RDWR)); MU_ASSERT (mu_mailer_send_message (mailer, msg, from_addr, rcpt_addr)); mu_mailer_close (mailer); mu_mailer_destroy (&mailer); return 0; }