0.8.8claws46
[claws.git] / src / imap.c
index b20f6cb4e9ade59cb33eef9a0f8ec0357f4e6063..5e8fd8344a218355604652a3ee80a528196f2d53 100644 (file)
@@ -43,7 +43,6 @@
 #include "procmsg.h"
 #include "procheader.h"
 #include "folder.h"
-#include "statusbar.h"
 #include "prefs_account.h"
 #include "codeconv.h"
 #include "utils.h"
@@ -51,7 +50,7 @@
 #include "log.h"
 
 #define IMAP4_PORT     143
-#if USE_SSL
+#if USE_OPENSSL
 #define IMAPS_PORT     993
 #endif
 
@@ -96,7 +95,8 @@ static gint imap_scan_tree_recursive  (IMAPSession    *session,
                                         FolderItem     *item);
 static GSList *imap_parse_list         (Folder         *folder,
                                         IMAPSession    *session,
-                                        const gchar    *real_path);
+                                        const gchar    *real_path,
+                                        gchar          *separator);
 
 static void imap_create_missing_folders        (Folder                 *folder);
 static FolderItem *imap_create_special_folder
@@ -123,7 +123,7 @@ static GSList *imap_delete_cached_messages  (GSList         *mlist,
                                                 guint32         last_uid);
 static void imap_delete_all_cached_messages    (FolderItem     *item);
 
-#if USE_SSL
+#if USE_OPENSSL
 static SockInfo *imap_open             (const gchar    *server,
                                         gushort         port,
                                         SSLType         ssl_type);
@@ -132,7 +132,7 @@ static SockInfo *imap_open          (const gchar    *server,
                                         gushort         port);
 #endif
 
-#if USE_SSL
+#if USE_OPENSSL
 static SockInfo *imap_open_tunnel(const gchar *server,
                                  const gchar *tunnelcmd,
                                  SSLType ssl_type);
@@ -141,7 +141,7 @@ static SockInfo *imap_open_tunnel(const gchar *server,
                                  const gchar *tunnelcmd);
 #endif
 
-#if USE_SSL
+#if USE_OPENSSL
 static SockInfo *imap_init_sock(SockInfo *sock, SSLType         ssl_type);
 #else
 static SockInfo *imap_init_sock(SockInfo *sock);
