コード例 #1
0
ファイル: index-mail.c プロジェクト: via/dovecot-clouddb
static int index_mail_cache_sent_date(struct index_mail *mail)
{
	struct index_mail_data *data = &mail->data;
	const char *str;
	time_t t;
	int ret, tz;

	if (data->sent_date.time != (uint32_t)-1)
		return 0;

	if ((ret = mail_get_first_header(&mail->mail.mail, "Date", &str)) < 0)
		return ret;

	if (ret == 0 ||
	    !message_date_parse((const unsigned char *)str,
				strlen(str), &t, &tz)) {
		/* 0 = not found / invalid */
		t = 0;
		tz = 0;
	}
	data->sent_date.time = t;
	data->sent_date.timezone = tz;
	index_mail_cache_add(mail, MAIL_CACHE_SENT_DATE,
			     &data->sent_date, sizeof(data->sent_date));
	return 0;
}
コード例 #2
0
static int
cmd_deduplicate_box(struct doveadm_mail_cmd_context *_ctx,
		    const struct mailbox_info *info,
		    struct mail_search_args *search_args)
{
	struct deduplicate_cmd_context *ctx =
		(struct deduplicate_cmd_context *)_ctx;
	struct doveadm_mail_iter *iter;
	struct mailbox *box;
	struct mail *mail;
	enum mail_error error;
	pool_t pool;
	HASH_TABLE(const char *, struct uidlist *) hash;
	const char *key, *errstr;
	struct uidlist *value;
	int ret = 0;

	if (doveadm_mail_iter_init(_ctx, info, search_args, 0, NULL,
				   &iter) < 0)
		return -1;

	pool = pool_alloconly_create("deduplicate", 10240);
	hash_table_create(&hash, pool, 0, str_hash, strcmp);
	while (doveadm_mail_iter_next(iter, &mail)) {
		if (ctx->by_msgid) {
			if (mail_get_first_header(mail, "Message-ID", &key) < 0) {
				errstr = mailbox_get_last_error(mail->box, &error);
				if (error == MAIL_ERROR_NOTFOUND)
					continue;
				i_error("Couldn't lookup Message-ID: for UID=%u: %s",
					mail->uid, errstr);
				doveadm_mail_failed_error(_ctx, error);
				ret = -1;
				break;
			}
		} else {
			if (mail_get_special(mail, MAIL_FETCH_GUID, &key) < 0) {
				errstr = mailbox_get_last_error(mail->box, &error);
				if (error == MAIL_ERROR_NOTFOUND)
					continue;
				i_error("Couldn't lookup GUID: for UID=%u: %s",
					mail->uid, errstr);
				doveadm_mail_failed_error(_ctx, error);
				ret = -1;
				break;
			}
		}
		if (key != NULL && *key != '\0') {
			value = p_new(pool, struct uidlist, 1);
			value->uid = mail->uid;
			value->next = hash_table_lookup(hash, key);

			if (value->next == NULL) {
				key = p_strdup(pool, key);
				hash_table_insert(hash, key, value);
			} else {
				hash_table_update(hash, key, value);
			}
		}
	}
コード例 #3
0
static const struct var_expand_table *
get_var_expand_table(struct mail *mail, const char *reason,
		     const char *recipient)
{
	static struct var_expand_table static_tab[] = {
		{ 'n', NULL, "crlf" },
		{ 'r', NULL, "reason" },
		{ 's', NULL, "subject" },
		{ 't', NULL, "to" },
		{ '\0', NULL, NULL }
	};
	struct var_expand_table *tab;
	const char *subject;

	tab = t_malloc(sizeof(static_tab));
	memcpy(tab, static_tab, sizeof(static_tab));

	tab[0].value = "\r\n";
	tab[1].value = reason;
	if (mail_get_first_header(mail, "Subject", &subject) <= 0)
		subject = "";
	tab[2].value = str_sanitize(subject, 80);
	tab[3].value = recipient;

	return tab;
}
コード例 #4
0
ファイル: mail-log-plugin.c プロジェクト: via/dovecot-clouddb
static void
mail_log_append_mail_header(string_t *str, struct mail *mail,
			    const char *name, const char *header)
{
	const char *value;

	if (mail_get_first_header(mail, header, &value) <= 0)
		value = "";
	str_printfa(str, "%s=%s", name, str_sanitize(value, HEADER_LOG_LEN));
}
コード例 #5
0
ファイル: sieve-tool.c プロジェクト: aclindsa/pigeonhole
void sieve_tool_get_envelope_data
	(struct mail *mail, const char **recipient, const char **sender)
{
	/* Get recipient address */
	if ( *recipient == NULL )
		(void)mail_get_first_header(mail, "Envelope-To", recipient);
	if ( *recipient == NULL )
		(void)mail_get_first_header(mail, "To", recipient);
	if ( *recipient == NULL )
		*recipient = "*****@*****.**";

	/* Get sender address */
	if ( *sender == NULL )
		(void)mail_get_first_header(mail, "Return-path", sender);
	if ( *sender == NULL )
		(void)mail_get_first_header(mail, "Sender", sender);
	if ( *sender == NULL )
		(void)mail_get_first_header(mail, "From", sender);
	if ( *sender == NULL )
		*sender = "*****@*****.**";
}
コード例 #6
0
ファイル: index-sort.c プロジェクト: bdraco/core
int index_sort_header_get(struct mail_search_sort_program *program, uint32_t seq,
			  enum mail_sort_type sort_type, string_t *dest)
{
	struct mail *mail = program->temp_mail;
	const char *str;
	int ret;
	bool reply_or_fw;

