summaryrefslogtreecommitdiffstats
path: root/imap
diff options
context:
space:
mode:
authorThomas Roessler <roessler@does-not-exist.org>1999-09-08 06:05:51 +0000
committerThomas Roessler <roessler@does-not-exist.org>1999-09-08 06:05:51 +0000
commitf24c25bff3454897fbb8a6a888d1311e867f800e (patch)
treeba7cd964ac22925d28b350b26dd2712ec3be87a3 /imap
parent491856cbb79b2f643facf291c1918bfb919966bd (diff)
The attached patch:
* gets Mutt to properly log off the IMAP server when quitting. Clients don't care, but it's polite and proper. * further updates the flags changes from yesterday * uses CLOSE instead of EXPUNGE when closing a mailbox and purging messages, for some slight speed gain. * purges all messages marked for deletion in one command (if purging), making for very cool speed gains switching mailboxes if you're on, say, a few high volume mailing lists. Yeah, baby! (I personally love this one). (From Brendan Cully <brendan@kublai.com>)
Diffstat (limited to 'imap')
-rw-r--r--imap/imap.c95
-rw-r--r--imap/imap.h2
-rw-r--r--imap/imap_private.h3
3 files changed, 90 insertions, 10 deletions
diff --git a/imap/imap.c b/imap/imap.c
index b577de91..c1540451 100644
--- a/imap/imap.c
+++ b/imap/imap.c
@@ -54,6 +54,17 @@ static int imap_check_acl (IMAP_DATA *idata);
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;
@@ -64,11 +75,6 @@ void imap_make_sequence (char *buf, size_t buflen)
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)
{
@@ -354,7 +360,7 @@ int imap_handle_untagged (IMAP_DATA *idata, char *s)
}
else
{
- dprint (1, (debugfile, "imap_unhandle_untagged(): unhandled request: %s\n",
+ dprint (1, (debugfile, "imap_handle_untagged(): unhandled request: %s\n",
s));
}
@@ -1277,7 +1283,64 @@ int imap_sync_mailbox (CONTEXT *ctx, int expunge)
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++)
@@ -1337,7 +1400,20 @@ int imap_sync_mailbox (CONTEXT *ctx, int expunge)
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;
@@ -1346,7 +1422,7 @@ int imap_sync_mailbox (CONTEXT *ctx, int 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;
}
@@ -1387,7 +1463,8 @@ void imap_fastclose_mailbox (CONTEXT *ctx)
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;
diff --git a/imap/imap.h b/imap/imap.h
index 52e71ada..15395f01 100644
--- a/imap/imap.h
+++ b/imap/imap.h
@@ -23,11 +23,13 @@
#include "mailbox.h"
int imap_check_mailbox (CONTEXT *ctx, int *index_hint);
+int imap_close_connection (CONTEXT *ctx);
int imap_open_mailbox (CONTEXT *ctx);
int imap_open_mailbox_append (CONTEXT *ctx);
int imap_parse_path (char *path, char *host, size_t hlen, int *port,
char **mbox);
int imap_select_mailbox (CONTEXT *ctx, const char* path);
+void imap_set_logout (CONTEXT *ctx);
int imap_sync_mailbox (CONTEXT *ctx, int expunge);
void imap_fastclose_mailbox (CONTEXT *ctx);
int imap_buffy_check (char *path);
diff --git a/imap/imap_private.h b/imap/imap_private.h
index 3fcfbc0d..618f9d4b 100644
--- a/imap/imap_private.h
+++ b/imap/imap_private.h
@@ -37,7 +37,8 @@ enum
IMAP_EXPUNGE,
IMAP_BYE,
IMAP_OK_FAIL,
- IMAP_REOPENED
+ IMAP_REOPENED,
+ IMAP_LOGOUT
};
enum