static gint
mbox_folder_cmp_uids (CamelFolder *folder,
                      const gchar *uid1,
                      const gchar *uid2)
{
	CamelMboxMessageInfo *a, *b;
	gint res;

	g_return_val_if_fail (folder != NULL, 0);
	g_return_val_if_fail (folder->summary != NULL, 0);

	a = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid1);
	b = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid2);

	if (!a || !b) {
		/* It's not a problem when one of the messages is not in the summary */
		if (a)
			camel_message_info_unref (a);
		if (b)
			camel_message_info_unref (b);

		if (a == b)
			return 0;
		if (!a)
			return -1;
		return 1;
	}

	res = a->frompos < b->frompos ? -1 : a->frompos == b->frompos ? 0 : 1;

	camel_message_info_unref (a);
	camel_message_info_unref (b);

	return res;
}
static gchar *
mbox_folder_get_filename (CamelFolder *folder,
                          const gchar *uid,
                          GError **error)
{
	CamelLocalFolder *lf = (CamelLocalFolder *) folder;
	CamelMboxMessageInfo *info;
	goffset frompos;
	gchar *filename = NULL;

	d (printf ("Getting message %s\n", uid));

	/* lock the folder first, burn if we can't, need write lock for summary check */
	if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1)
		return NULL;

	/* check for new messages always */
	if (camel_local_summary_check ((CamelLocalSummary *) folder->summary, lf->changes, NULL, error) == -1) {
		camel_local_folder_unlock (lf);
		return NULL;
	}

	/* get the message summary info */
	info = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid);

	if (info == NULL) {
		set_cannot_get_message_ex (
			error, CAMEL_FOLDER_ERROR_INVALID_UID,
			uid, lf->folder_path, _("No such message"));
		goto fail;
	}

	if (info->frompos == -1) {
		camel_message_info_unref (info);
		goto fail;
	}

	frompos = info->frompos;
	camel_message_info_unref (info);

	filename = g_strdup_printf ("%s%s!%" PRId64, lf->folder_path, G_DIR_SEPARATOR_S, (gint64) frompos);

