FolderItem item;
guint lastuid;
+ guint uid_next;
GSList *uid_list;
};
{
F_IMAP,
"imap",
+ "IMAP4",
+ /* Folder functions */
+ imap_folder_new,
+ imap_folder_destroy,
+ imap_scan_tree,
+ imap_create_tree,
+
+ /* FolderItem functions */
imap_folder_item_new,
imap_folder_item_destroy,
- imap_fetch_msg,
+ imap_create_folder,
+ imap_rename_folder,
+ imap_remove_folder,
+ imap_get_num_list,
+ NULL,
+ NULL,
+ NULL,
+ imap_check_msgnum_validity,
+
+ /* Message functions */
imap_get_msginfo,
imap_get_msginfos,
+ imap_fetch_msg,
imap_add_msg,
imap_move_msg,
NULL,
imap_remove_all_msg,
imap_is_msg_changed,
NULL,
- imap_get_num_list,
- imap_scan_tree,
- imap_create_tree,
- imap_create_folder,
- imap_rename_folder,
- imap_remove_folder,
- imap_folder_destroy,
- NULL,
- NULL,
- NULL,
- NULL,
- imap_check_msgnum_validity,
};
+FolderClass *imap_get_class()
+{
+ return &imap_class;
+}
+
Folder *imap_folder_new(const gchar *name, const gchar *path)
{
Folder *folder;
item = g_new0(IMAPFolderItem, 1);
item->lastuid = 0;
+ item->uid_next = 0;
item->uid_list = NULL;
return (FolderItem *)item;
IMAPFolderItem *item = (IMAPFolderItem *)node->data;
item->lastuid = 0;
+ item->uid_next = 0;
g_slist_free(item->uid_list);
item->uid_list = NULL;
gushort port;
g_return_val_if_fail(folder != NULL, NULL);
- g_return_val_if_fail(FOLDER_TYPE(folder) == F_IMAP, NULL);
+ g_return_val_if_fail(FOLDER_CLASS(folder) == &imap_class, NULL);
g_return_val_if_fail(folder->account != NULL, NULL);
#if USE_OPENSSL
gint ok;
g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(FOLDER_TYPE(folder) == F_IMAP, -1);
+ g_return_val_if_fail(FOLDER_CLASS(folder) == &imap_class, -1);
g_return_val_if_fail(dest != NULL, -1);
g_return_val_if_fail(msginfo != NULL, -1);
gchar *dir;
g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(FOLDER_TYPE(folder) == F_IMAP, -1);
+ g_return_val_if_fail(FOLDER_CLASS(folder) == &imap_class, -1);
g_return_val_if_fail(item != NULL, -1);
session = imap_session_get(folder);
guint32 uid;
g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(FOLDER_TYPE(folder) == F_IMAP, -1);
+ g_return_val_if_fail(FOLDER_CLASS(folder) == &imap_class, -1);
g_return_val_if_fail(item != NULL, -1);
g_return_val_if_fail(msglist != NULL, -1);
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_TYPE(item->folder) == F_IMAP, NULL);
+ g_return_val_if_fail(FOLDER_CLASS(item->folder) == &imap_class, NULL);
g_return_val_if_fail(first_uid <= last_uid, NULL);
if (imap_cmd_envelope(SESSION(session)->sock, first_uid, last_uid)
g_return_if_fail(item != NULL);
g_return_if_fail(item->folder != NULL);
- g_return_if_fail(FOLDER_TYPE(item->folder) == F_IMAP);
+ g_return_if_fail(FOLDER_CLASS(item->folder) == &imap_class);
debug_print("Deleting all cached messages...\n");
g_return_val_if_fail(msginfo->folder->folder != NULL, -1);
folder = msginfo->folder->folder;
- g_return_val_if_fail(FOLDER_TYPE(folder) == F_IMAP, -1);
+ g_return_val_if_fail(FOLDER_CLASS(folder) == &imap_class, -1);
session = imap_session_get(folder);
if (!session) return -1;
g_return_val_if_fail(msginfo->folder->folder != NULL, -1);
folder = msginfo->folder->folder;
- g_return_val_if_fail(FOLDER_TYPE(folder) == F_IMAP, -1);
+ g_return_val_if_fail(FOLDER_CLASS(folder) == &imap_class, -1);
session = imap_session_get(folder);
if (!session) return -1;
{
IMAPFolderItem *item = (IMAPFolderItem *)_item;
IMAPSession *session;
- gint ok, lastuid_old, nummsgs = 0, exists, resent, unseen, uid_val;
+ gint ok, lastuid_old, nummsgs = 0, exists, recent, unseen, uid_val, uid_next;
GSList *uidlist, *elem;
gchar *dir, *cmd_buf;
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);
- g_return_val_if_fail(FOLDER_TYPE(folder) == F_IMAP, -1);
+ g_return_val_if_fail(FOLDER_CLASS(folder) == &imap_class, -1);
g_return_val_if_fail(folder->account != NULL, -1);
session = imap_session_get(folder);
g_return_val_if_fail(session != NULL, -1);
- ok = imap_select(session, IMAP_FOLDER(folder), item->item.path,
- &exists, &resent, &unseen, &uid_val);
+ ok = imap_status(session, IMAP_FOLDER(folder), item->item.path,
+ &exists, &recent, &uid_next, &uid_val, &unseen);
if (ok != IMAP_SUCCESS)
return -1;
- if (exists == 0)
+ /* If old uid_next matches new uid_next we can be sure no message
+ was added to the folder */
+ if (uid_next == item->uid_next) {
+ nummsgs = g_slist_length(item->uid_list);
+
+ /* If number of messages is still the same we
+ know our caches message numbers are still valid,
+ otherwise if the number of messages has decrease
+ we discard our cache to start a new scan to find
+ out which numbers have been removed */
+ if (exists == nummsgs) {
+ *msgnum_list = g_slist_copy(item->uid_list);
+ return nummsgs;
+ } else if (exists < nummsgs) {
+ debug_print("Freeing imap uid cache");
+ item->lastuid = 0;
+ g_slist_free(item->uid_list);
+ item->uid_list = NULL;
+ }
+ }
+ item->uid_next = uid_next;
+
+ if (exists == 0) {
+ *msgnum_list = NULL;
return 0;
+ }
+
+ ok = imap_select(session, IMAP_FOLDER(folder), item->item.path,
+ &exists, &recent, &unseen, &uid_val);
+ if (ok != IMAP_SUCCESS)
+ return -1;
cmd_buf = g_strdup_printf("UID %d:*", item->lastuid + 1);
ok = imap_cmd_search(SESSION(session)->sock, cmd_buf, &uidlist);
lastuid_old = item->lastuid;
*msgnum_list = g_slist_copy(item->uid_list);
+ nummsgs = g_slist_length(*msgnum_list);
debug_print("Got %d uids from cache\n", g_slist_length(item->uid_list));
for (elem = uidlist; elem != NULL; elem = g_slist_next(elem)) {
}
g_slist_free(uidlist);
- if (g_slist_length(item->uid_list) != exists) {
+ if (nummsgs != exists) {
/* Cache contains more messages then folder, we have cached
- an old UID of a message that was removed */
+ an old UID of a message that was removed and new messages
+ have been added too, otherwise the uid_next check would
+ not have failed */
debug_print("Freeing imap uid cache");
item->lastuid = 0;
g_slist_free(item->uid_list);
g_return_val_if_fail(folder != NULL, FALSE);
g_return_val_if_fail(item != NULL, FALSE);
g_return_val_if_fail(item->item.folder != NULL, FALSE);
- g_return_val_if_fail(FOLDER_TYPE(item->item.folder) == F_IMAP, FALSE);
+ g_return_val_if_fail(FOLDER_CLASS(item->item.folder) == &imap_class, FALSE);
session = imap_session_get(folder);
g_return_val_if_fail(session != NULL, FALSE);