From 9e2b5e4869ee123e4847097cf5549159c6d3e1cf Mon Sep 17 00:00:00 2001 From: Paul Mangan Date: Thu, 28 Jun 2001 08:44:31 +0000 Subject: [PATCH] more sync with sylpheed 0.5.0pre3 --- ChangeLog | 19 +++ ChangeLog.claws | 4 + ChangeLog.jp | 20 +++ src/folder.c | 10 ++ src/folder.h | 3 + src/folderview.c | 91 ++++++++++++-- src/folderview.h | 1 + src/imap.c | 308 ++++++++++++++++++++++++++++++++++++++--------- src/imap.h | 1 + 9 files changed, 390 insertions(+), 67 deletions(-) diff --git a/ChangeLog b/ChangeLog index 40c6dc004..1684212be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2001-06-28 + + * src/folderview.[ch]: + folderview_update_tree(): new. It updates one folder tree. + folderview_update_tree_cb(): new. + Added "Update folder tree" to the popup menu, and modified some + expressions. + +2001-06-27 + + * src/imap.c: implemented the autoscan of IMAP4 folder list. + imap_scan_tree(): new. It scans the whole IMAP4 folder. + imap_scan_tree_recursive(): new. It traverses the IMAP4 folder tree. + imap_parse_list(): new. It parses the LIST response. + imap_get_real_path(): new. It converts local path into IMAP4 path. + * src/folder.h: added no_sub and no_select to FolderItem. + * src/folder.c: folder_tree_destroy(): reset some variables. + * src/folderview.c: folderview_scan_tree_func(): supported IMAP4. + 2001-06-26 * src/imap.c: imap_parse_envelope(): fixed a bug that didn't diff --git a/ChangeLog.claws b/ChangeLog.claws index 9a3fbdc51..66b26517b 100644 --- a/ChangeLog.claws +++ b/ChangeLog.claws @@ -1,3 +1,7 @@ +2001-06-28 [paul] + + * more sync with sylpheed 0.5.0pre3 + 2001-06-27 [alfons] * src/summaryview.c diff --git a/ChangeLog.jp b/ChangeLog.jp index 9a9f81be6..b7f759644 100644 --- a/ChangeLog.jp +++ b/ChangeLog.jp @@ -1,3 +1,23 @@ +2001-06-28 + + * src/folderview.[ch]: + folderview_update_tree(): ¿·µ¬¡£°ì¤Ä¤Î¥Õ¥©¥ë¥À¥Ä¥ê¡¼¤ò¹¹¿·¤¹¤ë¡£ + folderview_update_tree_cb(): ¿·µ¬¡£ + ¡Ö¥Õ¥©¥ë¥À¥Ä¥ê¡¼¤ò¹¹¿·¡×¤ò¥Ý¥Ã¥×¥¢¥Ã¥×¥á¥Ë¥å¡¼¤ËÄɲä·¡¢É½¸½¤ò + ¤¤¤¯¤Ä¤«Êѹ¹¡£ + +2001-06-27 + + * src/imap.c: IMAP4 ¥Õ¥©¥ë¥À¥ê¥¹¥È¤Î¼«Æ°¥¹¥­¥ã¥ó¤ò¼ÂÁõ¡£ + imap_scan_tree(): ¿·µ¬¡£ IMAP4 ¥Õ¥©¥ë¥ÀÁ´ÂΤò¥¹¥­¥ã¥ó¤¹¤ë¡£ + imap_scan_tree_recursive(): ¿·µ¬¡£ IMAP4 ¥Õ¥©¥ë¥À¥Ä¥ê¡¼¤ò + ¥È¥é¥Ð¡¼¥¹¤¹¤ë¡£ + imap_parse_list(): ¿·µ¬¡£¥í¡¼¥«¥ë¥Ñ¥¹¤ò IMAP4 ¥Ñ¥¹¤ËÊÑ´¹¤¹¤ë¡£ + * src/folder.h: no_sub ¤È no_select ¤ò FolderItem ¤ËÄɲᣠ+ * src/folder.c: folder_tree_destroy(): ÊÑ¿ô¤ò¤¤¤¯¤Ä¤«¥ê¥»¥Ã¥È¤¹¤ë + ¤è¤¦¤Ë¤·¤¿¡£ + * src/folderview.c: folderview_scan_tree_func(): IMAP4 ¤ËÂбþ¡£ + 2001-06-26 * src/imap.c: imap_parse_envelope(): ¼¡¤Î¹Ô¤Ë³¤¯ FETCH ±þÅú¤ò diff --git a/src/folder.c b/src/folder.c index a8c609ad7..ab98e1f3f 100644 --- a/src/folder.c +++ b/src/folder.c @@ -151,6 +151,8 @@ FolderItem *folder_item_new(const gchar *name, const gchar *path) item->unread = 0; item->total = 0; item->last_num = -1; + item->no_sub = FALSE; + item->no_select = FALSE; item->parent = NULL; item->folder = NULL; item->data = NULL; @@ -247,6 +249,13 @@ void folder_tree_destroy(Folder *folder) { /* TODO: destroy all FolderItem before */ g_node_destroy(folder->node); + + folder->inbox = NULL; + folder->outbox = NULL; + folder->draft = NULL; + folder->queue = NULL; + folder->trash = NULL; + folder->node = NULL; } void folder_add(Folder *folder) @@ -932,6 +941,7 @@ static void folder_init(Folder *folder, FolderType type, const gchar *name) folder->remove_msg = imap_remove_msg; folder->remove_all_msg = imap_remove_all_msg; folder->scan = imap_scan_folder; + folder->scan_tree = imap_scan_tree; folder->create_tree = imap_create_tree; folder->create_folder = imap_create_folder; folder->remove_folder = imap_remove_folder; diff --git a/src/folder.h b/src/folder.h index 96bade32a..688b3ae10 100644 --- a/src/folder.h +++ b/src/folder.h @@ -211,6 +211,9 @@ struct _FolderItem gint last_num; + gboolean no_sub; + gboolean no_select; + FolderItem *parent; Folder *folder; diff --git a/src/folderview.c b/src/folderview.c index a56e80770..2bd3c55bf 100644 --- a/src/folderview.c +++ b/src/folderview.c @@ -147,6 +147,10 @@ static void folderview_col_resized (GtkCList *clist, gint width, FolderView *folderview); +static void folderview_update_tree_cb (FolderView *folderview, + guint action, + GtkWidget *widget); + static void folderview_new_folder_cb (FolderView *folderview, guint action, GtkWidget *widget); @@ -225,6 +229,7 @@ static GtkItemFactoryEntry folderview_mail_popup_entries[] = {N_("/_Rename folder..."), NULL, folderview_rename_folder_cb, 0, NULL}, {N_("/_Delete folder"), NULL, folderview_delete_folder_cb, 0, NULL}, {N_("/---"), NULL, NULL, 0, ""}, + {N_("/_Update folder tree"), NULL, folderview_update_tree_cb, 0, NULL}, {N_("/Remove _mailbox"), NULL, folderview_remove_mailbox_cb, 0, NULL}, {N_("/---"), NULL, NULL, 0, ""}, {N_("/_Property..."), NULL, NULL, 0, NULL}, @@ -237,7 +242,8 @@ static GtkItemFactoryEntry folderview_imap_popup_entries[] = {N_("/_Rename folder..."), NULL, NULL, 0, NULL}, {N_("/_Delete folder"), NULL, folderview_rm_imap_folder_cb, 0, NULL}, {N_("/---"), NULL, NULL, 0, ""}, - {N_("/Remove _IMAP4 server"), NULL, folderview_rm_imap_server_cb, 0, NULL}, + {N_("/_Update folder tree"), NULL, folderview_update_tree_cb, 0, NULL}, + {N_("/Remove _IMAP4 account"), NULL, folderview_rm_imap_server_cb, 0, NULL}, {N_("/---"), NULL, NULL, 0, ""}, {N_("/_Property..."), NULL, NULL, 0, NULL}, {N_("/_Scoring..."), NULL, folderview_scoring_cb, 0, NULL} @@ -249,7 +255,7 @@ static GtkItemFactoryEntry folderview_news_popup_entries[] = NULL, folderview_new_news_group_cb, 0, NULL}, {N_("/_Remove newsgroup"), NULL, folderview_rm_news_group_cb, 0, NULL}, {N_("/---"), NULL, NULL, 0, ""}, - {N_("/Remove _news server"), NULL, folderview_rm_news_server_cb, 0, NULL}, + {N_("/Remove _news account"), NULL, folderview_rm_news_server_cb, 0, NULL}, {N_("/---"), NULL, NULL, 0, ""}, {N_("/_Property..."), NULL, NULL, 0, NULL}, {N_("/_Scoring..."), NULL, folderview_scoring_cb, 0, NULL} @@ -567,6 +573,16 @@ static void folderview_scan_tree_func(Folder *folder, FolderItem *item, gpointer data) { GList *list; + gchar *rootpath; + + if (folder->type == F_MH || folder->type == F_MBOX || + folder->type == F_MAILDIR) + rootpath = LOCAL_FOLDER(folder)->rootpath; + else if (folder->type == F_IMAP && folder->account && + folder->account->recv_server) + rootpath = folder->account->recv_server; + else + return; for (list = folderview_list; list != NULL; list = list->next) { FolderView *folderview = (FolderView *)list->data; @@ -575,12 +591,11 @@ static void folderview_scan_tree_func(Folder *folder, FolderItem *item, if (item->path) str = g_strdup_printf(_("Scanning folder %s%c%s ..."), - LOCAL_FOLDER(folder)->rootpath, - G_DIR_SEPARATOR, + rootpath, G_DIR_SEPARATOR, item->path); else str = g_strdup_printf(_("Scanning folder %s ..."), - LOCAL_FOLDER(folder)->rootpath); + rootpath); STATUSBAR_PUSH(mainwin, str); STATUSBAR_POP(mainwin); @@ -611,6 +626,32 @@ static GtkWidget *label_window_create(const gchar *str) return window; } +void folderview_update_tree(Folder *folder) +{ + GList *list; + GtkWidget *window; + + g_return_if_fail(folder != NULL); + + if (!folder->scan_tree) return; + + window = label_window_create(_("Updating folder tree...")); + + folder_set_ui_func(folder, folderview_scan_tree_func, NULL); + folder->scan_tree(folder); + folder_set_ui_func(folder, NULL, NULL); + + folder_write_list(); + + for (list = folderview_list; list != NULL; list = list->next) { + FolderView *folderview = (FolderView *)list->data; + + folderview_set(folderview); + } + + gtk_widget_destroy(window); +} + void folderview_update_all(void) { GList *list; @@ -1134,6 +1175,8 @@ static void folderview_button_pressed(GtkWidget *ctree, GdkEventButton *event, if (folder->type == F_MH && item->parent == NULL) { menu_set_sensitive(folderview->mail_factory, "/Create new folder...", TRUE); + menu_set_sensitive(folderview->mail_factory, + "/Update folder tree", TRUE); menu_set_sensitive(folderview->mail_factory, "/Remove mailbox", TRUE); } else if (folder->type == F_MH && item->stype != F_NORMAL) { @@ -1154,7 +1197,9 @@ static void folderview_button_pressed(GtkWidget *ctree, GdkEventButton *event, menu_set_sensitive(folderview->imap_factory, "/Create new folder...", TRUE); menu_set_sensitive(folderview->imap_factory, - "/Remove IMAP4 server", TRUE); + "/Update folder tree", TRUE); + menu_set_sensitive(folderview->imap_factory, + "/Remove IMAP4 account", TRUE); } else if (folder->type == F_IMAP && item->stype != F_NORMAL) { menu_set_sensitive(folderview->imap_factory, "/Create new folder...", TRUE); @@ -1169,7 +1214,7 @@ static void folderview_button_pressed(GtkWidget *ctree, GdkEventButton *event, menu_set_sensitive(folderview->news_factory, "/Subscribe to newsgroup...", TRUE); menu_set_sensitive(folderview->news_factory, - "/Remove news server", TRUE); + "/Remove news account", TRUE); } else if (folder->type == F_NEWS) { menu_set_sensitive(folderview->news_factory, "/Subscribe to newsgroup...", TRUE); @@ -1377,6 +1422,23 @@ static GtkCTreeNode *folderview_find_by_name(GtkCTree *ctree, return NULL; } +static void folderview_update_tree_cb(FolderView *folderview, guint action, + GtkWidget *widget) +{ + GtkCTree *ctree = GTK_CTREE(folderview->ctree); + FolderItem *item; + + if (!folderview->selected) return; + + summary_show(folderview->summaryview, NULL, FALSE); + + item = gtk_ctree_node_get_row_data(ctree, folderview->selected); + g_return_if_fail(item != NULL); + g_return_if_fail(item->folder != NULL); + + folderview_update_tree(item->folder); +} + static void folderview_new_folder_cb(FolderView *folderview, guint action, GtkWidget *widget) { @@ -1718,8 +1780,13 @@ static void folderview_new_imap_folder_cb(FolderView *folderview, guint action, } new_item = item->folder->create_folder(item->folder, item, new_folder); + if (!new_item) { + alertpanel_error(_("Can't create the folder `%s'."), + new_folder); + g_free(new_folder); + return; + } g_free(new_folder); - if (!new_item) return; gtk_clist_freeze(GTK_CLIST(ctree)); @@ -1795,9 +1862,9 @@ static void folderview_rm_imap_server_cb(FolderView *folderview, guint action, g_return_if_fail(item->folder->type == F_IMAP); g_return_if_fail(item->folder->account != NULL); - message = g_strdup_printf(_("Really delete IMAP4 server `%s'?"), + message = g_strdup_printf(_("Really delete IMAP4 account `%s'?"), item->folder->name); - avalue = alertpanel(_("Delete IMAP4 server"), message, + avalue = alertpanel(_("Delete IMAP4 account"), message, _("Yes"), _("+No"), NULL); g_free(message); @@ -1926,9 +1993,9 @@ static void folderview_rm_news_server_cb(FolderView *folderview, guint action, g_return_if_fail(item->folder->type == F_NEWS); g_return_if_fail(item->folder->account != NULL); - message = g_strdup_printf(_("Really delete news server `%s'?"), + message = g_strdup_printf(_("Really delete news account `%s'?"), item->folder->name); - avalue = alertpanel(_("Delete news server"), message, + avalue = alertpanel(_("Delete news account"), message, _("Yes"), _("+No"), NULL); g_free(message); diff --git a/src/folderview.h b/src/folderview.h index 9b8140a9d..9db0ba4d6 100644 --- a/src/folderview.h +++ b/src/folderview.h @@ -70,6 +70,7 @@ void folderview_update_msg_num (FolderView *folderview, gint new, gint unread, gint total); +void folderview_update_tree (Folder *folder); void folderview_update_all (void); void folderview_update_item (FolderItem *item, diff --git a/src/imap.c b/src/imap.c index 42e5ae900..915b4af11 100644 --- a/src/imap.c +++ b/src/imap.c @@ -52,6 +52,12 @@ static IMAPSession *imap_session_get (Folder *folder); static gchar *imap_query_password (const gchar *server, const gchar *user); +static void imap_scan_tree_recursive (IMAPSession *session, + FolderItem *item, + IMAPNameSpace *namespace); +static GSList *imap_parse_list (IMAPSession *session, + const gchar *path); + static gint imap_do_copy (Folder *folder, FolderItem *dest, MsgInfo *msginfo, @@ -101,6 +107,8 @@ static void imap_parse_namespace (IMAPSession *session, IMAPFolder *folder); static IMAPNameSpace *imap_find_namespace (IMAPFolder *folder, const gchar *path); +static gchar *imap_get_real_path (IMAPFolder *folder, + const gchar *path); static gchar *imap_parse_atom (SockInfo *sock, gchar *src, @@ -453,11 +461,6 @@ gint imap_add_msg(Folder *folder, FolderItem *dest, const gchar *file, if (!session) return -1; - if (dest->last_num < 0) { - imap_scan_folder(folder, dest); - if (dest->last_num < 0) return -1; - } - ok = imap_cmd_append(SESSION(session)->sock, dest->path, file); if (ok != IMAP_SUCCESS) { g_warning(_("can't append message %s\n"), file); @@ -477,7 +480,6 @@ static gint imap_do_copy(Folder *folder, FolderItem *dest, MsgInfo *msginfo, { gchar *destdir; IMAPSession *session; - IMAPNameSpace *namespace; gint ok; g_return_val_if_fail(folder != NULL, -1); @@ -493,10 +495,7 @@ static gint imap_do_copy(Folder *folder, FolderItem *dest, MsgInfo *msginfo, return -1; } - Xstrdup_a(destdir, dest->path, return -1); - namespace = imap_find_namespace(IMAP_FOLDER(folder), destdir); - if (namespace && namespace->separator) - imap_path_separator_subst(destdir, namespace->separator); + destdir = imap_get_real_path(IMAP_FOLDER(folder), dest->path); if (remove_source) debug_print(_("Moving message %s%c%d to %s ...\n"), @@ -512,10 +511,12 @@ static gint imap_do_copy(Folder *folder, FolderItem *dest, MsgInfo *msginfo, if (ok == IMAP_SUCCESS && remove_source) { imap_set_message_flags(session, msginfo->msgnum, msginfo->msgnum, IMAP_FLAG_DELETED, TRUE); - imap_cmd_expunge(SESSION(session)->sock); + ok = imap_cmd_expunge(SESSION(session)->sock); } + g_free(destdir); statusbar_pop_all(); + return ok; } @@ -527,7 +528,6 @@ static gint imap_do_copy_msgs_with_dest(Folder *folder, FolderItem *dest, GSList *cur; MsgInfo *msginfo; IMAPSession *session; - IMAPNameSpace *namespace; gint ok; g_return_val_if_fail(folder != NULL, -1); @@ -537,10 +537,7 @@ static gint imap_do_copy_msgs_with_dest(Folder *folder, FolderItem *dest, session = imap_session_get(folder); if (!session) return -1; - Xstrdup_a(destdir, dest->path, return -1); - namespace = imap_find_namespace(IMAP_FOLDER(folder), destdir); - if (namespace && namespace->separator) - imap_path_separator_subst(destdir, namespace->separator); + destdir = imap_get_real_path(IMAP_FOLDER(folder), dest->path); for (cur = msglist; cur != NULL; cur = cur->next) { msginfo = (MsgInfo *)cur->data; @@ -570,9 +567,11 @@ static gint imap_do_copy_msgs_with_dest(Folder *folder, FolderItem *dest, } if (remove_source) - imap_cmd_expunge(SESSION(session)->sock); + ok = imap_cmd_expunge(SESSION(session)->sock); + g_free(destdir); statusbar_pop_all(); + return IMAP_SUCCESS; } @@ -681,16 +680,184 @@ void imap_scan_folder(Folder *folder, FolderItem *item) { } +void imap_scan_tree(Folder *folder) +{ + IMAPFolder *imapfolder = IMAP_FOLDER(folder); + FolderItem *item, *inbox; + IMAPSession *session; + IMAPNameSpace *namespace = NULL; + gchar *imap_dir = ""; + gchar *root_folder = NULL; + + g_return_if_fail(folder != NULL); + g_return_if_fail(folder->account != NULL); + + session = imap_session_get(folder); + if (!session) return; + + if (imapfolder->namespace && imapfolder->namespace->data) + namespace = (IMAPNameSpace *)imapfolder->namespace->data; + + if (folder->account->imap_dir && *folder->account->imap_dir) { + gchar *tmpdir; + Xstrdup_a(tmpdir, folder->account->imap_dir, return); + strtailchomp(tmpdir, '/'); + Xalloca(imap_dir, strlen(tmpdir) + 2, return); + root_folder = g_strconcat + (namespace && namespace->name ? namespace->name : "", + imap_dir, NULL); + if (namespace && namespace->separator) + subst_char(root_folder, namespace->separator, '/'); + } + + folder_tree_destroy(folder); + item = folder_item_new(folder->name, root_folder); + item->folder = folder; + folder->node = g_node_new(item); + g_free(root_folder); + + inbox = folder_item_new("INBOX", "INBOX"); + inbox->stype = F_INBOX; + folder_item_append(item, inbox); + folder->inbox = inbox; + + imap_scan_tree_recursive(session, item, namespace); +} + +static void imap_scan_tree_recursive(IMAPSession *session, + FolderItem *item, + IMAPNameSpace *namespace) +{ + IMAPFolder *imapfolder; + FolderItem *new_item; + GSList *item_list, *cur; + gchar *real_path; + + g_return_if_fail(item != NULL); + g_return_if_fail(item->folder != NULL); + g_return_if_fail(item->no_sub == FALSE); + + imapfolder = IMAP_FOLDER(item->folder); + + if (item->folder->ui_func) + item->folder->ui_func(item->folder, item, + item->folder->ui_func_data); + + if (item->path) { + real_path = imap_get_real_path(imapfolder, item->path); + imap_cmd_gen_send(SESSION(session)->sock, "LIST \"\" %s%c%%", + real_path, + namespace && namespace->separator + ? namespace->separator : '/'); + } else { + real_path = g_strdup(namespace && namespace->name + ? namespace->name : ""); + imap_cmd_gen_send(SESSION(session)->sock, "LIST \"\" %s%%", + real_path); + } + + strtailchomp(real_path, namespace && namespace->separator + ? namespace->separator : '/'); + + item_list = imap_parse_list(session, real_path); + for (cur = item_list; cur != NULL; cur = cur->next) { + new_item = cur->data; + folder_item_append(item, new_item); + if (new_item->no_sub == FALSE) + imap_scan_tree_recursive(session, new_item, namespace); + } +} + +static GSList *imap_parse_list(IMAPSession *session, const gchar *path) +{ + gchar buf[IMAPBUFSIZE]; + gchar flags[256]; + gchar separator[16]; + gchar *p; + gchar *name; + GSList *item_list = NULL; + GString *str; + FolderItem *new_item; + + debug_print("getting list of %s ...\n", *path ? path : "\"\""); + + str = g_string_new(NULL); + + for (;;) { + if (sock_gets(SESSION(session)->sock, buf, sizeof(buf)) <= 0) { + log_warning(_("error occured while getting LIST.\n")); + break; + } + strretchomp(buf); + if (buf[0] != '*' || buf[1] != ' ') { + log_print("IMAP4< %s\n", buf); + break; + } + debug_print("IMAP4< %s\n", buf); + + g_string_assign(str, buf); + p = str->str + 2; + if (strncmp(p, "LIST ", 5) != 0) continue; + p += 5; + + if (*p != '(') continue; + p++; + p = strchr_cpy(p, ')', flags, sizeof(flags)); + if (!p) continue; + while (*p == ' ') p++; + + p = strchr_cpy(p, ' ', separator, sizeof(separator)); + if (!p) continue; + extract_quote(separator, '"'); + if (!strcmp(separator, "NIL")) + separator[0] = '\0'; + + buf[0] = '\0'; + while (*p == ' ') p++; + if (*p == '{' || *p == '"') + p = imap_parse_atom(SESSION(session)->sock, p, + buf, sizeof(buf), str); + else + strncpy2(buf, p, sizeof(buf)); + strtailchomp(buf, separator[0]); + if (buf[0] == '\0') continue; + if (!strcmp(buf, path)) continue; + if (!strcmp(buf, "INBOX")) continue; + + if (separator[0] != '\0') + subst_char(buf, separator[0], '/'); + name = g_basename(buf); + if (name[0] == '.') continue; + + new_item = folder_item_new(name, buf); + if (strcasestr(flags, "\\Noinferiors") != NULL) + new_item->no_sub = TRUE; + if (strcasestr(flags, "\\Noselect") != NULL) + new_item->no_select = TRUE; + + item_list = g_slist_append(item_list, new_item); + + debug_print("folder %s has been added.\n", buf); + } + + g_string_free(str, TRUE); + statusbar_pop_all(); + + return item_list; +} + gint imap_create_tree(Folder *folder) { IMAPFolder *imapfolder = IMAP_FOLDER(folder); FolderItem *item; FolderItem *new_item; gchar *trash_path; + gchar *imap_dir = ""; g_return_val_if_fail(folder != NULL, -1); g_return_val_if_fail(folder->node != NULL, -1); g_return_val_if_fail(folder->node->data != NULL, -1); + g_return_val_if_fail(folder->account != NULL, -1); imap_session_get(folder); @@ -701,30 +868,42 @@ gint imap_create_tree(Folder *folder) folder_item_append(item, new_item); folder->inbox = new_item; + if (folder->account->imap_dir && *folder->account->imap_dir) { + gchar *tmpdir; + + Xstrdup_a(tmpdir, folder->account->imap_dir, return -1); + strtailchomp(tmpdir, '/'); + Xalloca(imap_dir, strlen(tmpdir) + 2, return -1); + g_snprintf(imap_dir, strlen(tmpdir) + 2, "%s%c", tmpdir, '/'); + } + if (imapfolder->namespace && imapfolder->namespace->data) { - IMAPNameSpace *namespace; + IMAPNameSpace *namespace = + (IMAPNameSpace *)imapfolder->namespace->data; - namespace = (IMAPNameSpace *)imapfolder->namespace->data; - if (*namespace->name == '\0') - trash_path = g_strdup("trash"); - else { + if (*namespace->name != '\0') { gchar *name; Xstrdup_a(name, namespace->name, return -1); - strtailchomp(name, namespace->separator); - subst_char(name, namespace->separator, - G_DIR_SEPARATOR); - trash_path = g_strconcat(name, G_DIR_SEPARATOR_S, - "trash", NULL); - } + subst_char(name, namespace->separator, '/'); + trash_path = g_strconcat(name, imap_dir, "trash", NULL); + } else + trash_path = g_strconcat(imap_dir, "trash", NULL); } else - trash_path = g_strdup("trash"); + trash_path = g_strconcat(imap_dir, "trash", NULL); new_item = imap_create_folder(folder, item, trash_path); if (!new_item) { + gchar *path; + new_item = folder_item_new("Trash", trash_path); folder_item_append(item, new_item); + + path = folder_item_get_path(new_item); + if (!is_dir_exist(path)) + make_dir_hier(path); + g_free(path); } else { g_free(new_item->name); new_item->name = g_strdup("Trash"); @@ -744,9 +923,11 @@ FolderItem *imap_create_folder(Folder *folder, FolderItem *parent, IMAPNameSpace *namespace; FolderItem *new_item; gchar *new_name; + const gchar *p; gint ok; g_return_val_if_fail(folder != NULL, NULL); + g_return_val_if_fail(folder->account != NULL, NULL); g_return_val_if_fail(parent != NULL, NULL); g_return_val_if_fail(name != NULL, NULL); @@ -754,9 +935,16 @@ FolderItem *imap_create_folder(Folder *folder, FolderItem *parent, if (!session) return NULL; if (parent->path) - dirpath = g_strconcat(parent->path, G_DIR_SEPARATOR_S, name, - NULL); - else + dirpath = g_strconcat(parent->path, "/", name, NULL); + else if ((p = strchr(name, '/')) != NULL && *(p + 1) != '\0') + dirpath = g_strdup(name); + else if (folder->account->imap_dir && *folder->account->imap_dir) { + gchar *imap_dir; + + Xstrdup_a(imap_dir, folder->account->imap_dir, return NULL); + strtailchomp(imap_dir, '/'); + dirpath = g_strconcat(imap_dir, "/", name, NULL); + } else dirpath = g_strdup(name); Xstrdup_a(imappath, dirpath, {g_free(dirpath); return NULL;}); @@ -765,9 +953,9 @@ FolderItem *imap_create_folder(Folder *folder, FolderItem *parent, if (namespace && namespace->separator) { imap_path_separator_subst(imappath, namespace->separator); imap_path_separator_subst(new_name, namespace->separator); - strtailchomp(dirpath, '/'); strtailchomp(new_name, namespace->separator); } + strtailchomp(dirpath, '/'); if (strcmp(name, "INBOX") != 0) { GPtrArray *argbuf; @@ -810,6 +998,11 @@ FolderItem *imap_create_folder(Folder *folder, FolderItem *parent, folder_item_append(parent, new_item); g_free(dirpath); + dirpath = folder_item_get_path(new_item); + if (!is_dir_exist(dirpath)) + make_dir_hier(dirpath); + g_free(dirpath); + return new_item; } @@ -817,7 +1010,6 @@ gint imap_remove_folder(Folder *folder, FolderItem *item) { gint ok; IMAPSession *session; - IMAPNameSpace *namespace; gchar *path; g_return_val_if_fail(folder != NULL, -1); @@ -827,18 +1019,16 @@ gint imap_remove_folder(Folder *folder, FolderItem *item) session = imap_session_get(folder); if (!session) return -1; - Xstrdup_a(path, item->path, return -1); - namespace = imap_find_namespace(IMAP_FOLDER(folder), path); - if (namespace && namespace->separator) - imap_path_separator_subst(path, namespace->separator); - + path = imap_get_real_path(IMAP_FOLDER(folder), item->path); ok = imap_cmd_delete(SESSION(session)->sock, path); statusbar_pop_all(); if (ok != IMAP_SUCCESS) { log_warning(_("can't delete mailbox\n")); + g_free(path); return -1; } + g_free(path); folder_item_remove(item); return 0; @@ -1077,6 +1267,22 @@ static IMAPNameSpace *imap_find_namespace(IMAPFolder *folder, return namespace; } +static gchar *imap_get_real_path(IMAPFolder *folder, const gchar *path) +{ + gchar *real_path; + IMAPNameSpace *namespace; + + g_return_val_if_fail(folder != NULL, NULL); + g_return_val_if_fail(path != NULL, NULL); + + real_path = g_strdup(path); + namespace = imap_find_namespace(folder, path); + if (namespace && namespace->separator) + imap_path_separator_subst(real_path, namespace->separator); + + return real_path; +} + static gchar *imap_parse_atom(SockInfo *sock, gchar *src, gchar *dest, gint dest_len, GString *str) { @@ -1418,18 +1624,14 @@ static gint imap_select(IMAPSession *session, IMAPFolder *folder, guint32 *uid_validity) { gchar *real_path; - IMAPNameSpace *namespace; gint ok; - Xstrdup_a(real_path, path, return -1); - namespace = imap_find_namespace(folder, path); - if (namespace && namespace->separator) - imap_path_separator_subst(real_path, namespace->separator); - + real_path = imap_get_real_path(folder, path); ok = imap_cmd_select(SESSION(session)->sock, real_path, exists, recent, unseen, uid_validity); if (ok != IMAP_SUCCESS) log_warning(_("can't select folder: %s\n"), real_path); + g_free(real_path); return ok; } @@ -1473,19 +1675,15 @@ static gint imap_status_uidnext(IMAPSession *session, IMAPFolder *folder, const gchar *path, guint32 *uid_next) { gchar *real_path; - IMAPNameSpace *namespace; gint ok; - Xstrdup_a(real_path, path, return -1); - namespace = imap_find_namespace(folder, path); - if (namespace && namespace->separator) - imap_path_separator_subst(real_path, namespace->separator); - + real_path = imap_get_real_path(folder, path); ok = imap_cmd_status(SESSION(session)->sock, real_path, "UIDNEXT", uid_next); if (ok != IMAP_SUCCESS) log_warning(_("can't get the next uid of folder: %s\n"), real_path); + g_free(real_path); return ok; } @@ -1599,7 +1797,7 @@ static gint imap_cmd_select(SockInfo *sock, const gchar *folder, resp_str = search_array_contain_str(argbuf, "EXISTS"); if (resp_str) { if (sscanf(resp_str,"%d EXISTS", exists) != 1) { - g_warning("imap_select(): invalid EXISTS line.\n"); + g_warning("imap_cmd_select(): invalid EXISTS line.\n"); THROW; } } @@ -1607,7 +1805,7 @@ static gint imap_cmd_select(SockInfo *sock, const gchar *folder, resp_str = search_array_contain_str(argbuf, "RECENT"); if (resp_str) { if (sscanf(resp_str, "%d RECENT", recent) != 1) { - g_warning("imap_select(): invalid RECENT line.\n"); + g_warning("imap_cmd_select(): invalid RECENT line.\n"); THROW; } } @@ -1616,7 +1814,7 @@ static gint imap_cmd_select(SockInfo *sock, const gchar *folder, if (resp_str) { if (sscanf(resp_str, "OK [UIDVALIDITY %u] ", uid_validity) != 1) { - g_warning("imap_select(): invalid UIDVALIDITY line.\n"); + g_warning("imap_cmd_select(): invalid UIDVALIDITY line.\n"); THROW; } } @@ -1624,7 +1822,7 @@ static gint imap_cmd_select(SockInfo *sock, const gchar *folder, resp_str = search_array_contain_str(argbuf, "UNSEEN"); if (resp_str) { if (sscanf(resp_str, "OK [UNSEEN %d] ", unseen) != 1) { - g_warning("imap_select(): invalid UNSEEN line.\n"); + g_warning("imap_cmd_select(): invalid UNSEEN line.\n"); THROW; } } diff --git a/src/imap.h b/src/imap.h index cbce77de1..958ad8476 100644 --- a/src/imap.h +++ b/src/imap.h @@ -109,6 +109,7 @@ gint imap_remove_all_msg (Folder *folder, void imap_scan_folder (Folder *folder, FolderItem *item); +void imap_scan_tree (Folder *folder); gint imap_create_tree (Folder *folder); -- 2.25.1