fail:
	/* and unlock now we're finished with it */
	camel_local_folder_unlock (lf);

	return filename;
}
Esempio n. 3
0
static void
mail_browser_set_message (EMailReader *reader,
                          const gchar *uid)
{
	EMailReaderInterface *iface;
	EMailBrowser *browser;
	CamelMessageInfo *info;
	CamelFolder *folder;

	browser = E_MAIL_BROWSER (reader);

	/* Chain up to parent's set_message() method. */
	iface = g_type_default_interface_peek (E_TYPE_MAIL_READER);
	iface->set_message (reader, uid);

	if (uid == NULL) {
		e_mail_browser_close (browser);
		return;
	}

	folder = e_mail_reader_ref_folder (reader);

	info = camel_folder_get_message_info (folder, uid);

	if (info != NULL) {
		gtk_window_set_title (
			GTK_WINDOW (reader),
			camel_message_info_subject (info));
		camel_message_info_unref (info);
	}

	g_clear_object (&folder);
}
Esempio n. 4
0
static void
import_mbox_add_message (CamelFolder *folder,
			 CamelMimeMessage *msg,
			 GCancellable *cancellable,
			 GError **error)
{
	CamelMessageInfo *info;
	CamelMedium *medium;
	guint32 flags = 0;
	const gchar *tmp;

	g_return_if_fail (CAMEL_IS_FOLDER (folder));
	g_return_if_fail (CAMEL_IS_MIME_MESSAGE (msg));

	medium = CAMEL_MEDIUM (msg);

	tmp = camel_medium_get_header (medium, "X-Mozilla-Status");
	if (tmp)
		flags |= decode_mozilla_status (tmp);
	tmp = camel_medium_get_header (medium, "Status");
	if (tmp)
		flags |= decode_status (tmp);
	tmp = camel_medium_get_header (medium, "X-Status");
	if (tmp)
		flags |= decode_status (tmp);

	info = camel_message_info_new (NULL);

	camel_message_info_set_flags (info, flags, ~0);
	camel_folder_append_message_sync (
		folder, msg, info, NULL,
		cancellable, error);
	camel_message_info_unref (info);
}
Esempio n. 5
0
/* check a message is present */
void
test_folder_message (CamelFolder *folder,
                     const gchar *uid)
{
	CamelMimeMessage *msg;
	CamelMessageInfo *info;
	GPtrArray *s;
	gint i;
	gint found;
	GError *error = NULL;

	push ("uid %s is in folder", uid);

	/* first try getting info */
	info = camel_folder_get_message_info (folder, uid);
	check (info != NULL);
	check (strcmp (camel_message_info_get_uid (info), uid) == 0);
	camel_message_info_unref (info);

	/* then, getting message */
	msg = camel_folder_get_message_sync (folder, uid, NULL, &error);
	check_msg (error == NULL, "%s", error->message);
	check (msg != NULL);

	/* cross check with info */
	test_message_info (msg, info);

	g_object_unref (msg);

	/* see if it is in the summary (only once) */
	s = camel_folder_get_summary (folder);
	check (s != NULL);
	found = 0;
	for (i = 0; i < s->len; i++) {
		info = s->pdata[i];
		if (strcmp (camel_message_info_get_uid (info), uid) == 0)
			found++;
	}
	check (found == 1);
	camel_folder_free_summary (folder, s);

	/* check it is in the uid list */
	s = camel_folder_get_uids (folder);
	check (s != NULL);
	found = 0;
	for (i = 0; i < s->len; i++) {
		if (strcmp (s->pdata[i], uid) == 0)
			found++;
	}
	check (found == 1);
	camel_folder_free_uids (folder, s);

	g_clear_error (&error);

	pull ();
}
static gint
maildir_folder_cmp_uids (CamelFolder *folder,
                         const gchar *uid1,
                         const gchar *uid2)
{
	CamelMessageInfo *a, *b;
	time_t tma, tmb;

	g_return_val_if_fail (folder != NULL, 0);
	g_return_val_if_fail (folder->summary != NULL, 0);

	a = camel_folder_summary_get (folder->summary, uid1);
	b = camel_folder_summary_get (folder->summary, uid2);

	if (!a || !b) {
		/* It's not a problem when one of the messages is not in the summary */
		if (a)
			camel_message_info_unref (a);
		if (b)
			camel_message_info_unref (b);

		if (a == b)
			return 0;
		if (!a)
			return -1;
		return 1;
	}

	tma = camel_message_info_get_date_received (a);
	tmb = camel_message_info_get_date_received (b);

	camel_message_info_unref (a);
	camel_message_info_unref (b);

	return tma < tmb ? -1 : tma == tmb ? 0 : 1;
}
static void
unset_flagged_flag (const gchar *uid,
                    CamelFolderSummary *summary)
{
	CamelMessageInfo *info;

	info = camel_folder_summary_get (summary, uid);
	if (info) {
		CamelMessageInfoBase *base = (CamelMessageInfoBase *) info;

		if ((base->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0) {
			base->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
			base->dirty = TRUE;
		}

		camel_message_info_unref (info);
	}
}
static gboolean
nntp_folder_expunge_sync (CamelFolder *folder,
                          GCancellable *cancellable,
                          GError **error)
{
	CamelFolderSummary *summary;
	CamelFolderChangeInfo *changes;
	GPtrArray *known_uids;
	guint ii;

	summary = folder->summary;

	camel_folder_summary_prepare_fetch_all (summary, NULL);
	known_uids = camel_folder_summary_get_array (summary);

	if (known_uids == NULL)
		return TRUE;

	changes = camel_folder_change_info_new ();

	for (ii = 0; ii < known_uids->len; ii++) {
		CamelMessageInfo *info;
		const gchar *uid;

		uid = g_ptr_array_index (known_uids, ii);
		info = camel_folder_summary_get (summary, uid);

		if (camel_message_info_flags (info) & CAMEL_MESSAGE_DELETED) {
			camel_folder_change_info_remove_uid (changes, uid);
			camel_folder_summary_remove (summary, info);
		}

		camel_message_info_unref (info);
	}

	camel_folder_summary_save_to_db (summary, NULL);
	camel_folder_changed (folder, changes);

	camel_folder_change_info_free (changes);
	camel_folder_summary_free_array (known_uids);

	return TRUE;
}
Esempio n. 9
0
static void
mail_browser_message_selected_cb (EMailBrowser *browser,
                                  const gchar *uid)
{
	CamelMessageInfo *info;
	CamelFolder *folder;
	EMailReader *reader;
	guint32 state;

	reader = E_MAIL_READER (browser);
	state = e_mail_reader_check_state (reader);
	e_mail_reader_update_actions (reader, state);

	if (uid == NULL)
		return;

	folder = e_mail_reader_ref_folder (reader);

	info = camel_folder_get_message_info (folder, uid);

	if (info != NULL) {
		EMailDisplay *display;
		const gchar *title;

		display = e_mail_reader_get_mail_display (reader);

		title = camel_message_info_subject (info);
		if (title == NULL || *title == '\0')
			title = _("(No Subject)");

		gtk_window_set_title (GTK_WINDOW (browser), title);
		gtk_widget_grab_focus (GTK_WIDGET (display));

		camel_message_info_set_flags (
			info, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);

		camel_message_info_unref (info);
	}

	g_clear_object (&folder);
}
Esempio n. 10
0
/* check the total/unread is what we think it should be */
void
test_folder_counts (CamelFolder *folder,
                    gint total,
                    gint unread)
{
	GPtrArray *s;
	gint i, myunread;
	CamelMessageInfo *info;

	push ("test folder counts %d total %d unread", total, unread);

	/* use the summary */
	s = camel_folder_get_summary (folder);
	check (s != NULL);
	check (s->len == total);
	myunread = s->len;
	for (i = 0; i < s->len; i++) {
		info = s->pdata[i];
		if (camel_message_info_get_flags (info) & CAMEL_MESSAGE_SEEN)
			myunread--;
	}
	check (unread == myunread);
	camel_folder_free_summary (folder, s);

	/* use the uid list */
	s = camel_folder_get_uids (folder);
	check (s != NULL);
	check (s->len == total);
	myunread = s->len;
	for (i = 0; i < s->len; i++) {
		info = camel_folder_get_message_info (folder, s->pdata[i]);
		if (camel_message_info_get_flags (info) & CAMEL_MESSAGE_SEEN)
			myunread--;
		camel_message_info_unref (info);
	}
	check (unread == myunread);
	camel_folder_free_uids (folder, s);

	pull ();
}
Esempio n. 11
0
/* this should probably take a folder instead of a session ... */
void
test_folder_message_ops (CamelSession *session,
                         const gchar *name,
                         gint local,
                         const gchar *mailbox)
{
	CamelStore *store;
	CamelService *service;
	CamelFolder *folder;
	CamelMimeMessage *msg;
	gint j;
	gint indexed, max;
	GPtrArray *uids;
	CamelMessageInfo *info;
	GError *error = NULL;

	max = local ? 2 : 1;

	for (indexed = 0; indexed < max; indexed++) {
		gchar *what = g_strdup_printf ("folder ops: %s %s", name, local ? (indexed?"indexed":"non-indexed"):"");
		gint flags;

		camel_test_start (what);
		test_free (what);

		push ("getting store");
		service = camel_session_add_service (
			session, name, name, CAMEL_PROVIDER_STORE, &error);
		check_msg (error == NULL, "adding store: %s", error->message);
		check (CAMEL_IS_STORE (service));
		store = CAMEL_STORE (service);
		g_clear_error (&error);
		pull ();

		push ("creating %sindexed folder", indexed?"":"non-");
		if (indexed)
			flags = CAMEL_STORE_FOLDER_CREATE | CAMEL_STORE_FOLDER_BODY_INDEX;
		else
			flags = CAMEL_STORE_FOLDER_CREATE;
		folder = camel_store_get_folder_sync (
			store, mailbox, flags, NULL, &error);

		/* we can't create mailbox outside of namespace, since we have no api for it, try
		 * using inbox namespace, works for courier */
		if (folder == NULL) {
			gchar *mbox = g_strdup_printf ("INBOX/%s", mailbox);
			mailbox = mbox;
			g_clear_error (&error);
			folder = camel_store_get_folder_sync (
				store, mailbox, flags, NULL, &error);
		}

		check_msg (error == NULL, "%s", error->message);
		check (folder != NULL);

		/* verify empty/can't get nonexistant stuff */
		test_folder_counts (folder, 0, 0);
		test_folder_not_message (folder, "0");
		test_folder_not_message (folder, "");

		for (j = 0; j < 10; j++) {
			gchar *content, *subject;

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

			push ("appending simple message %d", j);
			camel_folder_append_message_sync (
				folder, msg, NULL, NULL, NULL, &error);
			check_msg (error == NULL, "%s", error->message);

#if 0
			/* sigh, this shouldn't be required, but the imap code is too dumb to do it itself */
			if (!local) {
				push ("forcing a refresh of folder updates");
				camel_folder_refresh_info (folder, ex);
				check_msg (error == NULL, "%s", error->message);
				pull ();
			}
#endif
			/*if (!local)
			  camel_test_nonfatal ("unread counts dont seem right for imap");*/

			test_folder_counts (folder, j + 1, j + 1);

			/*if (!local)
			  camel_test_fatal ();*/

			push ("checking it is in the right uid slot & exists");
			uids = camel_folder_get_uids (folder);
			check (uids != NULL);
			check (uids->len == j + 1);
			if (uids->len > j)
				test_folder_message (folder, uids->pdata[j]);
			pull ();

			push ("checking it is the right message (subject): %s", subject);
			if (uids->len > j) {
				info = camel_folder_get_message_info (folder, uids->pdata[j]);
				check (info != NULL);
				check_msg (
					strcmp (camel_message_info_get_subject (info), subject) == 0,
					"info->subject %s", camel_message_info_get_subject (info));
				camel_message_info_unref (info);
			}
			camel_folder_free_uids (folder, uids);
			pull ();

			test_free (subject);

			/*if (!local)
			  camel_test_fatal ();*/

			check_unref (msg, 1);
			pull ();
		}

		if (local)
			check_unref (folder, 1);
		else
			check_unref (folder, 2);
		pull ();

#if 0
		push ("deleting test folder, with messages in it");
		camel_store_delete_folder (store, mailbox, ex);
		check (camel_exception_is_set (ex));
		camel_exception_clear (ex);
		pull ();
#endif

		push ("re-opening folder");
		folder = camel_store_get_folder_sync (
			store, mailbox, flags, NULL, &error);
		check_msg (error == NULL, "%s", error->message);
		check (folder != NULL);
		g_clear_error (&error);

			/* verify counts */
		test_folder_counts (folder, 10, 10);

		/* re-check uid's, after a reload */
		uids = camel_folder_get_uids (folder);
		check (uids != NULL);
		check (uids->len == 10);
		for (j = 0; j < 10; j++) {
			gchar *subject = g_strdup_printf ("Test message %d", j);

			push ("verify reload of %s", subject);
			test_folder_message (folder, uids->pdata[j]);

			info = camel_folder_get_message_info (folder, uids->pdata[j]);
			check_msg (
				strcmp (camel_message_info_get_subject (info), subject) == 0,
				"info->subject %s", camel_message_info_get_subject (info));
			test_free (subject);
			camel_message_info_unref (info);
			pull ();
		}

		push ("deleting first message & expunging");
		camel_folder_delete_message (folder, uids->pdata[0]);
		test_folder_counts (folder, 10, 9);
		camel_folder_expunge_sync (folder, NULL, &error);
		check_msg (error == NULL, "%s", error->message);
		g_clear_error (&error);
		test_folder_not_message (folder, uids->pdata[0]);
		test_folder_counts (folder, 9, 9);

		camel_folder_free_uids (folder, uids);

		uids = camel_folder_get_uids (folder);
		check (uids != NULL);
		check (uids->len == 9);
		for (j = 0; j < 9; j++) {
			gchar *subject = g_strdup_printf ("Test message %d", j + 1);

			push ("verify after expunge of %s", subject);
			test_folder_message (folder, uids->pdata[j]);

			info = camel_folder_get_message_info (folder, uids->pdata[j]);
			check_msg (
				strcmp (camel_message_info_get_subject (info), subject) == 0,
				"info->subject %s", camel_message_info_get_subject (info));
			test_free (subject);
			camel_message_info_unref (info);
			pull ();
		}
		pull ();

		push ("deleting last message & expunging");
		camel_folder_delete_message (folder, uids->pdata[8]);
		/* sync? */
		test_folder_counts (folder, 9, 8);
		camel_folder_expunge_sync (folder, NULL, &error);
		check_msg (error == NULL, "%s", error->message);
		g_clear_error (&error);
		test_folder_not_message (folder, uids->pdata[8]);
		test_folder_counts (folder, 8, 8);

		camel_folder_free_uids (folder, uids);

		uids = camel_folder_get_uids (folder);
		check (uids != NULL);
		check (uids->len == 8);
		for (j = 0; j < 8; j++) {
			gchar *subject = g_strdup_printf ("Test message %d", j + 1);

			push ("verify after expunge of %s", subject);
			test_folder_message (folder, uids->pdata[j]);

			info = camel_folder_get_message_info (folder, uids->pdata[j]);
			check_msg (
				strcmp (camel_message_info_get_subject (info), subject) == 0,
				"info->subject %s", camel_message_info_get_subject (info));
			test_free (subject);
			camel_message_info_unref (info);
			pull ();
		}
		pull ();

		push ("deleting all messages & expunging");
		for (j = 0; j < 8; j++) {
			camel_folder_delete_message (folder, uids->pdata[j]);
		}
		/* sync? */
		test_folder_counts (folder, 8, 0);
		camel_folder_expunge_sync (folder, NULL, &error);
		check_msg (error == NULL, "%s", error->message);
		g_clear_error (&error);
		for (j = 0; j < 8; j++) {
			test_folder_not_message (folder, uids->pdata[j]);
		}
		test_folder_counts (folder, 0, 0);

		camel_folder_free_uids (folder, uids);
		pull ();

		if (local)
			check_unref (folder, 1);
		else
			check_unref (folder, 2);
		pull (); /* re-opening folder */

		if (g_ascii_strcasecmp (mailbox, "INBOX") != 0) {
			push ("deleting test folder, with no messages in it");
			camel_store_delete_folder_sync (
				store, mailbox, NULL, &error);
			check_msg (error == NULL, "%s", error->message);
			g_clear_error (&error);
			pull ();
		}

		if (!local) {
			push ("disconneect service");
			camel_service_disconnect_sync (
				CAMEL_SERVICE (store), TRUE, NULL, &error);
			check_msg (error == NULL, "%s", error->message);
			g_clear_error (&error);
			pull ();
		}

		check_unref (store, 1);
		camel_test_end ();
	}
}
static gchar *
maildir_folder_get_filename (CamelFolder *folder,
                             const gchar *uid,
                             GError **error)
{
	CamelLocalFolder *lf = (CamelLocalFolder *) folder;
	CamelMaildirMessageInfo *mdi;
	CamelMessageInfo *info;
	gchar *res;

	/* get the message summary info */
	if ((info = camel_folder_summary_get (folder->summary, uid)) == NULL) {
		set_cannot_get_message_ex (
			error, CAMEL_FOLDER_ERROR_INVALID_UID,
			uid, lf->folder_path, _("No such message"));
		return NULL;
	}

	mdi = (CamelMaildirMessageInfo *) info;

	/* If filename is NULL, it means folder_summary_check is not yet executed.
	 * Try to find the file in the folder and use it, otherwise construct its
	 * name based on actual flags.
	*/
	if (!camel_maildir_info_filename (mdi)) {
		const gchar *uid = camel_message_info_get_uid (info);

		if (uid) {
			GDir *dir;
			gchar *dirname;

			dirname = g_strdup_printf ("%s/cur", lf->folder_path);
			dir = g_dir_open (dirname, 0, NULL);
			g_free (dirname);

			if (dir) {
				const gchar *filename;
				gint uid_len = strlen (uid);

				while (filename = g_dir_read_name (dir), filename) {
					if (g_str_has_prefix (filename, uid) && (filename[uid_len] == '\0' || filename[uid_len] == CAMEL_MAILDIR_FLAG_SEP)) {
						camel_maildir_info_set_filename (mdi, g_strdup (filename));
						break;
					}
				}

				g_dir_close (dir);
			}
		}

		if (!camel_maildir_info_filename (mdi)) {
			camel_maildir_info_set_filename (mdi, camel_maildir_summary_info_to_name (mdi));
		}
	}

	res = g_strdup_printf ("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi));

	camel_message_info_unref (info);

	return res;
}
static gboolean
maildir_folder_transfer_messages_to_sync (CamelFolder *source,
                                          GPtrArray *uids,
                                          CamelFolder *dest,
                                          gboolean delete_originals,
                                          GPtrArray **transferred_uids,
                                          GCancellable *cancellable,
                                          GError **error)
{
	gboolean fallback = FALSE;

	if (delete_originals && CAMEL_IS_MAILDIR_FOLDER (source) && CAMEL_IS_MAILDIR_FOLDER (dest)
	    && camel_folder_get_parent_store (source) == camel_folder_get_parent_store (dest)) {
		gint i;
		CamelLocalFolder *lf = (CamelLocalFolder *) source;
		CamelLocalFolder *df = (CamelLocalFolder *) dest;

		camel_operation_push_message (
			cancellable, _("Moving messages"));

		camel_folder_freeze (dest);
		camel_folder_freeze (source);

		for (i = 0; i < uids->len; i++) {
			gchar *uid = (gchar *) uids->pdata[i];
			gchar *s_filename, *d_filename, *new_filename;
			CamelMaildirMessageInfo *mdi;
			CamelMessageInfo *info;

			if ((info = camel_folder_summary_get (source->summary, uid)) == NULL) {
				set_cannot_get_message_ex (
					error, CAMEL_FOLDER_ERROR_INVALID_UID,
					uid, lf->folder_path, _("No such message"));
				return FALSE;
			}

			mdi = (CamelMaildirMessageInfo *) info;
			new_filename = camel_maildir_summary_info_to_name (mdi);

			d_filename = g_strdup_printf ("%s/cur/%s", df->folder_path, new_filename);
			s_filename = g_strdup_printf ("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi));

			if (g_rename (s_filename, d_filename) != 0) {
				if (errno == EXDEV) {
					i = uids->len + 1;
					fallback = TRUE;
				} else {
					g_set_error (
						error, G_IO_ERROR,
						g_io_error_from_errno (errno),
						_("Cannot transfer message to destination folder: %s"),
						g_strerror (errno));
					camel_message_info_unref (info);
					g_free (s_filename);
					g_free (d_filename);
					g_free (new_filename);
					break;
				}
			} else {
				CamelMessageInfo *clone;
				CamelMaildirMessageInfo *mclone;

				clone = camel_message_info_clone (info);
				clone->summary = dest->summary;

				mclone = (CamelMaildirMessageInfo *) clone;
				/* preserve also UID, as it matches the file name */
				mclone->info.info.uid = camel_pstring_strdup (camel_message_info_get_uid (info));
				camel_maildir_info_set_filename (clone, g_strdup (new_filename));
				/* unset deleted flag when transferring from trash folder */
				if ((source->folder_flags & CAMEL_FOLDER_IS_TRASH) != 0)
					camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED, 0);
				/* unset junk flag when transferring from junk folder */
				if ((source->folder_flags & CAMEL_FOLDER_IS_JUNK) != 0)
					camel_message_info_set_flags (info, CAMEL_MESSAGE_JUNK, 0);
				camel_folder_summary_add (dest->summary, clone);

				camel_folder_change_info_add_uid (df->changes, camel_message_info_get_uid (clone));

				camel_folder_set_message_flags (
					source, uid, CAMEL_MESSAGE_DELETED |
					CAMEL_MESSAGE_SEEN, ~0);
				camel_folder_change_info_remove_uid (lf->changes, camel_message_info_get_uid (info));
				camel_folder_summary_remove (source->summary, info);
			}

			camel_message_info_unref (info);
			g_free (s_filename);
			g_free (d_filename);
			g_free (new_filename);
		}

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

		if (df && camel_folder_change_info_changed (df->changes)) {
			camel_folder_changed (dest, df->changes);
			camel_folder_change_info_clear (df->changes);
		}

		camel_folder_thaw (source);
		camel_folder_thaw (dest);

		camel_operation_pop_message (cancellable);
	} else
		fallback = TRUE;

	if (fallback) {
		CamelFolderClass *folder_class;

		/* Chain up to parent's transfer_messages_to() method. */
		folder_class = CAMEL_FOLDER_CLASS (camel_maildir_folder_parent_class);
		return folder_class->transfer_messages_to_sync (
			source, uids, dest, delete_originals,
			transferred_uids, cancellable, error);
	}

	return TRUE;
}
static CamelMimeMessage *
mbox_folder_get_message_sync (CamelFolder *folder,
                              const gchar *uid,
                              GCancellable *cancellable,
                              GError **error)
{
	CamelLocalFolder *lf = (CamelLocalFolder *) folder;
	CamelMimeMessage *message = NULL;
	CamelMboxMessageInfo *info;
	CamelMimeParser *parser = NULL;
	gint fd, retval;
	gint retried = FALSE;
	goffset frompos;

	d (printf ("Getting message %s\n", uid));

	/* lock the folder first, burn if we can't, need write lock for summary check */
	if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1)
		return NULL;

	/* check for new messages always */
	if (camel_local_summary_check ((CamelLocalSummary *) folder->summary, lf->changes, cancellable, error) == -1) {
		camel_local_folder_unlock (lf);
		return NULL;
	}

retry:
	/* get the message summary info */
	info = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid);

	if (info == NULL) {
		set_cannot_get_message_ex (
			error, CAMEL_FOLDER_ERROR_INVALID_UID,
			uid, lf->folder_path, _("No such message"));
		goto fail;
	}

	if (info->frompos == -1) {
		camel_message_info_unref (info);
		goto fail;
	}

	frompos = info->frompos;
	camel_message_info_unref (info);

	/* we use an fd instead of a normal stream here - the reason is subtle, camel_mime_part will cache
	 * the whole message in memory if the stream is non-seekable (which it is when built from a parser
	 * with no stream).  This means we dont have to lock the mbox for the life of the message, but only
	 * while it is being created. */

	fd = g_open (lf->folder_path, O_LARGEFILE | O_RDONLY | O_BINARY, 0);
	if (fd == -1) {
		set_cannot_get_message_ex (
			error, CAMEL_ERROR_GENERIC,
			uid, lf->folder_path, g_strerror (errno));
		goto fail;
	}

	/* we use a parser to verify the message is correct, and in the correct position */
	parser = camel_mime_parser_new ();
	camel_mime_parser_init_with_fd (parser, fd);
	camel_mime_parser_scan_from (parser, TRUE);

	camel_mime_parser_seek (parser, frompos, SEEK_SET);
	if (camel_mime_parser_step (parser, NULL, NULL) != CAMEL_MIME_PARSER_STATE_FROM
	    || camel_mime_parser_tell_start_from (parser) != frompos) {

		g_warning ("Summary doesn't match the folder contents!  eek!\n"
			"  expecting offset %ld got %ld, state = %d", (glong) frompos,
			(glong) camel_mime_parser_tell_start_from (parser),
			camel_mime_parser_state (parser));

		g_object_unref (parser);
		parser = NULL;

		if (!retried) {
			retried = TRUE;
			camel_local_summary_check_force ((CamelLocalSummary *) folder->summary);
			retval = camel_local_summary_check ((CamelLocalSummary *) folder->summary, lf->changes, cancellable, error);
			if (retval != -1)
				goto retry;
		}

		set_cannot_get_message_ex (
			error, CAMEL_FOLDER_ERROR_INVALID,
			uid, lf->folder_path,
			_("The folder appears to be irrecoverably corrupted."));
		goto fail;
	}

	message = camel_mime_message_new ();
	if (!camel_mime_part_construct_from_parser_sync (
		(CamelMimePart *) message, parser, cancellable, error)) {
		g_prefix_error (
			error, _("Cannot get message %s from folder %s: "),
			uid, lf->folder_path);
		g_object_unref (message);
		message = NULL;
		goto fail;
	}

	camel_medium_remove_header ((CamelMedium *) message, "X-Evolution");

fail:
	/* and unlock now we're finished with it */
	camel_local_folder_unlock (lf);

	if (parser)
		g_object_unref (parser);

	/* use the opportunity to notify of changes (particularly if we had a rebuild) */
	if (camel_folder_change_info_changed (lf->changes)) {
		camel_folder_changed (folder, lf->changes);
		camel_folder_change_info_clear (lf->changes);
	}

	return message;
}
Esempio n. 15
0
static void
import_kmail_folder (struct _import_mbox_msg *m,
                     gchar *k_path_in,
                     GCancellable *cancellable,
                     GError **error)
{
	const gchar *special_folders []= {"cur", "tmp", "new", NULL};
	gchar *special_path;
	const CamelStore *store;
	CamelFolder *folder;
	CamelMimeParser *mp = NULL;
	CamelMessageInfo *info;
	CamelMimeMessage *msg;
	guint32 flags = 0;

	gchar *e_uri, *e_path;
	gchar *k_path;
	const gchar *d;
	gchar *mail_url;
	GDir *dir;
	struct stat st;
	gint fd, i;

	e_uri = kuri_to_euri (k_path_in);
	/* we need to drop some folders, like: Trash */
	if (!e_uri)
		return;

	/* In case we using async way in the future */
	k_path = g_strdup (k_path_in);
	store = evolution_get_local_store ();
	e_path = e_uri + strlen (EVOLUTION_LOCAL_BASE) + 1;
	e_mail_store_create_folder_sync ((CamelStore *)store, e_path, NULL, NULL);
	folder = e_mail_session_uri_to_folder_sync (
			m->session, e_uri, CAMEL_STORE_FOLDER_CREATE,
			cancellable, NULL);

	if (folder == NULL) {
		g_free (k_path);
		g_warning ("evolution error: cannot get the folder\n");
		return;
	}

	camel_operation_push_message (
			cancellable, _("Importing '%s'"),
			camel_folder_get_display_name (folder));
	camel_folder_freeze (folder);

	for (i = 0; special_folders [i]; i++) {
		camel_operation_progress (cancellable, 100*i/3);
		special_path = g_build_filename (k_path, special_folders[i], NULL);
		dir = g_dir_open (special_path, 0, NULL);
		while ((d = g_dir_read_name (dir))) {
			if ((strcmp (d, ".") == 0) || (strcmp (d, "..") == 0)) {
				continue;
			}
			mail_url = g_build_filename (special_path, d, NULL);
			if (g_stat (mail_url, &st) == -1) {
				g_free (mail_url);
				continue;
			}
			if (S_ISREG (st.st_mode)) {
				fd = g_open (mail_url, O_RDONLY | O_BINARY, 0);
				g_free (mail_url);
				if (fd == -1) {
					continue;
				}
				mp = camel_mime_parser_new ();
				camel_mime_parser_scan_from (mp, FALSE);
				if (camel_mime_parser_init_with_fd (mp, fd) == -1) {
					/* will never happen - 0 is unconditionally returned */
					g_object_unref (mp);
					continue;
				}
				msg = camel_mime_message_new ();
				if (!camel_mime_part_construct_from_parser_sync (
						(CamelMimePart *) msg, mp, NULL, NULL)) {
					/* set exception? */
					g_object_unref (mp);
					g_object_unref (msg);
					continue;
				}
				info = camel_message_info_new (NULL);
				if (strcmp (special_folders[i], "cur") == 0) {
					flags |= CAMEL_MESSAGE_SEEN;
				} else if (strcmp (special_folders[i], "tmp") == 0) {
					flags |= CAMEL_MESSAGE_DELETED; /* Mark the 'tmp' mails as 'deleted' */
				}
				camel_message_info_set_flags (info, flags, ~0);
				camel_folder_append_message_sync (
					folder, msg, info, NULL,
					cancellable, error);
				camel_message_info_unref (info);
				g_object_unref (msg);
				g_object_unref (mp);
			} else {
				g_free (mail_url);
			}
		}
	}
	camel_operation_progress (cancellable, 100);
	camel_folder_synchronize_sync (folder, FALSE, NULL, NULL);
	camel_folder_thaw (folder);
	camel_operation_pop_message (cancellable);

	g_free (k_path);
}