Beispiel #1
0
void procmsg_copy_messages(GSList *mlist)
{
	GSList *cur, *copylist = NULL;
	MsgInfo *msginfo;
	FolderItem *dest = NULL;

	if (!mlist) return;

	folder_item_update_freeze();

	for (cur = mlist; cur != NULL; cur = cur->next) {
		msginfo = (MsgInfo *)cur->data;
		if (!dest) {
			dest = msginfo->to_folder;
			copylist = g_slist_append(copylist, msginfo);
		} else if (dest == msginfo->to_folder) {
			copylist = g_slist_append(copylist, msginfo);
		} else {
			folder_item_copy_msgs(dest, copylist);
			g_slist_free(copylist);
			copylist = NULL;
			dest = msginfo->to_folder;
			copylist = g_slist_append(copylist, msginfo);
		}
		procmsg_msginfo_set_to_folder(msginfo, NULL);
	}

	if (copylist) {
		folder_item_copy_msgs(dest, copylist);
		g_slist_free(copylist);
	}

	folder_item_update_thaw();
}
Beispiel #2
0
void rssyl_update_format()
{
	RUpdateFormatCtx *ctx = NULL;
	GSList *oldfeeds;
	gchar *old_feeds_xml = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
			RSSYL_DIR, G_DIR_SEPARATOR_S, "feeds.xml", NULL);

	if (!g_file_test(old_feeds_xml,
				G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
		g_free(old_feeds_xml);
		return;
	}

	debug_print("RSSyl: Old format found, updating.\n");

	oldfeeds = rssyl_old_feed_metadata_parse(old_feeds_xml);

	/* We find all rssyl root folders and perform magic on each */
	ctx = g_new0(RUpdateFormatCtx, 1);
	ctx->o_prev = NULL;
	ctx->o_parent = NULL;
	ctx->n_prev = NULL;
	ctx->n_parent = NULL;
	ctx->n_first = NULL;
	ctx->oldfeeds = oldfeeds;
	ctx->oldroots = NULL;
	ctx->reached_first_new = FALSE;

	folder_item_update_freeze();

	/* Go through all RSSyl folders, making new copies */
	folder_func_to_all_folders((FolderItemFunc)rssyl_update_format_func, ctx);

	g_slist_foreach(ctx->oldroots, _delete_old_roots_func, NULL);
	g_slist_free(ctx->oldroots);

	prefs_matcher_write_config();
	folder_write_list();

	folder_item_update_thaw();

	g_free(ctx);

	g_remove(old_feeds_xml);
	g_free(old_feeds_xml);
}
Beispiel #3
0
/* return values: -2 skipped, -1 error, 0 OK */
gint export_to_mbox(FolderItem *src, const gchar *mbox)
{
	GSList *mlist;
	gint ret;
	
	cm_return_val_if_fail(src != NULL, -1);
	cm_return_val_if_fail(src->folder != NULL, -1);
	cm_return_val_if_fail(mbox != NULL, -1);

	debug_print("Exporting messages from %s into %s...\n",
		    src->path, mbox);

	mlist = folder_item_get_msg_list(src);

	folder_item_update_freeze();
	ret = export_list_to_mbox(mlist, mbox);
	folder_item_update_thaw();

	procmsg_msg_list_free(mlist);

	return ret;
}
Beispiel #4
0
gboolean rssyl_subscribe(FolderItem *parent, const gchar *url,
		gboolean verbose)
{
	gchar *myurl = NULL, *tmpname = NULL, *tmpname2 = NULL;
	RFetchCtx *ctx;
	FolderItem *new_item;
	RFolderItem *ritem;
	gint i = 1;
	RSubCtx *sctx;
	gboolean edit_properties = FALSE;
	gchar *official_title = NULL;

	g_return_val_if_fail(parent != NULL, FALSE);
	g_return_val_if_fail(url != NULL, FALSE);

	log_print(LOG_PROTOCOL, RSSYL_LOG_SUBSCRIBING, url);

	myurl = my_normalize_url(url);

	/* Fetch the feed. */
	ctx = rssyl_prep_fetchctx_from_url(myurl);
	g_free(myurl);
	g_return_val_if_fail(ctx != NULL, FALSE);

	rssyl_fetch_feed(ctx, verbose);

	debug_print("RSSyl: fetch success == %s\n",
			ctx->success ? "TRUE" : "FALSE");

	if (!ctx->success) {
		/* User notification was already handled inside rssyl_fetch_feed(),
		 * let's just return quietly. */
		feed_free(ctx->feed);
		g_free(ctx->error);
		g_free(ctx);
		return FALSE;
	}

	if (verbose) {
		sctx = g_new0(RSubCtx, 1);
		sctx->feed = ctx->feed;
		sctx->edit_properties = FALSE;

		debug_print("RSSyl: Calling subscribe dialog routine...\n");
		rssyl_subscribe_dialog(sctx);

		if (sctx->feed == NULL) {
			debug_print("RSSyl: User cancelled subscribe.\n");
			g_free(sctx);
			return FALSE;
		}

		edit_properties = sctx->edit_properties;
		if (sctx->official_title != NULL) {
			debug_print("RSSyl: custom official title\n");
			official_title = g_strdup(sctx->official_title);
		}

		if (sctx->edit_properties)
			debug_print("RSSyl: User wants to edit properties of the new feed.\n");
		else
			debug_print("RSSyl: User does not want to edit properties of the new feed.\n");
		g_free(sctx->official_title);
		g_free(sctx);
	}

	/* OK, feed is succesfully fetched and correct, let's add it to CM. */

	/* Create a folder for it. */
	tmpname = rssyl_format_string(ctx->feed->title, TRUE, TRUE);
	tmpname2 = g_strdup(tmpname);

#ifdef G_OS_WIN32
	/* Windows does not allow its filenames to start or end with a dot,
	 * or to end with a space. */
	if (tmpname2[0] == '.')
		tmpname2[0] = '_';
	if (tmpname2[strlen(tmpname2) - 1] == '.')
		tmpname2[strlen(tmpname2) - 1] = '_';
	if (tmpname2[strlen(tmpname2) - 1] == ' ')
		tmpname2[strlen(tmpname2) - 1] = '_';
#endif

	while (folder_find_child_item_by_name(parent, tmpname2) != 0 && i < 20) {
		debug_print("RSSyl: Folder '%s' already exists, trying another name\n",
				tmpname2);
		g_free(tmpname2);
		tmpname2 = g_strdup_printf("%s__%d", tmpname, ++i);
	}
	/* TODO: handle cases where i reaches 20 */

	folder_item_update_freeze();

	new_item = folder_create_folder(parent, tmpname2);
	g_free(tmpname);
	g_free(tmpname2);

	if (!new_item) {
		if (verbose)
			alertpanel_error(_("Couldn't create folder for new feed '%s'."),
					myurl);
		feed_free(ctx->feed);
		g_free(ctx->error);
		g_free(ctx); 
		g_free(myurl);
		return FALSE;
	}

	debug_print("RSSyl: Adding '%s'\n", ctx->feed->url);

	ritem = (RFolderItem *)new_item;
	ritem->url = g_strdup(ctx->feed->url);

	if (official_title != NULL) {
		debug_print("RSSyl: storing official feed title '%s'\n", official_title);
		ritem->official_title = official_title;
	}

	if (feed_n_items(ctx->feed) > 0)
		feed_foreach_item(ctx->feed, rssyl_subscribe_foreach_func, (gpointer)ritem);

	folder_item_scan(new_item);
	folder_write_list();

	if (edit_properties)
		rssyl_gtk_prop(ritem);

	folder_item_update_thaw();

	return TRUE;
}
Beispiel #5
0
gboolean rssyl_parse_feed(RFolderItem *ritem, Feed *feed)
{
	gchar *tmp = NULL, *tmp2 = NULL;
	gint i = 1;

	g_return_val_if_fail(ritem != NULL, FALSE);
	g_return_val_if_fail(feed != NULL, FALSE);
	g_return_val_if_fail(feed->title != NULL, FALSE);

	debug_print("RSSyl: parse_feed\n");

	/* Set the last_update timestamp here, so it is the same for all items */
	ritem->last_update = time(NULL);

	/* If the upstream feed changed its title, change name of our folder
	 * accordingly even if user has renamed it before. This makes sure that
	 * user will be aware of the upstream title change. */
	if( !ritem->ignore_title_rename &&
			(ritem->official_title == NULL ||
			strcmp(feed->title, ritem->official_title)) ) {
		g_free(ritem->official_title);
		ritem->official_title = g_strdup(feed->title);

		tmp = rssyl_format_string(feed->title, TRUE, TRUE);

		tmp2 = g_strdup(tmp);
		while (folder_item_rename(&ritem->item, tmp2) != 0 && i < 20) {
			g_free(tmp2);
			tmp2 = g_strdup_printf("%s__%d", tmp, ++i);
			debug_print("RSSyl: couldn't rename, trying '%s'\n", tmp2);
		}
		/* TODO: handle case when i reaches 20 */
	
		g_free(tmp);
		g_free(tmp2);

		/* FIXME: update name in properties */
		/* FIXME: store feed properties */
	}

	folder_item_update_freeze();

	/* Read contents of folder, so we can check for duplicates/updates */
	rssyl_folder_read_existing(ritem);

	if( claws_is_exiting() ) {
		debug_print("RSSyl: Claws-Mail is exiting, bailing out\n");
		log_print(LOG_PROTOCOL, RSSYL_LOG_ABORTED_EXITING, ritem->url);
		folder_item_update_thaw();
		return TRUE;
	}

	/* Populate the ->deleted_items list so that we can check it when
	 * adding each item. */
	ritem->deleted_items = rssyl_deleted_update(ritem);

	/* Parse each item in the feed, adding or updating existing items if
	 * necessary */
	if( feed_n_items(feed) > 0 )
		feed_foreach_item(feed, rssyl_foreach_parse_func, (gpointer)ritem);

	if( !ritem->keep_old && !ritem->fetching_comments ) {
		rssyl_folder_read_existing(ritem);
		rssyl_expire_items(ritem, feed);
	}

	rssyl_deleted_free(ritem->deleted_items);

	folder_item_scan(&ritem->item);
	folder_item_update_thaw();

	if( !ritem->fetching_comments )
		log_print(LOG_PROTOCOL, RSSYL_LOG_UPDATED, ritem->url);

	return TRUE;
}
Beispiel #6
0
static gint inc_start(IncProgressDialog *inc_dialog)
{
	IncSession *session;
	GList *qlist;
	Pop3Session *pop3_session;
	IncState inc_state;
	gint error_num = 0;
	gint new_msgs = 0;
	gchar *msg;
	gchar *fin_msg;
	FolderItem *processing, *inbox;
	GSList *msglist, *msglist_element;
	gboolean cancelled = FALSE;

	qlist = inc_dialog->queue_list;
	while (qlist != NULL) {
		GList *next = qlist->next;

		session = qlist->data;
		pop3_session = POP3_SESSION(session->session); 
		pop3_session->user = g_strdup(pop3_session->ac_prefs->userid);
		if (pop3_session->ac_prefs->passwd)
			pop3_session->pass =
				g_strdup(pop3_session->ac_prefs->passwd);
		else {
			gchar *pass;

			if (inc_dialog->show_dialog)
				manage_window_focus_in
					(inc_dialog->dialog->window,
					 NULL, NULL);

			pass = input_dialog_query_password_keep
				(pop3_session->ac_prefs->recv_server,
				 pop3_session->user,
				 &(pop3_session->ac_prefs->session_passwd));

			if (inc_dialog->show_dialog)
				manage_window_focus_out
					(inc_dialog->dialog->window,
					 NULL, NULL);

			if (pass) {
				pop3_session->pass = pass;
			}
		}

		qlist = next;
	}

#define SET_PIXMAP_AND_TEXT(pix, str)					   \
{									   \
	progress_dialog_list_set(inc_dialog->dialog,			   \
				 inc_dialog->cur_row,			   \
				 pix,					   \
				 NULL,					   \
				 str);					   \
}

	for (; inc_dialog->queue_list != NULL && !cancelled; inc_dialog->cur_row++) {
		session = inc_dialog->queue_list->data;
		pop3_session = POP3_SESSION(session->session);
		GSList *filtered, *unfiltered;

		if (pop3_session->pass == NULL) {
			SET_PIXMAP_AND_TEXT(okpix, _("Cancelled"));
			inc_session_destroy(session);
			inc_dialog->queue_list =
				g_list_remove(inc_dialog->queue_list, session);
			continue;
		}

		inc_progress_dialog_clear(inc_dialog);
		progress_dialog_scroll_to_row(inc_dialog->dialog,
					      inc_dialog->cur_row);

		SET_PIXMAP_AND_TEXT(currentpix, _("Retrieving"));

		/* begin POP3 session */
		inc_state = inc_pop3_session_do(session);

		switch (inc_state) {
		case INC_SUCCESS:
			if (pop3_session->cur_total_num > 0)
				msg = g_strdup_printf(
					ngettext("Done (%d message (%s) received)",
						 "Done (%d messages (%s) received)",
					 pop3_session->cur_total_num),
					 pop3_session->cur_total_num,
					 to_human_readable((goffset)pop3_session->cur_total_recv_bytes));
			else
				msg = g_strdup_printf(_("Done (no new messages)"));
			SET_PIXMAP_AND_TEXT(okpix, msg);
			g_free(msg);
			break;
		case INC_CONNECT_ERROR:
			SET_PIXMAP_AND_TEXT(errorpix, _("Connection failed"));
			break;
		case INC_AUTH_FAILED:
			SET_PIXMAP_AND_TEXT(errorpix, _("Auth failed"));
			if (pop3_session->ac_prefs->session_passwd) {
				g_free(pop3_session->ac_prefs->session_passwd);
				pop3_session->ac_prefs->session_passwd = NULL;
			}
			break;
		case INC_LOCKED:
			SET_PIXMAP_AND_TEXT(errorpix, _("Locked"));
			break;
		case INC_ERROR:
		case INC_NO_SPACE:
		case INC_IO_ERROR:
		case INC_SOCKET_ERROR:
		case INC_EOF:
			SET_PIXMAP_AND_TEXT(errorpix, _("Error"));
			break;
		case INC_TIMEOUT:
			SET_PIXMAP_AND_TEXT(errorpix, _("Timeout"));
			break;
		case INC_CANCEL:
			SET_PIXMAP_AND_TEXT(okpix, _("Cancelled"));
			if (!inc_dialog->show_dialog)
				cancelled = TRUE;
			break;
		default:
			break;
		}
		
		if (pop3_session->error_val == PS_AUTHFAIL) {
			if(!prefs_common.no_recv_err_panel) {
				if((prefs_common.recv_dialog_mode == RECV_DIALOG_ALWAYS) ||
				    ((prefs_common.recv_dialog_mode == RECV_DIALOG_MANUAL) && focus_window))
					manage_window_focus_in(inc_dialog->dialog->window, NULL, NULL);
			}
		}

		/* CLAWS: perform filtering actions on dropped message */
		/* CLAWS: get default inbox (perhaps per account) */
		if (pop3_session->ac_prefs->inbox) {
			/* CLAWS: get destination folder / mailbox */
			inbox = folder_find_item_from_identifier(pop3_session->ac_prefs->inbox);
			if (!inbox)
				inbox = folder_get_default_inbox();
		} else
			inbox = folder_get_default_inbox();

		/* get list of messages in processing */
		processing = folder_get_default_processing();
		folder_item_scan(processing);
		msglist = folder_item_get_msg_list(processing);

		/* process messages */
		folder_item_update_freeze();
		
		procmsg_msglist_filter(msglist, pop3_session->ac_prefs, 
				&filtered, &unfiltered, 
				pop3_session->ac_prefs->filter_on_recv);

		filtering_move_and_copy_msgs(msglist);
		if (unfiltered != NULL)		
			folder_item_move_msgs(inbox, unfiltered);

		for(msglist_element = msglist; msglist_element != NULL; 
		    msglist_element = msglist_element->next) {
			MsgInfo *msginfo = (MsgInfo *)msglist_element->data;
			procmsg_msginfo_free(msginfo);
		}
		folder_item_update_thaw();
		
		g_slist_free(msglist);
		g_slist_free(filtered);
		g_slist_free(unfiltered);

		statusbar_pop_all();

		new_msgs += pop3_session->cur_total_num;

		pop3_write_uidl_list(pop3_session);

		if (inc_state != INC_SUCCESS && inc_state != INC_CANCEL) {
			error_num++;
			if (inc_dialog->show_dialog)
				manage_window_focus_in
					(inc_dialog->dialog->window,
					 NULL, NULL);
			inc_put_error(inc_state, pop3_session);
			if (inc_dialog->show_dialog)
				manage_window_focus_out
					(inc_dialog->dialog->window,
					 NULL, NULL);
			if (inc_state == INC_NO_SPACE ||
			    inc_state == INC_IO_ERROR)
				break;
		}
		folder_item_free_cache(processing, TRUE);

		inc_session_destroy(session);
		inc_dialog->queue_list =
			g_list_remove(inc_dialog->queue_list, session);
	}

#undef SET_PIXMAP_AND_TEXT

	if (new_msgs > 0)
		fin_msg = g_strdup_printf(ngettext("Finished (%d new message)",
					  	   "Finished (%d new messages)",
					  	   new_msgs), new_msgs);
	else
		fin_msg = g_strdup_printf(_("Finished (no new messages)"));

	progress_dialog_set_label(inc_dialog->dialog, fin_msg);

	while (inc_dialog->queue_list != NULL) {
		session = inc_dialog->queue_list->data;
		inc_session_destroy(session);
		inc_dialog->queue_list =
			g_list_remove(inc_dialog->queue_list, session);
	}

	if (prefs_common.close_recv_dialog || !inc_dialog->show_dialog)
		inc_progress_dialog_destroy(inc_dialog);
	else {
		gtk_window_set_title(GTK_WINDOW(inc_dialog->dialog->window),
				     fin_msg);
		gtk_button_set_label(GTK_BUTTON(inc_dialog->dialog->cancel_btn),
				     GTK_STOCK_CLOSE);
	}

	g_free(fin_msg);

	return new_msgs;
}
Beispiel #7
0
gint proc_mbox(FolderItem *dest, const gchar *mbox, gboolean apply_filter,
	       PrefsAccount *account)
