]> granicus.if.org Git - neomutt/commitdiff
IMAP fixes from Brendan Cully.
authorThomas Roessler <roessler@does-not-exist.org>
Tue, 18 Jul 2000 07:48:48 +0000 (07:48 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Tue, 18 Jul 2000 07:48:48 +0000 (07:48 +0000)
imap/imap.c
imap/imap_private.h
imap/message.c
imap/socket.c
imap/utf7.c

index 754c92f1345ae338eb69c7927817e4799f604385..dd73f03171758aaa52c627fc3a47bb26cb170b8d 100644 (file)
@@ -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;
index 92284f20d8e44ec51c6ffd0291fe34702f73fa74..0923966e7d0470a51bbe83f6cc36e7af147cb1f2 100644 (file)
@@ -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);
 
index e608fc2ae254fd43e7655fda4943b684183a5c5c..6c1b2fca66368d08ad795e79060e9b677774f1a5 100644 (file)
@@ -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.
index f418e0202f535075bf12a5ef46b1106767486439..2d8c93dabbbd068bd484d36eac42c63a5a089f0d 100644 (file)
@@ -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)
index 071926063c06895457d6d5d455daf86f31ad70a2..4733b81417f7416f2890b8866ff5e133c7230adc 100644 (file)
@@ -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;