From 89a7d4396b35e8047cbe519e81e22d99a1efd018 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Sun, 5 Nov 2006 17:56:39 +0100 Subject: [PATCH] rewrite mutt_read_rfc822_header to have a more consistent API. Signed-off-by: Pierre Habouzit --- lib-mime/mime.h | 9 ++++- lib-mime/rfc822parse.c | 89 ++++++++++++++++++++++-------------------- pattern.c | 2 +- protos.h | 1 - 4 files changed, 55 insertions(+), 46 deletions(-) diff --git a/lib-mime/mime.h b/lib-mime/mime.h index 498473c..51585a0 100644 --- a/lib-mime/mime.h +++ b/lib-mime/mime.h @@ -31,6 +31,7 @@ #define MUTT_LIB_MIME_MIME_H #include +#include #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: */ diff --git a/lib-mime/rfc822parse.c b/lib-mime/rfc822parse.c index 3d9211c..6a3c164 100644 --- a/lib-mime/rfc822parse.c +++ b/lib-mime/rfc822parse.c @@ -53,49 +53,53 @@ * 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 != ':') { diff --git a/pattern.c b/pattern.c index 6f5e66a..9b325a2 100644 --- 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 */ diff --git a/protos.h b/protos.h index 7129041..b4c17bd 100644 --- 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); -- 2.20.1