static GMimeMessage * create_reply_message(void *ctx, notmuch_config_t *config, notmuch_message_t *message, notmuch_bool_t reply_all) { const char *subject, *from_addr = NULL; const char *in_reply_to, *orig_references, *references; /* The 1 means we want headers in a "pretty" order. */ GMimeMessage *reply = g_mime_message_new (1); if (reply == NULL) { fprintf (stderr, "Out of memory\n"); return NULL; } subject = notmuch_message_get_header (message, "subject"); if (subject) { if (strncasecmp (subject, "Re:", 3)) subject = talloc_asprintf (ctx, "Re: %s", subject); g_mime_message_set_subject (reply, subject); } from_addr = add_recipients_from_message (reply, config, message, reply_all); if (from_addr == NULL) from_addr = guess_from_received_header (config, message); if (from_addr == NULL) from_addr = notmuch_config_get_user_primary_email (config); from_addr = talloc_asprintf (ctx, "%s <%s>", notmuch_config_get_user_name (config), from_addr); g_mime_object_set_header (GMIME_OBJECT (reply), "From", from_addr); in_reply_to = talloc_asprintf (ctx, "<%s>", notmuch_message_get_message_id (message)); g_mime_object_set_header (GMIME_OBJECT (reply), "In-Reply-To", in_reply_to); orig_references = notmuch_message_get_header (message, "references"); if (!orig_references) /* Treat errors like missing References headers. */ orig_references = ""; references = talloc_asprintf (ctx, "%s%s%s", *orig_references ? orig_references : "", *orig_references ? " " : "", in_reply_to); g_mime_object_set_header (GMIME_OBJECT (reply), "References", references); return reply; }
static GMimeMessage * create_reply_message(void *ctx, notmuch_config_t *config, notmuch_message_t *message, notmuch_bool_t reply_all) { const char *subject, *from_addr = NULL; const char *in_reply_to, *orig_references, *references; /* The 1 means we want headers in a "pretty" order. */ GMimeMessage *reply = g_mime_message_new (1); if (reply == NULL) { fprintf (stderr, "Out of memory\n"); return NULL; } subject = notmuch_message_get_header (message, "subject"); if (subject) { if (strncasecmp (subject, "Re:", 3)) subject = talloc_asprintf (ctx, "Re: %s", subject); g_mime_message_set_subject (reply, subject); } from_addr = add_recipients_from_message (reply, config, message, reply_all); /* * Sadly, there is no standard way to find out to which email * address a mail was delivered - what is in the headers depends * on the MTAs used along the way. * * If none of the user's email addresses are in the To: or Cc: * headers, we try a number of heuristics which hopefully will * answer this question. * * First, check for Envelope-To:, X-Original-To:, and * Delivered-To: headers. */ if (from_addr == NULL) from_addr = get_from_in_to_headers (config, message); /* * Check for a (for <*****@*****.**>) clause in Received: headers, * and the domain part of known email addresses in the 'by' part * of Received: headers */ if (from_addr == NULL) from_addr = guess_from_in_received_headers (config, message); /* Default to user's primary address. */ if (from_addr == NULL) from_addr = notmuch_config_get_user_primary_email (config); from_addr = talloc_asprintf (ctx, "%s <%s>", notmuch_config_get_user_name (config), from_addr); g_mime_object_set_header (GMIME_OBJECT (reply), "From", from_addr); in_reply_to = talloc_asprintf (ctx, "<%s>", notmuch_message_get_message_id (message)); g_mime_object_set_header (GMIME_OBJECT (reply), "In-Reply-To", in_reply_to); orig_references = notmuch_message_get_header (message, "references"); if (!orig_references) /* Treat errors like missing References headers. */ orig_references = ""; references = talloc_asprintf (ctx, "%s%s%s", *orig_references ? orig_references : "", *orig_references ? " " : "", in_reply_to); g_mime_object_set_header (GMIME_OBJECT (reply), "References", references); return reply; }
gboolean write_smtp_reply (struct smtp_session *session) { gchar logbuf[1024], *new_subject; const gchar *old_subject; struct smtp_metric_callback_data cd; GMimeStream *stream; gint old_fd, sublen; /* Check metrics */ cd.session = session; cd.action = METRIC_ACTION_NOACTION; cd.res = NULL; cd.log_buf = logbuf; cd.log_offset = rspamd_snprintf (logbuf, sizeof (logbuf), "id: <%s>, qid: <%s>, ", session->task->message_id, session->task->queue_id); cd.log_size = sizeof (logbuf); if (session->task->user) { cd.log_offset += rspamd_snprintf (logbuf + cd.log_offset, sizeof (logbuf) - cd.log_offset, "user: %s, ", session->task->user); } g_hash_table_foreach (session->task->results, smtp_metric_callback, &cd); msg_info ("%s", logbuf); if (cd.action <= METRIC_ACTION_REJECT) { if (!rspamd_dispatcher_write (session->dispatcher, session->ctx->reject_message, 0, FALSE, TRUE)) { return FALSE; } if (!rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) { return FALSE; } destroy_session (session->s); return FALSE; } else if (cd.action <= METRIC_ACTION_ADD_HEADER || cd.action <= METRIC_ACTION_REWRITE_SUBJECT) { old_fd = session->temp_fd; if (!make_smtp_tempfile (session)) { session->error = SMTP_ERROR_FILE; session->state = SMTP_STATE_CRITICAL_ERROR; rspamd_dispatcher_restore (session->dispatcher); if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) { goto err; } destroy_session (session->s); return FALSE; } if (cd.action <= METRIC_ACTION_REWRITE_SUBJECT) { /* XXX: add this action */ old_subject = g_mime_message_get_subject (session->task->message); if (old_subject != NULL) { sublen = strlen (old_subject) + sizeof (SPAM_SUBJECT); new_subject = rspamd_mempool_alloc (session->pool, sublen); rspamd_snprintf (new_subject, sublen, "%s%s", SPAM_SUBJECT, old_subject); } else { new_subject = SPAM_SUBJECT; } g_mime_message_set_subject (session->task->message, new_subject); } else if (cd.action <= METRIC_ACTION_ADD_HEADER) { #ifndef GMIME24 g_mime_message_add_header (session->task->message, "X-Spam", "true"); #else g_mime_object_append_header (GMIME_OBJECT ( session->task->message), "X-Spam", "true"); #endif } stream = g_mime_stream_fs_new (session->temp_fd); g_mime_stream_fs_set_owner (GMIME_STREAM_FS (stream), FALSE); close (old_fd); if (g_mime_object_write_to_stream (GMIME_OBJECT (session->task->message), stream) == -1) { msg_err ("cannot write MIME object to stream: %s", strerror (errno)); session->error = SMTP_ERROR_FILE; session->state = SMTP_STATE_CRITICAL_ERROR; rspamd_dispatcher_restore (session->dispatcher); if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) { goto err; } destroy_session (session->s); return FALSE; } g_object_unref (stream); } /* XXX: Add other actions */ return smtp_send_upstream_message (session); err: session->error = SMTP_ERROR_FILE; session->state = SMTP_STATE_CRITICAL_ERROR; if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) { return FALSE; } destroy_session (session->s); return FALSE; }
static int notmuch_reply_format_default(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params) { GMimeMessage *reply; notmuch_messages_t *messages; notmuch_message_t *message; const char *subject, *from_addr = NULL; const char *in_reply_to, *orig_references, *references; const notmuch_show_format_t *format = &format_reply; for (messages = notmuch_query_search_messages (query); notmuch_messages_valid (messages); notmuch_messages_move_to_next (messages)) { message = notmuch_messages_get (messages); /* The 1 means we want headers in a "pretty" order. */ reply = g_mime_message_new (1); if (reply == NULL) { fprintf (stderr, "Out of memory\n"); return 1; } subject = notmuch_message_get_header (message, "subject"); if (subject) { if (strncasecmp (subject, "Re:", 3)) subject = talloc_asprintf (ctx, "Re: %s", subject); g_mime_message_set_subject (reply, subject); } from_addr = add_recipients_from_message (reply, config, message); if (from_addr == NULL) from_addr = guess_from_received_header (config, message); if (from_addr == NULL) from_addr = notmuch_config_get_user_primary_email (config); from_addr = talloc_asprintf (ctx, "%s <%s>", notmuch_config_get_user_name (config), from_addr); g_mime_object_set_header (GMIME_OBJECT (reply), "From", from_addr); in_reply_to = talloc_asprintf (ctx, "<%s>", notmuch_message_get_message_id (message)); g_mime_object_set_header (GMIME_OBJECT (reply), "In-Reply-To", in_reply_to); orig_references = notmuch_message_get_header (message, "references"); references = talloc_asprintf (ctx, "%s%s%s", orig_references ? orig_references : "", orig_references ? " " : "", in_reply_to); g_mime_object_set_header (GMIME_OBJECT (reply), "References", references); show_reply_headers (reply); g_object_unref (G_OBJECT (reply)); reply = NULL; printf ("On %s, %s wrote:\n", notmuch_message_get_header (message, "date"), notmuch_message_get_header (message, "from")); show_message_body (notmuch_message_get_filename (message), format, params); notmuch_message_destroy (message); } return 0; }