static int imap_check_capabilities (IMAP_DATA *idata);
static int imap_create_mailbox (IMAP_DATA *idata, char *mailbox);
+void imap_error (const char *where, const char *msg)
+{
+ mutt_error (_("imap_error(): unexpected response in %s: %s\n"), where, msg);
+}
+
+void imap_set_logout (CONTEXT *ctx)
+{
+ if (CTX_DATA)
+ CTX_DATA->status = IMAP_LOGOUT;
+}
+
void imap_make_sequence (char *buf, size_t buflen)
{
static int sequence = 0;
sequence = 0;
}
-void imap_error (const char *where, const char *msg)
-{
- mutt_error (_("imap_error(): unexpected response in %s: %s\n"), where, msg);
-}
-
/* imap_parse_date: date is of the form: DD-MMM-YYYY HH:MM:SS +ZZzz */
time_t imap_parse_date (char *s)
{
}
else
{
- dprint (1, (debugfile, "imap_unhandle_untagged(): unhandled request: %s\n",
+ dprint (1, (debugfile, "imap_handle_untagged(): unhandled request: %s\n",
s));
}
char seq[8];
char buf[LONG_STRING];
char flags[LONG_STRING];
+ char tmp[LONG_STRING];
int n;
+ int setstart = 0;
+
+ if (CTX_DATA->state != IMAP_SELECTED)
+ {
+ dprint (2, (debugfile, "imap_sync_mailbox: no mailbox selected\n"));
+ return -1;
+ }
+
+ /* if we are expunging anyway, we can do deleted messages very quickly... */
+ if (expunge && mutt_bit_isset (CTX_DATA->rights, IMAP_ACL_DELETE))
+ {
+ buf[0] = '\0';
+ for (n = 0; n < ctx->msgcount; n++)
+ {
+ if (ctx->hdrs[n]->changed && ctx->hdrs[n]->deleted)
+ {
+ if (setstart == 0)
+ {
+ setstart = n+1;
+ if (!buf[0])
+ snprintf (buf, sizeof (buf), "%u", n+1);
+ else
+ {
+ strncpy (tmp, buf, sizeof (tmp));
+ snprintf (buf, sizeof (buf), "%s,%u", tmp, n+1);
+ }
+ }
+ /* tie up if the last message is also deleted */
+ else if (n == ctx->msgcount-1)
+ {
+ strncpy (tmp, buf, sizeof (tmp));
+ snprintf (buf, sizeof (buf), "%s:%u", tmp, n+1);
+ }
+ /* the normal flag update can skip this message */
+ ctx->hdrs[n]->changed = 0;
+ }
+ else if (setstart && (n > setstart))
+ {
+ setstart = 0;
+ strncpy (tmp, buf, sizeof (tmp));
+ snprintf (buf, sizeof (buf), "%s:%u", tmp, n);
+ }
+ }
+ /* if we have a message set, then let's delete */
+ if (buf[0])
+ {
+ snprintf (tmp, sizeof (tmp), _("Marking %d messages for deletion..."), ctx->deleted);
+ mutt_message (tmp);
+ imap_make_sequence (seq, sizeof (seq));
+ snprintf (tmp, sizeof (tmp), "%s STORE %s +FLAGS.SILENT (\\Deleted)\r\n",
+ seq, buf);
+ if (imap_exec (buf, sizeof (buf), CTX_DATA, seq, tmp, 0) != 0)
+ /* continue, let regular store try before giving up */
+ dprint(2, (debugfile, "imap_sync_mailbox: fast delete failed\n"));
+ }
+ }
/* save status changes */
for (n = 0; n < ctx->msgcount; n++)
if (expunge == 1)
{
- if (mutt_bit_isset(CTX_DATA->rights, IMAP_ACL_DELETE))
+ /* expunge is implicit if closing */
+ if (ctx->closing)
+ {
+ mutt_message _("Closing mailbox...");
+ imap_make_sequence (seq, sizeof (seq));
+ snprintf (buf, sizeof (buf), "%s CLOSE\r\n", seq);
+ if (imap_exec (buf, sizeof (buf), CTX_DATA, seq, buf, 0) != 0)
+ {
+ imap_error ("imap_sync_mailbox()", buf);
+ return -1;
+ }
+ CTX_DATA->state = IMAP_AUTHENTICATED;
+ }
+ else if (mutt_bit_isset(CTX_DATA->rights, IMAP_ACL_DELETE))
{
mutt_message _("Expunging messages from server...");
CTX_DATA->status = IMAP_EXPUNGE;
if (imap_exec (buf, sizeof (buf), CTX_DATA, seq, buf, 0) != 0)
{
imap_error ("imap_sync_mailbox()", buf);
- return (-1);
+ return -1;
}
CTX_DATA->status = 0;
}
safe_free ((void **) &CTX_DATA->cache[i].path);
}
}
- if (CTX_DATA->status == IMAP_BYE || CTX_DATA->status == IMAP_FATAL)
+ if (CTX_DATA->status == IMAP_BYE || CTX_DATA->status == IMAP_FATAL ||
+ CTX_DATA->status == IMAP_LOGOUT)
{
imap_close_connection (ctx);
CTX_DATA->conn->data = NULL;
{
if (imap_sync_mailbox (ctx, purge) == -1)
return -1;
+ if (ctx->magic == M_IMAP && !purge)
+ mutt_message (_("%d kept."), ctx->msgcount);
}
+ else
#endif
- if (!purge)
{
- for (i = 0; i < ctx->msgcount; i++)
- ctx->hdrs[i]->deleted = 0;
- ctx->deleted = 0;
- }
+ if (!purge)
+ {
+ for (i = 0; i < ctx->msgcount; i++)
+ ctx->hdrs[i]->deleted = 0;
+ ctx->deleted = 0;
+ }
- if (ctx->changed || ctx->deleted)
- {
- if (sync_mailbox (ctx) == -1)
- return (-1);
- }
+ if (ctx->changed || ctx->deleted)
+ {
+ if (sync_mailbox (ctx) == -1)
+ return -1;
+ }
-#ifdef USE_IMAP
- if (ctx->magic == M_IMAP && !purge)
- mutt_message (_("%d kept."), ctx->msgcount);
- else
-#endif
- if (move_messages)
- mutt_message (_("%d kept, %d moved, %d deleted."),
- ctx->msgcount - ctx->deleted, read_msgs, ctx->deleted);
- else
- mutt_message (_("%d kept, %d deleted."),
- ctx->msgcount - ctx->deleted, ctx->deleted);
+ if (move_messages)
+ mutt_message (_("%d kept, %d moved, %d deleted."),
+ ctx->msgcount - ctx->deleted, read_msgs, ctx->deleted);
+ else
+ mutt_message (_("%d kept, %d deleted."),
+ ctx->msgcount - ctx->deleted, ctx->deleted);
- if (ctx->msgcount == ctx->deleted &&
- (ctx->magic == M_MMDF || ctx->magic == M_MBOX) &&
- !mutt_is_spool(ctx->path) && !option (OPTSAVEEMPTY))
- mx_unlink_empty (ctx->path);
+ if (ctx->msgcount == ctx->deleted &&
+ (ctx->magic == M_MMDF || ctx->magic == M_MBOX) &&
+ !mutt_is_spool(ctx->path) && !option (OPTSAVEEMPTY))
+ mx_unlink_empty (ctx->path);
+ }
mx_fastclose_mailbox (ctx);