From: Thomas Roessler Date: Tue, 18 Jul 2000 07:48:48 +0000 (+0000) Subject: IMAP fixes from Brendan Cully. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=076a584ba44872fbb701573d3cbdcdbca250e689;p=neomutt IMAP fixes from Brendan Cully. --- diff --git a/imap/imap.c b/imap/imap.c index 754c92f13..dd73f0317 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 92284f20d..0923966e7 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 e608fc2ae..6c1b2fca6 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 f418e0202..2d8c93dab 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 071926063..4733b8141 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;