/*
* m_getfld.c -- read/parse a message
*
- * $Id$
- *
* This code is Copyright (c) 2002, by the authors of nmh. See the
* COPYRIGHT file in the root directory of the nmh distribution for
* complete copyright information.
# define _cnt _r /* Retch */
# define _filbuf __srget /* Puke */
# define DEFINED__FILBUF_TO_SOMETHING_SPECIFIC
-#endif
-#ifdef SCO_5_STDIO
-# define _ptr __ptr
-# define _cnt __cnt
-# define _base __base
-# define _filbuf(fp) ((fp)->__cnt = 0, __filbuf(fp))
-# define DEFINED__FILBUF_TO_SOMETHING_SPECIFIC
+# if defined __CYGWIN__
+ /* Cygwin's stdio.h does not declare __srget(). */
+ int __srget(FILE *);
+# endif /* __CYGWIN__ */
#endif
#ifndef DEFINED__FILBUF_TO_SOMETHING_SPECIFIC
* . hit the end of the buffer. (loop)
*/
if (c == '\n') {
- *cp = *buf = 0;
- advise (NULL, "eol encountered in field \"%s\"", name);
- state = FMTERR;
- goto finish;
+ /* We hit the end of the line without seeing ':' to
+ * terminate the field name. This is usually (always?)
+ * spam. But, blowing up is lame, especially when
+ * scan(1)ing a folder with such messages. Pretend such
+ * lines are the first of the body (at least mutt also
+ * handles it this way). */
+
+ /* See if buf can hold this line, since we were assuming
+ * we had a buffer of NAMESZ, not bufsz. */
+ /* + 1 for the newline */
+ if (bufsz < j + 1) {
+ /* No, it can't. Oh well, guess we'll blow up. */
+ *cp = *buf = 0;
+ advise (NULL, "eol encountered in field \"%s\"", name);
+ state = FMTERR;
+ goto finish;
+ }
+ memcpy (buf, name, j - 1);
+ buf[j - 1] = '\n';
+ buf[j] = '\0';
+ /* mhparse.c:get_content wants to find the position of the
+ * body start, but it thinks there's a blank line between
+ * the header and the body (naturally!), so seek back so
+ * that things line up even though we don't have that
+ * blank line in this case. Simpler parsers (e.g. mhl)
+ * get extra newlines, but that should be harmless enough,
+ * right? This is a corrupt message anyway. */
+ fseek (iob, ftell (iob) - 2, SEEK_SET);
+ return BODY;
}
if ((i -= j) <= 0) {
*cp = *buf = 0;
- advise (NULL, "field name \"%s\" exceeds %d bytes", name, NAMESZ - 1);
+ advise (NULL, "field name \"%s\" exceeds %d bytes", name, NAMESZ - 2);
state = LENERR;
goto finish;
}
ep = bp + c - 1;
if ((sp = pat_map[*ep])) {
do {
- cp = sp;
- while (*--ep == *--cp)
- ;
- if (cp < fdelim) {
- if (ep >= bp)
- /*
- * ep < bp means that all the buffer
- * contains is a prefix of delim.
- * If this prefix is really a delim, the
- * m_eom call at entry should have found
- * it. Thus it's not a delim and we can
- * take all of it.
+ /* This if() is true unless (a) the buffer is too
+ * small to contain this delimiter prefix, or
+ * (b) it contains exactly enough chars for the
+ * delimiter prefix.
+ * For case (a) obviously we aren't going to match.
+ * For case (b), if the buffer really contained exactly
+ * a delim prefix, then the m_eom call at entry
+ * should have found it. Thus it's not a delim
+ * and we know we won't get a match.
+ */
+ if (((sp - fdelim) + 2) <= c) {
+ cp = sp;
+ /* Unfortunately although fdelim has a preceding NUL
+ * we can't use this as a sentinel in case the buffer
+ * contains a NUL in exactly the wrong place (this
+ * would cause us to run off the front of fdelim).
+ */
+ while (*--ep == *--cp)
+ if (cp < fdelim)
+ break;
+ if (cp < fdelim) {
+ /* we matched the entire delim prefix,
+ * so only take the buffer up to there.
+ * we know ep >= bp -- check above prevents underrun
*/
c = (ep - bp) + 2;
- break;
- }
+ break;
+ }
+ }
/* try matching one less char of delim string */
ep = bp + c - 1;
} while (--sp > fdelim);
}
-#ifdef RPATHS
-static char unixbuf[BUFSIZ] = "";
-#endif /* RPATHS */
-
void
m_unknown(FILE *iob)
{
&& strncmp (text, "From ", 5) == 0) {
msg_style = MS_MBOX;
delimstr = "\nFrom ";
-#ifndef RPATHS
while ((c = getc (iob)) != '\n' && c >= 0)
;
-#else /* RPATHS */
- cp = unixbuf;
- while ((c = getc (iob)) != '\n' && cp - unixbuf < BUFSIZ - 1)
- *cp++ = c;
- *cp = 0;
-#endif /* RPATHS */
} else {
/* not a Unix style maildrop */
fseek (iob, pos, SEEK_SET);
register long pos = 0L;
register int i;
char text[10];
-#ifdef RPATHS
- register char *cp;
-#endif /* RPATHS */
pos = ftell (iob);
if ((i = fread (text, sizeof *text, edelimlen, iob)) != edelimlen
}
if (msg_style == MS_MBOX) {
-#ifndef RPATHS
while ((c = getc (iob)) != '\n')
if (c < 0)
break;
-#else /* RPATHS */
- cp = unixbuf;
- while ((c = getc (iob)) != '\n' && c >= 0 && cp - unixbuf < BUFSIZ - 1)
- *cp++ = c;
- *cp = 0;
-#endif /* RPATHS */
- }
-
- return 1;
-}
-
-
-#ifdef RPATHS
-/*
- * Return the Return-Path and Delivery-Date
- * header information.
- *
- * Currently, I'm assuming that the "From " line
- * takes one of the following forms.
- *
- * From sender date remote from host (for UUCP delivery)
- * From sender@host date (for sendmail delivery)
- */
-
-int
-get_returnpath (char *rp, int rplen, char *dd, int ddlen)
-{
- char *ap, *bp, *cp, *dp;
-
- ap = unixbuf;
- if (!(bp = cp = strchr(ap, ' ')))
- return 0;
-
- /*
- * Check for "remote from" in envelope to see
- * if this message uses UUCP style addressing
- */
- while ((cp = strchr(++cp, 'r'))) {
- if (strncmp (cp, "remote from", 11) == 0) {
- cp = strrchr (cp, ' ');
- break;
- }
- }
-
- /*
- * Get the Return-Path information from
- * the "From " envelope.
- */
- if (cp) {
- /* return path for UUCP style addressing */
- dp = strchr (++cp, '\n');
- snprintf (rp, rplen, "%.*s!%.*s\n", (int)(dp - cp), cp, (int)(bp - ap), ap);
- } else {
- /* return path for standard domain addressing */
- snprintf (rp, rplen, "%.*s\n", (int)(bp - ap), ap);
}
- /*
- * advance over the spaces to get to
- * delivery date on envelope
- */
- while (*bp == ' ')
- bp++;
-
- /* Now get delivery date from envelope */
- snprintf (dd, ddlen, "%.*s\n", 24, bp);
-
- unixbuf[0] = 0;
return 1;
}
-#endif /* RPATHS */
static unsigned char *