	index_sort_set_seq(program, mail, seq);
	str_truncate(dest, 0);

	switch (sort_type & MAIL_SORT_MASK) {
	case MAIL_SORT_SUBJECT:
		ret = mail_get_first_header(mail, "Subject", &str);
		if (ret < 0)
			break;
		if (ret == 0) {
			/* nonexistent header */
			return 1;
		}
		str = imap_get_base_subject_cased(pool_datastack_create(),
						  str, &reply_or_fw);
		str_append(dest, str);
		return 1;
	case MAIL_SORT_CC:
		ret = get_first_mailbox(mail, "Cc", &str);
		break;
	case MAIL_SORT_FROM:
		ret = get_first_mailbox(mail, "From", &str);
		break;
	case MAIL_SORT_TO:
		ret = get_first_mailbox(mail, "To", &str);
		break;
	case MAIL_SORT_DISPLAYFROM:
		ret = get_display_name(mail, "From", &str);
		break;
	case MAIL_SORT_DISPLAYTO:
		ret = get_display_name(mail, "To", &str);
		break;
	default:
		i_unreached();
	}
	if (ret < 0) {
		index_sort_program_set_mail_failed(program, mail);
		if (!program->failed)
			return 0;
		return -1;
	}

	(void)uni_utf8_to_decomposed_titlecase(str, strlen(str), dest);
	return 1;
}
コード例 #7
0
static const char *
testsuite_message_get_address(struct mail *mail, const char *header)
{
	struct message_address *addr;
	const char *str;

	if (mail_get_first_header(mail, header, &str) <= 0)
		return NULL;
	addr = message_address_parse(pool_datastack_create(),
	             (const unsigned char *)str,
	             strlen(str), 1, FALSE);
	return (addr == NULL ||
		addr->mailbox == NULL || *addr->mailbox == '\0' ? NULL :
			( addr->domain == NULL || *addr->domain == '\0' ? addr->mailbox :
				t_strconcat(addr->mailbox, "@", addr->domain, NULL)));
}
コード例 #8
0
ファイル: index-sort.c プロジェクト: LTD-Beget/dovecot
static int
get_first_addr(struct mail *mail, const char *header,
	       struct message_address **addr_r)
{
	const char *str;
	int ret;

	if ((ret = mail_get_first_header(mail, header, &str)) <= 0) {
		*addr_r = NULL;
		return ret;
	}

	*addr_r = message_address_parse(pool_datastack_create(),
					(const unsigned char *)str,
					strlen(str), 1, TRUE);
	return 0;
}
コード例 #9
0
static void testsuite_message_set_data(struct mail *mail)
{
	const char *recipient = NULL, *sender = NULL;

	/*
	 * Collect necessary message data
	 */

	/* Get recipient address */
	recipient = testsuite_message_get_address(mail, "Envelope-To");
	if ( recipient == NULL )
		recipient = testsuite_message_get_address(mail, "To");
	if ( recipient == NULL )
		recipient = "*****@*****.**";

	/* Get sender address */
	sender = testsuite_message_get_address(mail, "Return-path");
	if ( sender == NULL )
		sender = testsuite_message_get_address(mail, "Sender");
	if ( sender == NULL )
		sender = testsuite_message_get_address(mail, "From");
	if ( sender == NULL )
		sender = "*****@*****.**";

	memset(&testsuite_msgdata, 0, sizeof(testsuite_msgdata));
	testsuite_msgdata.mail = mail;
	testsuite_msgdata.auth_user = sieve_tool_get_username(sieve_tool);

	str_truncate(envelope_from, 0);
	str_append(envelope_from, sender);
	testsuite_msgdata.return_path = str_c(envelope_from);

	str_truncate(envelope_to, 0);
	str_append(envelope_to, recipient);
	testsuite_msgdata.final_envelope_to = str_c(envelope_to);

	str_truncate(envelope_orig_to, 0);
	str_append(envelope_orig_to, recipient);
	testsuite_msgdata.orig_envelope_to = str_c(envelope_orig_to);

	(void)mail_get_first_header(mail, "Message-ID", &testsuite_msgdata.id);
}
コード例 #10
0
ファイル: index-sort.c プロジェクト: LTD-Beget/dovecot
int index_sort_header_get(struct mail *mail, uint32_t seq,
			  enum mail_sort_type sort_type, string_t *dest)
{
	const char *str;
	int ret;
	bool reply_or_fw;

