#include "statusbar.h"
#include "msgcache.h"
#include "imap-thread.h"
+#include "account.h"
typedef struct _IMAPFolder IMAPFolder;
typedef struct _IMAPSession IMAPSession;
const gchar *user,
const gchar *pass,
const gchar *type);
-static gint imap_cmd_logout (IMAPSession *session);
static gint imap_cmd_noop (IMAPSession *session);
#if USE_OPENSSL
static gint imap_cmd_starttls (IMAPSession *session);
g_node_traverse(folder->node, G_IN_ORDER, G_TRAVERSE_ALL, -1, imap_reset_uid_lists_func, NULL);
}
-void imap_get_capabilities(IMAPSession *session)
+int imap_get_capabilities(IMAPSession *session)
{
struct mailimap_capability_data *capabilities = NULL;
clistiter *cur;
+ int result = -1;
if (session->capability != NULL)
- return;
+ return MAILIMAP_NO_ERROR;
- capabilities = imap_threaded_capability(session->folder);
+ capabilities = imap_threaded_capability(session->folder, &result);
- if (capabilities == NULL)
- return;
+ if (result != MAILIMAP_NO_ERROR) {
+ return MAILIMAP_ERROR_CAPABILITY;
+ }
+
+ if (capabilities == NULL) {
+ return MAILIMAP_NO_ERROR;
+ }
for(cur = clist_begin(capabilities->cap_list) ; cur != NULL ;
cur = clist_next(cur)) {
debug_print("got capa %s\n", cap->cap_data.cap_name);
}
mailimap_capability_data_free(capabilities);
+ return MAILIMAP_NO_ERROR;
}
gboolean imap_has_capability(IMAPSession *session, const gchar *cap)
{
gint ok = IMAP_ERROR;
static time_t last_login_err = 0;
+ gchar *ext_info = "";
- imap_get_capabilities(session);
+ if (imap_get_capabilities(session) != MAILIMAP_NO_ERROR)
+ return IMAP_ERROR;
switch(type) {
case IMAP_AUTH_ANON:
if (ok == IMAP_ERROR) /* we always try LOGIN before giving up */
ok = imap_cmd_login(session, user, pass, "LOGIN");
}
+
if (ok == IMAP_SUCCESS)
session->authenticated = TRUE;
else {
- gchar *ext_info = NULL;
-
if (type == IMAP_AUTH_CRAM_MD5) {
ext_info = _("\n\nCRAM-MD5 logins only work if libetpan has been "
"compiled with SASL support and the "
"CRAM-MD5 SASL plugin is installed.");
- } else {
- ext_info = "";
- }
-
+ }
+
if (time(NULL) - last_login_err > 10) {
if (!prefs_common.no_recv_err_panel) {
alertpanel_error(_("Connection to %s failed: "
{
RemoteFolder *rfolder = REMOTE_FOLDER(folder);
IMAPSession *session = NULL;
- static time_t last_failure = 0;
g_return_val_if_fail(folder != NULL, NULL);
g_return_val_if_fail(FOLDER_CLASS(folder) == &imap_class, NULL);
} */
} else {
imap_reset_uid_lists(folder);
- if (time(NULL) - last_failure <= 2)
+ if (time(NULL) - rfolder->last_failure <= 2)
return NULL;
session = imap_session_new(folder, folder->account);
}
if(session == NULL) {
- last_failure = time(NULL);
+ rfolder->last_failure = time(NULL);
return NULL;
}
imap_session_authenticate(IMAP_SESSION(session), folder->account);
if (!IMAP_SESSION(session)->authenticated) {
+ imap_threaded_disconnect(session->folder);
+ SESSION(session)->state = SESSION_DISCONNECTED;
session_destroy(SESSION(session));
rfolder->session = NULL;
- last_failure = time(NULL);
+ rfolder->last_failure = time(NULL);
return NULL;
}
IMAPSession *session;
gushort port;
int r;
- int authenticated;
+ int authenticated = FALSE;
#ifdef USE_OPENSSL
/* FIXME: IMAP over SSL only... */
static void imap_session_authenticate(IMAPSession *session,
const PrefsAccount *account)
{
- gchar *pass;
+ gchar *pass, *acc_pass;
+ gboolean failed = FALSE;
g_return_if_fail(account->userid != NULL);
-
- pass = account->passwd;
+ acc_pass = account->passwd;
+try_again:
+ pass = acc_pass;
if (!pass && account->imap_auth_type != IMAP_AUTH_ANON) {
gchar *tmp_pass;
tmp_pass = input_dialog_query_password(account->recv_server, account->userid);
statusbar_print_all(_("Connecting to IMAP4 server %s...\n"),
account->recv_server);
if (imap_auth(session, account->userid, pass, account->imap_auth_type) != IMAP_SUCCESS) {
- imap_threaded_disconnect(session->folder);
- imap_cmd_logout(session);
statusbar_pop_all();
+ if (!failed) {
+ acc_pass = NULL;
+ failed = TRUE;
+ goto try_again;
+ } else {
+ alertpanel_error(_("Couldn't login to IMAP server %s."), account->recv_server);
+ }
+
return;
- }
+ }
+
statusbar_pop_all();
session->authenticated = TRUE;
+ return;
}
static void imap_session_destroy(Session *session)
if (cached)
debug_print("message %d has been already %scached (%d/%d).\n", uid,
- have_size == cached->size ? "fully ":"",
+ have_size >= cached->size ? "fully ":"",
have_size, (int)cached->size);
- if (cached && (cached->size == have_size || !body)) {
+ if (cached && (cached->size <= have_size || !body)) {
procmsg_msginfo_free(cached);
procmsg_msginfo_free(msginfo);
file_strip_crs(filename);
if (new_uid == 0) {
new_uid = dest->last_num+1;
}
- if (last_uid < new_uid)
+ if (last_uid < new_uid) {
last_uid = new_uid;
+ }
g_free(real_file);
}
int r;
gint ok;
+ if (!strcmp(type, "LOGIN") && imap_has_capability(session, "LOGINDISABLED")) {
+ gint ok = IMAP_ERROR;
+ if (imap_has_capability(session, "STARTTLS")) {
+#if USE_OPENSSL
+ log_warning(_("Server requires TLS to log in.\n"));
+ ok = imap_cmd_starttls(session);
+ if (ok != IMAP_SUCCESS) {
+ log_warning(_("Can't start TLS session.\n"));
+ return IMAP_ERROR;
+ } else {
+ /* refresh capas */
+ imap_free_capabilities(session);
+ if (imap_get_capabilities(session) != MAILIMAP_NO_ERROR) {
+ log_warning(_("Can't refresh capabilities.\n"));
+ return IMAP_ERROR;
+ }
+ }
+#else
+ log_error(_("Connection to %s failed: "
+ "server requires TLS, but Sylpheed-Claws "
+ "has been compiled without OpenSSL "
+ "support.\n"),
+ SESSION(session)->server);
+ return IMAP_ERROR;
+#endif
+ } else {
+ log_error(_("Server logins are disabled.\n"));
+ return IMAP_ERROR;
+ }
+ }
+
log_print("IMAP4> Logging %s to %s using %s\n",
user,
SESSION(session)->server,
return ok;
}
-static gint imap_cmd_logout(IMAPSession *session)
-{
- imap_threaded_disconnect(session->folder);
-
- return IMAP_SUCCESS;
-}
-
static gint imap_cmd_noop(IMAPSession *session)
{
int r;
flag_list = imap_flag_to_lep(flags);
r = imap_threaded_append(session->folder, destfolder,
- file, flag_list, new_uid);
+ file, flag_list, (int *)new_uid);
mailimap_flag_list_free(flag_list);
if (r != MAILIMAP_NO_ERROR) {
{
IMAPFolderItem *item = (IMAPFolderItem *)_item;
IMAPSession *session;
- gint ok, nummsgs = 0, exists, uid_val, uid_next = 0;
+ gint ok, nummsgs = 0, exists;
+ guint32 uid_next = 0, uid_val = 0;
GSList *uidlist = NULL;
gchar *dir;
gboolean selected_folder;
else {
*old_uids_valid = FALSE;
- debug_print("Freeing imap uid cache\n");
+ debug_print("Freeing imap uid cache (%d != %d)\n",
+ (int)item->item.mtime, uid_val);
item->lastuid = 0;
g_slist_free(item->uid_list);
item->uid_list = NULL;
imapset = cur->data;
if (reverse_seen) {
r = imap_threaded_search(folder, IMAP_SEARCH_TYPE_SEEN,
- imapset, &lep_uidlist);
+ full_search ? NULL:imapset, &lep_uidlist);
}
else {
r = imap_threaded_search(folder,
IMAP_SEARCH_TYPE_UNSEEN,
- imapset, &lep_uidlist);
+ full_search ? NULL:imapset, &lep_uidlist);
}
if (r == MAILIMAP_NO_ERROR) {
GSList * uidlist;
}
r = imap_threaded_search(folder, IMAP_SEARCH_TYPE_FLAGGED,
- imapset, &lep_uidlist);
+ full_search ? NULL:imapset, &lep_uidlist);
if (r == MAILIMAP_NO_ERROR) {
GSList * uidlist;
if (item->opened || item->processing_pending || item == folder->inbox) {
r = imap_threaded_search(folder, IMAP_SEARCH_TYPE_ANSWERED,
- imapset, &lep_uidlist);
+ full_search ? NULL:imapset, &lep_uidlist);
if (r == MAILIMAP_NO_ERROR) {
GSList * uidlist;
}
r = imap_threaded_search(folder, IMAP_SEARCH_TYPE_DELETED,
- imapset, &lep_uidlist);
+ full_search ? NULL:imapset, &lep_uidlist);
if (r == MAILIMAP_NO_ERROR) {
GSList * uidlist;
((IMAPFolder *)folder)->refcnt++;
}
+void imap_disconnect_all(void)
+{
+ GList *list;
+ for (list = account_get_list(); list != NULL; list = list->next) {
+ PrefsAccount *account = list->data;
+ if (account->protocol == A_IMAP4) {
+ RemoteFolder *folder = (RemoteFolder *)account->folder;
+ if (folder && folder->session) {
+ IMAPSession *session = (IMAPSession *)folder->session;
+ imap_threaded_disconnect(FOLDER(folder));
+ SESSION(session)->state = SESSION_DISCONNECTED;
+ session_destroy(SESSION(session));
+ folder->session = NULL;
+ }
+ }
+ }
+}
+
void imap_folder_unref(Folder *folder)
{
if (((IMAPFolder *)folder)->refcnt > 0)
return &imap_class;
}
+
+void imap_disconnect_all(void)
+{
+}
+
#endif
void imap_synchronise(FolderItem *item)