static GMimeStream * lbmss_stream_substream(GMimeStream * stream, gint64 start, gint64 end) { LibBalsaMimeStreamShared *stream_shared; GMimeStreamFs *fstream; stream_shared = g_object_new(LIBBALSA_TYPE_MIME_STREAM_SHARED, NULL, NULL); stream_shared->lock = lbmss_lock_ref(LIBBALSA_MIME_STREAM_SHARED(stream)->lock); fstream = GMIME_STREAM_FS(stream_shared); fstream->owner = FALSE; fstream->fd = GMIME_STREAM_FS(stream)->fd; g_mime_stream_construct(GMIME_STREAM(fstream), start, end); return GMIME_STREAM(fstream); }
/** * libbalsa_mime_stream_shared_new: * @fd: file descriptor * * Create a new GMimeStreamShared object around @fd. * * Returns a stream using @fd. * **/ GMimeStream * libbalsa_mime_stream_shared_new(int fd) { LibBalsaMimeStreamShared *stream_shared; GMimeStreamFs *fstream; gint64 start; stream_shared = g_object_new(LIBBALSA_TYPE_MIME_STREAM_SHARED, NULL, NULL); stream_shared->lock = lbmss_lock_new(); fstream = GMIME_STREAM_FS(stream_shared); fstream->owner = TRUE; fstream->eos = FALSE; fstream->fd = fd; start = lseek(fd, 0, SEEK_CUR); g_mime_stream_construct(GMIME_STREAM(fstream), start, -1); return GMIME_STREAM(fstream); }
gboolean write_part_to_fd (GMimePart *part, int fd, GError **err) { GMimeStream *stream; GMimeDataWrapper *wrapper; gboolean rv; stream = g_mime_stream_fs_new (fd); if (!GMIME_IS_STREAM(stream)) { g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_GMIME, "failed to create stream"); return FALSE; } g_mime_stream_fs_set_owner (GMIME_STREAM_FS(stream), FALSE); wrapper = g_mime_part_get_content_object (part); if (!GMIME_IS_DATA_WRAPPER(wrapper)) { g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_GMIME, "failed to create wrapper"); g_object_unref (stream); return FALSE; } g_object_ref (part); /* FIXME: otherwise, the unrefs below * give errors...*/ if (g_mime_data_wrapper_write_to_stream (wrapper, stream) == -1) { rv = FALSE; g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_GMIME, "failed to write to stream"); } else rv = TRUE; g_object_unref (wrapper); g_object_unref (stream); return rv; }
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; }