aboutsummaryrefslogtreecommitdiff
path: root/libsylph
diff options
context:
space:
mode:
authorhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2007-09-14 08:12:20 +0000
committerhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2007-09-14 08:12:20 +0000
commitab880a9066b4f32d08ba99903d09a4a5675dd214 (patch)
treeda3d3294e3feacc04b2022c72dcf920b6551ed23 /libsylph
parent7f69beae19a44f3e2df8097add8c89f34a01e058 (diff)
modified the method of getting IMAP4 folder list.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@1900 ee746299-78ed-0310-b773-934348b2243d
Diffstat (limited to 'libsylph')
-rw-r--r--libsylph/folder.c41
-rw-r--r--libsylph/folder.h1
-rw-r--r--libsylph/imap.c139
3 files changed, 141 insertions, 40 deletions
diff --git a/libsylph/folder.c b/libsylph/folder.c
index 0649ca21..cb630521 100644
--- a/libsylph/folder.c
+++ b/libsylph/folder.c
@@ -209,6 +209,47 @@ void folder_item_append(FolderItem *parent, FolderItem *item)
item->node = g_node_append_data(parent->node, item);
}
+FolderItem *folder_item_copy(FolderItem *item)
+{
+ FolderItem *new_item;
+
+ new_item = g_new0(FolderItem, 1);
+
+ new_item->stype = item->stype;
+ new_item->name = g_strdup(item->name);
+ new_item->path = g_strdup(item->path);
+ new_item->mtime = item->mtime;
+ new_item->new = item->new;
+ new_item->unread = item->unread;
+ new_item->total = item->total;
+ new_item->unmarked_num = item->unmarked_num;
+ new_item->last_num = item->last_num;
+ new_item->no_sub = item->no_sub;
+ new_item->no_select = item->no_select;
+ new_item->collapsed = item->collapsed;
+ new_item->threaded = item->threaded;
+ new_item->opened = item->opened;
+ new_item->updated = item->updated;
+ new_item->cache_dirty = item->cache_dirty;
+ new_item->mark_dirty = item->mark_dirty;
+ new_item->node = item->node;
+ new_item->parent = item->parent;
+ new_item->folder = item->folder;
+ new_item->account = item->account;
+ new_item->ac_apply_sub = item->ac_apply_sub;
+ new_item->auto_to = g_strdup(item->auto_to);
+ new_item->use_auto_to_on_reply = item->use_auto_to_on_reply;
+ new_item->auto_cc = g_strdup(item->auto_cc);
+ new_item->auto_bcc = g_strdup(item->auto_bcc);
+ new_item->auto_replyto = g_strdup(item->auto_replyto);
+ new_item->mark_queue = item->mark_queue;
+ new_item->last_selected = item->last_selected;
+ new_item->qsearch_cond_type = item->qsearch_cond_type;
+ new_item->data = item->data;
+
+ return new_item;
+}
+
static gboolean folder_item_remove_func(GNode *node, gpointer data)
{
FolderItem *item = FOLDER_ITEM(node->data);
diff --git a/libsylph/folder.h b/libsylph/folder.h
index 3d2e577b..db9c3bf9 100644
--- a/libsylph/folder.h
+++ b/libsylph/folder.h
@@ -325,6 +325,7 @@ FolderItem *folder_item_new (const gchar *name,
const gchar *path);
void folder_item_append (FolderItem *parent,
FolderItem *item);
+FolderItem *folder_item_copy (FolderItem *item);
void folder_item_remove (FolderItem *item);
void folder_item_remove_children (FolderItem *item);
void folder_item_destroy (FolderItem *item);
diff --git a/libsylph/imap.c b/libsylph/imap.c
index bcac6355..35c053e7 100644
--- a/libsylph/imap.c
+++ b/libsylph/imap.c
@@ -176,10 +176,15 @@ static gint imap_auth (IMAPSession *session,
IMAPAuthType type);
static gint imap_scan_tree_recursive (IMAPSession *session,
+ FolderItem *item,
+ GSList *item_list);
+static GSList *imap_get_folder_list (IMAPSession *session,
FolderItem *item);
static GSList *imap_parse_list (IMAPSession *session,
const gchar *real_path,
gchar *separator);
+static GSList *imap_get_part_folder_list(GSList *item_list,
+ FolderItem *item);
static void imap_create_missing_folders (Folder *folder);
static FolderItem *imap_create_special_folder
@@ -1702,6 +1707,7 @@ static gint imap_scan_tree(Folder *folder)
FolderItem *item = NULL;
IMAPSession *session;
gchar *root_folder = NULL;
+ GSList *item_list, *cur;
g_return_val_if_fail(folder != NULL, -1);
g_return_val_if_fail(folder->account != NULL, -1);
@@ -1757,56 +1763,33 @@ static gint imap_scan_tree(Folder *folder)
folder->node = item->node = g_node_new(item);
}
- imap_scan_tree_recursive(session, FOLDER_ITEM(folder->node->data));
+ item_list = imap_get_folder_list(session, item);
+ imap_scan_tree_recursive(session, item, item_list);
imap_create_missing_folders(folder);
+ for (cur = item_list; cur != NULL; cur = cur->next)
+ folder_item_destroy(FOLDER_ITEM(cur->data));
+ g_slist_free(item_list);
+
return 0;
}
-static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item)
+static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item,
+ GSList *item_list)
{
Folder *folder;
IMAPFolder *imapfolder;
FolderItem *new_item;
- GSList *item_list, *cur;
+ GSList *part_list, *cur;
GNode *node;
- gchar *real_path;
- gchar *wildcard_path;
- gchar separator;
- gchar wildcard[3];
g_return_val_if_fail(item != NULL, -1);
g_return_val_if_fail(item->folder != NULL, -1);
g_return_val_if_fail(item->no_sub == FALSE, -1);
folder = item->folder;
- imapfolder = IMAP_FOLDER(folder);
-
- separator = imap_get_path_separator(imapfolder, item->path);
- if (folder->ui_func)
- folder->ui_func(folder, item, folder->ui_func_data);
-
- if (item->path) {
- wildcard[0] = separator;
- wildcard[1] = '%';
- wildcard[2] = '\0';
- real_path = imap_get_real_path(imapfolder, item->path);
- } else {
- wildcard[0] = '%';
- wildcard[1] = '\0';
- real_path = g_strdup("");
- }
-
- Xstrcat_a(wildcard_path, real_path, wildcard,
- {g_free(real_path); return IMAP_ERROR;});
- QUOTE_IF_REQUIRED(wildcard_path, wildcard_path);
-
- imap_cmd_gen_send(session, "LIST \"\" %s", wildcard_path);
-
- strtailchomp(real_path, separator);
- item_list = imap_parse_list(session, real_path, NULL);
- g_free(real_path);
+ part_list = imap_get_part_folder_list(item_list, item);
node = item->node->children;
while (node != NULL) {
@@ -1815,7 +1798,7 @@ static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item)
new_item = NULL;
- for (cur = item_list; cur != NULL; cur = cur->next) {
+ for (cur = part_list; cur != NULL; cur = cur->next) {
FolderItem *cur_item = FOLDER_ITEM(cur->data);
if (!strcmp2(old_item->path, cur_item->path)) {
new_item = cur_item;
@@ -1848,7 +1831,7 @@ static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item)
node = next;
}
- for (cur = item_list; cur != NULL; cur = cur->next) {
+ for (cur = part_list; cur != NULL; cur = cur->next) {
FolderItem *cur_item = FOLDER_ITEM(cur->data);
new_item = NULL;
for (node = item->node->children; node != NULL;
@@ -1856,13 +1839,12 @@ static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item)
if (!strcmp2(FOLDER_ITEM(node->data)->path,
cur_item->path)) {
new_item = FOLDER_ITEM(node->data);
- folder_item_destroy(cur_item);
cur_item = NULL;
break;
}
}
if (!new_item) {
- new_item = cur_item;
+ new_item = folder_item_copy(cur_item);
debug_print("new folder '%s' found.\n", new_item->path);
folder_item_append(item, new_item);
}
@@ -1899,14 +1881,50 @@ static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item)
imap_scan_folder(folder, new_item);
#endif
if (new_item->no_sub == FALSE)
- imap_scan_tree_recursive(session, new_item);
+ imap_scan_tree_recursive(session, new_item, item_list);
}
- g_slist_free(item_list);
+ g_slist_free(part_list);
return IMAP_SUCCESS;
}
+static GSList *imap_get_folder_list(IMAPSession *session, FolderItem *item)
+{
+ Folder *folder;
+ IMAPFolder *imapfolder;
+ gchar *real_path;
+ gchar *wildcard_path;
+ gchar separator;
+ gchar wildcard[3];
+ GSList *item_list;
+
+ folder = item->folder;
+ imapfolder = IMAP_FOLDER(folder);
+
+ separator = imap_get_path_separator(imapfolder, item->path);
+
+ if (folder->ui_func)
+ folder->ui_func(folder, item, folder->ui_func_data);
+
+ if (item->path) {
+ real_path = imap_get_real_path(imapfolder, item->path);
+ strtailchomp(real_path, separator);
+ wildcard_path = g_strdup_printf("%s%c*", real_path, separator);
+ } else {
+ real_path = g_strdup("");
+ wildcard_path = g_strdup("*");
+ }
+
+ imap_cmd_gen_send(session, "LIST \"\" \"%s\"", wildcard_path);
+
+ item_list = imap_parse_list(session, real_path, NULL);
+ g_free(real_path);
+ g_free(wildcard_path);
+
+ return item_list;
+}
+
static GSList *imap_parse_list(IMAPSession *session, const gchar *real_path,
gchar *separator)
{
@@ -1984,7 +2002,7 @@ static GSList *imap_parse_list(IMAPSession *session, const gchar *real_path,
strcasestr(flags, "\\Noselect") != NULL)
new_item->no_select = TRUE;
- item_list = g_slist_append(item_list, new_item);
+ item_list = g_slist_prepend(item_list, new_item);
debug_print("folder '%s' found.\n", loc_path);
g_free(loc_path);
@@ -1993,9 +2011,50 @@ static GSList *imap_parse_list(IMAPSession *session, const gchar *real_path,
g_string_free(str, TRUE);
+ item_list = g_slist_reverse(item_list);
return item_list;
}
+static GSList *imap_get_part_folder_list(GSList *item_list, FolderItem *item)
+{
+ FolderItem *cur_item;
+ GSList *part_list = NULL, *cur;
+ gint len;
+
+ if (!item->path) {
+ debug_print("imap_get_part_folder_list(): get root folders\n");
+ for (cur = item_list; cur != NULL; cur = cur->next) {
+ cur_item = FOLDER_ITEM(cur->data);
+
+ if (!strchr(cur_item->path, '/')) {
+ part_list = g_slist_prepend(part_list,
+ cur_item);
+ debug_print("append '%s'\n", cur_item->path);
+ }
+ }
+ part_list = g_slist_reverse(part_list);
+ return part_list;
+ }
+
+ len = strlen(item->path);
+ debug_print("imap_get_part_folder_list(): get folders under '%s'\n",
+ item->path);
+
+ for (cur = item_list; cur != NULL; cur = cur->next) {
+ cur_item = FOLDER_ITEM(cur->data);
+
+ if (!strncmp(cur_item->path, item->path, len) &&
+ cur_item->path[len] == '/' &&
+ !strchr(cur_item->path + len + 1, '/')) {
+ part_list = g_slist_prepend(part_list, cur_item);
+ debug_print("append '%s'\n", cur_item->path);
+ }
+ }
+
+ part_list = g_slist_reverse(part_list);
+ return part_list;
+}
+
static gint imap_create_tree(Folder *folder)
{
g_return_val_if_fail(folder != NULL, -1);