0.9.3claws10
[claws.git] / src / imap.c
index 412abb1b2a9f78c6772d6acacbda713670a12a90..fd890dd7736dcf14f78c283f18d9c6a7c1770167 100644 (file)
@@ -49,6 +49,8 @@
 #include "procheader.h"
 #include "prefs_account.h"
 #include "codeconv.h"
+#include "md5.h"
+#include "base64.h"
 #include "utils.h"
 #include "inputdialog.h"
 #include "log.h"
@@ -101,6 +103,7 @@ struct _IMAPNameSpace
 #define IMAP_ERROR     7
 
 #define IMAPBUFSIZE    8192
+#define IMAPCMDLIMIT   1000
 
 typedef enum
 {
@@ -193,9 +196,14 @@ static void imap_folder_item_destroy       (Folder         *folder,
 
 static IMAPSession *imap_session_get   (Folder         *folder);
 
+static gint imap_auth                  (IMAPSession    *session,
+                                        const gchar    *user,
+                                        const gchar    *pass,
+                                        IMAPAuthType    type);
+
 static gint imap_scan_tree_recursive   (IMAPSession    *session,
                                         FolderItem     *item);
-static GSList *imap_parse_list         (Folder         *folder,
+static GSList *imap_parse_list         (IMAPFolder     *folder,
                                         IMAPSession    *session,
                                         const gchar    *real_path,
                                         gchar          *separator);
@@ -281,9 +289,15 @@ static gint imap_greeting          (IMAPSession    *session);
 static gboolean imap_has_capability    (IMAPSession    *session,
                                         const gchar    *cap);
 void imap_free_capabilities            (IMAPSession    *session);
-static const IMAPSet numberlist_to_imapset(MsgNumberList *list);
+static const IMAPSet numberlist_to_imapset
+                                       (MsgNumberList *list);
 
 /* low-level IMAP4rev1 commands */
+static gint imap_cmd_authenticate
+                               (IMAPSession    *session,
+                                const gchar    *user,
+                                const gchar    *pass,
+                                IMAPAuthType    type);
 static gint imap_cmd_login     (IMAPSession    *sock,
                                 const gchar    *user,
                                 const gchar    *pass);
@@ -383,6 +397,9 @@ static void imap_change_flags                       (Folder         *folder,
                                                 FolderItem     *item,
                                                 MsgInfo        *msginfo,
                                                 MsgPermFlags   newflags);
+static gchar *imap_folder_get_path             (Folder         *folder);
+static gchar *imap_item_get_path               (Folder         *folder,
+                                                FolderItem     *item);
 
 FolderClass imap_class =
 {
@@ -399,6 +416,7 @@ FolderClass imap_class =
        /* FolderItem functions */
        imap_folder_item_new,
        imap_folder_item_destroy,
+       imap_item_get_path,
        imap_create_folder,
        imap_rename_folder,
        imap_remove_folder,
@@ -440,7 +458,7 @@ void imap_folder_destroy(Folder *folder)
 {
        gchar *dir;
 
-       dir = folder_get_path(folder);
+       dir = imap_folder_get_path(folder);
        if (is_dir_exist(dir))
                remove_dir_recursive(dir);
        g_free(dir);
@@ -497,25 +515,24 @@ static void imap_reset_uid_lists(Folder *folder)
        g_node_traverse(folder->node, G_IN_ORDER, G_TRAVERSE_ALL, -1, imap_reset_uid_lists_func, NULL); 
 }
 
+static gint imap_auth(IMAPSession *session, const gchar *user, const gchar *pass,
+                     IMAPAuthType type)
+{
+       if (type == 0 || type == IMAP_AUTH_LOGIN)
+               return imap_cmd_login(session, user, pass);
+       else
+               return imap_cmd_authenticate(session, user, pass, type);
+}
+
 static IMAPSession *imap_session_get(Folder *folder)
 {
        RemoteFolder *rfolder = REMOTE_FOLDER(folder);
        IMAPSession *session = NULL;
-       gushort port;
 
        g_return_val_if_fail(folder != NULL, NULL);
        g_return_val_if_fail(FOLDER_CLASS(folder) == &imap_class, NULL);
        g_return_val_if_fail(folder->account != NULL, NULL);
 
-#if USE_OPENSSL
-       port = folder->account->set_imapport ? folder->account->imapport
-               : folder->account->ssl_imap == SSL_TUNNEL
-               ? IMAPS_PORT : IMAP4_PORT;
-#else
-       port = folder->account->set_imapport ? folder->account->imapport
-               : IMAP4_PORT;
-#endif
-
        /* Make sure we have a session */
        if (rfolder->session != NULL) {
                session = IMAP_SESSION(rfolder->session);
@@ -560,14 +577,14 @@ static IMAPSession *imap_session_get(Folder *folder)
                        /* 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);
+                               log_warning(_("Connecting %s failed"),
+                                           folder->account->recv_server);
                                session_destroy(SESSION(session));
                                session = NULL;
                        } else {
-                               log_warning(_("IMAP4 connection to %s:%d has been"
+                               log_warning(_("IMAP4 connection to %s has been"
                                              " disconnected. Reconnecting...\n"),
-                                           folder->account->recv_server, port);
+                                           folder->account->recv_server);
                                session_destroy(SESSION(session));
                                /* Clear folders session to make imap_session_get create
                                   a new session, because of rfolder->session == NULL
@@ -591,7 +608,6 @@ IMAPSession *imap_session_new(const PrefsAccount *account)
        IMAPSession *session;
        SockInfo *imap_sock;
        gushort port;
-       gboolean is_preauth;
 
 #ifdef USE_OPENSSL
        /* FIXME: IMAP over SSL only... */ 
@@ -642,7 +658,7 @@ IMAPSession *imap_session_new(const PrefsAccount *account)
        session->capability = NULL;
 
        session->mbox = NULL;
-       session->authenticated = is_preauth;
+       session->authenticated = FALSE;
        session->cmd_count = 0;
 
        /* Only need to log in if the connection was not PREAUTH */
@@ -667,7 +683,7 @@ IMAPSession *imap_session_new(const PrefsAccount *account)
                }
 
                imap_free_capabilities(session);
-               session->authenticated = is_preauth;
+               session->authenticated = FALSE;
                session->cmd_count = 1;
 
                if (imap_greeting(session) != IMAP_SUCCESS) {
@@ -677,7 +693,7 @@ IMAPSession *imap_session_new(const PrefsAccount *account)
        }
 #endif
        log_message("IMAP connection is %s-authenticated\n",
-                   (is_preauth) ? "pre" : "un");
+                   (session->authenticated) ? "pre" : "un");
 
        return session;
 }
@@ -698,7 +714,7 @@ void imap_session_authenticate(IMAPSession *session, const PrefsAccount *account
                g_free(tmp_pass);
        }
 
-       if (imap_cmd_login(session, account->userid, pass) != IMAP_SUCCESS) {
+       if (imap_auth(session, account->userid, pass, account->imap_auth_type) != IMAP_SUCCESS) {
                imap_cmd_logout(session);
                return;
        }
@@ -1045,7 +1061,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, NULL);
+       item_list = imap_parse_list(imapfolder, session, real_path, NULL);
        g_free(real_path);
 
        for (cur = item_list; cur != NULL; cur = cur->next) {
@@ -1085,7 +1101,7 @@ static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item)
        return IMAP_SUCCESS;
 }
 
-static GSList *imap_parse_list(Folder *folder, IMAPSession *session,
+static GSList *imap_parse_list(IMAPFolder *folder, IMAPSession *session,
                               const gchar *real_path, gchar *separator)
 {
        gchar buf[IMAPBUFSIZE];
@@ -1152,7 +1168,7 @@ static GSList *imap_parse_list(Folder *folder, IMAPSession *session,
 
                loc_name = imap_modified_utf7_to_locale(name);
                loc_path = imap_modified_utf7_to_locale(buf);
-               new_item = folder_item_new(folder, loc_name, loc_path);
+               new_item = folder_item_new(FOLDER(folder), loc_name, loc_path);
                if (strcasestr(flags, "\\Noinferiors") != NULL)
                        new_item->no_sub = TRUE;
                if (strcmp(buf, "INBOX") != 0 &&
@@ -1238,6 +1254,52 @@ static FolderItem *imap_create_special_folder(Folder *folder,
        return new_item;
 }
 
+static gchar *imap_folder_get_path(Folder *folder)
+{
+       gchar *folder_path;
+
+       g_return_val_if_fail(folder != NULL, NULL);
+        g_return_val_if_fail(folder->account != NULL, NULL);
+
+        folder_path = g_strconcat(get_imap_cache_dir(),
+                                  G_DIR_SEPARATOR_S,
+                                  folder->account->recv_server,
+                                  G_DIR_SEPARATOR_S,
+                                  folder->account->userid,
+                                  NULL);
+
+       return folder_path;
+}
+
+static gchar *imap_item_get_path(Folder *folder, FolderItem *item)
+{
+       gchar *folder_path, *path;
+
+       g_return_val_if_fail(folder != NULL, NULL);
+       g_return_val_if_fail(item != NULL, NULL);
+       folder_path = imap_folder_get_path(folder);
+
+       g_return_val_if_fail(folder_path != NULL, NULL);
+        if (folder_path[0] == G_DIR_SEPARATOR) {
+                if (item->path)
+                        path = g_strconcat(folder_path, G_DIR_SEPARATOR_S,
+                                           item->path, NULL);
+                else
+                        path = g_strdup(folder_path);
+        } else {
+                if (item->path)
+                        path = g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S,
+                                           folder_path, G_DIR_SEPARATOR_S,
+                                           item->path, NULL);
+                else
+                        path = g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S,
+                                           folder_path, NULL);
+        }
+        g_free(folder_path);
+
+       return path;
+}
+
 FolderItem *imap_create_folder(Folder *folder, FolderItem *parent,
                               const gchar *name)
 {
@@ -1470,64 +1532,69 @@ static GSList *imap_get_uncached_messages(IMAPSession *session,
        GSList *llast = NULL;
        GString *str;
        MsgInfo *msginfo;
+       IMAPSet imapset;
 
        g_return_val_if_fail(session != NULL, NULL);
        g_return_val_if_fail(item != NULL, NULL);
        g_return_val_if_fail(item->folder != NULL, NULL);
        g_return_val_if_fail(FOLDER_CLASS(item->folder) == &imap_class, NULL);
 
-       if (imap_cmd_envelope(session, numberlist_to_imapset(numlist))
-           != IMAP_SUCCESS) {
-               log_warning(_("can't get envelope\n"));
-               return NULL;
-       }
+       imapset = numberlist_to_imapset(numlist);
+       while (imapset != NULL) {
+               if (imap_cmd_envelope(session, imapset)
+                   != IMAP_SUCCESS) {
+                       log_warning(_("can't get envelope\n"));
+                       continue;
+               }
 
-       str = g_string_new(NULL);
+               str = g_string_new(NULL);
 
-       for (;;) {
-               if ((tmp = sock_getline(SESSION(session)->sock)) == NULL) {
-                       log_warning(_("error occurred while getting envelope.\n"));
-                       g_string_free(str, TRUE);
-                       return newlist;
-               }
-               strretchomp(tmp);
-               if (tmp[0] != '*' || tmp[1] != ' ') {
-                       log_print("IMAP4< %s\n", tmp);
-                       g_free(tmp);
-                       break;
-               }
-               if (strstr(tmp, "FETCH") == NULL) {
+               for (;;) {
+                       if ((tmp = sock_getline(SESSION(session)->sock)) == NULL) {
+                               log_warning(_("error occurred while getting envelope.\n"));
+                               g_string_free(str, TRUE);
+                               break;
+                       }
+                       strretchomp(tmp);
+                       if (tmp[0] != '*' || tmp[1] != ' ') {
+                               log_print("IMAP4< %s\n", tmp);
+                               g_free(tmp);
+                               break;
+                       }
+                       if (strstr(tmp, "FETCH") == NULL) {
+                               log_print("IMAP4< %s\n", tmp);
+                               g_free(tmp);
+                               continue;
+                       }
                        log_print("IMAP4< %s\n", tmp);
+                       g_string_assign(str, tmp);
                        g_free(tmp);
-                       continue;
-               }
-               log_print("IMAP4< %s\n", tmp);
-               g_string_assign(str, tmp);
-               g_free(tmp);
-
-               msginfo = imap_parse_envelope
-                       (SESSION(session)->sock, item, str);
-               if (!msginfo) {
-                       log_warning(_("can't parse envelope: %s\n"), str->str);
-                       continue;
-               }
-               if (item->stype == F_QUEUE) {
-                       MSG_SET_TMP_FLAGS(msginfo->flags, MSG_QUEUED);
-               } else if (item->stype == F_DRAFT) {
-                       MSG_SET_TMP_FLAGS(msginfo->flags, MSG_DRAFT);
-               }
 
-               msginfo->folder = item;
+                       msginfo = imap_parse_envelope
+                               (SESSION(session)->sock, item, str);
+                       if (!msginfo) {
+                               log_warning(_("can't parse envelope: %s\n"), str->str);
+                               continue;
+                       }
+                       if (item->stype == F_QUEUE) {
+                               MSG_SET_TMP_FLAGS(msginfo->flags, MSG_QUEUED);
+                       } else if (item->stype == F_DRAFT) {
+                               MSG_SET_TMP_FLAGS(msginfo->flags, MSG_DRAFT);
+                       }
+
+                       msginfo->folder = item;
 
-               if (!newlist)
-                       llast = newlist = g_slist_append(newlist, msginfo);
-               else {
-                       llast = g_slist_append(llast, msginfo);
-                       llast = llast->next;
+                       if (!newlist)
+                               llast = newlist = g_slist_append(newlist, msginfo);
+                       else {
+                               llast = g_slist_append(llast, msginfo);
+                               llast = llast->next;
+                       }
                }
-       }
 
-       g_string_free(str, TRUE);
+               g_string_free(str, TRUE);
+               imapset = numberlist_to_imapset(NULL);
+       }
 
        return newlist;
 }
@@ -1716,7 +1783,7 @@ static void imap_get_namespace_by_list(IMAPSession *session, IMAPFolder *folder)
                return;
 
        imap_gen_send(session, "LIST \"\" \"\"");
-       item_list = imap_parse_list(NULL, session, "", &separator);
+       item_list = imap_parse_list(folder, session, "", &separator);
        for (cur = item_list; cur != NULL; cur = cur->next)
                folder_item_destroy(FOLDER_ITEM(cur->data));
        g_slist_free(item_list);
@@ -2045,6 +2112,7 @@ static gint imap_set_message_flags(IMAPSession *session,
 {
        GString *buf;
        gint ok;
+       IMAPSet imapset;
 
        buf = g_string_new(is_set ? "+FLAGS (" : "-FLAGS (");
 
@@ -2059,8 +2127,12 @@ static gint imap_set_message_flags(IMAPSession *session,
 
        g_string_append_c(buf, ')');
 
-       ok = imap_cmd_store(session, numberlist_to_imapset(numlist),
-                           buf->str);
+       imapset = numberlist_to_imapset(numlist);
+       while (imapset != NULL) {
+               ok = imap_cmd_store(session, imapset,
+                                   buf->str);
+               imapset = numberlist_to_imapset(NULL);
+       }
        g_string_free(buf, TRUE);
 
        return ok;
@@ -2171,6 +2243,51 @@ catch:
 
 /* low-level IMAP4rev1 commands */
 
+static gint imap_cmd_authenticate(IMAPSession *session, const gchar *user,
+                                 const gchar *pass, IMAPAuthType type)
+{
+       gchar *auth_type;
+       gint ok;
+       gchar *buf;
+       gchar *challenge;
+       gint challenge_len;
+       gchar hexdigest[33];
+       gchar *response;
+       gchar *response64;
+
+       auth_type = "CRAM-MD5";
+
+       imap_gen_send(session, "AUTHENTICATE %s", auth_type);
+       ok = imap_gen_recv(session, &buf);
+       if (ok != IMAP_SUCCESS || buf[0] != '+' || buf[1] != ' ') {
+               g_free(buf);
+               return IMAP_ERROR;
+       }
+
+       challenge = g_malloc(strlen(buf + 2) + 1);
+       challenge_len = base64_decode(challenge, buf + 2, -1);
+       challenge[challenge_len] = '\0';
+       log_print("IMAP< [Decoded: %s]\n", challenge);
+       g_free(buf);
+
+       md5_hex_hmac(hexdigest, challenge, challenge_len, pass, strlen(pass));
+       g_free(challenge);
+
+       response = g_strdup_printf("%s %s", user, hexdigest);
+       log_print("IMAP> [Encoded: %s]\n", response);
+       response64 = g_malloc((strlen(response) + 3) * 2 + 1);
+       base64_encode(response64, response, strlen(response));
+       g_free(response);
+
+       log_print("IMAP> %s\n", response64);
+       sock_puts(SESSION(session)->sock, response64);
+       ok = imap_cmd_ok(session, NULL);
+       if (ok != IMAP_SUCCESS)
+               log_warning(_("IMAP4 authentication failed.\n"));
+
+       return ok;
+}
+
 static gint imap_cmd_login(IMAPSession *session,
                           const gchar *user, const gchar *pass)
 {
@@ -2244,7 +2361,7 @@ void imap_free_capabilities(IMAPSession *session)
 static const IMAPSet numberlist_to_imapset(MsgNumberList *list)
 {
        static GString *imapset = NULL;
-       MsgNumberList *numlist, *elem;
+       static MsgNumberList *numlist, *elem;
        guint first, last, next;
 
        if (imapset == NULL)
@@ -2252,13 +2369,19 @@ static const IMAPSet numberlist_to_imapset(MsgNumberList *list)
        else
                g_string_truncate(imapset, 0);
 
-       numlist = g_slist_copy(list);
-       numlist = g_slist_sort(numlist, g_int_compare);
+       if (list != NULL) {
+               g_slist_free(numlist);
+               numlist = g_slist_copy(list);
+               numlist = g_slist_sort(numlist, g_int_compare);
+       } else if (numlist == NULL) {
+               return NULL;
+       }
 
        first = GPOINTER_TO_INT(numlist->data);
        last = first;
        for(elem = g_slist_next(numlist); elem != NULL; elem = g_slist_next(elem)) {
                next = GPOINTER_TO_INT(elem->data);
+
                if(next != (last + 1)) {
                        if (imapset->len > 0)
                                g_string_append(imapset, ",");
@@ -2267,18 +2390,34 @@ static const IMAPSet numberlist_to_imapset(MsgNumberList *list)
                        else
                                g_string_sprintfa(imapset, "%d:%d", first, last);
 
+                       if (imapset->len > IMAPCMDLIMIT) {
+                               last = 0;
+                               break;
+                       }
+
                        first = next;
                }
                last = next;
        }
-       if (imapset->len > 0)
-               g_string_append(imapset, ",");
-       if (first == last)
-               g_string_sprintfa(imapset, "%d", first);
-       else
-               g_string_sprintfa(imapset, "%d:%d", first, last);
+       if (last != 0) {
+               if (imapset->len > 0)
+                       g_string_append(imapset, ",");
+               if (first == last)
+                       g_string_sprintfa(imapset, "%d", first);
+               else
+                       g_string_sprintfa(imapset, "%d:%d", first, last);
 
-       g_slist_free(numlist);
+               g_slist_free(numlist);
+               numlist = NULL;
+       } else {
+               MsgNumberList *remaining;
+
+               remaining = elem->next;
+               remaining = g_slist_prepend(remaining, elem->data);
+               elem->next = NULL;
+               g_slist_free(numlist);
+               numlist = remaining;
+       }
 
        return imapset->str;
 }
@@ -2512,15 +2651,19 @@ static gint imap_cmd_fetch(IMAPSession *session, guint32 uid, const gchar *filen
                }
                if (strstr(buf, "FETCH") != NULL)
                        break;
+               g_free(buf);
        }
-       if (ok != IMAP_SUCCESS)
+       if (ok != IMAP_SUCCESS) {
+               g_free(buf);
                return ok;
+       }
 
        cur_pos = strchr(buf, '{');
        if (cur_pos == NULL) {
                g_free(buf);
                return IMAP_ERROR;
        }
+
        cur_pos = strchr_cpy(cur_pos + 1, '}', size_str, sizeof(size_str));
        if (cur_pos == NULL) {
                g_free(buf);
@@ -2728,7 +2871,7 @@ static gint imap_cmd_expunge(IMAPSession *session)
 
 static gint imap_cmd_ok(IMAPSession *session, GPtrArray *argbuf)
 {
-       gint ok;
+       gint ok = IMAP_SUCCESS;
        gchar *buf;
        gint cmd_num;
        gchar *data;
@@ -2738,40 +2881,36 @@ static gint imap_cmd_ok(IMAPSession *session, GPtrArray *argbuf)
                // make sure data is long enough for any substring of buf
                data = alloca(strlen(buf) + 1);
 
+               // untagged line read
                if (buf[0] == '*' && buf[1] == ' ') {
                        gint num;
                        if (argbuf)
                                g_ptr_array_add(argbuf, g_strdup(buf + 2));
 
-                       if (sscanf(buf + 2, "%d %s", &num, data) < 2)
-                               continue;
-
-                       if (!strcmp(data, "EXISTS")) {
-                               session->exists = num;
-                               session->folder_content_changed = TRUE;
-                       }
+                       if (sscanf(buf + 2, "%d %s", &num, data) >= 2) {
+                               if (!strcmp(data, "EXISTS")) {
+                                       session->exists = num;
+                                       session->folder_content_changed = TRUE;
+                               }
 
-                       if(!strcmp(data, "EXPUNGE")) {
-                               session->exists--;
-                               session->folder_content_changed = TRUE;
+                               if(!strcmp(data, "EXPUNGE")) {
+                                       session->exists--;
+                                       session->folder_content_changed = TRUE;
+                               }
                        }
-
-                       continue;
-               }
-
-               if (sscanf(buf, "%d %s", &cmd_num, data) < 2) {
-                       g_free(buf);
-                       return IMAP_ERROR;
-               } else if (cmd_num == session->cmd_count &&
-                        !strcmp(data, "OK")) {
+               // tagged line with correct tag and OK response found
+               } else if ((sscanf(buf, "%d %s", &cmd_num, data) >= 2) &&
+                          (cmd_num == session->cmd_count) &&
+                          !strcmp(data, "OK")) {
                        if (argbuf)
                                g_ptr_array_add(argbuf, g_strdup(buf));
-                       g_free(buf);
-                       return IMAP_SUCCESS;
+                       break;
+               // everything else
                } else {
-                       g_free(buf);
-                       return IMAP_ERROR;
+                       ok = IMAP_ERROR;
+                       break;
                }
+               g_free(buf);
        }
        g_free(buf);
 
@@ -2780,18 +2919,18 @@ static gint imap_cmd_ok(IMAPSession *session, GPtrArray *argbuf)
 
 static void imap_gen_send(IMAPSession *session, const gchar *format, ...)
 {
-       gchar buf[IMAPBUFSIZE];
-       gchar tmp[IMAPBUFSIZE];
+       gchar *buf;
+       gchar *tmp;
        gchar *p;
        va_list args;
 
        va_start(args, format);
-       g_vsnprintf(tmp, sizeof(tmp), format, args);
+       tmp = g_strdup_vprintf(format, args);
        va_end(args);
 
        session->cmd_count++;
 
-       g_snprintf(buf, sizeof(buf), "%d %s\r\n", session->cmd_count, tmp);
+       buf = g_strdup_printf("%d %s\r\n", session->cmd_count, tmp);
        if (!strncasecmp(tmp, "LOGIN ", 6) && (p = strchr(tmp + 6, ' '))) {
                *p = '\0';
                log_print("IMAP4> %d %s ********\n", session->cmd_count, tmp);
@@ -2799,6 +2938,8 @@ static void imap_gen_send(IMAPSession *session, const gchar *format, ...)
                log_print("IMAP4> %d %s\n", session->cmd_count, tmp);
 
        sock_write_all(SESSION(session)->sock, buf, strlen(buf));
+       g_free(tmp);
+       g_free(buf);
 }
 
 static gint imap_gen_recv(IMAPSession *session, gchar **buf)
@@ -2914,7 +3055,7 @@ static gchar *imap_modified_utf7_to_locale(const gchar *mutf7_str)
        to = g_malloc(strlen(mutf7_str) + 1);
        to_p = to;
 
-       while (from_p = mutf7_str; *from_p != '\0'; from_p++) {
+       for (from_p = mutf7_str; *from_p != '\0'; from_p++) {
                if (*from_p == '&' && *(from_p + 1) == '-') {
                        *to_p++ = '&';
                        from_p++;
@@ -3003,7 +3144,7 @@ static gchar *imap_locale_to_modified_utf7(const gchar *from)
        to = g_malloc(strlen(from) * 2 + 1);
        to_p = to;
 
-       while (from_p = from; *from_p != '\0'; from_p++) {
+       for (from_p = from; *from_p != '\0'; from_p++) {
                if (*from_p == '&') {
                        *to_p++ = '&';
                        *to_p++ = '-';