static gint imap_cmd_fetch (SockInfo *sock,
guint32 uid,
const gchar *filename);
-static gint imap_cmd_append (SockInfo *sock,
+static gint imap_cmd_append (IMAPSession *session,
const gchar *destfolder,
- const gchar *file);
+ const gchar *file,
+ gint32 *newuid);
static gint imap_cmd_copy (IMAPSession *session,
gint32 msgnum,
const gchar *destfolder,
{
gchar *destdir;
IMAPSession *session;
- gint ok;
+ gint ok, newuid;
g_return_val_if_fail(folder != NULL, -1);
g_return_val_if_fail(dest != NULL, -1);
if (!session) return -1;
destdir = imap_get_real_path(IMAP_FOLDER(folder), dest->path);
- ok = imap_cmd_append(SESSION(session)->sock, destdir, file);
+ ok = imap_cmd_append(session, destdir, file, &newuid);
g_free(destdir);
if (ok != IMAP_SUCCESS) {
FILE_OP_ERROR(file, "unlink");
}
- return 0;
+ return newuid;
}
static gint imap_do_copy(Folder *folder, FolderItem *dest, MsgInfo *msginfo,
gchar *destdir;
IMAPSession *session;
IMAPFlags iflags = 0;
- gint messages, recent, unseen;
- guint32 newuid = 0, uid_validity;
+ guint32 newuid = 0;
gint ok;
g_return_val_if_fail(folder != NULL, -1);
return -1;
}
- /* if we don't have UIDPLUS we get UID-NEXT and hope that the
- message really gets this uid */
- if (!imap_has_capability(session, "UIDPLUS")) {
- ok = imap_status(session, IMAP_FOLDER(folder), dest->path,
- &messages, &recent, &newuid, &uid_validity, &unseen);
- if (ok != IMAP_SUCCESS) {
- g_warning("can't copy message\n");
- return -1;
- }
- }
-
destdir = imap_get_real_path(IMAP_FOLDER(folder), dest->path);
/* ensure source folder selected */
return ok;
}
-static gint imap_cmd_append(SockInfo *sock, const gchar *destfolder,
- const gchar *file)
+static gint imap_cmd_append(IMAPSession *session, const gchar *destfolder,
+ const gchar *file, gint32 *new_uid)
{
gint ok;
- gint size;
+ gint size, newuid;
gchar *destfolder_;
gchar buf[BUFFSIZE], *imapbuf;
FILE *fp;
+ GPtrArray *reply;
+ gchar *okmsginfo;
g_return_val_if_fail(file != NULL, IMAP_ERROR);
return -1;
}
QUOTE_IF_REQUIRED(destfolder_, destfolder);
- imap_cmd_gen_send(sock, "APPEND %s (\\Seen) {%d}", destfolder_, size);
+ imap_cmd_gen_send(SESSION(session)->sock, "APPEND %s (\\Seen) {%d}", destfolder_, size);
- ok = imap_cmd_gen_recv(sock, &imapbuf);
+ ok = imap_cmd_gen_recv(SESSION(session)->sock, &imapbuf);
if (ok != IMAP_SUCCESS || imapbuf[0] != '+' || imapbuf[1] != ' ') {
log_warning(_("can't append %s to %s\n"), file, destfolder_);
g_free(imapbuf);
while (fgets(buf, sizeof(buf), fp) != NULL) {
strretchomp(buf);
- if (sock_puts(sock, buf) < 0) {
+ if (sock_puts(SESSION(session)->sock, buf) < 0) {
fclose(fp);
- sock_close(sock);
+ sock_close(SESSION(session)->sock);
return -1;
}
}
if (ferror(fp)) {
FILE_OP_ERROR(file, "fgets");
fclose(fp);
- sock_close(sock);
+ sock_close(SESSION(session)->sock);
return -1;
}
- sock_puts(sock, "");
+ sock_puts(SESSION(session)->sock, "");
fclose(fp);
- return imap_cmd_ok(sock, NULL);
-}
-
-#if 0
-static void imap_uidplus_copy(IMAPSession *session, MsgInfo *msginfo,
- const gchar *destfolder, const gchar *okmsginfo)
-{
- unsigned int olduid, newuid;
- IMAPFlags iflags = 0;
-
- if (okmsginfo == NULL)
- return;
-
- if (sscanf(okmsginfo, "%*u OK [COPYUID %*llu %u %u]", &olduid, &newuid) != 2)
- return;
-
- if (olduid != msginfo->msgnum) /* this should NEVER happen */
- return;
- if (imap_select(session, IMAP_FOLDER(msginfo->folder->folder), destfolder,
- NULL, NULL, NULL, NULL) != IMAP_SUCCESS)
- return;
-
- if (msginfo->flags.perm_flags & MSG_MARKED) iflags |= IMAP_FLAG_FLAGGED;
- if (msginfo->flags.perm_flags & MSG_REPLIED) iflags |= IMAP_FLAG_ANSWERED;
- if (iflags)
- imap_set_message_flags(session, newuid, newuid, iflags, TRUE);
+ reply = g_ptr_array_new();
- if (msginfo->flags.perm_flags & MSG_UNREAD)
- imap_set_message_flags(session, newuid, newuid, IMAP_FLAG_SEEN, FALSE);
+ *new_uid = 0;
+ ok = imap_cmd_ok(SESSION(session)->sock, reply);
+ if (ok != IMAP_SUCCESS)
+ log_warning(_("can't append message to %s\n"), destfolder_);
+ else if (
+ (new_uid != NULL) &&
+ (imap_has_capability(session, "UIDPLUS") && reply->len > 0) &&
+ ((okmsginfo = g_ptr_array_index(reply, reply->len - 1)) != NULL) &&
+ (sscanf(okmsginfo, "%*u OK [APPENDUID %*u %u]", &newuid) == 1)) {
+ *new_uid = newuid;
+ }
- imap_select(session, IMAP_FOLDER(msginfo->folder->folder), msginfo->folder->path,
- NULL, NULL, NULL, NULL);
+ ptr_array_free_strings(reply);
+ g_ptr_array_free(reply, TRUE);
+ return ok;
}
-#endif
-static gint imap_cmd_copy(IMAPSession *session,
- gint32 msgnum, const gchar *destfolder, gint32 *new_uid)
+
+static gint imap_cmd_copy(IMAPSession * session,
+ gint32 msgnum,
+ const gchar * destfolder, gint32 * new_uid)
{
gint ok;
gint32 olduid, newuid;
reply = g_ptr_array_new();
+ *new_uid = 0;
ok = imap_cmd_ok(SESSION(session)->sock, reply);
if (ok != IMAP_SUCCESS)
log_warning(_("can't copy %d to %s\n"), msgnum, destfolder_);
return FALSE;
}
-gint imap_get_num_list(Folder *folder, FolderItem *_item, GSList **msgnum_list)
+static gint get_list_of_uids(Folder *folder, IMAPFolderItem *item, GSList **msgnum_list)
{
- IMAPFolderItem *item = (IMAPFolderItem *)_item;
+ gint ok, nummsgs = 0, lastuid_old;
IMAPSession *session;
- 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_CLASS(folder) == &imap_class, -1);
- g_return_val_if_fail(folder->account != NULL, -1);
+ gchar *cmd_buf;
session = imap_session_get(folder);
g_return_val_if_fail(session != NULL, -1);
- ok = imap_status(session, IMAP_FOLDER(folder), item->item.path,
- &exists, &recent, &uid_next, &uid_val, &unseen);
- if (ok != IMAP_SUCCESS)
- return -1;
-
- /* 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);
+ NULL, NULL, NULL, NULL);
if (ok != IMAP_SUCCESS)
return -1;
}
g_slist_free(uidlist);
+ return nummsgs;
+}
+
+gint imap_get_num_list(Folder *folder, FolderItem *_item, GSList **msgnum_list)
+{
+ IMAPFolderItem *item = (IMAPFolderItem *)_item;
+ IMAPSession *session;
+ gint ok, nummsgs = 0, exists, recent, unseen, uid_val, uid_next;
+ GSList *uidlist;
+ gchar *dir;
+
+ 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_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_status(session, IMAP_FOLDER(folder), item->item.path,
+ &exists, &recent, &uid_next, &uid_val, &unseen);
+ if (ok != IMAP_SUCCESS)
+ return -1;
+
+ /* 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;
+ }
+
+ nummsgs = get_list_of_uids(folder, item, &uidlist);
+
if (nummsgs != exists) {
/* Cache contains more messages then folder, we have cached
an old UID of a message that was removed and new messages
g_slist_free(*msgnum_list);
- return imap_get_num_list(folder, _item, msgnum_list);
+ nummsgs = get_list_of_uids(folder, item, &uidlist);
}
+ *msgnum_list = uidlist;
+
dir = folder_item_get_path((FolderItem *)item);
debug_print("removing old messages from %s\n", dir);
remove_numbered_files_not_in_list(dir, *msgnum_list);