From 2ddb31bb4cf51711d786e1a994f2a91ed80e7cee Mon Sep 17 00:00:00 2001 From: hiro Date: Fri, 27 May 2005 09:04:28 +0000 Subject: fixed a crash bug of IMAP4. git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@292 ee746299-78ed-0310-b773-934348b2243d --- src/imap.c | 146 +++++++++++++++++++++++++++++++++++++--------------------- src/procmsg.h | 1 + 2 files changed, 94 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/imap.c b/src/imap.c index dec32a70..50e09611 100644 --- a/src/imap.c +++ b/src/imap.c @@ -84,6 +84,8 @@ static Folder *imap_folder_new (const gchar *name, static void imap_folder_destroy (Folder *folder); static Session *imap_session_new (PrefsAccount *account); +static gint imap_session_connect (IMAPSession *session); +static gint imap_session_reconnect (IMAPSession *session); static void imap_session_destroy (Session *session); /* static void imap_session_destroy_all (void); */ @@ -455,11 +457,14 @@ static IMAPSession *imap_session_get(Folder *folder) log_warning(_("IMAP4 connection to %s has been" " disconnected. Reconnecting...\n"), folder->account->recv_server); - session_destroy(rfolder->session); - rfolder->session = imap_session_new(folder->account); - if (rfolder->session) + if (imap_session_reconnect(IMAP_SESSION(rfolder->session)) + == IMAP_SUCCESS) imap_parse_namespace(IMAP_SESSION(rfolder->session), IMAP_FOLDER(folder)); + else { + session_destroy(rfolder->session); + rfolder->session = NULL; + } } return IMAP_SESSION(rfolder->session); @@ -526,25 +531,12 @@ static gint imap_auth(IMAPSession *session, const gchar *user, static Session *imap_session_new(PrefsAccount *account) { IMAPSession *session; - SockInfo *sock; - gchar *pass; gushort port; g_return_val_if_fail(account != NULL, NULL); g_return_val_if_fail(account->recv_server != NULL, NULL); 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 USE_SSL port = account->set_imapport ? account->imapport : account->ssl_imap == SSL_TUNNEL ? IMAPS_PORT : IMAP4_PORT; @@ -552,26 +544,19 @@ static Session *imap_session_new(PrefsAccount *account) port = account->set_imapport ? account->imapport : IMAP4_PORT; #endif - log_message(_("creating IMAP4 connection to %s:%d ...\n"), - account->recv_server, port); - -#if USE_SSL - if ((sock = imap_open(account->recv_server, port, - account->ssl_imap)) == NULL) -#else - if ((sock = imap_open(account->recv_server, port)) == NULL) -#endif - return NULL; - session = g_new0(IMAPSession, 1); session_init(SESSION(session)); SESSION(session)->type = SESSION_IMAP; + SESSION(session)->sock = NULL; SESSION(session)->server = g_strdup(account->recv_server); - SESSION(session)->sock = sock; + SESSION(session)->port = port; +#if USE_SSL + SESSION(session)->ssl_type = account->ssl_imap; +#endif SESSION(session)->last_access_time = time(NULL); - SESSION(session)->data = NULL; + SESSION(session)->data = account; SESSION(session)->destroy = imap_session_destroy; @@ -581,15 +566,55 @@ static Session *imap_session_new(PrefsAccount *account) session_list = g_list_append(session_list, session); - if (imap_greeting(session) != IMAP_SUCCESS) { + if (imap_session_connect(session) != IMAP_SUCCESS) { session_destroy(SESSION(session)); return NULL; } - if (imap_cmd_capability(session) != IMAP_SUCCESS) { - session_destroy(SESSION(session)); - return NULL; + return SESSION(session); +} + +static gint imap_session_connect(IMAPSession *session) +{ + SockInfo *sock; + PrefsAccount *account; + gchar *pass; + + g_return_val_if_fail(session != NULL, IMAP_ERROR); + + account = (PrefsAccount *)(SESSION(session)->data); + + log_message(_("creating IMAP4 connection to %s:%d ...\n"), + SESSION(session)->server, SESSION(session)->port); + + pass = account->passwd; + if (!pass) { + gchar *tmp_pass; + tmp_pass = input_dialog_query_password(account->recv_server, + account->userid); + if (!tmp_pass) + return IMAP_ERROR; + Xstrdup_a(pass, tmp_pass, + {g_free(tmp_pass); return IMAP_ERROR;}); + g_free(tmp_pass); } + +#if USE_SSL + if ((sock = imap_open(SESSION(session)->server, SESSION(session)->port, + SESSION(session)->ssl_type)) == NULL) +#else + if ((sock = imap_open(SESSION(session)->server, SESSION(session)->port)) + == NULL) +#endif + return IMAP_ERROR; + + SESSION(session)->sock = sock; + + if (imap_greeting(session) != IMAP_SUCCESS) + return IMAP_ERROR; + if (imap_cmd_capability(session) != IMAP_SUCCESS) + return IMAP_ERROR; + if (imap_has_capability(session, "UIDPLUS")) session->uidplus = TRUE; @@ -601,13 +626,10 @@ static Session *imap_session_new(PrefsAccount *account) ok = imap_cmd_starttls(session); if (ok != IMAP_SUCCESS) { log_warning(_("Can't start TLS session.\n")); - session_destroy(SESSION(session)); - return NULL; - } - if (!ssl_init_socket_with_method(sock, SSL_METHOD_TLSv1)) { - session_destroy(SESSION(session)); - return NULL; + return IMAP_ERROR; } + if (!ssl_init_socket_with_method(sock, SSL_METHOD_TLSv1)) + return IMAP_SOCKET; } #endif @@ -615,11 +637,26 @@ static Session *imap_session_new(PrefsAccount *account) imap_auth(session, account->userid, pass, account->imap_auth_type) != IMAP_SUCCESS) { imap_cmd_logout(session); - session_destroy(SESSION(session)); - return NULL; + return IMAP_AUTHFAIL; } - return SESSION(session); + return IMAP_SUCCESS; +} + +static gint imap_session_reconnect(IMAPSession *session) +{ + g_return_val_if_fail(session != NULL, IMAP_ERROR); + + session_disconnect(SESSION(session)); + + imap_capability_free(session); + session->uidplus = FALSE; + g_free(session->mbox); + session->mbox = NULL; + session->authenticated = FALSE; + SESSION(session)->state = SESSION_READY; + + return imap_session_connect(session); } static void imap_session_destroy(Session *session) @@ -3259,6 +3296,7 @@ static gint imap_cmd_search(IMAPSession *session, const gchar *criteria, GArray *array; gchar *str; gchar *p, *ep; + gint i; guint32 uid; g_return_val_if_fail(criteria != NULL, IMAP_ERROR); @@ -3269,20 +3307,22 @@ static gint imap_cmd_search(IMAPSession *session, const gchar *criteria, imap_cmd_gen_send(session, "UID SEARCH %s", criteria); if ((ok = imap_cmd_ok(session, argbuf)) != IMAP_SUCCESS) THROW(ok); - str = search_array_str(argbuf, "SEARCH"); - if (!str) THROW(IMAP_ERROR); - array = g_array_new(FALSE, FALSE, sizeof(guint32)); - p = str + strlen("SEARCH"); + for (i = 0; i < argbuf->len; i++) { + str = g_ptr_array_index(argbuf, i); + if (strncmp(str, "SEARCH", 6) != 0) + continue; - while (*p != '\0') { - uid = strtoul(p, &ep, 10); - if (p < ep && uid > 0) { - g_array_append_val(array, uid); - p = ep; - } else - break; + p = str + 6; + while (*p != '\0') { + uid = strtoul(p, &ep, 10); + if (p < ep && uid > 0) { + g_array_append_val(array, uid); + p = ep; + } else + break; + } } *result = array; diff --git a/src/procmsg.h b/src/procmsg.h index 18138bf2..c8c692d1 100644 --- a/src/procmsg.h +++ b/src/procmsg.h @@ -128,6 +128,7 @@ typedef guint32 MsgTmpFlags; #define MSG_IS_ENCRYPTED(msg) (((msg).tmp_flags & MSG_ENCRYPTED) != 0) #define MSG_IS_IMAP(msg) (((msg).tmp_flags & MSG_IMAP) != 0) #define MSG_IS_NEWS(msg) (((msg).tmp_flags & MSG_NEWS) != 0) +#define MSG_IS_SIGNED(msg) (((msg).tmp_flags & MSG_SIGNED) != 0) #define MSG_IS_MIME(msg) (((msg).tmp_flags & MSG_MIME) != 0) #define MSG_IS_INVALID(msg) (((msg).tmp_flags & MSG_INVALID) != 0) #define MSG_IS_RECEIVED(msg) (((msg).tmp_flags & MSG_RECEIVED) != 0) -- cgit v1.2.3