	mail_set_seq(mail, seq);
	str_truncate(dest, 0);

	switch (sort_type & MAIL_SORT_MASK) {
	case MAIL_SORT_SUBJECT:
		if ((ret = mail_get_first_header(mail, "Subject", &str)) <= 0)
			return ret;
		str = imap_get_base_subject_cased(pool_datastack_create(),
						  str, &reply_or_fw);
		str_append(dest, str);
		return 0;
	case MAIL_SORT_CC:
		ret = get_first_mailbox(mail, "Cc", &str);
		break;
	case MAIL_SORT_FROM:
		ret = get_first_mailbox(mail, "From", &str);
		break;
	case MAIL_SORT_TO:
		ret = get_first_mailbox(mail, "To", &str);
		break;
	case MAIL_SORT_DISPLAYFROM:
		ret = get_display_name(mail, "From", &str);
		break;
	case MAIL_SORT_DISPLAYTO:
		ret = get_display_name(mail, "To", &str);
		break;
	default:
		i_unreached();
	}

	(void)uni_utf8_to_decomposed_titlecase(str, strlen(str), dest);
	return ret;
}
コード例 #11
0
ファイル: istream-mail.c プロジェクト: bechtoldt/dovecot-core
static const char *
i_stream_mail_get_cached_mail_id(struct mail_istream *mstream)
{
	static const char *headers[] = {
		"Message-Id",
		"Date",
		"Subject"
	};
	struct mail *mail = mstream->mail;
	enum mail_lookup_abort orig_lookup_abort;
	const char *value, *ret = "";
	unsigned int i;

	orig_lookup_abort = mail->lookup_abort;
	mail->lookup_abort = MAIL_LOOKUP_ABORT_NOT_IN_CACHE;
	for (i = 0; i < N_ELEMENTS(headers); i++) {
		if (mail_get_first_header(mail, headers[i], &value) > 0) {
			ret = t_strdup_printf("%s=%s", headers[i], value);
			break;
		}
	}
	mail->lookup_abort = orig_lookup_abort;
	return ret;
}
コード例 #12
0
int mail_send_rejection(struct mail_deliver_context *ctx, const char *recipient,
			const char *reason)
{
    struct mail *mail = ctx->src_mail;
    struct istream *input;
    struct smtp_client *smtp_client;
    struct ostream *output;
    const char *return_addr, *hdr;
    const char *value, *msgid, *orig_msgid, *boundary;
    string_t *str;
    int ret;

    if (mail_get_first_header(mail, "Message-ID", &orig_msgid) < 0)
	    orig_msgid = NULL;

    if (mail_get_first_header(mail, "Auto-Submitted", &value) > 0 &&
	strcasecmp(value, "no") != 0) {
	    i_info("msgid=%s: Auto-submitted message discarded: %s",
		   orig_msgid == NULL ? "" : str_sanitize(orig_msgid, 80),
		   str_sanitize(reason, 512));
	    return 0;
    }

    return_addr = mail_deliver_get_return_address(ctx);
    if (return_addr == NULL) {
	    i_info("msgid=%s: Return-Path missing, rejection reason: %s",
		   orig_msgid == NULL ? "" : str_sanitize(orig_msgid, 80),
		   str_sanitize(reason, 512));
	    return 0;
    }

    if (mailbox_get_settings(mail->box)->mail_debug) {
	    i_debug("Sending a rejection to %s: %s", recipient,
		    str_sanitize(reason, 512));
    }

    smtp_client = smtp_client_open(ctx->set, return_addr, NULL, &output);

    msgid = mail_deliver_get_new_message_id(ctx);
    boundary = t_strdup_printf("%s/%s", my_pid, ctx->set->hostname);

    str = t_str_new(512);
    str_printfa(str, "Message-ID: %s\r\n", msgid);
    str_printfa(str, "Date: %s\r\n", message_date_create(ioloop_time));
    str_printfa(str, "From: Mail Delivery Subsystem <%s>\r\n",
		ctx->set->postmaster_address);
    str_printfa(str, "To: <%s>\r\n", return_addr);
    str_append(str, "MIME-Version: 1.0\r\n");
    str_printfa(str, "Content-Type: "
		"multipart/report; report-type=%s;\r\n"
		"\tboundary=\"%s\"\r\n",
		ctx->dsn ? "delivery-status" : "disposition-notification",
		boundary);
    str_append(str, "Subject: ");
    var_expand(str, ctx->set->rejection_subject,
	       get_var_expand_table(mail, reason, recipient));
    str_append(str, "\r\n");

    str_append(str, "Auto-Submitted: auto-replied (rejected)\r\n");
    str_append(str, "Precedence: bulk\r\n");
    str_append(str, "\r\nThis is a MIME-encapsulated message\r\n\r\n");

    /* human readable status report */
    str_printfa(str, "--%s\r\n", boundary);
    str_append(str, "Content-Type: text/plain; charset=utf-8\r\n");
    str_append(str, "Content-Disposition: inline\r\n");
    str_append(str, "Content-Transfer-Encoding: 8bit\r\n\r\n");

    var_expand(str, ctx->set->rejection_reason,
	       get_var_expand_table(mail, reason, recipient));
    str_append(str, "\r\n");

    if (ctx->dsn) {
	    /* DSN status report: For LDA rejects. currently only used when
	       user is out of quota */
	    str_printfa(str, "--%s\r\n"
			"Content-Type: message/delivery-status\r\n\r\n",
			boundary);
	    str_printfa(str, "Reporting-MTA: dns; %s\r\n", ctx->set->hostname);
	    if (mail_get_first_header(mail, "Original-Recipient", &hdr) > 0)
		    str_printfa(str, "Original-Recipient: rfc822; %s\r\n", hdr);
	    str_printfa(str, "Final-Recipient: rfc822; %s\r\n", recipient);
	    str_append(str, "Action: failed\r\n");
	    str_printfa(str, "Status: %s\r\n", ctx->mailbox_full ? "5.2.2" : "5.2.0");
    } else {
	    /* MDN status report: For Sieve "reject" */
	    str_printfa(str, "--%s\r\n"
			"Content-Type: message/disposition-notification\r\n\r\n",
			boundary);
	    str_printfa(str, "Reporting-UA: %s; Dovecot Mail Delivery Agent\r\n",
			ctx->set->hostname);
	    if (mail_get_first_header(mail, "Original-Recipient", &hdr) > 0)
		    str_printfa(str, "Original-Recipient: rfc822; %s\r\n", hdr);
	    str_printfa(str, "Final-Recipient: rfc822; %s\r\n", recipient);

	    if (orig_msgid != NULL)
		    str_printfa(str, "Original-Message-ID: %s\r\n", orig_msgid);
	    str_append(str, "Disposition: "
		       "automatic-action/MDN-sent-automatically; deleted\r\n");
    }
    str_append(str, "\r\n");

    /* original message's headers */
    str_printfa(str, "--%s\r\nContent-Type: message/rfc822\r\n\r\n", boundary);
    o_stream_nsend(output, str_data(str), str_len(str));

    if (mail_get_hdr_stream(mail, NULL, &input) == 0) {
	    /* Note: If you add more headers, they need to be sorted.
	       We'll drop Content-Type because we're not including the message
	       body, and having a multipart Content-Type may confuse some
	       MIME parsers when they don't see the message boundaries. */
	    static const char *const exclude_headers[] = {
		    "Content-Type"
	    };

	    input = i_stream_create_header_filter(input,
	    		HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR |
			HEADER_FILTER_HIDE_BODY, exclude_headers,
			N_ELEMENTS(exclude_headers),
			*null_header_filter_callback, (void *)NULL);

	    ret = o_stream_send_istream(output, input);
	    i_stream_unref(&input);

	    i_assert(ret != 0);
    }

    str_truncate(str, 0);
    str_printfa(str, "\r\n\r\n--%s--\r\n", boundary);
    o_stream_nsend(output, str_data(str), str_len(str));
    return smtp_client_close(smtp_client);
}