#define MUTT_LIB_MIME_MIME_H
#include <stdlib.h>
+#include <stdio.h>
#include "mime-types.h"
/* 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 *);
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: */
* 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)
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);
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;
char *p;
off_t loc;
int matched;
- size_t linelen = LONG_STRING;
+ ssize_t linelen = LONG_STRING;
char buf[LONG_STRING + 1];
if (hdr) {
}
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 != ':') {