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; }
static int uuencode (const char *progname, int argc, char **argv) { GMimeStream *istream, *ostream, *fstream; GMimeContentEncoding encoding; const char *filename, *name; GMimeFilter *filter; gboolean base64; struct stat st; int fd, opt; base64 = FALSE; encoding = GMIME_CONTENT_ENCODING_UUENCODE; while ((opt = getopt_long (argc, argv, "hvm", longopts, NULL)) != -1) { switch (opt) { case 'h': usage (progname); return 0; case 'v': version (progname); return 0; case 'm': base64 = TRUE; encoding = GMIME_CONTENT_ENCODING_BASE64; break; default: printf ("Try `%s --help' for more information.\n", progname); return -1; } } if (optind >= argc) { printf ("Try `%s --help' for more information.\n", progname); return -1; } if (optind + 1 < argc) filename = argv[optind++]; else filename = NULL; name = argv[optind]; /* open our input file... */ if ((fd = filename ? open (filename, O_RDONLY, 0) : dup (0)) == -1) { fprintf (stderr, "%s: %s: %s\n", progname, filename ? filename : "stdin", g_strerror (errno)); return -1; } /* stat() our input file for file mode permissions */ if (fstat (fd, &st) == -1) { fprintf (stderr, "%s: %s: %s\n", progname, filename ? filename : "stdin", g_strerror (errno)); close (fd); return -1; } printf ("begin%s %.3o %s\n", base64 ? "-base64" : "", st.st_mode & 0777, name); fflush (stdout); istream = g_mime_stream_fs_new (fd); /* open our output stream */ ostream = g_mime_stream_fs_new (1); g_mime_stream_fs_set_owner ((GMimeStreamFs *) ostream, FALSE); fstream = g_mime_stream_filter_new (ostream); /* attach an encode filter */ filter = g_mime_filter_basic_new (encoding, TRUE); g_mime_stream_filter_add ((GMimeStreamFilter *) fstream, filter); g_object_unref (filter); if (g_mime_stream_write_to_stream (istream, fstream) == -1) { fprintf (stderr, "%s: %s\n", progname, g_strerror (errno)); g_object_unref (fstream); g_object_unref (istream); g_object_unref (ostream); return -1; } g_mime_stream_flush (fstream); g_object_unref (fstream); g_object_unref (istream); if (g_mime_stream_write_string (ostream, base64 ? "====\n" : "end\n") == -1) { fprintf (stderr, "%s: %s\n", progname, g_strerror (errno)); g_object_unref (ostream); return -1; } g_object_unref (ostream); return 0; }