@@ -173,6 +173,8 @@ static gint imap_status                     (IMAPSession    *session,
 
 static void imap_parse_namespace               (IMAPSession    *session,
                                                 IMAPFolder     *folder);
+static void imap_get_namespace_by_list         (IMAPSession    *session,
+                                                IMAPFolder     *folder);
 static IMAPNameSpace *imap_find_namespace      (IMAPFolder     *folder,
                                                 const gchar    *path);
 static gchar imap_get_path_separator           (IMAPFolder     *folder,
@@ -350,8 +352,6 @@ static void imap_folder_init(Folder *folder, const gchar *name,
 
        folder->get_num_list          = imap_get_num_list;
        folder->get_msginfo           = imap_get_msginfo;
-       
-       ((IMAPFolder *)folder)->selected_folder = NULL;
 }
 
 static FolderItem *imap_folder_item_new(Folder *folder)
@@ -398,13 +398,14 @@ static void imap_reset_uid_lists(Folder *folder)
 static IMAPSession *imap_session_get(Folder *folder)
 {
        RemoteFolder *rfolder = REMOTE_FOLDER(folder);
+       Session *session = NULL;
        gushort port;
 
        g_return_val_if_fail(folder != NULL, NULL);
        g_return_val_if_fail(folder->type == F_IMAP, NULL);
        g_return_val_if_fail(folder->account != NULL, NULL);
 
-#if USE_SSL
+#if USE_OPENSSL
        port = folder->account->set_imapport ? folder->account->imapport
                : folder->account->ssl_imap == SSL_TUNNEL
                ? IMAPS_PORT : IMAP4_PORT;
@@ -413,21 +414,29 @@ static IMAPSession *imap_session_get(Folder *folder)
                : IMAP4_PORT;
 #endif
 
-       if (!rfolder->session) {
-               rfolder->session =
-                       imap_session_new(folder->account);
-               if (rfolder->session) {
-                       imap_parse_namespace(IMAP_SESSION(rfolder->session),
-                                            IMAP_FOLDER(folder));
-                       rfolder->session->last_access_time = time(NULL);
-                       g_free(((IMAPFolder *)folder)->selected_folder);
-                       ((IMAPFolder *)folder)->selected_folder = NULL;
-                       imap_reset_uid_lists(folder);
-               }
-               statusbar_pop_all();
-               return IMAP_SESSION(rfolder->session);
+       /* Make sure we have a session */
+       if (rfolder->session != NULL) {
+               session = rfolder->session;
+       } else {
+               imap_reset_uid_lists(folder);
+               session = imap_session_new(folder->account);
+       }
+       if(session == NULL)
+               return NULL;
+
+       /* Make sure session is authenticated */
+       if (!IMAP_SESSION(session)->authenticated)
+               imap_session_authenticate(IMAP_SESSION(session), folder->account);
+       if (!IMAP_SESSION(session)->authenticated) {
+               session_destroy(session);
+               rfolder->session = NULL;
+               return NULL;
        }
 
+       /* Make sure we have parsed the IMAP namespace */
+       imap_parse_namespace(IMAP_SESSION(session),
+                            IMAP_FOLDER(folder));
+
        /* I think the point of this code is to avoid sending a
         * keepalive if we've used the session recently and therefore
         * think it's still alive.  Unfortunately, most of the code
@@ -436,32 +445,36 @@ static IMAPSession *imap_session_get(Folder *folder)
         * A better solution than sending a NOOP every time would be
         * for every command to be prepared to retry until it is
         * successfully sent. -- mbp */
-       if (time(NULL) - rfolder->session->last_access_time < SESSION_TIMEOUT) {
-               rfolder->session->last_access_time = time(NULL);
-               statusbar_pop_all();
-               return IMAP_SESSION(rfolder->session);
-       }
-
-       if (imap_cmd_noop(rfolder->session->sock) != IMAP_SUCCESS) {
-               log_warning(_("IMAP4 connection to %s:%d has been"
-                             " disconnected. Reconnecting...\n"),
-                           folder->account->recv_server, port);
-               session_destroy(rfolder->session);
-               rfolder->session =
-                       imap_session_new(folder->account);
-               if (rfolder->session) {
-                       imap_parse_namespace(IMAP_SESSION(rfolder->session),
-                                            IMAP_FOLDER(folder));
-                       g_free(((IMAPFolder *)folder)->selected_folder);
-                       ((IMAPFolder *)folder)->selected_folder = NULL;
-                       imap_reset_uid_lists(folder);
+       if (time(NULL) - session->last_access_time > SESSION_TIMEOUT) {
+               /* verify that the session is still alive */
+               if (imap_cmd_noop(session->sock) != IMAP_SUCCESS) {
+                       /* Check if this is the first try to establish a
+                          connection, if yes we don't try to reconnect */
+                       if (rfolder->session == NULL) {
+                               log_warning(_("Connecting %s:%d failed"),
+                                           folder->account->recv_server, port);
+                               session_destroy(session);
+                               session = NULL;
+                       } else {
+                               log_warning(_("IMAP4 connection to %s:%d has been"
+                                             " disconnected. Reconnecting...\n"),
+                                           folder->account->recv_server, port);
+                               session_destroy(session);
+                               /* Clear folders session to make imap_session_get create
+                                  a new session, because of rfolder->session == NULL
+                                  it will not try to reconnect again and so avoid an
+                                  endless loop */
+                               rfolder->session = NULL;
+                               session = SESSION(imap_session_get(folder));
+                       }
                }
        }
 
-       if (rfolder->session)
-               rfolder->session->last_access_time = time(NULL);
-       statusbar_pop_all();
-       return IMAP_SESSION(rfolder->session);
+       rfolder->session = session;
+       if (session) {
+               session->last_access_time = time(NULL);
+       }
+       return IMAP_SESSION(session);
 }
 
 Session *imap_session_new(const PrefsAccount *account)
@@ -469,10 +482,9 @@ Session *imap_session_new(const PrefsAccount *account)
        IMAPSession *session;
        SockInfo *imap_sock;
        gushort port;
-       gchar *pass;
        gboolean is_preauth;
 
-#ifdef USE_SSL
+#ifdef USE_OPENSSL
        /* FIXME: IMAP over SSL only... */ 
        SSLType ssl_type;
 
@@ -486,7 +498,7 @@ Session *imap_session_new(const PrefsAccount *account)
 
        if (account->set_tunnelcmd) {
                log_message(_("creating tunneled IMAP4 connection\n"));
-#if USE_SSL
+#if USE_OPENSSL
                if ((imap_sock = imap_open_tunnel(account->recv_server, 
                                                  account->tunnelcmd,
                                                  ssl_type)) == NULL)
@@ -501,7 +513,7 @@ Session *imap_session_new(const PrefsAccount *account)
                log_message(_("creating IMAP4 connection to %s:%d ...\n"),
                            account->recv_server, port);
                
-#if USE_SSL
+#if USE_OPENSSL
                if ((imap_sock = imap_open(account->recv_server, port,
                                           ssl_type)) == NULL)
 #else
@@ -511,31 +523,14 @@ Session *imap_session_new(const PrefsAccount *account)
        }
 
        /* Only need to log in if the connection was not PREAUTH */
-       imap_greeting(imap_sock, &is_preauth);
+       if (imap_greeting(imap_sock, &is_preauth) != IMAP_SUCCESS) {
+               sock_close(imap_sock);
+               return NULL;
+       }
        log_message("IMAP connection is %s-authenticated\n",
                    (is_preauth) ? "pre" : "un");
-       if (!is_preauth) {
-               g_return_val_if_fail(account->userid != NULL, NULL);
-
-               pass = account->passwd;
-               if (!pass) {
-                       gchar *tmp_pass;
-                       tmp_pass = input_dialog_query_password(account->recv_server, account->userid);
-                       if (!tmp_pass)
-                               return NULL;
-                       Xstrdup_a(pass, tmp_pass, {g_free(tmp_pass); return NULL;});
-                       g_free(tmp_pass);
-               }
-
-               if (imap_cmd_login(imap_sock, account->userid, pass) != IMAP_SUCCESS) {
-                       imap_cmd_logout(imap_sock);
-                       sock_close(imap_sock);
-                       return NULL;
-               }
-       }
 
        session = g_new(IMAPSession, 1);
-
        SESSION(session)->type             = SESSION_IMAP;
        SESSION(session)->server           = g_strdup(account->recv_server);
        SESSION(session)->sock             = imap_sock;
@@ -547,12 +542,37 @@ Session *imap_session_new(const PrefsAccount *account)
        SESSION(session)->destroy          = imap_session_destroy;
 
        session->mbox = NULL;
+       session->authenticated = is_preauth;
 
        session_list = g_list_append(session_list, session);
 
        return SESSION(session);
 }
 
+void imap_session_authenticate(IMAPSession *session, const PrefsAccount *account)
+{
+       gchar *pass;
+
+       g_return_if_fail(account->userid != NULL);
+
+       pass = account->passwd;
+       if (!pass) {
+               gchar *tmp_pass;
+               tmp_pass = input_dialog_query_password(account->recv_server, account->userid);
+               if (!tmp_pass)
+                       return;
+               Xstrdup_a(pass, tmp_pass, {g_free(tmp_pass); return;});
+               g_free(tmp_pass);
+       }
+
+       if (imap_cmd_login(SESSION(session)->sock, account->userid, pass) != IMAP_SUCCESS) {
+               imap_cmd_logout(SESSION(session)->sock);
+               return;
+       }
+
+       session->authenticated = TRUE;
+}
+
 void imap_session_destroy(Session *session)
 {
        sock_close(session->sock);
@@ -594,7 +614,6 @@ GSList *imap_get_msg_list(Folder *folder, FolderItem *item, gboolean use_cache)
                mlist = procmsg_read_cache(item, FALSE);
                item->last_num = procmsg_get_last_num_in_msg_list(mlist);
                procmsg_set_flags(mlist, item);
-               statusbar_pop_all();
                return mlist;
        }
 
@@ -611,7 +630,6 @@ GSList *imap_get_msg_list(Folder *folder, FolderItem *item, gboolean use_cache)
                        last_uid = first_uid;
        } else {
                imap_delete_all_cached_messages(item);
-               statusbar_pop_all();
                return NULL;
        }
 
@@ -663,7 +681,6 @@ GSList *imap_get_msg_list(Folder *folder, FolderItem *item, gboolean use_cache)
        item->last_num = last_uid;
 
 catch:
-       statusbar_pop_all();
        return mlist;
 }
 
@@ -697,9 +714,8 @@ gchar *imap_fetch_msg(Folder *folder, FolderItem *item, gint uid)
 
        ok = imap_select(session, IMAP_FOLDER(folder), item->path,
                         NULL, NULL, NULL, NULL);
-       statusbar_pop_all();
        if (ok != IMAP_SUCCESS) {
-               g_warning(_("can't select mailbox %s\n"), item->path);
+               g_warning("can't select mailbox %s\n", item->path);
                g_free(filename);
                return NULL;
        }
@@ -707,10 +723,8 @@ gchar *imap_fetch_msg(Folder *folder, FolderItem *item, gint uid)
        debug_print("getting message %d...\n", uid);
        ok = imap_cmd_fetch(SESSION(session)->sock, (guint32)uid, filename);
 
-       statusbar_pop_all();
-
        if (ok != IMAP_SUCCESS) {
-               g_warning(_("can't fetch message %d\n"), uid);
+               g_warning("can't fetch message %d\n", uid);
                g_free(filename);
                return NULL;
        }
@@ -736,9 +750,8 @@ gint imap_add_msg(Folder *folder, FolderItem *dest, const gchar *file,
 
        ok = imap_status(session, IMAP_FOLDER(folder), dest->path,
                         &messages, &recent, &uid_next, &uid_validity, &unseen);
-       statusbar_pop_all();
        if (ok != IMAP_SUCCESS) {
-               g_warning(_("can't append message %s\n"), file);
+               g_warning("can't append message %s\n", file);
                return -1;
        }
 
@@ -747,7 +760,7 @@ gint imap_add_msg(Folder *folder, FolderItem *dest, const gchar *file,
        g_free(destdir);
 
        if (ok != IMAP_SUCCESS) {
-               g_warning(_("can't append message %s\n"), file);
+               g_warning("can't append message %s\n", file);
                return -1;
        }
 
@@ -764,7 +777,7 @@ static gint imap_do_copy(Folder *folder, FolderItem *dest, MsgInfo *msginfo,
 {
        gchar *destdir;
        IMAPSession *session;
-       gint messages, recent, unseen, exists;
+       gint messages, recent, unseen;
        guint32 uid_next, uid_validity;
        gint ok;
     
@@ -777,31 +790,26 @@ static gint imap_do_copy(Folder *folder, FolderItem *dest, MsgInfo *msginfo,
        if (!session) return -1;
 
        if (msginfo->folder == dest) {
-               g_warning(_("the src folder is identical to the dest.\n"));
+               g_warning("the src folder is identical to the dest.\n");
                return -1;
        }
 
        ok = imap_status(session, IMAP_FOLDER(folder), dest->path,
                         &messages, &recent, &uid_next, &uid_validity, &unseen);
-       statusbar_pop_all();
        if (ok != IMAP_SUCCESS) {
-               g_warning(_("can't copy message\n"));
+               g_warning("can't copy message\n");
                return -1;
        }
 
        destdir = imap_get_real_path(IMAP_FOLDER(folder), dest->path);
 
-    /* ensure source folder selected */
-    if (strcmp(((IMAPFolder *)folder)->selected_folder, 
-                    msginfo->folder->path) != 0) {
-           ok = imap_select(session, IMAP_FOLDER(folder), msginfo->folder->path,
-                            &exists, &recent, &unseen, &uid_validity);
-           statusbar_pop_all();
-           if (ok != IMAP_SUCCESS)
-                   return -1;
-    }
+       /* ensure source folder selected */
+       ok = imap_select(session, IMAP_FOLDER(folder), msginfo->folder->path,
+                        NULL, NULL, NULL, NULL);
+       if (ok != IMAP_SUCCESS)
+               return -1;
         
-    if (remove_source)
+       if (remove_source)
                debug_print("Moving message %s%c%d to %s ...\n",
                            msginfo->folder->path, G_DIR_SEPARATOR,
                            msginfo->msgnum, destdir);
@@ -819,7 +827,6 @@ static gint imap_do_copy(Folder *folder, FolderItem *dest, MsgInfo *msginfo,
        }
 
        g_free(destdir);
-       statusbar_pop_all();
 
        if (ok == IMAP_SUCCESS)
                return uid_next;
@@ -836,8 +843,6 @@ static gint imap_do_copy_msgs_with_dest(Folder *folder, FolderItem *dest,
        MsgInfo *msginfo;
        IMAPSession *session;
        gint ok = IMAP_SUCCESS;
-       gint exists, recent, unseen;
-       guint32 uid_validity;
 
        g_return_val_if_fail(folder != NULL, -1);
        g_return_val_if_fail(dest != NULL, -1);
@@ -852,20 +857,13 @@ static gint imap_do_copy_msgs_with_dest(Folder *folder, FolderItem *dest,
                msginfo = (MsgInfo *)cur->data;
 
                if (msginfo->folder == dest) {
-                       g_warning(_("the src folder is identical to the dest.\n"));
+                       g_warning("the src folder is identical to the dest.\n");
                        continue;
                }
 
-        /* ensure source folder selected */
-        if (strcmp(((IMAPFolder *)folder)->selected_folder, 
-                        msginfo->folder->path) != 0) {
-               ok = imap_select(session, IMAP_FOLDER(folder), 
-                    msginfo->folder->path, &exists, &recent, &unseen, 
-                    &uid_validity);
-               statusbar_pop_all();
-               if (ok != IMAP_SUCCESS)
-                       return -1;
-        }
+               /* ensure source folder selected */
+               ok = imap_select(session, IMAP_FOLDER(folder), 
+                                msginfo->folder->path, NULL, NULL, NULL, NULL);
         
                if (remove_source)
                        debug_print("Moving message %s%c%d to %s ...\n",
@@ -890,7 +888,6 @@ static gint imap_do_copy_msgs_with_dest(Folder *folder, FolderItem *dest,
                ok = imap_cmd_expunge(SESSION(session)->sock);
 
        g_free(destdir);
-       statusbar_pop_all();
 
        if (ok == IMAP_SUCCESS)
                return 0;
@@ -1000,8 +997,6 @@ gint imap_copy_msgs_with_dest(Folder *folder, FolderItem *dest,
 
 gint imap_remove_msg(Folder *folder, FolderItem *item, gint uid)
 {
-       gint exists, recent, unseen;
-       guint32 uid_validity;
        gint ok;
        IMAPSession *session;
        gchar *dir;
@@ -1014,22 +1009,19 @@ gint imap_remove_msg(Folder *folder, FolderItem *item, gint uid)
        if (!session) return -1;
 
        ok = imap_select(session, IMAP_FOLDER(folder), item->path,
-                        &exists, &recent, &unseen, &uid_validity);
-       statusbar_pop_all();
+                        NULL, NULL, NULL, NULL);
        if (ok != IMAP_SUCCESS)
                return ok;
 
        ok = imap_set_message_flags
                (IMAP_SESSION(REMOTE_FOLDER(folder)->session),
                 (guint32)uid, (guint32)uid, IMAP_FLAG_DELETED, TRUE);
-       statusbar_pop_all();
        if (ok != IMAP_SUCCESS) {
                log_warning(_("can't set deleted flags: %d\n"), uid);
                return ok;
        }
 
        ok = imap_cmd_expunge(SESSION(session)->sock);
-       statusbar_pop_all();
        if (ok != IMAP_SUCCESS) {
                log_warning(_("can't expunge\n"));
                return ok;
@@ -1045,8 +1037,6 @@ gint imap_remove_msg(Folder *folder, FolderItem *item, gint uid)
 
 gint imap_remove_msgs(Folder *folder, FolderItem *item, GSList *msglist)
 {
-       gint exists, recent, unseen;
-       guint32 uid_validity;
        gint ok;
        IMAPSession *session;
        gchar *dir;
@@ -1063,8 +1053,7 @@ gint imap_remove_msgs(Folder *folder, FolderItem *item, GSList *msglist)
        if (!session) return -1;
 
        ok = imap_select(session, IMAP_FOLDER(folder), item->path,
-                        &exists, &recent, &unseen, &uid_validity);
-       statusbar_pop_all();
+                        NULL, NULL, NULL, NULL);
        if (ok != IMAP_SUCCESS)
                return ok;
 
@@ -1074,7 +1063,6 @@ gint imap_remove_msgs(Folder *folder, FolderItem *item, GSList *msglist)
                ok = imap_set_message_flags
                        (IMAP_SESSION(REMOTE_FOLDER(folder)->session),
                         uid, uid, IMAP_FLAG_DELETED, TRUE);
-               statusbar_pop_all();
                if (ok != IMAP_SUCCESS) {
                        log_warning(_("can't set deleted flags: %d\n"), uid);
                        return ok;
@@ -1082,7 +1070,6 @@ gint imap_remove_msgs(Folder *folder, FolderItem *item, GSList *msglist)
        }
 
        ok = imap_cmd_expunge(SESSION(session)->sock);
-       statusbar_pop_all();
        if (ok != IMAP_SUCCESS) {
                log_warning(_("can't expunge\n"));
                return ok;
@@ -1103,8 +1090,8 @@ gint imap_remove_msgs(Folder *folder, FolderItem *item, GSList *msglist)
 
 gint imap_remove_all_msg(Folder *folder, FolderItem *item)
 {
-       gint exists, recent, unseen;
-       guint32 uid_validity;
+        gint exists, recent, unseen;
+        guint32 uid_validity;
        gint ok;
        IMAPSession *session;
        gchar *dir;
@@ -1117,7 +1104,6 @@ gint imap_remove_all_msg(Folder *folder, FolderItem *item)
 
        ok = imap_select(session, IMAP_FOLDER(folder), item->path,
                         &exists, &recent, &unseen, &uid_validity);
-       statusbar_pop_all();
        if (ok != IMAP_SUCCESS)
                return ok;
        if (exists == 0)
@@ -1126,14 +1112,12 @@ gint imap_remove_all_msg(Folder *folder, FolderItem *item)
        imap_cmd_gen_send(SESSION(session)->sock,
                          "STORE 1:%d +FLAGS (\\Deleted)", exists);
        ok = imap_cmd_ok(SESSION(session)->sock, NULL);
-       statusbar_pop_all();
        if (ok != IMAP_SUCCESS) {
                log_warning(_("can't set deleted flags: 1:%d\n"), exists);
                return ok;
        }
 
        ok = imap_cmd_expunge(SESSION(session)->sock);
-       statusbar_pop_all();
        if (ok != IMAP_SUCCESS) {
                log_warning(_("can't expunge\n"));
                return ok;
@@ -1168,7 +1152,6 @@ gint imap_scan_folder(Folder *folder, FolderItem *item)
 
        ok = imap_status(session, IMAP_FOLDER(folder), item->path,
                         &messages, &recent, &uid_next, &uid_validity, &unseen);
-       statusbar_pop_all();
        if (ok != IMAP_SUCCESS) return -1;
 
        item->new = unseen > 0 ? recent : 0;
@@ -1258,7 +1241,7 @@ static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item)
                          wildcard_path);
 
        strtailchomp(real_path, separator);
-       item_list = imap_parse_list(folder, session, real_path);
+       item_list = imap_parse_list(folder, session, real_path, NULL);
        g_free(real_path);
 
        for (cur = item_list; cur != NULL; cur = cur->next) {
@@ -1300,11 +1283,12 @@ static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item)
        return IMAP_SUCCESS;
 }
 
-static GSList *imap_parse_list(Folder *folder, IMAPSession *session, const gchar *real_path)
+static GSList *imap_parse_list(Folder *folder, IMAPSession *session,
+                              const gchar *real_path, gchar *separator)
 {
        gchar buf[IMAPBUFSIZE];
        gchar flags[256];
-       gchar separator[16];
+       gchar separator_str[16];
        gchar *p;
        gchar *name;
        gchar *loc_name, *loc_path;
@@ -1340,11 +1324,13 @@ static GSList *imap_parse_list(Folder *folder, IMAPSession *session, const gchar
                if (!p) continue;
                while (*p == ' ') p++;
 
-               p = strchr_cpy(p, ' ', separator, sizeof(separator));
+               p = strchr_cpy(p, ' ', separator_str, sizeof(separator_str));
                if (!p) continue;
-               extract_quote(separator, '"');
-               if (!strcmp(separator, "NIL"))
-                       separator[0] = '\0';
+               extract_quote(separator_str, '"');
+               if (!strcmp(separator_str, "NIL"))
+                       separator_str[0] = '\0';
+               if (separator)
+                       *separator = separator_str[0];
 
                buf[0] = '\0';
                while (*p == ' ') p++;
@@ -1353,12 +1339,12 @@ static GSList *imap_parse_list(Folder *folder, IMAPSession *session, const gchar
                                            buf, sizeof(buf), str);
                else
                        strncpy2(buf, p, sizeof(buf));
-               strtailchomp(buf, separator[0]);
+               strtailchomp(buf, separator_str[0]);
                if (buf[0] == '\0') continue;
                if (!strcmp(buf, real_path)) continue;
 
-               if (separator[0] != '\0')
-                       subst_char(buf, separator[0], '/');
+               if (separator_str[0] != '\0')
+                       subst_char(buf, separator_str[0], '/');
                name = g_basename(buf);
                if (name[0] == '.') continue;
 
@@ -1379,7 +1365,6 @@ static GSList *imap_parse_list(Folder *folder, IMAPSession *session, const gchar
        }
 
        g_string_free(str, TRUE);
-       statusbar_pop_all();
 
        return item_list;
 }
@@ -1437,12 +1422,12 @@ static FolderItem *imap_create_special_folder(Folder *folder,
        new_item = imap_create_folder(folder, item, name);
 
        if (!new_item) {
-               g_warning(_("Can't create '%s'\n"), name);
+               g_warning("Can't create '%s'\n", name);
                if (!folder->inbox) return NULL;
 
                new_item = imap_create_folder(folder, folder->inbox, name);
                if (!new_item)
-                       g_warning(_("Can't create '%s' under INBOX\n"), name);
+                       g_warning("Can't create '%s' under INBOX\n", name);
                else
                        new_item->stype = stype;
        } else
@@ -1503,7 +1488,6 @@ FolderItem *imap_create_folder(Folder *folder, FolderItem *parent,
                argbuf = g_ptr_array_new();
                ok = imap_cmd_list(SESSION(session)->sock, NULL, imap_path,
                                   argbuf);
-               statusbar_pop_all();
                if (ok != IMAP_SUCCESS) {
                        log_warning(_("can't create mailbox: LIST failed\n"));
                        g_free(imap_path);
@@ -1524,7 +1508,6 @@ FolderItem *imap_create_folder(Folder *folder, FolderItem *parent,
 
                if (!exist) {
                        ok = imap_cmd_create(SESSION(session)->sock, imap_path);
-                       statusbar_pop_all();
                        if (ok != IMAP_SUCCESS) {
                                log_warning(_("can't create mailbox\n"));
                                g_free(imap_path);
@@ -1577,7 +1560,6 @@ gint imap_rename_folder(Folder *folder, FolderItem *item, const gchar *name)
        session->mbox = NULL;
        ok = imap_cmd_examine(SESSION(session)->sock, "INBOX",
                              &exists, &recent, &unseen, &uid_validity);
-       statusbar_pop_all();
        if (ok != IMAP_SUCCESS) {
                g_free(real_oldpath);
                return -1;
@@ -1595,7 +1577,6 @@ gint imap_rename_folder(Folder *folder, FolderItem *item, const gchar *name)
        imap_path_separator_subst(real_newpath, separator);
 
        ok = imap_cmd_rename(SESSION(session)->sock, real_oldpath, real_newpath);
-       statusbar_pop_all();
        if (ok != IMAP_SUCCESS) {
                log_warning(_("can't rename mailbox: %s to %s\n"),
                            real_oldpath, real_newpath);
@@ -1654,14 +1635,12 @@ gint imap_remove_folder(Folder *folder, FolderItem *item)
 
        ok = imap_cmd_examine(SESSION(session)->sock, "INBOX",
                              &exists, &recent, &unseen, &uid_validity);
-       statusbar_pop_all();
        if (ok != IMAP_SUCCESS) {
                g_free(path);
                return -1;
        }
 
        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);
@@ -1805,7 +1784,7 @@ static void imap_delete_all_cached_messages(FolderItem *item)
        debug_print("done.\n");
 }
 
-#if USE_SSL
+#if USE_OPENSSL
 static SockInfo *imap_open_tunnel(const gchar *server,
                           const gchar *tunnelcmd,
                           SSLType ssl_type)
@@ -1820,7 +1799,7 @@ static SockInfo *imap_open_tunnel(const gchar *server,
                log_warning(_("Can't establish IMAP4 session with: %s\n"),
                            server);
                return NULL;
-#if USE_SSL
+#if USE_OPENSSL
        return imap_init_sock(sock, ssl_type);
 #else
        return imap_init_sock(sock);
@@ -1828,7 +1807,7 @@ static SockInfo *imap_open_tunnel(const gchar *server,
 }
 
 
-#if USE_SSL
+#if USE_OPENSSL
 static SockInfo *imap_open(const gchar *server, gushort port,
                           SSLType ssl_type)
 #else
@@ -1843,7 +1822,7 @@ static SockInfo *imap_open(const gchar *server, gushort port)
                return NULL;
        }
 
-#if USE_SSL
+#if USE_OPENSSL
        if (ssl_type == SSL_TUNNEL && !ssl_init_socket(sock)) {
                log_warning(_("Can't establish IMAP4 session with: %s:%d\n"),
                            server, port);
@@ -1856,14 +1835,14 @@ static SockInfo *imap_open(const gchar *server, gushort port)
 #endif
 }
 
-#if USE_SSL
+#if USE_OPENSSL
 static SockInfo *imap_init_sock(SockInfo *sock, SSLType ssl_type)
 #else
 static SockInfo *imap_init_sock(SockInfo *sock)
 #endif
 {
        imap_cmd_count = 0;
-#if USE_SSL
+#if USE_OPENSSL
        if (ssl_type == SSL_STARTTLS) {
                gint ok;
 
@@ -1956,6 +1935,7 @@ static void imap_parse_namespace(IMAPSession *session, IMAPFolder *folder)
        if (imap_cmd_namespace(SESSION(session)->sock, &ns_str)
            != IMAP_SUCCESS) {
                log_warning(_("can't get namespace\n"));
+               imap_get_namespace_by_list(session, folder);
                return;
        }
 
@@ -1970,6 +1950,32 @@ static void imap_parse_namespace(IMAPSession *session, IMAPFolder *folder)
        g_free(ns_str);
 }
 
+static void imap_get_namespace_by_list(IMAPSession *session, IMAPFolder *folder)
+{
+       GSList *item_list, *cur;
+       gchar separator = '\0';
+       IMAPNameSpace *namespace;
+
+       g_return_if_fail(session != NULL);
+       g_return_if_fail(folder != NULL);
+
+       if (folder->ns_personal != NULL ||
+           folder->ns_others   != NULL ||
+           folder->ns_shared   != NULL)
+               return;
+
+       imap_cmd_gen_send(SESSION(session)->sock, "LIST \"\" \"\"");
+       item_list = imap_parse_list(NULL, session, "", &separator);
+       for (cur = item_list; cur != NULL; cur = cur->next)
+               folder_item_destroy(FOLDER_ITEM(cur->data));
+       g_slist_free(item_list);
+
+       namespace = g_new(IMAPNameSpace, 1);
+       namespace->name = g_strdup("");
+       namespace->separator = separator;
+       folder->ns_personal = g_list_append(NULL, namespace);
+}
+
 static IMAPNameSpace *imap_find_namespace_from_list(GList *ns_list,
                                                    const gchar *path)
 {
@@ -2390,9 +2396,6 @@ static gint imap_select(IMAPSession *session, IMAPFolder *folder,
                session->mbox = g_strdup(path);
        g_free(real_path);
 
-       g_free(folder->selected_folder);
-       folder->selected_folder = g_strdup(path);
-       
        return ok;
 }
 
@@ -3048,7 +3051,7 @@ static gchar *imap_modified_utf7_to_locale(const gchar *mutf7_str)
        if (cd == (iconv_t)-1) {
                cd = iconv_open(conv_get_current_charset_str(), "UTF-7");
                if (cd == (iconv_t)-1) {
-                       g_warning(_("iconv cannot convert UTF-7 to %s\n"),
+                       g_warning("iconv cannot convert UTF-7 to %s\n",
                                  conv_get_current_charset_str());
                        iconv_ok = FALSE;
                        return g_strdup(mutf7_str);
@@ -3085,7 +3088,7 @@ static gchar *imap_modified_utf7_to_locale(const gchar *mutf7_str)
        to_p = to_str = g_malloc(to_len + 1);
 
        if (iconv(cd, &norm_utf7_p, &norm_utf7_len, &to_p, &to_len) == -1) {
-               g_warning(_("iconv cannot convert UTF-7 to %s\n"),
+               g_warning("iconv cannot convert UTF-7 to %s\n",
                          conv_get_current_charset_str());
                g_string_free(norm_utf7, TRUE);
                g_free(to_str);
@@ -3119,7 +3122,7 @@ static gchar *imap_locale_to_modified_utf7(const gchar *from)
        if (cd == (iconv_t)-1) {
                cd = iconv_open("UTF-7", conv_get_current_charset_str());
                if (cd == (iconv_t)-1) {
-                       g_warning(_("iconv cannot convert %s to UTF-7\n"),
+                       g_warning("iconv cannot convert %s to UTF-7\n",
                                  conv_get_current_charset_str());
                        iconv_ok = FALSE;
                        return g_strdup(from);
@@ -3152,7 +3155,7 @@ static gchar *imap_locale_to_modified_utf7(const gchar *from)
                        from_len -= mblen;
                        if (iconv(cd, &from_tmp, &mblen,
                                  &norm_utf7_p, &norm_utf7_len) == -1) {
-                               g_warning(_("iconv cannot convert %s to UTF-7\n"),
+                               g_warning("iconv cannot convert %s to UTF-7\n",
                                          conv_get_current_charset_str());
                                return g_strdup(from);
                        }
@@ -3230,13 +3233,11 @@ gint imap_get_num_list(Folder *folder, FolderItem *_item, GSList **msgnum_list)
 {
        IMAPFolderItem *item = (IMAPFolderItem *)_item;
        IMAPSession *session;
-       gint i, lastuid_old, nummsgs = 0;
-       gint ok, exists = 0, recent = 0, unseen = 0;
-       guint32 uid_validity = 0;
+       gint ok, i, lastuid_old, nummsgs = 0;
        GPtrArray *argbuf;
        gchar *cmdbuf = NULL;
        gchar *dir;
-       
+
        g_return_val_if_fail(folder != NULL, -1);
        g_return_val_if_fail(item != NULL, -1);
        g_return_val_if_fail(item->item.path != NULL, -1);
@@ -3247,7 +3248,7 @@ gint imap_get_num_list(Folder *folder, FolderItem *_item, GSList **msgnum_list)
        g_return_val_if_fail(session != NULL, -1);
 
        ok = imap_select(session, IMAP_FOLDER(folder), item->item.path,
-                        &exists, &recent, &unseen, &uid_validity);
+                        NULL, NULL, NULL, NULL);
        if (ok != IMAP_SUCCESS)
                return -1;