New swanky send/recieve thingy, well it so far only receives (pop/mbox).
2001-01-19 Not Zed <NotZed@Ximian.com> * mail-send-recv.c: New swanky send/recieve thingy, well it so far only receives (pop/mbox). Ignore all the warnings for now, and the ugly 'button' to run it. svn path=/trunk/; revision=7636
This commit is contained in:
@ -1,3 +1,9 @@
|
||||
2001-01-19 Not Zed <NotZed@Ximian.com>
|
||||
|
||||
* mail-send-recv.c: New swanky send/recieve thingy, well it so far
|
||||
only receives (pop/mbox). Ignore all the warnings for now, and
|
||||
the ugly 'button' to run it.
|
||||
|
||||
2001-01-18 Jeffrey Stedfast <fejj@ximian.com>
|
||||
|
||||
* folder-browser-factory.c: Added the next/previous toolbar
|
||||
|
||||
@ -77,6 +77,7 @@ evolution_mail_SOURCES = \
|
||||
mail-ops.h \
|
||||
mail-search-dialogue.c \
|
||||
mail-search-dialogue.h \
|
||||
mail-send-recv.c \
|
||||
mail-summary.c \
|
||||
mail-summary.h \
|
||||
mail-threads.c \
|
||||
|
||||
@ -33,6 +33,9 @@
|
||||
/* The FolderBrowser BonoboControls we have. */
|
||||
static EList *control_list = NULL;
|
||||
|
||||
/* this is temporary, remove later -Z */
|
||||
void mail_receive(void);
|
||||
|
||||
/*
|
||||
* Add with 'folder_browser'
|
||||
*/
|
||||
@ -97,6 +100,9 @@ BonoboUIVerb verbs [] = {
|
||||
BONOBO_UI_UNSAFE_VERB ("MailPrevious", previous_msg),
|
||||
BONOBO_UI_UNSAFE_VERB ("MailNext", next_msg),
|
||||
|
||||
/* This is just very temporary - !Z */
|
||||
BONOBO_UI_UNSAFE_VERB ("MailGetNew", mail_receive),
|
||||
|
||||
BONOBO_UI_VERB_END
|
||||
};
|
||||
|
||||
|
||||
604
mail/mail-send-recv.c
Normal file
604
mail/mail-send-recv.c
Normal file
@ -0,0 +1,604 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "filter/filter-context.h"
|
||||
#include "filter/filter-filter.h"
|
||||
#include "camel/camel-filter-driver.h"
|
||||
#include "camel/camel-folder.h"
|
||||
#include "camel/camel-session.h"
|
||||
#include "camel/camel-uid-cache.h"
|
||||
|
||||
#include "mail-mt.h"
|
||||
#include "mail-config.h"
|
||||
|
||||
/* for the dialogue stuff */
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <libgnomeui/gnome-stock.h>
|
||||
#include <libgnomeui/gnome-dialog.h>
|
||||
|
||||
/* send/receive email */
|
||||
|
||||
extern char *evolution_dir;
|
||||
extern CamelFolder *mail_tool_filter_get_folder_func (CamelFilterDriver *d, const char *uri, void *data);
|
||||
|
||||
static FilterContext *
|
||||
load_context(void)
|
||||
{
|
||||
char *userrules;
|
||||
char *systemrules;
|
||||
FilterContext *fc;
|
||||
|
||||
userrules = g_strdup_printf ("%s/filters.xml", evolution_dir);
|
||||
systemrules = g_strdup_printf ("%s/evolution/filtertypes.xml", EVOLUTION_DATADIR);
|
||||
fc = filter_context_new ();
|
||||
rule_context_load ((RuleContext *)fc, systemrules, userrules);
|
||||
g_free (userrules);
|
||||
g_free (systemrules);
|
||||
|
||||
return fc;
|
||||
}
|
||||
|
||||
static void
|
||||
setup_filter_driver(CamelFilterDriver *driver, FilterContext *fc, const char *source)
|
||||
{
|
||||
GString *fsearch, *faction;
|
||||
FilterFilter *rule = NULL;
|
||||
|
||||
if (TRUE /* perform_logging */) {
|
||||
char *filename = g_strdup_printf("%s/evolution-filter-log", evolution_dir);
|
||||
FILE *logfile = fopen(filename, "a+");
|
||||
g_free(filename);
|
||||
if (logfile)
|
||||
camel_filter_driver_set_logfile(driver, logfile);
|
||||
}
|
||||
|
||||
fsearch = g_string_new ("");
|
||||
faction = g_string_new ("");
|
||||
|
||||
while ((rule = (FilterFilter *)rule_context_next_rule((RuleContext *)fc, (FilterRule *)rule, source))) {
|
||||
g_string_truncate (fsearch, 0);
|
||||
g_string_truncate (faction, 0);
|
||||
|
||||
filter_rule_build_code ((FilterRule *)rule, fsearch);
|
||||
filter_filter_build_action (rule, faction);
|
||||
|
||||
camel_filter_driver_add_rule(driver, ((FilterRule *)rule)->name, fsearch->str, faction->str);
|
||||
}
|
||||
|
||||
g_string_free (fsearch, TRUE);
|
||||
g_string_free (faction, TRUE);
|
||||
}
|
||||
|
||||
/* used for both just filtering a folder + uid's, and for filtering a whole folder */
|
||||
struct _fetch_mail_msg {
|
||||
struct _mail_msg msg;
|
||||
|
||||
char *source_uri;
|
||||
CamelFolder *source_folder;
|
||||
GPtrArray *source_uids;
|
||||
CamelCancel *cancel;
|
||||
CamelFolder *destination;
|
||||
CamelFilterDriver *driver;
|
||||
int keep;
|
||||
|
||||
void (*done)(char *source, void *data);
|
||||
void *data;
|
||||
};
|
||||
|
||||
/* filter a folder, or a subset thereof, uses source_folder/source_uids */
|
||||
static void
|
||||
fetch_mail_filter_folder(struct _mail_msg *mm)
|
||||
{
|
||||
struct _fetch_mail_msg *m = (struct _fetch_mail_msg *)mm;
|
||||
CamelFolder *folder;
|
||||
CamelUIDCache *cache = NULL;
|
||||
GPtrArray *uids, *folder_uids = NULL, *cache_uids = NULL;
|
||||
|
||||
if (m->source_folder)
|
||||
folder = m->source_folder;
|
||||
else
|
||||
folder = m->source_folder = mail_tool_get_inbox (m->source_uri, &mm->ex);
|
||||
|
||||
if (folder == NULL || camel_folder_get_message_count (folder) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
camel_folder_freeze(folder);
|
||||
|
||||
if (m->source_uids)
|
||||
uids = m->source_uids;
|
||||
else
|
||||
uids = camel_folder_get_uids (folder);
|
||||
|
||||
if (m->keep) {
|
||||
char *cachename = mail_config_folder_to_cachename (folder, "cache-");
|
||||
|
||||
cache = camel_uid_cache_new (cachename);
|
||||
if (cache) {
|
||||
cache_uids = camel_uid_cache_get_new_uids (cache, uids);
|
||||
uids = cache_uids;
|
||||
}
|
||||
|
||||
g_free (cachename);
|
||||
}
|
||||
|
||||
camel_filter_driver_filter_folder(m->driver, folder, FILTER_SOURCE_INCOMING, uids, !m->keep, &mm->ex);
|
||||
|
||||
if (cache) {
|
||||
if (!camel_exception_is_set (&mm->ex))
|
||||
camel_uid_cache_save (cache);
|
||||
camel_uid_cache_destroy (cache);
|
||||
}
|
||||
|
||||
if (folder_uids)
|
||||
camel_folder_free_uids(folder, folder_uids);
|
||||
if (cache_uids)
|
||||
camel_uid_cache_free_uids (cache_uids);
|
||||
|
||||
/* sync and expunge */
|
||||
camel_folder_sync (folder, TRUE, &mm->ex);
|
||||
camel_folder_thaw(folder);
|
||||
}
|
||||
|
||||
static void
|
||||
fetch_mail_fetch(struct _mail_msg *mm)
|
||||
{
|
||||
struct _fetch_mail_msg *m = (struct _fetch_mail_msg *)mm;
|
||||
|
||||
if (m->cancel)
|
||||
camel_cancel_register(m->cancel);
|
||||
|
||||
if (m->destination == NULL) {
|
||||
if ( (m->destination = mail_tool_get_local_inbox(&mm->ex)) == NULL) {
|
||||
if (m->cancel)
|
||||
camel_cancel_unregister(m->cancel);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
camel_folder_freeze (m->destination);
|
||||
camel_filter_driver_set_default_folder(m->driver, m->destination);
|
||||
|
||||
/* FIXME: this should support keep_on_server too, which would then perform a spool
|
||||
access thingy, right? problem is matching raw messages to uid's etc. */
|
||||
if (!strncmp (m->source_uri, "mbox:", 5)) {
|
||||
char *path = mail_tool_do_movemail (m->source_uri, &mm->ex);
|
||||
|
||||
if (path && !camel_exception_is_set (&mm->ex)) {
|
||||
camel_filter_driver_filter_mbox(m->driver, path, FILTER_SOURCE_INCOMING, &mm->ex);
|
||||
|
||||
/* ok? zap the output file */
|
||||
if (!camel_exception_is_set (&mm->ex)) {
|
||||
unlink (path);
|
||||
}
|
||||
}
|
||||
g_free (path);
|
||||
} else {
|
||||
fetch_mail_filter_folder(mm);
|
||||
}
|
||||
|
||||
camel_folder_thaw (m->destination);
|
||||
|
||||
if (m->cancel)
|
||||
camel_cancel_unregister(m->cancel);
|
||||
}
|
||||
|
||||
static void
|
||||
fetch_mail_fetched(struct _mail_msg *mm)
|
||||
{
|
||||
struct _fetch_mail_msg *m = (struct _fetch_mail_msg *)mm;
|
||||
|
||||
if (m->done)
|
||||
m->done(m->source_uri, m->data);
|
||||
}
|
||||
|
||||
static void
|
||||
fetch_mail_free(struct _mail_msg *mm)
|
||||
{
|
||||
struct _fetch_mail_msg *m = (struct _fetch_mail_msg *)mm;
|
||||
int i;
|
||||
|
||||
g_free(m->source_uri);
|
||||
if (m->source_folder)
|
||||
camel_object_unref((CamelObject *)m->source_folder);
|
||||
if (m->source_uids) {
|
||||
for (i=0;i<m->source_uids->len;i++)
|
||||
g_free(m->source_uids->pdata[i]);
|
||||
g_ptr_array_free(m->source_uids, TRUE);
|
||||
}
|
||||
camel_cancel_unref(m->cancel);
|
||||
if (m->destination)
|
||||
camel_object_unref((CamelObject *)m->destination);
|
||||
camel_object_unref((CamelObject *)m->driver);
|
||||
}
|
||||
|
||||
static struct _mail_msg_op fetch_mail_op = {
|
||||
NULL, /* we do our own progress reporting */
|
||||
fetch_mail_fetch,
|
||||
fetch_mail_fetched,
|
||||
fetch_mail_free,
|
||||
};
|
||||
|
||||
/* ouch, a 'do everything' interface ... */
|
||||
void mail_filter_mail(const char *source, int keep,
|
||||
FilterContext *fc, const char *type,
|
||||
CamelCancel *cancel,
|
||||
CamelFilterGetFolderFunc get_folder, void *get_data,
|
||||
CamelFilterStatusFunc *status, void *status_data,
|
||||
void (*done)(char *source, void *data), void *data)
|
||||
{
|
||||
struct _fetch_mail_msg *m;
|
||||
|
||||
m = mail_msg_new(&fetch_mail_op, NULL, sizeof(*m));
|
||||
m->source_uri = g_strdup(source);
|
||||
m->keep = keep;
|
||||
m->cancel = cancel;
|
||||
camel_cancel_ref(cancel);
|
||||
m->done = done;
|
||||
m->data = data;
|
||||
|
||||
m->driver = camel_filter_driver_new(get_folder, get_data);
|
||||
setup_filter_driver(m->driver, fc, type);
|
||||
if (status)
|
||||
camel_filter_driver_set_status_func(m->driver, status, status_data);
|
||||
|
||||
e_thread_put(mail_thread_new, (EMsg *)m);
|
||||
}
|
||||
|
||||
/* this is not used yet, will be used to keep track of which folders were
|
||||
filtering to, and to let them refresh once in a while */
|
||||
struct _folder_info {
|
||||
char *uri;
|
||||
CamelFolder *folder;
|
||||
time_t update;
|
||||
int count; /* how many times updated, to slow it down as we go, if we have lots */
|
||||
};
|
||||
|
||||
struct _send_data {
|
||||
GList *infos;
|
||||
|
||||
int active; /* how many still active */
|
||||
|
||||
GnomeDialog *gd;
|
||||
int cancelled;
|
||||
|
||||
CamelFolder *inbox; /* since w'ere never asked to uypdate this one, do it ourselves */
|
||||
time_t inbox_update;
|
||||
|
||||
GMutex *lock;
|
||||
GHashTable *folders;
|
||||
};
|
||||
|
||||
struct _send_info {
|
||||
CamelCancel *cancel;
|
||||
char *uri;
|
||||
int keep;
|
||||
int cancelled;
|
||||
GtkProgressBar *bar;
|
||||
GtkButton *stop;
|
||||
time_t update;
|
||||
struct _send_data *data;
|
||||
};
|
||||
|
||||
static void
|
||||
receive_cancel(GtkButton *button, struct _send_info *info)
|
||||
{
|
||||
camel_cancel_cancel(info->cancel);
|
||||
gtk_progress_set_format_string((GtkProgress *)info->bar, _("Cancelling ..."));
|
||||
info->cancelled = TRUE;
|
||||
gtk_widget_set_sensitive((GtkWidget *)info->stop, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
free_folder_info(void *key, struct _folder_info *info, void *data)
|
||||
{
|
||||
camel_object_unref((CamelObject *)info->folder);
|
||||
g_free(info->uri);
|
||||
}
|
||||
|
||||
static void
|
||||
free_info_data(void *datain)
|
||||
{
|
||||
struct _send_data *data = datain;
|
||||
GList *list = data->infos;
|
||||
|
||||
while (list) {
|
||||
struct _send_info *info = list->data;
|
||||
g_free(info->uri);
|
||||
camel_cancel_unref(info->cancel);
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
g_list_free(data->infos);
|
||||
g_hash_table_foreach(data->folders, (GHFunc)free_folder_info, NULL);
|
||||
g_hash_table_destroy(data->folders);
|
||||
g_mutex_free(data->lock);
|
||||
if (data->inbox)
|
||||
camel_object_unref((CamelObject *)data->inbox);
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
static void
|
||||
dialogue_clicked(GnomeDialog *gd, int button, struct _send_data *data)
|
||||
{
|
||||
GList *scan;
|
||||
|
||||
switch(button) {
|
||||
case 0: /* ok */
|
||||
gnome_dialog_close(gd);
|
||||
break;
|
||||
case 1:
|
||||
printf("cancelled whole thing\n");
|
||||
if (!data->cancelled) {
|
||||
data->cancelled = TRUE;
|
||||
scan = data->infos;
|
||||
while (scan) {
|
||||
struct _send_info *info = scan->data;
|
||||
receive_cancel(info->stop, info);
|
||||
scan = scan->next;
|
||||
}
|
||||
}
|
||||
gnome_dialog_set_sensitive(gd, 1, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct _send_data *build_dialogue(GSList *sources)
|
||||
{
|
||||
GnomeDialog *gd;
|
||||
GtkFrame *frame;
|
||||
GtkTable *table;
|
||||
int row;
|
||||
GList *list = NULL;
|
||||
struct _send_data *data;
|
||||
|
||||
data = g_malloc0(sizeof(*data));
|
||||
data->lock = g_mutex_new();
|
||||
data->folders = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
data->inbox = mail_tool_get_local_inbox(NULL);
|
||||
|
||||
gd = (GnomeDialog *)gnome_dialog_new(_("Send & Receive mail"), GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, NULL);
|
||||
gnome_dialog_set_sensitive(gd, 0, FALSE);
|
||||
|
||||
frame= (GtkFrame *)gtk_frame_new(_("Receive list"));
|
||||
gtk_box_pack_start((GtkBox *)gd->vbox, (GtkWidget *)frame, TRUE, TRUE, 0);
|
||||
table = (GtkTable *)gtk_table_new(g_slist_length(sources), 3, FALSE);
|
||||
gtk_container_add((GtkContainer *)frame, (GtkWidget *)table);
|
||||
gtk_widget_show((GtkWidget *)frame);
|
||||
|
||||
row = 0;
|
||||
while (sources) {
|
||||
MailConfigService *source = sources->data;
|
||||
GtkLabel *label;
|
||||
GtkProgressBar *bar;
|
||||
GtkButton *stop;
|
||||
struct _send_info *info;
|
||||
|
||||
/* imap is handled differently */
|
||||
if (!strncmp(source->url, "imap:", 5)) {
|
||||
sources = sources->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
info = g_malloc0(sizeof(*info));
|
||||
printf("adding source %s\n", source->url);
|
||||
|
||||
label = (GtkLabel *)gtk_label_new(source->url);
|
||||
bar = (GtkProgressBar *)gtk_progress_bar_new();
|
||||
stop = (GtkButton *)gnome_stock_button(GNOME_STOCK_BUTTON_CANCEL);
|
||||
|
||||
gtk_progress_set_format_string((GtkProgress *)bar, _("Waiting ..."));
|
||||
gtk_progress_set_show_text((GtkProgress *)bar, TRUE);
|
||||
|
||||
gtk_table_attach(table, (GtkWidget *)label, 0, 1, row, row+1, GTK_EXPAND|GTK_FILL, 0, 3, 1);
|
||||
gtk_table_attach(table, (GtkWidget *)bar, 1, 2, row, row+1, GTK_EXPAND|GTK_FILL, 0, 3, 1);
|
||||
gtk_table_attach(table, (GtkWidget *)stop, 2, 3, row, row+1, GTK_EXPAND|GTK_FILL, 0, 3, 1);
|
||||
|
||||
info->bar = bar;
|
||||
info->uri = g_strdup(source->url);
|
||||
info->keep = source->keep_on_server;
|
||||
info->cancel = camel_cancel_new();
|
||||
info->stop = stop;
|
||||
info->data = data;
|
||||
data->active++;
|
||||
|
||||
list = g_list_prepend(list, info);
|
||||
|
||||
gtk_signal_connect((GtkObject *)stop, "clicked", receive_cancel, info);
|
||||
sources = sources->next;
|
||||
row++;
|
||||
}
|
||||
|
||||
gtk_widget_show_all((GtkWidget *)table);
|
||||
gtk_widget_show((GtkWidget *)gd);
|
||||
|
||||
gtk_signal_connect((GtkObject *)gd, "clicked", dialogue_clicked, data);
|
||||
|
||||
data->infos = list;
|
||||
data->gd = gd;
|
||||
gtk_object_set_data_full((GtkObject *)gd, "info_data", data, free_info_data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
update_folders(char *uri, struct _folder_info *info, void *data)
|
||||
{
|
||||
time_t now = *((time_t *)data);
|
||||
|
||||
printf("checking update for folder: %s\n", info->uri);
|
||||
|
||||
/* let it flow through to the folders every 10 seconds */
|
||||
/* we back off slowly as we progress */
|
||||
if (now > info->update+10+info->count*5) {
|
||||
printf("upating a folder: %s\n", info->uri);
|
||||
camel_folder_thaw(info->folder);
|
||||
camel_folder_freeze(info->folder);
|
||||
info->update = now;
|
||||
info->count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* for forwarding stuff to the gui thread */
|
||||
struct _status_msg {
|
||||
struct _mail_msg msg;
|
||||
char *desc;
|
||||
int pc;
|
||||
struct _send_info *info;
|
||||
};
|
||||
|
||||
static void
|
||||
do_show_status(struct _mail_msg *mm)
|
||||
{
|
||||
struct _status_msg *m = (struct _status_msg *)mm;
|
||||
|
||||
gtk_progress_set_percentage((GtkProgress *)m->info->bar, (gfloat)(m->pc/100.0));
|
||||
gtk_progress_set_format_string((GtkProgress *)m->info->bar, m->desc);
|
||||
}
|
||||
|
||||
static void
|
||||
do_free_status(struct _mail_msg *mm)
|
||||
{
|
||||
struct _status_msg *m = (struct _status_msg *)mm;
|
||||
|
||||
g_free(m->desc);
|
||||
}
|
||||
|
||||
struct _mail_msg_op status_op = {
|
||||
NULL,
|
||||
do_show_status,
|
||||
NULL,
|
||||
do_free_status,
|
||||
};
|
||||
|
||||
static void
|
||||
receive_status (CamelFilterDriver *driver, enum camel_filter_status_t status, int pc, const char *desc, void *data)
|
||||
{
|
||||
struct _send_info *info = data;
|
||||
time_t now;
|
||||
struct _status_msg *m;
|
||||
|
||||
/* only update every second */
|
||||
now = time(0);
|
||||
if (now <= info->update)
|
||||
return;
|
||||
|
||||
info->update = now;
|
||||
|
||||
/* let it flow through to the folder, every now and then too? */
|
||||
g_hash_table_foreach(info->data->folders, (GHFunc)update_folders, &now);
|
||||
|
||||
if (info->data->inbox && now > info->data->inbox_update+20) {
|
||||
printf("updating inbox too\n");
|
||||
/* this doesn't seem to work right :( */
|
||||
camel_folder_thaw(info->data->inbox);
|
||||
camel_folder_freeze(info->data->inbox);
|
||||
info->data->inbox_update = now;
|
||||
}
|
||||
|
||||
/* we just pile them onto the port, assuming it can handle it.
|
||||
We could also have a receiver port and see if they've been processed
|
||||
yet, so if this is necessary its not too hard to add */
|
||||
/* the mail_gui_port receiver will free everything for us */
|
||||
switch (status) {
|
||||
case FILTER_STATUS_START:
|
||||
case FILTER_STATUS_END:
|
||||
m = mail_msg_new(&status_op, NULL, sizeof(*m));
|
||||
m->desc = g_strdup(desc);
|
||||
m->pc = pc;
|
||||
m->info = info;
|
||||
e_msgport_put(mail_gui_port, (EMsg *)m);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
receive_done (char *uri, void *data)
|
||||
{
|
||||
struct _send_info *info = data;
|
||||
|
||||
if (info->cancelled)
|
||||
gtk_progress_set_format_string((GtkProgress *)info->bar, _("Cancelled."));
|
||||
else
|
||||
gtk_progress_set_format_string((GtkProgress *)info->bar, _("Complete."));
|
||||
|
||||
gtk_widget_set_sensitive((GtkWidget *)info->stop, FALSE);
|
||||
|
||||
info->data->active--;
|
||||
if (info->data->active == 0) {
|
||||
gnome_dialog_set_sensitive(info->data->gd, 0, TRUE);
|
||||
gnome_dialog_set_sensitive(info->data->gd, 1, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/* although we dont do anythign smart here yet, there is no need for this interface to
|
||||
be available to anyone else.
|
||||
This can also be used to hook into which folders are being updated, and occasionally
|
||||
let them refresh */
|
||||
static CamelFolder *
|
||||
receive_get_folder(CamelFilterDriver *d, const char *uri, void *data)
|
||||
{
|
||||
struct _send_info *info = data;
|
||||
CamelFolder *mail_tool_uri_to_folder_noex (const char *uri);
|
||||
CamelFolder *folder;
|
||||
struct _folder_info *oldinfo;
|
||||
char *oldkey;
|
||||
|
||||
g_mutex_lock(info->data->lock);
|
||||
folder = g_hash_table_lookup(info->data->folders, uri);
|
||||
g_mutex_unlock(info->data->lock);
|
||||
if (folder) {
|
||||
camel_object_ref((CamelObject *)folder);
|
||||
return folder;
|
||||
}
|
||||
folder = mail_tool_uri_to_folder_noex(uri);
|
||||
/* we recheck that the folder hasn't snuck in while we were loading it ... */
|
||||
/* and we assume the newer one is the same, but unref the old one anyway */
|
||||
g_mutex_lock(info->data->lock);
|
||||
if (g_hash_table_lookup_extended(info->data->folders, uri, (void **)&oldkey, (void **)&oldinfo)) {
|
||||
camel_object_unref((CamelObject *)oldinfo->folder);
|
||||
oldinfo->folder = folder;
|
||||
} else {
|
||||
oldinfo = g_malloc0(sizeof(*oldinfo));
|
||||
oldinfo->folder = folder;
|
||||
oldinfo->uri = g_strdup(uri);
|
||||
g_hash_table_insert(info->data->folders, oldinfo->uri, oldinfo);
|
||||
}
|
||||
g_mutex_unlock(info->data->lock);
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
void mail_receive(void)
|
||||
{
|
||||
GSList *sources;
|
||||
GList *scan;
|
||||
FilterContext *fc;
|
||||
struct _send_data *data;
|
||||
|
||||
sources = mail_config_get_sources ();
|
||||
if (!sources)
|
||||
return;
|
||||
|
||||
fc = load_context();
|
||||
|
||||
data = build_dialogue(sources);
|
||||
scan = data->infos;
|
||||
while (scan) {
|
||||
struct _send_info *info = scan->data;
|
||||
mail_filter_mail(info->uri, info->keep,
|
||||
fc, FILTER_SOURCE_INCOMING,
|
||||
info->cancel,
|
||||
receive_get_folder, info,
|
||||
receive_status, info,
|
||||
receive_done, info);
|
||||
scan = scan->next;
|
||||
}
|
||||
|
||||
gtk_object_unref((GtkObject *)fc);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user