/* return values: -1 error, >=0 number of msgs added */
{
	FILE *mbox_fp;
	gchar buf[MESSAGEBUFSIZE];
	gchar *tmp_file;
	gint msgs = 0;
	gint lines;
	MsgInfo *msginfo;
	gboolean more;
	GSList *to_filter = NULL, *filtered = NULL, *unfiltered = NULL, *cur, *to_add = NULL;
	gboolean printed = FALSE;
	FolderItem *dropfolder;

	cm_return_val_if_fail(dest != NULL, -1);
	cm_return_val_if_fail(mbox != NULL, -1);

	debug_print("Getting messages from %s into %s...\n", mbox, dest->path);

	if ((mbox_fp = g_fopen(mbox, "rb")) == NULL) {
		FILE_OP_ERROR(mbox, "fopen");
		alertpanel_error(_("Could not open mbox file:\n%s\n"), mbox);
		return -1;
	}

	/* ignore empty lines on the head */
	do {
		if (fgets(buf, sizeof(buf), mbox_fp) == NULL) {
			g_warning("can't read mbox file.\n");
			fclose(mbox_fp);
			return -1;
		}
	} while (buf[0] == '\n' || buf[0] == '\r');

	if (strncmp(buf, "From ", 5) != 0) {
		g_warning("invalid mbox format: %s\n", mbox);
		fclose(mbox_fp);
		return -1;
	}

	tmp_file = get_tmp_file();

	folder_item_update_freeze();

	if (apply_filter)
		dropfolder = folder_get_default_processing();
	else
		dropfolder = dest;
	
	do {
		FILE *tmp_fp;
		gint empty_lines;
		gint msgnum;
		
		if (msgs > 0 && msgs%500 == 0) {
			if (printed)
				statusbar_pop_all();
			statusbar_print_all(
					ngettext("Importing from mbox... (%d mail imported)",
						"Importing from mbox... (%d mails imported)", msgs), msgs);
			printed=TRUE;
			GTK_EVENTS_FLUSH();
		}
	
		if ((tmp_fp = g_fopen(tmp_file, "wb")) == NULL) {
			FILE_OP_ERROR(tmp_file, "fopen");
			g_warning("can't open temporary file\n");
			fclose(mbox_fp);
			g_free(tmp_file);
			return -1;
		}
		if (change_file_mode_rw(tmp_fp, tmp_file) < 0) {
			FILE_OP_ERROR(tmp_file, "chmod");
		}

		empty_lines = 0;
		lines = 0;

		/* process all lines from mboxrc file */
		while (fgets(buf, sizeof(buf), mbox_fp) != NULL) {
			int offset;

			/* eat empty lines */
			if (buf[0] == '\n' || buf[0] == '\r') {
				empty_lines++;
				continue;
			}

			/* From separator or quoted From */
			offset = 0;
			/* detect leading '>' char(s) */
			while ((buf[offset] == '>')) {
				offset++;
			}
			if (!strncmp(buf+offset, "From ", 5)) {
				/* From separator: */
				if (offset == 0) {
					/* expect next mbox item */
					break;
				}

				/* quoted From: */
				/* flush any eaten empty line */
				if (empty_lines > 0) {
					while (empty_lines-- > 0) {
						FPUTS_TO_TMP_ABORT_IF_FAIL("\n");
				}
					empty_lines = 0;
				}
				/* store the unquoted line */
				FPUTS_TO_TMP_ABORT_IF_FAIL(buf + 1);
				continue;
			}

			/* other line */
			/* flush any eaten empty line */
			if (empty_lines > 0) {			
				while (empty_lines-- > 0) {
					FPUTS_TO_TMP_ABORT_IF_FAIL("\n");
			}
				empty_lines = 0;
			}
			/* store the line itself */
					FPUTS_TO_TMP_ABORT_IF_FAIL(buf);
		}
		/* end of mbox item or end of mbox */

		/* flush any eaten empty line (but the last one) */
		if (empty_lines > 0) {
			while (--empty_lines > 0) {
				FPUTS_TO_TMP_ABORT_IF_FAIL("\n");
			}
		}

		/* more emails to expect? */
		more = !feof(mbox_fp);

		/* warn if email part is empty (it's the minimum check 
		   we can do */
		if (lines == 0) {
			g_warning("malformed mbox: %s: message %d is empty\n", mbox, msgs);
			fclose(tmp_fp);
			fclose(mbox_fp);
			claws_unlink(tmp_file);
			return -1;
		}

		if (fclose(tmp_fp) == EOF) {
			FILE_OP_ERROR(tmp_file, "fclose");
			g_warning("can't write to temporary file\n");
			fclose(mbox_fp);
			claws_unlink(tmp_file);
			g_free(tmp_file);
			return -1;
		}

		if (apply_filter) {
			if ((msgnum = folder_item_add_msg(dropfolder, tmp_file, NULL, TRUE)) < 0) {
				fclose(mbox_fp);
				claws_unlink(tmp_file);
				g_free(tmp_file);
				return -1;
			}
			msginfo = folder_item_get_msginfo(dropfolder, msgnum);
			to_filter = g_slist_prepend(to_filter, msginfo);
		} else {
			MsgFileInfo *finfo = g_new0(MsgFileInfo, 1);
			finfo->file = tmp_file;
			
			to_add = g_slist_prepend(to_add, finfo);
			tmp_file = get_tmp_file();
			
			/* flush every 500 */
			if (msgs > 0 && msgs % 500 == 0) {
				folder_item_add_msgs(dropfolder, to_add, TRUE);
				procmsg_message_file_list_free(to_add);
				to_add = NULL;
			}
		}
		msgs++;
	} while (more);

	if (printed)
		statusbar_pop_all();

	if (apply_filter) {

		folder_item_set_batch(dropfolder, FALSE);
		procmsg_msglist_filter(to_filter, account, 
				&filtered, &unfiltered, TRUE);
		folder_item_set_batch(dropfolder, TRUE);

		filtering_move_and_copy_msgs(to_filter);
		for (cur = filtered; cur; cur = g_slist_next(cur)) {
			MsgInfo *info = (MsgInfo *)cur->data;
			procmsg_msginfo_free(info);
		}

		unfiltered = g_slist_reverse(unfiltered);
		if (unfiltered) {
			folder_item_move_msgs(dest, unfiltered);
			for (cur = unfiltered; cur; cur = g_slist_next(cur)) {
				MsgInfo *info = (MsgInfo *)cur->data;
				procmsg_msginfo_free(info);
			}
		}

		g_slist_free(unfiltered);
		g_slist_free(filtered);
		g_slist_free(to_filter);
	} else if (to_add) {
		folder_item_add_msgs(dropfolder, to_add, TRUE);
		procmsg_message_file_list_free(to_add);
		to_add = NULL;
	}

	folder_item_update_thaw();
	
	g_free(tmp_file);
	fclose(mbox_fp);
	debug_print("%d messages found.\n", msgs);

	return msgs;
}