summaryrefslogtreecommitdiffstats
path: root/imap
diff options
context:
space:
mode:
authorThomas Roessler <roessler@does-not-exist.org>2000-07-18 07:48:48 +0000
committerThomas Roessler <roessler@does-not-exist.org>2000-07-18 07:48:48 +0000
commit2276418fdb25e61a395967fd30cef274967baaa9 (patch)
treefc56c8c3f4d711c32801fcaffea1840bbb5d7817 /imap
parente52e44a54575122b897068af60267592d5eccbd9 (diff)
IMAP fixes from Brendan Cully.
Diffstat (limited to 'imap')
-rw-r--r--imap/imap.c40
-rw-r--r--imap/imap_private.h5
-rw-r--r--imap/message.c39
-rw-r--r--imap/socket.c14
-rw-r--r--imap/utf7.c6
5 files changed, 65 insertions, 39 deletions
diff --git a/imap/imap.c b/imap/imap.c
index 754c92f1..dd73f031 100644
--- a/imap/imap.c
+++ b/imap/imap.c
@@ -118,22 +118,42 @@ time_t imap_parse_date (char *s)
return (mutt_mktime (&t, 0) + tz);
}
-/* imap_read_bytes: read bytes bytes from server into file */
-int imap_read_bytes (FILE *fp, CONNECTION *conn, long bytes)
+/* imap_read_literal: read bytes bytes from server into file. Not explicitly
+ * buffered, relies on FILE buffering. NOTE: strips \r from \r\n.
+ * Apparently even literals use \r\n-terminated strings ?! */
+int imap_read_literal (FILE* fp, CONNECTION* conn, long bytes)
{
long pos;
- long len;
- char buf[LONG_STRING];
+ char c;
+
+ int r = 0;
- for (pos = 0; pos < bytes; )
+ dprint (2, (debugfile, "imap_read_literal: reading %ld bytes\n", bytes));
+
+ for (pos = 0; pos < bytes; pos++)
{
- len = mutt_socket_readln_d (buf, sizeof (buf), conn, IMAP_LOG_HDR);
- if (len < 0)
+ if (mutt_socket_readchar (conn, &c) != 1)
+ {
+ dprint (1, (debugfile, "imap_read_literal: error during read, %ld bytes read\n", pos));
return -1;
+ }
+
+ if (r == 1 && c != '\n')
+ fputc ('\r', fp);
- pos += len;
- fputs (buf, fp);
- fputs ("\n", fp);
+ if (c == '\r')
+ {
+ r = 1;
+ continue;
+ }
+ else
+ r = 0;
+
+ fputc (c, fp);
+#ifdef DEBUG
+ if (debuglevel >= IMAP_LOG_LTRL)
+ fputc (c, debugfile);
+#endif
}
return 0;
diff --git a/imap/imap_private.h b/imap/imap_private.h
index 92284f20..0923966e 100644
--- a/imap/imap_private.h
+++ b/imap/imap_private.h
@@ -29,8 +29,7 @@
/* logging levels */
#define IMAP_LOG_CMD 2
-#define IMAP_LOG_HDR 3
-#define IMAP_LOG_BODY 4
+#define IMAP_LOG_LTRL 4
#define IMAP_LOG_PASS 5
/* number of entries in the hash table */
@@ -176,7 +175,7 @@ int imap_open_connection (IMAP_DATA* idata, CONNECTION* conn);
time_t imap_parse_date (char* s);
int imap_parse_list_response(CONNECTION* conn, char* buf, int buflen,
char** name, int* noselect, int* noinferiors, char* delim);
-int imap_read_bytes (FILE* fp, CONNECTION* conn, long bytes);
+int imap_read_literal (FILE* fp, CONNECTION* conn, long bytes);
int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint);
void imap_logout (CONNECTION* conn);
diff --git a/imap/message.c b/imap/message.c
index e608fc2a..6c1b2fca 100644
--- a/imap/message.c
+++ b/imap/message.c
@@ -82,6 +82,10 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
return -1;
unlink (tempfile);
+ /* make sure context has room to hold the mailbox */
+ while ((msgend) >= ctx->hdrmax)
+ mx_alloc_memory (ctx);
+
for (msgno = msgbegin; msgno <= msgend ; msgno++)
{
mutt_message (_("Fetching message headers... [%d/%d]"), msgno + 1,
@@ -122,6 +126,9 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
if (buf[0] == '*')
{
rc = msg_fetch_header (ctx, h, buf, fp);
+ /* make sure we don't get remnants from older larger message headers */
+ fputs ("\n\n", fp);
+
if ((rc == -1 && imap_handle_untagged (CTX_DATA, buf)) || rc == -2)
{
imap_free_header_data ((void**) &(h->data));
@@ -131,6 +138,7 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
}
/* update context with message header */
+
ctx->hdrs[ctx->msgcount] = mutt_new_header ();
ctx->hdrs[ctx->msgcount]->index = ctx->msgcount;
@@ -160,12 +168,12 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
while ((msgno + 1) >= fetchlast && mutt_strncmp (seq, buf, SEQLEN) != 0);
/* in case we get new mail while fetching the headers */
- if (((IMAP_DATA *) ctx->data)->status == IMAP_NEW_MAIL)
+ if (CTX_DATA->status == IMAP_NEW_MAIL)
{
- msgend = ((IMAP_DATA *) ctx->data)->newMailCount - 1;
- while ((msgend + 1) > ctx->hdrmax)
- mx_alloc_memory (ctx);
- ((IMAP_DATA *) ctx->data)->status = 0;
+ msgend = CTX_DATA->newMailCount - 1;
+ while ((msgend) >= ctx->hdrmax)
+ mx_alloc_memory (ctx);
+ CTX_DATA->status = 0;
}
}
@@ -176,12 +184,11 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
{
- char seq[8];
+ char seq[SEQLEN+1];
char buf[LONG_STRING];
char path[_POSIX_PATH_MAX];
char *pc;
long bytes;
- int pos, len;
IMAP_CACHE *cache;
/* see if we already have the message in our cache */
@@ -253,18 +260,10 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
imap_error ("imap_fetch_message()", buf);
goto bail;
}
- for (pos = 0; pos < bytes; )
- {
- len = mutt_socket_readln_d (buf, sizeof (buf), CTX_DATA->conn,
- IMAP_LOG_BODY);
- if (len < 0)
- goto bail;
- pos += len;
- fputs (buf, msg->fp);
- fputs ("\n", msg->fp);
- }
- if (mutt_socket_readln_d (buf, sizeof (buf), CTX_DATA->conn,
- IMAP_LOG_BODY) < 0)
+ if (imap_read_literal (msg->fp, CTX_DATA->conn, bytes) < 0)
+ goto bail;
+ /* pick up trailing line */
+ if (mutt_socket_readln (buf, sizeof (buf), CTX_DATA->conn) < 0)
goto bail;
pc = buf;
}
@@ -652,7 +651,7 @@ static int msg_fetch_header (CONTEXT* ctx, IMAP_HEADER* h, char* buf, FILE* fp)
if (imap_get_literal_count (buf, &bytes) < 0)
return rc;
- imap_read_bytes (fp, CTX_DATA->conn, bytes);
+ imap_read_literal (fp, CTX_DATA->conn, bytes);
/* we may have other fields of the FETCH _after_ the literal
* (eg Domino puts FLAGS here). Nothing wrong with that, either.
diff --git a/imap/socket.c b/imap/socket.c
index f418e020..2d8c93da 100644
--- a/imap/socket.c
+++ b/imap/socket.c
@@ -89,22 +89,28 @@ int mutt_socket_readln_d (char* buf, size_t buflen, CONNECTION* conn, int dbg)
char ch;
int i;
- for (i = 0; i < buflen; i++)
+ for (i = 0; i < buflen-1; i++)
{
if (mutt_socket_readchar (conn, &ch) != 1)
- return (-1);
+ {
+ dprint (1, (debugfile, "mutt_socket_readln_d: read error"));
+ buf[i] = '\0';
+ return -1;
+ }
if (ch == '\n')
break;
buf[i] = ch;
}
- if (i)
+
+ /* strip \r from \r\n termination */
+ if (i && buf[i-1] == '\r')
buf[i-1] = '\0';
else
buf[i] = '\0';
dprint (dbg, (debugfile, "< %s\n", buf));
- return (i + 1);
+ return i+1;
}
CONNECTION* mutt_socket_find (const IMAP_MBOX* mx, int newconn)
diff --git a/imap/utf7.c b/imap/utf7.c
index 07192606..4733b814 100644
--- a/imap/utf7.c
+++ b/imap/utf7.c
@@ -48,7 +48,8 @@ static char B64Chars[64] = {
* form, such as &ACY- (instead of &-) or &AMA-&AMA- (instead
* of &AMAAwA-).
*/
-char *utf7_to_utf8 (const char *u7, size_t u7len, char **u8, size_t *u8len)
+static char *utf7_to_utf8 (const char *u7, size_t u7len, char **u8,
+ size_t *u8len)
{
char *buf, *p;
int b, ch, k;
@@ -140,7 +141,8 @@ char *utf7_to_utf8 (const char *u7, size_t u7len, char **u8, size_t *u8len)
* Unicode characters above U+FFFF are replaced by U+FFFE.
* If input data is invalid, return 0 and don't store anything.
*/
-char *utf8_to_utf7 (const char *u8, size_t u8len, char **u7, size_t *u7len)
+static char *utf8_to_utf7 (const char *u8, size_t u8len, char **u7,
+ size_t *u7len)
{
char *buf, *p;
int ch;