more sync with sylpheed 0.5.0pre3
authorPaul Mangan <paul@claws-mail.org>
Thu, 28 Jun 2001 08:44:31 +0000 (08:44 +0000)
committerPaul Mangan <paul@claws-mail.org>
Thu, 28 Jun 2001 08:44:31 +0000 (08:44 +0000)
ChangeLog
ChangeLog.claws
ChangeLog.jp
src/folder.c
src/folder.h
src/folderview.c
src/folderview.h
src/imap.c
src/imap.h

index 40c6dc0..1684212 100644 (file)
--- 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
index 9a3fbdc..66b2651 100644 (file)
@@ -1,3 +1,7 @@
+2001-06-28 [paul]
+
+       * more sync with sylpheed 0.5.0pre3
+
 2001-06-27 [alfons]
 
        * src/summaryview.c
index 9a9f81b..b7f7596 100644 (file)
@@ -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 ±þÅú¤ò
index a8c609a..ab98e1f 100644 (file)
@@ -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;
index 96bade3..688b3ae 100644 (file)
@@ -211,6 +211,9 @@ struct _FolderItem
 
        gint last_num;
 
+       gboolean no_sub;
+       gboolean no_select;
+
        FolderItem *parent;
 
        Folder *folder;
index a56e807..2bd3c55 100644 (file)
@@ -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, "<Separator>"},
+       {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, "<Separator>"},
        {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, "<Separator>"},
-       {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, "<Separator>"},
        {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, "<Separator>"},
-       {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, "<Separator>"},
        {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);
 
index 9b8140a..9db0ba4 100644 (file)
@@ -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,
index 42e5ae9..915b4af 100644 (file)
@@ -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;
                }
        }
index cbce77d..958ad84 100644 (file)
@@ -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);