summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--imap/Makefile.am10
-rw-r--r--imap/command.c17
-rw-r--r--imap/imap.c21
-rw-r--r--imap/imap_private.h2
-rw-r--r--imap/message.c10
-rw-r--r--init.c4
-rw-r--r--mutt_socket.c16
-rw-r--r--mx.c12
8 files changed, 57 insertions, 35 deletions
diff --git a/imap/Makefile.am b/imap/Makefile.am
index efb97def..9f4a3f38 100644
--- a/imap/Makefile.am
+++ b/imap/Makefile.am
@@ -9,9 +9,9 @@ GSSSOURCES = auth_gss.c
endif
if USE_SASL
-SASLSOURCES = auth_sasl.c
+AUTHENTICATORS = auth_sasl.c $(GSSSOURCES)
else
-CRAMSOURCES = auth_cram.c md5c.c
+AUTHENTICATORS = auth_anon.c auth_cram.c md5c.c $(GSSSOURCES)
endif
if USE_SSL
@@ -26,6 +26,6 @@ INCLUDES = -I$(top_srcdir) -I../intl
noinst_LIBRARIES = libimap.a
noinst_HEADERS = auth.h imap_private.h md5.h message.h $(SSLHEADERS)
-libimap_a_SOURCES = auth.c auth_anon.c auth_login.c browse.c \
- command.c imap.c imap.h message.c utf7.c \
- util.c $(GSSSOURCES) $(SASLSOURCES) $(CRAMSOURCES) $(SSLSOURCES)
+libimap_a_SOURCES = auth.c auth_login.c browse.c command.c imap.c imap.h \
+ message.c utf7.c util.c $(AUTHENTICATORS) $(SSLSOURCES)
+
diff --git a/imap/command.c b/imap/command.c
index 8d628296..609f04e6 100644
--- a/imap/command.c
+++ b/imap/command.c
@@ -85,7 +85,10 @@ int imap_cmd_resp (IMAP_DATA* idata)
if ((c = mutt_socket_readln (idata->buf + len, idata->blen - len,
idata->conn)) < 0)
{
- dprint (1, (debugfile, "imap_cmd_resp: Error while reading server response.\n"));
+ dprint (1, (debugfile, "imap_cmd_resp: Error while reading server response, closing connection.\n"));
+ mutt_socket_close (idata->conn);
+ idata->state = IMAP_DISCONNECTED;
+ idata->status = IMAP_FATAL;
return IMAP_CMD_FAIL;
}
@@ -136,12 +139,12 @@ void imap_cmd_finish (IMAP_DATA* idata)
}
if ((idata->status == IMAP_NEW_MAIL ||
- (idata->reopen & (IMAP_REOPEN_PENDING|IMAP_NEWMAIL_PENDING)))
+ (idata->reopen & (IMAP_EXPUNGE_PENDING|IMAP_NEWMAIL_PENDING)))
&& (idata->reopen & IMAP_REOPEN_ALLOW))
{
int count = idata->newMailCount;
- if (!(idata->reopen & IMAP_REOPEN_PENDING) &&
+ if (!(idata->reopen & IMAP_EXPUNGE_PENDING) &&
((idata->status == IMAP_NEW_MAIL) || (idata->reopen & IMAP_NEWMAIL_PENDING))
&& count > idata->ctx->msgcount)
{
@@ -156,7 +159,7 @@ void imap_cmd_finish (IMAP_DATA* idata)
{
imap_expunge_mailbox (idata);
idata->check_status = IMAP_REOPENED;
- idata->reopen &= ~(IMAP_REOPEN_PENDING|IMAP_NEWMAIL_PENDING);
+ idata->reopen &= ~(IMAP_EXPUNGE_PENDING|IMAP_NEWMAIL_PENDING);
}
}
@@ -252,7 +255,7 @@ int imap_handle_untagged (IMAP_DATA* idata, char* s)
/* new mail arrived */
count = atoi (pn);
- if ( !(idata->reopen & IMAP_REOPEN_PENDING) &&
+ if ( !(idata->reopen & IMAP_EXPUNGE_PENDING) &&
count < idata->ctx->msgcount)
{
/* something is wrong because the server reported fewer messages
@@ -270,7 +273,7 @@ int imap_handle_untagged (IMAP_DATA* idata, char* s)
"imap_handle_untagged: superfluous EXISTS message.\n"));
else
{
- if (!(idata->reopen & IMAP_REOPEN_PENDING))
+ if (!(idata->reopen & IMAP_EXPUNGE_PENDING))
{
dprint (2, (debugfile,
"imap_handle_untagged: New mail in %s - %d messages total.\n",
@@ -378,7 +381,7 @@ static void cmd_parse_expunge (IMAP_DATA* idata, char* s)
HEADER_DATA (h)->sid--;
}
- idata->reopen |= IMAP_REOPEN_PENDING;
+ idata->reopen |= IMAP_EXPUNGE_PENDING;
}
/* cmd_parse_myrights: set rights bits according to MYRIGHTS response */
diff --git a/imap/imap.c b/imap/imap.c
index 102b9820..86ec6511 100644
--- a/imap/imap.c
+++ b/imap/imap.c
@@ -196,8 +196,7 @@ int imap_read_literal (FILE* fp, IMAP_DATA* idata, long bytes)
/* imap_expunge_mailbox: Purge IMAP portion of expunged messages from the
* context. Must not be done while something has a handle on any headers
- * (eg inside pager or editor). mx_update_tables and mutt_sort_headers
- * must be called afterwards. */
+ * (eg inside pager or editor). That is, check IMAP_REOPEN_ALLOW. */
void imap_expunge_mailbox (IMAP_DATA* idata)
{
HEADER* h;
@@ -225,6 +224,11 @@ void imap_expunge_mailbox (IMAP_DATA* idata)
imap_free_header_data (&h->data);
}
}
+
+ /* We may be called on to expunge at any time. We can't rely on the caller
+ * to always know to rethread */
+ mx_update_tables (idata->ctx, 0);
+ mutt_sort_headers (idata->ctx, 1);
}
#if 0
@@ -1124,7 +1128,8 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint)
if (*flags && (imap_exec (idata, buf, 0) != 0) &&
(err_continue != M_YES))
{
- err_continue = imap_continue ("imap_sync_mailbox: STORE failed", buf);
+ err_continue = imap_continue ("imap_sync_mailbox: STORE failed",
+ idata->buf);
if (err_continue != M_YES)
return -1;
}
@@ -1141,7 +1146,7 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint)
mutt_message _("Expunging messages from server...");
if (imap_exec (idata, "EXPUNGE", 0) != 0)
{
- imap_error ("imap_sync_mailbox: EXPUNGE failed", buf);
+ imap_error ("imap_sync_mailbox: EXPUNGE failed", idata->buf);
return -1;
}
}
@@ -1164,12 +1169,8 @@ void imap_close_mailbox (CONTEXT* ctx)
if ((idata->state == IMAP_SELECTED) && (ctx == idata->ctx))
{
- if (!(idata->noclose))
- {
- mutt_message _("Closing mailbox...");
- if (imap_exec (idata, "CLOSE", 0) != 0)
- imap_error ("CLOSE failed", idata->buf);
- }
+ if (!(idata->noclose) && imap_exec (idata, "CLOSE", 0))
+ imap_error ("CLOSE failed", idata->buf);
idata->state = IMAP_AUTHENTICATED;
FREE (&(idata->mailbox));
diff --git a/imap/imap_private.h b/imap/imap_private.h
index fe197a64..412e9521 100644
--- a/imap/imap_private.h
+++ b/imap/imap_private.h
@@ -44,7 +44,7 @@
#define SEQLEN 5
#define IMAP_REOPEN_ALLOW (1<<0)
-#define IMAP_REOPEN_PENDING (1<<1)
+#define IMAP_EXPUNGE_PENDING (1<<1)
#define IMAP_NEWMAIL_PENDING (1<<2)
/* imap_exec flags (see imap_exec) */
diff --git a/imap/message.c b/imap/message.c
index a5e5fccd..74c4da85 100644
--- a/imap/message.c
+++ b/imap/message.c
@@ -199,6 +199,9 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
int uid;
int cacheno;
IMAP_CACHE *cache;
+ /* Sam's weird courier server returns an OK response even when FETCH
+ * fails. Thanks Sam. */
+ short fetched = 0;
int rc;
idata = (IMAP_DATA*) ctx->data;
@@ -245,11 +248,12 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
do
{
if ((rc = imap_cmd_resp (idata)) != IMAP_CMD_CONTINUE)
- continue;
+ break;
pc = idata->buf;
pc = imap_next_word (pc);
pc = imap_next_word (pc);
+
if (!mutt_strncasecmp ("FETCH", pc, 5))
{
while (*pc)
@@ -278,6 +282,8 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
if ((rc = imap_cmd_resp (idata)) != IMAP_CMD_CONTINUE)
goto bail;
pc = idata->buf;
+
+ fetched = 1;
}
/* UW-IMAP will provide a FLAGS update here if the FETCH causes a
* change (eg from \Unseen to \Seen).
@@ -336,7 +342,7 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
if (rc != IMAP_CMD_DONE)
goto bail;
- if (!imap_code (idata->buf))
+ if (!fetched || !imap_code (idata->buf))
goto bail;
/* Update the header information. Previously, we only downloaded a
diff --git a/init.c b/init.c
index 533f8b71..7d26ea6c 100644
--- a/init.c
+++ b/init.c
@@ -1836,6 +1836,10 @@ void mutt_init (int skip_sys_rc, LIST *commands)
set_option (OPTLOCALES);
#endif
+ /* Unset suspend by default if we're the session leader */
+ if (getsid(0) == getpid())
+ unset_option (OPTSUSPEND);
+
mutt_init_history ();
diff --git a/mutt_socket.c b/mutt_socket.c
index 14704508..bc39fdf6 100644
--- a/mutt_socket.c
+++ b/mutt_socket.c
@@ -63,6 +63,12 @@ int mutt_socket_write_d (CONNECTION *conn, const char *buf, int dbg)
dprint (dbg, (debugfile,"> %s", buf));
+ if (conn->fd < 0)
+ {
+ dprint (1, (debugfile, "mutt_socket_write: attempt to write to closed connection\n"));
+ return -1;
+ }
+
if ((rc = conn->write (conn, buf, mutt_strlen (buf))) < 0)
{
dprint (1, (debugfile, "mutt_socket_write: error writing, closing socket\n"));
@@ -79,7 +85,13 @@ int mutt_socket_readchar (CONNECTION *conn, char *c)
{
if (conn->bufpos >= conn->available)
{
- conn->available = conn->read (conn);
+ if (conn->fd >= 0)
+ conn->available = conn->read (conn);
+ else
+ {
+ dprint (1, (debugfile, "mutt_socket_readchar: attempt to read closed from connection.\n"));
+ return -1;
+ }
conn->bufpos = 0;
if (conn->available <= 0)
return conn->available; /* returns 0 for EOF or -1 for other error */
@@ -98,9 +110,7 @@ int mutt_socket_readln_d (char* buf, size_t buflen, CONNECTION* conn, int dbg)
{
if (mutt_socket_readchar (conn, &ch) != 1)
{
- dprint (1, (debugfile, "mutt_socket_readln_d: read error, closing socket"));
buf[i] = '\0';
- mutt_socket_close (conn);
return -1;
}
if (ch == '\n')
diff --git a/mx.c b/mx.c
index 4f50560d..8106137b 100644
--- a/mx.c
+++ b/mx.c
@@ -1118,15 +1118,13 @@ int mx_sync_mailbox (CONTEXT *ctx, int *index_hint)
if (purge)
{
#ifdef USE_IMAP
- /* IMAP uses the active flag, since deleted messages may remain after
- * a sync */
- if (ctx->magic == M_IMAP)
- mx_update_tables (ctx, 0);
- else
+ /* IMAP does this automatically after handling EXPUNGE */
+ if (ctx->magic != M_IMAP)
#endif
+ {
mx_update_tables (ctx, 1);
-
- mutt_sort_headers (ctx, 1); /* rethread from scratch */
+ mutt_sort_headers (ctx, 1); /* rethread from scratch */
+ }
}
}