GList *ns_others;
GList *ns_shared;
gchar last_seen_separator;
+ guint refcnt;
};
struct _IMAPSession
gboolean authenticated;
- gchar **capability;
+ GSList *capability;
gboolean uidplus;
gchar *mbox;
/* low-level IMAP4rev1 commands */
static gint imap_cmd_login (IMAPSession *session,
const gchar *user,
- const gchar *pass);
+ const gchar *pass,
+ const gchar *type);
static gint imap_cmd_logout (IMAPSession *session);
static gint imap_cmd_noop (IMAPSession *session);
#if USE_OPENSSL
{
gchar *dir;
+ while (imap_folder_get_refcnt(folder) > 0)
+ gtk_main_iteration();
+
dir = imap_folder_get_path(folder);
if (is_dir_exist(dir))
remove_dir_recursive(dir);
g_node_traverse(folder->node, G_IN_ORDER, G_TRAVERSE_ALL, -1, imap_reset_uid_lists_func, NULL);
}
+void imap_get_capabilities(IMAPSession *session)
+{
+ struct mailimap_capability_data *capabilities = NULL;
+ clistiter *cur;
+
+ if (session->capability != NULL)
+ return;
+
+ capabilities = imap_threaded_capability(session->folder);
+ for(cur = clist_begin(capabilities->cap_list) ; cur != NULL ;
+ cur = clist_next(cur)) {
+ struct mailimap_capability * cap =
+ clist_content(cur);
+ if (cap->cap_data.cap_name == NULL)
+ continue;
+ session->capability = g_slist_append
+ (session->capability,
+ g_strdup(cap->cap_data.cap_name));
+ debug_print("got capa %s\n", cap->cap_data.cap_name);
+ }
+ mailimap_capability_data_free(capabilities);
+}
+
+gboolean imap_has_capability(IMAPSession *session, const gchar *cap)
+{
+ GSList *cur;
+ for (cur = session->capability; cur; cur = cur->next) {
+ if (!g_ascii_strcasecmp(cur->data, cap))
+ return TRUE;
+ }
+ return FALSE;
+}
+
static gint imap_auth(IMAPSession *session, const gchar *user, const gchar *pass,
IMAPAuthType type)
{
- gint ok;
-
- ok = imap_cmd_login(session, user, pass);
+ gint ok = IMAP_ERROR;
+ static time_t last_login_err = 0;
+ imap_get_capabilities(session);
+
+ switch(type) {
+ case IMAP_AUTH_CRAM_MD5:
+ ok = imap_cmd_login(session, user, pass, "CRAM-MD5");
+ break;
+ case IMAP_AUTH_LOGIN:
+ ok = imap_cmd_login(session, user, pass, "LOGIN");
+ break;
+ default:
+ debug_print("capabilities:\n"
+ "\t CRAM-MD5 %d\n"
+ "\t LOGIN %d\n",
+ imap_has_capability(session, "CRAM-MD5"),
+ imap_has_capability(session, "LOGIN"));
+ if (imap_has_capability(session, "CRAM-MD5"))
+ ok = imap_cmd_login(session, user, pass, "CRAM-MD5");
+ 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) {
+ alertpanel_error(_("Connection to %s failed: login refused.%s"),
+ SESSION(session)->server, ext_info);
+ }
+ last_login_err = time(NULL);
+ }
return ok;
}
gchar *tmp_pass;
tmp_pass = input_dialog_query_password(account->recv_server, account->userid);
if (!tmp_pass)
- return;
+ tmp_pass = g_strdup(""); /* allow empty password */
Xstrdup_a(pass, tmp_pass, {g_free(tmp_pass); return;});
g_free(tmp_pass);
}
return cnt;
}
+static void strip_crs(const gchar *file)
+{
+ FILE *fp = NULL, *outfp = NULL;
+ gchar buf[4096];
+ gchar *out = get_tmp_file();
+ if (file == NULL)
+ goto freeout;
+
+ fp = fopen(file, "rb");
+ if (!fp)
+ goto freeout;
+
+ outfp = fopen(out, "wb");
+ if (!outfp) {
+ fclose(fp);
+ goto freeout;
+ }
+
+ while (fgets(buf, sizeof (buf), fp) != NULL) {
+ while (strstr(buf, "\r")) {
+ gchar *cr = strstr(buf, "\r") ;
+ *cr = '\n';
+ cr++;
+ *cr = '\0';
+ }
+ fputs(buf, outfp);
+ }
+
+ fclose(fp);
+ fclose(outfp);
+ rename_force(out, file);
+freeout:
+ g_free(out);
+}
+
static gchar *imap_fetch_msg_full(Folder *folder, FolderItem *item, gint uid,
gboolean headers, gboolean body)
{
MsgInfo *msginfo = imap_parse_msg(filename, item);
MsgInfo *cached = msgcache_get_msg(item->cache,uid);
guint have_size = get_size_with_lfs(msginfo);
- debug_print("message %d has been already %scached (%d/%d).\n", uid,
+
+ if (cached)
+ debug_print("message %d has been already %scached (%d/%d).\n", uid,
have_size == cached->size ? "fully ":"",
- have_size, cached? (int)cached->size : -1);
+ have_size, (int)cached->size);
if (cached && (cached->size == have_size || !body)) {
procmsg_msginfo_free(cached);
procmsg_msginfo_free(msginfo);
+ strip_crs(filename);
return filename;
} else {
procmsg_msginfo_free(cached);
return NULL;
}
+ strip_crs(filename);
return filename;
}
iflags |= IMAP_FLAG_SEEN;
}
- if (dest->stype == F_OUTBOX ||
- dest->stype == F_QUEUE ||
- dest->stype == F_DRAFT ||
- dest->stype == F_TRASH)
+ if (folder_has_parent_of_type(dest, F_QUEUE) ||
+ folder_has_parent_of_type(dest, F_OUTBOX) ||
+ folder_has_parent_of_type(dest, F_DRAFT) ||
+ folder_has_parent_of_type(dest, F_TRASH))
iflags |= IMAP_FLAG_SEEN;
ok = imap_cmd_append(session, destdir, fileinfo->file, iflags,
{
GSList *list = folder_item_get_msg_list(item);
gint res = imap_remove_msgs(folder, item, list, NULL);
- g_slist_free(list);
+ procmsg_msg_list_free(list);
return res;
}
if (!folder->trash)
folder->trash = imap_create_special_folder
(folder, F_TRASH, "Trash");
+ if (!folder->queue)
+ folder->queue = imap_create_special_folder
+ (folder, F_QUEUE, "Queue");
+ if (!folder->outbox)
+ folder->outbox = imap_create_special_folder
+ (folder, F_OUTBOX, "Sent");
+ if (!folder->draft)
+ folder->draft = imap_create_special_folder
+ (folder, F_DRAFT, "Drafts");
}
static FolderItem *imap_create_special_folder(Folder *folder,
cur = numlist;
data->total = g_slist_length(numlist);
debug_print("messages list : %i\n", data->total);
- log_print(_("IMAP> Getting uncached messages for %s\n"), item->path);
+
while (cur != NULL) {
GSList * partial_result;
int count;
if (prefs_common.work_offline && !imap_gtk_should_override()) {
g_free(data);
- log_error(_("IMAP< Error\n"));
return NULL;
}
partial_result =
(GSList *)imap_get_uncached_messages_thread(data);
- {
- gchar buf[32];
- g_snprintf(buf, sizeof(buf), "%d / %d",
- data->cur, data->total);
- gtk_progress_bar_set_text
- (GTK_PROGRESS_BAR(mainwindow_get_mainwindow()->progressbar), buf);
- gtk_progress_bar_set_fraction
- (GTK_PROGRESS_BAR(mainwindow_get_mainwindow()->progressbar),
- (gfloat)data->cur / (gfloat)data->total);
- debug_print("update progress %g\n",
- (gfloat)data->cur / (gfloat)data->total);
- }
+ statusbar_progress_all(data->cur,data->total, 1);
g_slist_free(newlist);
}
g_free(data);
- gtk_progress_bar_set_fraction
- (GTK_PROGRESS_BAR(mainwindow_get_mainwindow()->progressbar), 0);
- gtk_progress_bar_set_text
- (GTK_PROGRESS_BAR(mainwindow_get_mainwindow()->progressbar), "");
+ statusbar_progress_all(0,0,0);
statusbar_pop_all();
- log_print(_("IMAP< Done\n"));
return result;
}
static void imap_free_capabilities(IMAPSession *session)
{
- g_strfreev(session->capability);
+ slist_free_strings(session->capability);
+ g_slist_free(session->capability);
session->capability = NULL;
}
challenge_len = base64_decode(challenge, buf + 2, -1);
challenge[challenge_len] = '\0';
g_free(buf);
- log_print(_("IMAP< [Decoded: %s]\n"), challenge);
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)
#endif
static gint imap_cmd_login(IMAPSession *session,
- const gchar *user, const gchar *pass)
+ const gchar *user, const gchar *pass,
+ const gchar *type)
{
int r;
gint ok;
- static time_t last_login_err = 0;
- log_print(_("IMAP> Logging in to %s\n"), SESSION(session)->server);
- r = imap_threaded_login(session->folder, user, pass);
+ log_print("IMAP4> Logging %s to %s using %s\n",
+ user,
+ SESSION(session)->server,
+ type);
+ r = imap_threaded_login(session->folder, user, pass, type);
if (r != MAILIMAP_NO_ERROR) {
- if (time(NULL) - last_login_err > 10) {
- alertpanel_error(_("Connection to %s failed: login refused."),
- SESSION(session)->server);
- }
- last_login_err = time(NULL);
- log_error(_("IMAP< Error\n"));
+ log_error("IMAP4< Error logging in to %s\n",
+ SESSION(session)->server);
ok = IMAP_ERROR;
} else {
- log_print(_("IMAP< Done\n"));
ok = IMAP_SUCCESS;
}
return ok;
static gint imap_cmd_logout(IMAPSession *session)
{
- log_print(_("IMAP> Logging out of %s\n"), SESSION(session)->server);
imap_threaded_disconnect(session->folder);
return IMAP_SUCCESS;
{
int r;
- log_print(_("IMAP> Starting TLS\n"));
r = imap_threaded_starttls(session->folder);
if (r != MAILIMAP_NO_ERROR) {
debug_print("starttls err %d\n", r);
- log_error(_("IMAP< Error\n"));
return IMAP_ERROR;
}
- log_print(_("IMAP< Done\n"));
return IMAP_SUCCESS;
}
#endif
{
int r;
- log_print(_("IMAP> Selecting %s\n"), folder);
r = imap_threaded_select(session->folder, folder,
exists, recent, unseen, uid_validity);
if (r != MAILIMAP_NO_ERROR) {
debug_print("select err %d\n", r);
- log_error(_("IMAP< Error\n"));
return IMAP_ERROR;
}
- log_print(_("IMAP< Done\n"));
return IMAP_SUCCESS;
}
{
int r;
- log_print(_("IMAP> Examining %s\n"), folder);
r = imap_threaded_examine(session->folder, folder,
exists, recent, unseen, uid_validity);
if (r != MAILIMAP_NO_ERROR) {
debug_print("examine err %d\n", r);
- log_error(_("IMAP< Error\n"));
+
return IMAP_ERROR;
}
- log_print(_("IMAP< Done\n"));
return IMAP_SUCCESS;
}
static gint imap_cmd_create(IMAPSession *session, const gchar *folder)
{
int r;
- log_print(_("IMAP> Creating %s\n"), folder);
+
r = imap_threaded_create(session->folder, folder);
if (r != MAILIMAP_NO_ERROR) {
- log_error(_("IMAP< Error\n"));
+
return IMAP_ERROR;
}
- log_print(_("IMAP< Done\n"));
+
return IMAP_SUCCESS;
}
const gchar *new_folder)
{
int r;
- log_print(_("IMAP> Renaming %s to %s\n"), old_folder, new_folder);
+
r = imap_threaded_rename(session->folder, old_folder,
new_folder);
if (r != MAILIMAP_NO_ERROR) {
- log_error(_("IMAP< Error\n"));
+
return IMAP_ERROR;
}
- log_print(_("IMAP< Done\n"));
+
return IMAP_SUCCESS;
}
{
int r;
- log_print(_("IMAP> Deleting %s\n"), folder);
+
r = imap_threaded_delete(session->folder, folder);
if (r != MAILIMAP_NO_ERROR) {
- log_error(_("IMAP< Error\n"));
+
return IMAP_ERROR;
}
- log_print(_("IMAP< Done\n"));
+
return IMAP_SUCCESS;
}
g_return_val_if_fail(set != NULL, IMAP_ERROR);
g_return_val_if_fail(destfolder != NULL, IMAP_ERROR);
- log_print(_("IMAP> Copying to %s\n"), destfolder);
r = imap_threaded_copy(session->folder, set, destfolder);
if (r != MAILIMAP_NO_ERROR) {
- log_error(_("IMAP< Error\n"));
+
return IMAP_ERROR;
}
- log_print(_("IMAP< Done\n"));
+
return IMAP_SUCCESS;
}
store_att_flags =
mailimap_store_att_flags_new_remove_flags_silent(flag_list);
- log_print(_("IMAP> Storing\n"));
r = imap_threaded_store(session->folder, set, store_att_flags);
if (r != MAILIMAP_NO_ERROR) {
- log_error(_("IMAP< Error\n"));
+
return IMAP_ERROR;
}
- log_print(_("IMAP< Done\n"));
+
return IMAP_SUCCESS;
}
if (prefs_common.work_offline && !imap_gtk_should_override()) {
return -1;
}
- log_print(_("IMAP> Expunging\n"));
+
r = imap_threaded_expunge(session->folder);
if (r != MAILIMAP_NO_ERROR) {
- log_error(_("IMAP< Error\n"));
+
return IMAP_ERROR;
}
- log_print(_("IMAP< Done\n"));
+
return IMAP_SUCCESS;
}
session = imap_session_get(folder);
g_return_val_if_fail(session != NULL, -1);
- log_print(_("IMAP> Getting numbers list for %s\n"), item->item.path);
-
selected_folder = (session->mbox != NULL) &&
(!strcmp(session->mbox, item->item.path));
if (selected_folder) {
ok = imap_cmd_noop(session);
if (ok != IMAP_SUCCESS) {
- log_error(_("IMAP< Error\n"));
+
return -1;
}
exists = session->exists;
ok = imap_status(session, IMAP_FOLDER(folder), item->item.path,
&exists, &recent, &uid_next, &uid_val, &unseen, FALSE);
if (ok != IMAP_SUCCESS) {
- log_error(_("IMAP< Error\n"));
+
return -1;
}
if(item->item.mtime == uid_val)
out which numbers have been removed */
if (exists == nummsgs) {
*msgnum_list = g_slist_copy(item->uid_list);
- log_print(_("IMAP< Done\n"));
return nummsgs;
} else if (exists < nummsgs) {
debug_print("Freeing imap uid cache");
if (exists == 0) {
*msgnum_list = NULL;
- log_print(_("IMAP< Done\n"));
return 0;
}
nummsgs = get_list_of_uids(folder, item, &uidlist);
if (nummsgs < 0) {
- log_error(_("IMAP< Error\n"));
+
return -1;
}
debug_print("get_num_list - ok - %i\n", nummsgs);
- log_print(_("IMAP< Done\n"));
return nummsgs;
}
g_return_val_if_fail(item != NULL, NULL);
g_return_val_if_fail(file != NULL, NULL);
- if (item->stype == F_QUEUE) {
+ if (folder_has_parent_of_type(item, F_QUEUE)) {
MSG_SET_TMP_FLAGS(flags, MSG_QUEUED);
- } else if (item->stype == F_DRAFT) {
+ } else if (folder_has_parent_of_type(item, F_DRAFT)) {
MSG_SET_TMP_FLAGS(flags, MSG_DRAFT);
}
if (ok != IMAP_SUCCESS)
return NULL;
- if (!(item->stype == F_QUEUE || item->stype == F_DRAFT)) {
+ if (!(folder_has_parent_of_type(item, F_DRAFT) ||
+ folder_has_parent_of_type(item, F_QUEUE))) {
ret = g_slist_concat(ret,
imap_get_uncached_messages(session, item,
msgnum_list));
free(dup_name);
continue;
}
+
+ if (dup_name[strlen(dup_name)-1] == '/') {
+ g_free(base);
+ free(dup_name);
+ continue;
+ }
loc_name = imap_modified_utf7_to_utf8(base);
loc_path = imap_modified_utf7_to_utf8(dup_name);
MsgFlags flags = {0, 0};
MSG_SET_TMP_FLAGS(flags, MSG_IMAP);
- if (item->stype == F_QUEUE) {
+ if (folder_has_parent_of_type(item, F_QUEUE)) {
MSG_SET_TMP_FLAGS(flags, MSG_QUEUED);
- } else if (item->stype == F_DRAFT) {
+ } else if (folder_has_parent_of_type(item, F_DRAFT)) {
MSG_SET_TMP_FLAGS(flags, MSG_DRAFT);
}
flags.perm_flags = info->flags;
return flag_list;
}
+
+guint imap_folder_get_refcnt(Folder *folder)
+{
+ return ((IMAPFolder *)folder)->refcnt;
+}
+
+void imap_folder_ref(Folder *folder)
+{
+ ((IMAPFolder *)folder)->refcnt++;
+}
+
+void imap_folder_unref(Folder *folder)
+{
+ if (((IMAPFolder *)folder)->refcnt > 0)
+ ((IMAPFolder *)folder)->refcnt--;
+}
+
#else /* HAVE_LIBETPAN */
static FolderClass imap_class;
return &imap_class;
}
-
#endif