rewrite mutt_read_rfc822_header to have a more consistent API.
authorPierre Habouzit <madcoder@debian.org>
Sun, 5 Nov 2006 16:56:39 +0000 (17:56 +0100)
committerPierre Habouzit <madcoder@debian.org>
Sun, 5 Nov 2006 16:56:39 +0000 (17:56 +0100)
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
lib-mime/mime.h
lib-mime/rfc822parse.c
pattern.c
protos.h

index 498473c..51585a0 100644 (file)
@@ -31,6 +31,7 @@
 #define MUTT_LIB_MIME_MIME_H
 
 #include <stdlib.h>
+#include <stdio.h>
 
 #include "mime-types.h"
 
@@ -52,6 +53,12 @@ extern const char *BodyEncodings[];
 /*                Standard for ARPA Internet Text Messages                  */
 /****************************************************************************/
 
+extern const char RFC822Specials[];
+
+ssize_t mutt_read_rfc822_line(FILE*, char**, ssize_t*);
+
+/*** addresses ***/
+
 address_t *address_dup(address_t *addr);
 address_t *address_list_dup(address_t *addr);
 void rfc822_qualify(address_t *, const char *);
@@ -62,8 +69,6 @@ ssize_t rfc822_write_address(char *, ssize_t, address_t *, int);
 ssize_t rfc822_write_address_single(char *, ssize_t, address_t *, int);
 ssize_t rfc822_strcpy(char *, ssize_t, const char *, const char *);
 
-extern const char RFC822Specials[];
-
 /****************************************************************************/
 /* RFC 2047                                                                 */
 /*       MIME (Multipurpose Internet Mail Extensions) Part Three:           */
index 3d9211c..6a3c164 100644 (file)
  * lines.  ``line'' must point to a dynamically allocated string; it is
  * increased if more space is required to fit the whole line.
  */
-char *mutt_read_rfc822_line (FILE * f, char *line, size_t * linelen)
+ssize_t mutt_read_rfc822_line(FILE *f, char **line, ssize_t *n)
 {
-  char *buf = line;
-  char ch;
-  size_t offset = 0;
-
-  for (;;) {
-    if (fgets (buf, *linelen - offset, f) == NULL ||    /* end of file or */
-        (ISSPACE (*line) && !offset)) { /* end of headers */
-      *line = 0;
-      return (line);
-    }
+    ssize_t pos = 0;
 
-    buf += m_strlen(buf) - 1;
-    if (*buf == '\n') {
-      /* we did get a full line. remove trailing space */
-      while (ISSPACE (*buf))
-        *buf-- = 0;             /* we cannot come beyond line's beginning because
-                                 * it begins with a non-space */
-
-      /* check to see if the next line is a continuation line */
-      if ((ch = fgetc (f)) != ' ' && ch != '\t') {
-        ungetc (ch, f);
-        return (line);          /* next line is a separate header field or EOH */
-      }
+    for (;;) {
+        char *p = *line;
 
-      /* eat tabs and spaces from the beginning of the continuation line */
-      while ((ch = fgetc (f)) == ' ' || ch == '\t');
-      ungetc (ch, f);
-      *++buf = ' ';             /* string is still terminated because we removed
-                                   at least one whitespace char above */
-    }
+        /* end of file or end of headers */
+        if (!fgets(p + pos, *n - pos, f) || (ISSPACE(*p) && pos == 0)) {
+            *p = '\0';
+            return 0;
+        }
+
+        pos += m_strlen(p + pos);
+        if (p[pos - 1] == '\n') {
+            int c;
+
+            /* remove trailing spaces. safe: p[0] is not a space */
+            do {
+                p[--pos] = '\0';
+            } while (ISSPACE(p[pos]));
+
+            /* check to see if the next line is a continuation line */
+            c = fgetc(f);
+            if (c != ' ' && c != '\t') {
+                /* next line is a separate header field or EOH */
+                ungetc(c, f);
+                return pos;
+            }
 
-    buf++;
-    offset = buf - line;
-    if (*linelen < offset + STRING) {
-      /* grow the buffer */
-      *linelen += STRING;
-      p_realloc(&line, *linelen);
-      buf = line + offset;
+            /* eat tabs and spaces from the beginning of the continuation line */
+            do {
+                c = fgetc(f);
+            } while (c == ' ' || c == '\t');
+            ungetc(c, f);
+
+            /* string is still terminated because we removed at least one
+               whitespace char above */
+            p[pos++] = ' ';
+        }
+
+        if (*n < pos + STRING) {
+            /* grow the buffer */
+            *n += STRING;
+            p_realloc(line, *n);
+        }
     }
-  }
-  /* not reached */
 }
 
 LIST *mutt_parse_references (char *s, int in_reply_to)
@@ -408,7 +412,7 @@ BODY *mutt_read_mime_header (FILE * fp, int digest)
   BODY *p = mutt_new_body ();
   char *c;
   char *line = p_new(char, LONG_STRING);
-  size_t linelen = LONG_STRING;
+  ssize_t linelen = LONG_STRING;
 
   p->hdr_offset = ftello (fp);
 
@@ -416,7 +420,7 @@ BODY *mutt_read_mime_header (FILE * fp, int digest)
   p->type = digest ? TYPEMESSAGE : TYPETEXT;
   p->disposition = DISPINLINE;
 
-  while (*(line = mutt_read_rfc822_line (fp, line, &linelen)) != 0) {
+  while (mutt_read_rfc822_line(fp, &line, &linelen)) {
     /* Find the value of the current header */
     if ((c = strchr (line, ':'))) {
       *c++ = 0;
@@ -1253,7 +1257,7 @@ ENVELOPE *mutt_read_rfc822_header (FILE * f, HEADER * hdr, short user_hdrs,
   char *p;
   off_t loc;
   int matched;
-  size_t linelen = LONG_STRING;
+  ssize_t linelen = LONG_STRING;
   char buf[LONG_STRING + 1];
 
   if (hdr) {
@@ -1272,7 +1276,8 @@ ENVELOPE *mutt_read_rfc822_header (FILE * f, HEADER * hdr, short user_hdrs,
   }
 
   while ((loc = ftello (f)),
-         *(line = mutt_read_rfc822_line (f, line, &linelen)) != 0) {
+         mutt_read_rfc822_line (f, &line, &linelen))
+  {
     matched = 0;
 
     if ((p = strpbrk (line, ": \t")) == NULL || *p != ':') {
index 6f5e66a..9b325a2 100644 (file)
--- a/pattern.c
+++ b/pattern.c
@@ -215,7 +215,7 @@ msg_search (CONTEXT *ctx, pattern_t* pat, int msgno)
     /* search the file "fp" */
     while (lng > 0) {
       if (pat->op == M_HEADER) {
-        if (*(buf = mutt_read_rfc822_line (fp, buf, &blen)) == '\0')
+        if (!mutt_read_rfc822_line(fp, &buf, &blen))
           break;
       } else if (fgets (buf, blen - 1, fp) == NULL)
         break;                  /* don't loop forever */
index 7129041..b4c17bd 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -71,7 +71,6 @@ BODY *mutt_read_mime_header (FILE *, int);
 CONTENT *mutt_get_content_info (const char *fname, BODY * b);
 
 LIST *mutt_make_references (ENVELOPE * e);
-char* mutt_read_rfc822_line (FILE*, char*, size_t*);
 LIST *mutt_parse_references (char *, int);
 
 ENVELOPE *mutt_read_rfc822_header (FILE *, HEADER *, short, short);