static int
stream_close (CamelStream *stream)
{
	CamelSCALIXStream *scalix = (CamelSCALIXStream *) stream;
	
	if (camel_stream_close (scalix->stream) == -1)
		return -1;
	
	camel_object_unref (scalix->stream);
	scalix->stream = NULL;
	
	scalix->disconnected = TRUE;
	
	return 0;
}
static int
stream_close (CamelStream *stream)
{
	CamelIMAP4Stream *imap4 = (CamelIMAP4Stream *) stream;

	if (camel_stream_close (imap4->stream) == -1)
		return -1;

	camel_object_unref (imap4->stream);
	imap4->stream = NULL;

	imap4->disconnected = TRUE;

	return 0;
}
Example #3
0
gint
test_message_write_file (CamelMimeMessage *msg,
                         const gchar *name)
{
	CamelStream *stream;
	gint ret;

	stream = camel_stream_fs_new_with_name (
		name, O_CREAT | O_WRONLY, 0600, NULL);
	camel_data_wrapper_write_to_stream_sync (
		CAMEL_DATA_WRAPPER (msg), stream, NULL, NULL);
	ret = camel_stream_close (stream, NULL, NULL);

	check (G_OBJECT (stream)->ref_count == 1);
	g_object_unref (stream);

	return ret;
}
Example #4
0
static int
pipe_to_sa_full (CamelMimeMessage *msg, const char *in, char **argv, int rv_err, int wait_for_termination, GByteArray *output_buffer, GError **error)
{
	int result, status, errnosav, fds[2], out_fds[2];
	CamelStream *stream;
	char *program;
	pid_t pid;


	if (camel_debug_start ("junk")) {
		int i;

		printf ("pipe_to_sa ");
		for (i = 0; argv[i]; i++)
			printf ("%s ", argv[i]);
		printf ("\n");
		camel_debug_end ();
	}

	program = g_find_program_in_path (argv [0]);
	if (program == NULL) {
		d(printf ("program not found, returning %d\n", rv_err));
		g_set_error (error, EM_JUNK_ERROR, rv_err, _("SpamAssassin not found, code: %d"), rv_err);
		return rv_err;
	}
	g_free (program);

	if (pipe (fds) == -1) {
		errnosav = errno;
		d(printf ("failed to create a pipe (for use with spamassassin: %s\n", strerror (errno)));
		g_set_error (error, EM_JUNK_ERROR, errnosav, _("Failed to create pipe: %s"), strerror (errnosav));
		errno = errnosav;
		return rv_err;
	}

	if (output_buffer && pipe (out_fds) == -1) {
		errnosav = errno;
		d(printf ("failed to create a pipe (for use with spamassassin: %s\n", strerror (errno)));
		g_set_error (error, EM_JUNK_ERROR, errnosav, _("Failed to create pipe: %s"), strerror (errnosav));
		close (fds [0]);
		close (fds [1]);
		errno = errnosav;
		return rv_err;
	}

	if (!(pid = fork ())) {
		/* child process */
		int maxfd, fd, nullfd;

		nullfd = open ("/dev/null", O_WRONLY);

		if (dup2 (fds[0], STDIN_FILENO) == -1 ||
		    dup2 (nullfd, STDERR_FILENO) == -1 ||
		    (output_buffer == NULL && dup2 (nullfd, STDOUT_FILENO) == -1) ||
		    (output_buffer != NULL && dup2 (out_fds[1], STDOUT_FILENO) == -1))
			_exit (rv_err & 0377);
		close (fds [0]);
		if (output_buffer)
			close (out_fds [1]);

		setsid ();

		maxfd = sysconf (_SC_OPEN_MAX);
		for (fd = 3; fd < maxfd; fd++)
			fcntl (fd, F_SETFD, FD_CLOEXEC);

		execvp (argv[0], argv);
		_exit (rv_err & 0377);
	} else if (pid < 0) {
		errnosav = errno;
		close (fds[0]);
		close (fds[1]);
		if (output_buffer) {
			close (out_fds [0]);
			close (out_fds [1]);
		}
		if (errnosav != 0 && errnosav != -1)
			g_set_error (error, EM_JUNK_ERROR, errnosav, _("Error after fork: %s"), strerror (errnosav));
		errno = errnosav;
		return rv_err;
	}

	/* parent process */
	close (fds[0]);
	if (output_buffer)
		close (out_fds [1]);

	if (msg) {
		stream = camel_stream_fs_new_with_fd (fds[1]);

		camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (msg), stream);
		camel_stream_flush (stream);
		camel_stream_close (stream);
		camel_object_unref (stream);
	} else if (in) {
		camel_write (fds[1], in, strlen (in));
		close (fds[1]);
	}

	if (output_buffer) {
		CamelStreamMem *memstream;

		stream = camel_stream_fs_new_with_fd (out_fds[0]);

		memstream = (CamelStreamMem *) camel_stream_mem_new ();
		camel_stream_mem_set_byte_array (memstream, output_buffer);

		camel_stream_write_to_stream (stream, (CamelStream *) memstream);
		camel_object_unref (stream);
		g_byte_array_append (output_buffer, (unsigned char *)"", 1);

		d(printf ("child process output: %s len: %d\n", output_buffer->data, output_buffer->len));
	}

	if (wait_for_termination) {
		int res;

		d(printf ("wait for child %d termination\n", pid));
		result = waitpid (pid, &status, 0);

		d(printf ("child %d terminated with result %d status %d exited %d exitstatus %d\n", pid, result, status, WIFEXITED (status), WEXITSTATUS (status)));

		if (result == -1 && errno == EINTR) {
			/* child process is hanging... */
			kill (pid, SIGTERM);
			sleep (1);
			result = waitpid (pid, &status, WNOHANG);
			if (result == 0) {
				/* ...still hanging, set phasers to KILL */
				kill (pid, SIGKILL);
				sleep (1);
				result = waitpid (pid, &status, WNOHANG);
					g_set_error (error, EM_JUNK_ERROR, -2, _("SpamAssassin child process does not respond, killing..."));
			} else
				g_set_error (error, EM_JUNK_ERROR, -3, _("Wait for Spamassassin child process interrupted, terminating..."));
		}

		if (result != -1 && WIFEXITED (status))
			res = WEXITSTATUS (status);
		else
			res = rv_err;

		if (res != 0)
			g_set_error (error, EM_JUNK_ERROR, res, _("Pipe to SpamAssassin failed, error code: %d"), res);

		return res;
	} else
		return 0;
}
Example #5
0
gint main (gint argc, gchar **argv)
{
	CamelService *service;
	CamelSession *session;
	CamelStore *store;
	CamelFolder *folder;
	CamelMimeMessage *msg;
	gint i, j;
	CamelStream *mbox;
	CamelFilterDriver *driver;
	GError *error = NULL;

	camel_test_init (argc, argv);
	camel_test_provider_init (1, local_drivers);

	/* clear out any camel-test data */
	system ("/bin/rm -rf /tmp/camel-test");

	camel_test_start ("Simple filtering of mbox");

	session = camel_test_session_new ("/tmp/camel-test");

	/* todo: cross-check everything with folder_info checks as well */
	/* todo: work out how to do imap/pop/nntp tests */

	push ("getting store");
	service = camel_session_add_service (
		session, "test-uid", "mbox:///tmp/camel-test/mbox",
		CAMEL_PROVIDER_STORE, &error);
	check_msg (error == NULL, "getting store: %s", error->message);
	check (CAMEL_IS_STORE (service));
	store = CAMEL_STORE (service);
	g_clear_error (&error);
	pull ();

	push ("Creating output folders");
	for (i = 0; i < G_N_ELEMENTS (mailboxes); i++) {
		push ("creating %s", mailboxes[i].name);
		mailboxes[i].folder = folder = camel_store_get_folder_sync (
			store, mailboxes[i].name,
			CAMEL_STORE_FOLDER_CREATE, NULL, &error);
		check_msg (error == NULL, "%s", error->message);
		check (folder != NULL);

		/* we need an empty folder for this to work */
		test_folder_counts (folder, 0, 0);
		g_clear_error (&error);
		pull ();
	}
	pull ();

	/* append a bunch of messages with specific content */
	push ("creating 100 test message mbox");
	mbox = camel_stream_fs_new_with_name ("/tmp/camel-test/inbox", O_WRONLY|O_CREAT|O_EXCL, 0600, NULL);
	for (j = 0; j < 100; j++) {
		gchar *content, *subject;

		push ("creating test message");
		msg = test_message_create_simple ();
		content = g_strdup_printf ("data%d content\n", j);
		test_message_set_content_simple ((CamelMimePart *)msg, 0, "text/plain",
						content, strlen (content));
		test_free (content);
		subject = g_strdup_printf ("Test%d message%d subject", j, 100-j);
		camel_mime_message_set_subject (msg, subject);

		camel_mime_message_set_date (msg, j * 60 * 24, 0);
		pull ();

		camel_stream_write_string (mbox, "From \n", NULL, NULL);
		check (camel_data_wrapper_write_to_stream_sync (
			CAMEL_DATA_WRAPPER (msg), mbox, NULL, NULL) != -1);
#if 0
		push ("appending simple message %d", j);
		camel_folder_append_message (folder, msg, NULL, ex);
		check_msg (error == NULL, "%s", error->message);
		g_clear_error (&error);
		pull ();
#endif
		test_free (subject);

		check_unref (msg, 1);
	}
	check (camel_stream_close (mbox, NULL, NULL) != -1);
	check_unref (mbox, 1);
	pull ();

	push ("Building filters");
	driver = camel_filter_driver_new (session);
	camel_filter_driver_set_folder_func (driver, get_folder, NULL);
	for (i = 0; i < G_N_ELEMENTS (rules); i++) {
		camel_filter_driver_add_rule (driver, rules[i].name, rules[i].match, rules[i].action);
	}
	pull ();

	push ("Executing filters");
	camel_filter_driver_set_default_folder (driver, mailboxes[0].folder);
#if 0  /* FIXME We no longer filter mbox files. */
	camel_filter_driver_filter_mbox (
		driver, "/tmp/camel-test/inbox", NULL, NULL, &error);
#endif
	check_msg (error == NULL, "%s", error->message);

	/* now need to check the folder counts/etc */

	check_unref (driver, 1);
	g_clear_error (&error);
	pull ();

	/* this tests that invalid rules are caught */
	push ("Testing broken match rules");
	for (i = 0; i < G_N_ELEMENTS (brokens); i++) {
		push ("rule %s", brokens[i].match);
		driver = camel_filter_driver_new (session);
		camel_filter_driver_set_folder_func (driver, get_folder, NULL);
		camel_filter_driver_add_rule (driver, brokens[i].name, brokens[i].match, brokens[i].action);
#if 0  /* FIXME We no longer filter mbox files. */
		camel_filter_driver_filter_mbox (
			driver, "/tmp/camel-test/inbox", NULL, NULL, &error);
#endif
		check (error != NULL);
		check_unref (driver, 1);
		g_clear_error (&error);
		pull ();
	}
	pull ();

	push ("Testing broken action rules");
	for (i = 0; i < G_N_ELEMENTS (brokena); i++) {
		push ("rule %s", brokena[i].action);
		driver = camel_filter_driver_new (session);
		camel_filter_driver_set_folder_func (driver, get_folder, NULL);
		camel_filter_driver_add_rule (driver, brokena[i].name, brokena[i].match, brokena[i].action);
#if 0  /* FIXME We no longer filter mbox files. */
		camel_filter_driver_filter_mbox (
			driver, "/tmp/camel-test/inbox", NULL, NULL, &error);
#endif
		check (error != NULL);
		check_unref (driver, 1);
		g_clear_error (&error);
		pull ();
	}
	pull ();

	for (i = 0; i < G_N_ELEMENTS (mailboxes); i++) {
		check_unref (mailboxes[i].folder, 1);
	}

	check_unref (store, 1);

	check_unref (session, 1);

	camel_test_end ();

	return 0;
}
static gboolean
maildir_folder_append_message_sync (CamelFolder *folder,
                                    CamelMimeMessage *message,
                                    CamelMessageInfo *info,
                                    gchar **appended_uid,
                                    GCancellable *cancellable,
                                    GError **error)
{
	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
	CamelStream *output_stream;
	CamelMessageInfo *mi;
	CamelMaildirMessageInfo *mdi;
	gchar *name, *dest = NULL;
	gboolean success = TRUE;

	d(printf("Appending message\n"));

	/* If we can't lock, don't do anything */
	if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1)
		return FALSE;

	/* add it to the summary/assign the uid, etc */
	mi = camel_local_summary_add (
		CAMEL_LOCAL_SUMMARY (folder->summary),
		message, info, lf->changes, error);
	if (mi == NULL)
		goto check_changed;

	if ((camel_message_info_flags (mi) & CAMEL_MESSAGE_ATTACHMENTS) && !camel_mime_message_has_attachment (message))
		camel_message_info_set_flags (mi, CAMEL_MESSAGE_ATTACHMENTS, 0);

	mdi = (CamelMaildirMessageInfo *)mi;

	d(printf("Appending message: uid is %s filename is %s\n", camel_message_info_uid(mi), mdi->filename));

	/* write it out to tmp, use the uid we got from the summary */
	name = g_strdup_printf ("%s/tmp/%s", lf->folder_path, camel_message_info_uid(mi));
	output_stream = camel_stream_fs_new_with_name (
		name, O_WRONLY|O_CREAT, 0600, error);
	if (output_stream == NULL)
		goto fail_write;

	if (camel_data_wrapper_write_to_stream_sync (
		(CamelDataWrapper *)message, output_stream, cancellable, error) == -1
	    || camel_stream_close (output_stream, cancellable, error) == -1)
		goto fail_write;

	/* now move from tmp to cur (bypass new, does it matter?) */
	dest = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi));
	if (g_rename (name, dest) == -1) {
		g_set_error (
			error, G_IO_ERROR,
			g_io_error_from_errno (errno),
			"%s", g_strerror (errno));
		goto fail_write;
	}

	g_free (dest);
	g_free (name);

	if (appended_uid)
		*appended_uid = g_strdup(camel_message_info_uid(mi));

	if (output_stream)
		g_object_unref (output_stream);

	goto check_changed;

 fail_write:

	/* remove the summary info so we are not out-of-sync with the mh folder */
	camel_folder_summary_remove_uid (CAMEL_FOLDER_SUMMARY (folder->summary),
					 camel_message_info_uid (mi));

	g_prefix_error (
		error, _("Cannot append message to maildir folder: %s: "),
		name);

	if (output_stream) {
		g_object_unref (CAMEL_OBJECT (output_stream));
		unlink (name);
	}

	g_free (name);
	g_free (dest);

	success = FALSE;

 check_changed:
	camel_local_folder_unlock (lf);

	if (lf && camel_folder_change_info_changed (lf->changes)) {
		camel_folder_changed (folder, lf->changes);
		camel_folder_change_info_clear (lf->changes);
	}

	return success;
}
static gboolean
sendmail_send_to_sync (CamelTransport *transport,
                       CamelMimeMessage *message,
                       CamelAddress *from,
                       CamelAddress *recipients,
		       gboolean *out_sent_message_saved,
                       GCancellable *cancellable,
                       GError **error)
{
	CamelHeaderRaw *header, *savedbcc, *n, *tail;
	const gchar *from_addr, *addr;
	GPtrArray *argv_arr;
	gint i, len, fd[2], nullfd, wstat;
	CamelStream *filter;
	CamelMimeFilter *crlf;
	sigset_t mask, omask;
	CamelStream *out;
	CamelSendmailSettings *settings;
	const gchar *binary = SENDMAIL_PATH;
	gchar *custom_binary = NULL, *custom_args = NULL;
	gboolean success;
	pid_t pid;

	success = camel_internet_address_get (
		CAMEL_INTERNET_ADDRESS (from), 0, NULL, &from_addr);

	if (!success) {
		g_set_error (
			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			_("Failed to read From address"));
		return FALSE;
	}

	settings = CAMEL_SENDMAIL_SETTINGS (camel_service_ref_settings (CAMEL_SERVICE (transport)));

	if (!camel_sendmail_settings_get_send_in_offline (settings)) {
		CamelSession *session;
		gboolean is_online;

		session = camel_service_ref_session (CAMEL_SERVICE (transport));
		is_online = session && camel_session_get_online (session);
		g_clear_object (&session);

		if (!is_online) {
			g_set_error (
				error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE,
				_("Message send in offline mode is disabled"));
			return FALSE;
		}
	}

	if (camel_sendmail_settings_get_use_custom_binary (settings)) {
		custom_binary = camel_sendmail_settings_dup_custom_binary (settings);
		if (custom_binary && *custom_binary)
			binary = custom_binary;
	}

	if (camel_sendmail_settings_get_use_custom_args (settings)) {
		custom_args = camel_sendmail_settings_dup_custom_args (settings);
		/* means no arguments used */
		if (!custom_args)
			custom_args = g_strdup ("");
	}

	g_object_unref (settings);

	len = camel_address_length (recipients);
	for (i = 0; i < len; i++) {
		success = camel_internet_address_get (
			CAMEL_INTERNET_ADDRESS (recipients), i, NULL, &addr);

		if (!success) {
			g_set_error (
				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
				_("Could not parse recipient list"));
			g_free (custom_binary);
			g_free (custom_args);

			return FALSE;
		}
	}

	argv_arr = parse_sendmail_args (
		binary,
		custom_args ? custom_args : "-i -f %F -- %R",
		from_addr,
		recipients);

	if (!argv_arr) {
		g_set_error (
			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			_("Could not parse arguments"));

		g_free (custom_binary);
		g_free (custom_args);

		return FALSE;
	}

	/* unlink the bcc headers */
	savedbcc = NULL;
	tail = (CamelHeaderRaw *) &savedbcc;

	header = (CamelHeaderRaw *) &CAMEL_MIME_PART (message)->headers;
	n = header->next;
	while (n != NULL) {
		if (!g_ascii_strcasecmp (n->name, "Bcc")) {
			header->next = n->next;
			tail->next = n;
			n->next = NULL;
			tail = n;
		} else {
			header = n;
		}

		n = header->next;
	}

	if (pipe (fd) == -1) {
		g_set_error (
			error, G_IO_ERROR,
			g_io_error_from_errno (errno),
			_("Could not create pipe to '%s': %s: "
			"mail not sent"), binary, g_strerror (errno));

		/* restore the bcc headers */
		header->next = savedbcc;
		g_free (custom_binary);
		g_free (custom_args);
		g_ptr_array_free (argv_arr, TRUE);

		return FALSE;
	}

	/* Block SIGCHLD so the calling application doesn't notice
	 * sendmail exiting before we do.
	 */
	sigemptyset (&mask);
	sigaddset (&mask, SIGCHLD);
	sigprocmask (SIG_BLOCK, &mask, &omask);

	pid = fork ();
	switch (pid) {
	case -1:
		g_set_error (
			error, G_IO_ERROR,
			g_io_error_from_errno (errno),
			_("Could not fork '%s': %s: "
			"mail not sent"), binary, g_strerror (errno));
		close (fd[0]);
		close (fd[1]);
		sigprocmask (SIG_SETMASK, &omask, NULL);

		/* restore the bcc headers */
		header->next = savedbcc;
		g_free (custom_binary);
		g_free (custom_args);
		g_ptr_array_free (argv_arr, TRUE);

		return FALSE;
	case 0:
		/* Child process */
		nullfd = open ("/dev/null", O_RDWR);
		dup2 (fd[0], STDIN_FILENO);
		if (nullfd != -1) {
			/*dup2 (nullfd, STDOUT_FILENO);
			  dup2 (nullfd, STDERR_FILENO);*/
			close (nullfd);
		}
		close (fd[1]);

		execv (binary, (gchar **) argv_arr->pdata);
		_exit (255);
	}

	g_ptr_array_free (argv_arr, TRUE);

	/* Parent process. Write the message out. */
	close (fd[0]);
	out = camel_stream_fs_new_with_fd (fd[1]);

	/* XXX Workaround for lame sendmail implementations
	 *     that can't handle CRLF eoln sequences. */
	filter = camel_stream_filter_new (out);
	crlf = camel_mime_filter_crlf_new (
		CAMEL_MIME_FILTER_CRLF_DECODE,
		CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
	camel_stream_filter_add (CAMEL_STREAM_FILTER (filter), crlf);
	g_object_unref (crlf);
	g_object_unref (out);

	out = (CamelStream *) filter;
	if (camel_data_wrapper_write_to_stream_sync (
		CAMEL_DATA_WRAPPER (message), out, cancellable, error) == -1
	    || camel_stream_close (out, cancellable, error) == -1) {
		g_object_unref (out);
		g_prefix_error (error, _("Could not send message: "));

		/* Wait for sendmail to exit. */
		while (waitpid (pid, &wstat, 0) == -1 && errno == EINTR)
			;

		sigprocmask (SIG_SETMASK, &omask, NULL);

		/* restore the bcc headers */
		header->next = savedbcc;
		g_free (custom_binary);
		g_free (custom_args);

		return FALSE;
	}

	g_object_unref (out);

	/* Wait for sendmail to exit. */
	while (waitpid (pid, &wstat, 0) == -1 && errno == EINTR)
		;

	sigprocmask (SIG_SETMASK, &omask, NULL);

	/* restore the bcc headers */
	header->next = savedbcc;

	if (!WIFEXITED (wstat)) {
		g_set_error (
			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			_("'%s' exited with signal %s: mail not sent."),
			binary, g_strsignal (WTERMSIG (wstat)));
		g_free (custom_binary);
		g_free (custom_args);

		return FALSE;
	} else if (WEXITSTATUS (wstat) != 0) {
		if (WEXITSTATUS (wstat) == 255) {
			g_set_error (
				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
				_("Could not execute '%s': mail not sent."),
				binary);
		} else {
			g_set_error (
				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
				_("'%s' exited with status %d: "
				"mail not sent."),
				binary, WEXITSTATUS (wstat));
		}
		g_free (custom_binary);
		g_free (custom_args);

		return FALSE;
	}

	g_free (custom_binary);
	g_free (custom_args);

	return TRUE;
}
static gboolean
mh_folder_append_message_sync (CamelFolder *folder,
                               CamelMimeMessage *message,
                               CamelMessageInfo *info,
                               gchar **appended_uid,
                               GCancellable *cancellable,
                               GError **error)
{
	CamelLocalFolder *lf = (CamelLocalFolder *) folder;
	CamelStream *output_stream;
	CamelMessageInfo *mi;
	gchar *name;
	gboolean has_attachment;

	/* FIXME: probably needs additional locking (although mh doesn't appear do do it) */

	d(printf("Appending message\n"));

	/* If we can't lock, don't do anything */
	if (!lf || camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1)
		return FALSE;

	/* add it to the summary/assign the uid, etc */
	mi = camel_local_summary_add ((CamelLocalSummary *) folder->summary, message, info, lf->changes, error);
	if (mi == NULL)
		goto check_changed;

	has_attachment = camel_mime_message_has_attachment (message);
	if (((camel_message_info_flags (mi) & CAMEL_MESSAGE_ATTACHMENTS) && !has_attachment) ||
	    ((camel_message_info_flags (mi) & CAMEL_MESSAGE_ATTACHMENTS) == 0 && has_attachment)) {
		camel_message_info_set_flags (mi, CAMEL_MESSAGE_ATTACHMENTS, has_attachment ? CAMEL_MESSAGE_ATTACHMENTS : 0);
	}

	d(printf("Appending message: uid is %s\n", camel_message_info_uid(mi)));

	/* write it out, use the uid we got from the summary */
	name = g_strdup_printf("%s/%s", lf->folder_path, camel_message_info_uid(mi));
	output_stream = camel_stream_fs_new_with_name (
		name, O_WRONLY | O_CREAT, 0600, error);
	if (output_stream == NULL)
		goto fail_write;

	if (camel_data_wrapper_write_to_stream_sync (
		(CamelDataWrapper *) message, output_stream, cancellable, error) == -1
	    || camel_stream_close (output_stream, cancellable, error) == -1)
		goto fail_write;

	/* close this? */
	g_object_unref (output_stream);

	g_free (name);

	if (appended_uid)
		*appended_uid = g_strdup(camel_message_info_uid(mi));

	goto check_changed;

 fail_write:

	/* remove the summary info so we are not out-of-sync with the mh folder */
	camel_folder_summary_remove_uid (CAMEL_FOLDER_SUMMARY (folder->summary),
					 camel_message_info_uid (mi));

	g_prefix_error (
		error, _("Cannot append message to mh folder: %s: "), name);

	if (output_stream) {
		g_object_unref (output_stream);
		unlink (name);
	}

	g_free (name);

 check_changed:
	camel_local_folder_unlock (lf);

	if (camel_folder_change_info_changed (lf->changes)) {
		camel_folder_changed (folder, lf->changes);
		camel_folder_change_info_clear (lf->changes);
	}

	return TRUE;
}
Example #9
0
void
org_gnome_format_tnef(void *ep, EMFormatHookTarget *t)
{
	char *tmpdir = NULL, *name = NULL;
	CamelStream *out;
	struct dirent *d;
	DIR *dir;
	CamelMultipart *mp;
	CamelMimePart *mainpart;
	CamelDataWrapper *content;
	int len;
	TNEFStruct *tnef;
	tnef = (TNEFStruct *) g_malloc(sizeof(TNEFStruct));

	tmpdir = e_mkdtemp("tnef-attachment-XXXXXX");
	if (tmpdir == NULL)
		return;

	filepath = tmpdir;

	name = g_build_filename(tmpdir, ".evo-attachment.tnef", NULL);

	out = camel_stream_fs_new_with_name(name, O_RDWR|O_CREAT, 0666);
	if (out == NULL)
	    goto fail;
	content = camel_medium_get_content_object((CamelMedium *)t->part);
	if (content == NULL)
		goto fail;
	if (camel_data_wrapper_decode_to_stream(content, out) == -1
	    || camel_stream_close(out) == -1) {
		camel_object_unref(out);
 		goto fail;
	}
	camel_object_unref(out);

	/* Extracting the winmail.dat */
        TNEFInitialize(tnef);
	tnef->Debug = verbose;
        if (TNEFParseFile(name, tnef) == -1) {
            printf("ERROR processing file\n");
        }
	processTnef(tnef);

        TNEFFree(tnef);
	/* Extraction done */

	dir = opendir(tmpdir);
	if (dir == NULL)
	    goto fail;

	mainpart = camel_mime_part_new();

	mp = camel_multipart_new();
	camel_data_wrapper_set_mime_type((CamelDataWrapper *)mp, "multipart/mixed");
	camel_multipart_set_boundary(mp, NULL);

	camel_medium_set_content_object((CamelMedium *)mainpart, (CamelDataWrapper *)mp);

	while ((d = readdir(dir))) {
		CamelMimePart *part;
		CamelDataWrapper *content;
		CamelStream *stream;
		char *path;
		const char *type;

		if (!strcmp(d->d_name, ".")
		    || !strcmp(d->d_name, "..")
		    || !strcmp(d->d_name, ".evo-attachment.tnef"))
		    continue;

		path = g_build_filename(tmpdir, d->d_name, NULL);

		stream = camel_stream_fs_new_with_name(path, O_RDONLY, 0);
		content = camel_data_wrapper_new();
		camel_data_wrapper_construct_from_stream(content, stream);
		camel_object_unref(stream);

		part = camel_mime_part_new();
		camel_mime_part_set_encoding(part, CAMEL_TRANSFER_ENCODING_BINARY);

		camel_medium_set_content_object((CamelMedium *)part, content);
		camel_object_unref(content);

		type = em_utils_snoop_type(part);
		if (type)
		    camel_data_wrapper_set_mime_type((CamelDataWrapper *)part, type);

		camel_mime_part_set_filename(part, d->d_name);

		g_free(path);

		camel_multipart_add_part(mp, part);
	}

	closedir(dir);

	len = t->format->part_id->len;
	g_string_append_printf(t->format->part_id, ".tnef");

	if (camel_multipart_get_number(mp) > 0)
		em_format_part_as(t->format, t->stream, mainpart, "multipart/mixed");
	else if (t->item->handler.old)
	    t->item->handler.old->handler(t->format, t->stream, t->part, t->item->handler.old);

	g_string_truncate(t->format->part_id, len);

	camel_object_unref(mainpart);

	goto ok;
 fail:
	if (t->item->handler.old)
	    t->item->handler.old->handler(t->format, t->stream, t->part, t->item->handler.old);
 ok:
	g_free(name);
	g_free(tmpdir);
}
gboolean
e_composer_autosave_snapshot (EMsgComposer *composer)
{
	GtkhtmlEditor *editor;
	CamelMimeMessage *message;
	AutosaveState *state;
	CamelStream *stream;
	gint camelfd;
	const gchar *errmsg;

	g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE);

	editor = GTKHTML_EDITOR (composer);

	/* If the contents are unchanged, exit early. */
	if (!gtkhtml_editor_get_changed (editor))
		return TRUE;

	state = g_object_get_data (G_OBJECT (composer), "autosave");
	g_return_val_if_fail (state != NULL, FALSE);

	/* Open the autosave file on-demand. */
	if (!composer_autosave_state_open (state, NULL)) {
		errmsg = _("Could not open autosave file");
		goto fail;
	}

	/* Extract a MIME message from the composer. */
	message = e_msg_composer_get_message_draft (composer);
	if (message == NULL) {
		errmsg = _("Unable to retrieve message from editor");
		goto fail;
	}

	/* Move to the beginning of the autosave file. */
	if (lseek (state->fd, (off_t) 0, SEEK_SET) < 0) {
		camel_object_unref (message);
		errmsg = g_strerror (errno);
		goto fail;
	}

	/* Destroy the contents of the autosave file. */
	if (ftruncate (state->fd, (off_t) 0) < 0) {
		camel_object_unref (message);
		errmsg = g_strerror (errno);
		goto fail;
	}

	/* Duplicate the file descriptor for Camel. */
	if ((camelfd = dup (state->fd)) < 0) {
		camel_object_unref (message);
		errmsg = g_strerror (errno);
		goto fail;
	}

	/* Open a CamelStream to the autosave file. */
	stream = camel_stream_fs_new_with_fd (camelfd);

	/* Write the message to the CamelStream. */
	if (camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), stream) < 0) {
		camel_object_unref (message);
		camel_object_unref (stream);
		errmsg = g_strerror (errno);
		goto fail;
	}

	/* Close the CamelStream. */
	if (camel_stream_close (CAMEL_STREAM (stream)) < 0) {
		camel_object_unref (message);
		camel_object_unref (stream);
		errmsg = g_strerror (errno);
		goto fail;
	}

	/* Snapshot was successful; set various flags. */
	gtkhtml_editor_set_changed (editor, FALSE);
	e_composer_autosave_set_saved (composer, TRUE);

	camel_object_unref (message);
	camel_object_unref (stream);

	return TRUE;

fail:
	e_error_run (
		GTK_WINDOW (composer), "mail-composer:no-autosave",
		(state->filename != NULL) ? state->filename : "",
		errmsg, NULL);

	return FALSE;
}