X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=sbr%2Fm_getfld.c;h=be871c4e8031fba720d654c33a76022d975bfbee;hp=f62d0e80f5909280be7a12d6ae1fe8da5af941a6;hb=mmh-start;hpb=8f4c5da8971926f7eccc912f7998c343aef3c33b diff --git a/sbr/m_getfld.c b/sbr/m_getfld.c index f62d0e8..be871c4 100644 --- a/sbr/m_getfld.c +++ b/sbr/m_getfld.c @@ -2,11 +2,14 @@ /* * 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. */ #include -#include +#include +#include /* This module has a long and checkered history. First, it didn't burst maildrops correctly because it considered two CTRL-A:s in a row to be @@ -178,7 +181,7 @@ static int fdelimlen; static unsigned char *edelim; static int edelimlen; -static int (*eom_action)() = NULL; +static int (*eom_action)(int) = NULL; #ifdef _FSTDIO # define _ptr _p /* Gag */ @@ -261,6 +264,9 @@ m_getfld (int state, unsigned char *name, unsigned char *buf, bp = sp = (unsigned char *) iob->_IO_read_ptr - 1; j = (cnt = ((long) iob->_IO_read_end - (long) iob->_IO_read_ptr) + 1) < i ? cnt : i; +#elif defined(__DragonFly__) + bp = sp = (unsigned char *) ((struct __FILE_public *)iob)->_p - 1; + j = (cnt = ((struct __FILE_public *)iob)->_r+1) < i ? cnt : i; #else bp = sp = (unsigned char *) iob->_ptr - 1; j = (cnt = iob->_cnt+1) < i ? cnt : i; @@ -273,6 +279,8 @@ m_getfld (int state, unsigned char *name, unsigned char *buf, #ifdef LINUX_STDIO iob->_IO_read_ptr = iob->_IO_read_end; if (__underflow(iob) == EOF) { +#elif defined(__DragonFly__) + if (__srget(iob) == EOF) { #else if (_filbuf(iob) == EOF) { #endif @@ -286,6 +294,9 @@ m_getfld (int state, unsigned char *name, unsigned char *buf, } else { #ifdef LINUX_STDIO iob->_IO_read_ptr = bp + 1; +#elif defined(__DragonFly__) + ((struct __FILE_public *)iob)->_p = bp + 1; + ((struct __FILE_public *)iob)->_r = cnt - 1; #else iob->_ptr = bp + 1; iob->_cnt = cnt - 1; @@ -301,14 +312,39 @@ m_getfld (int state, unsigned char *name, unsigned char *buf, * . 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; } @@ -330,6 +366,9 @@ m_getfld (int state, unsigned char *name, unsigned char *buf, #ifdef LINUX_STDIO cnt = (long) iob->_IO_read_end - (long) iob->_IO_read_ptr; bp = (unsigned char *) --iob->_IO_read_ptr; +#elif defined(__DragonFly__) + cnt = ((struct __FILE_public *)iob)->_r++; + bp = (unsigned char *) --((struct __FILE_public *)iob)->_p; #else cnt = iob->_cnt++; bp = (unsigned char *) --iob->_ptr; @@ -344,6 +383,11 @@ m_getfld (int state, unsigned char *name, unsigned char *buf, j = ep - (unsigned char *) iob->_IO_read_ptr; memcpy (cp, iob->_IO_read_ptr, j); iob->_IO_read_ptr = ep; +#elif defined(__DragonFly__) + j = ep - (unsigned char *) ((struct __FILE_public *)iob)->_p; + memcpy (cp, ((struct __FILE_public *)iob)->_p, j); + ((struct __FILE_public *)iob)->_p = ep; + ((struct __FILE_public *)iob)->_r -= j; #else j = ep - (unsigned char *) iob->_ptr; memcpy (cp, iob->_ptr, j); @@ -363,6 +407,9 @@ m_getfld (int state, unsigned char *name, unsigned char *buf, #ifdef LINUX_STDIO c += bp - (unsigned char *) iob->_IO_read_ptr; memcpy( cp, iob->_IO_read_ptr, c); +#elif defined(__DragonFly__) + c += bp - (unsigned char *) ((struct __FILE_public *)iob)->_p; + memcpy( cp, ((struct __FILE_public *)iob)->_p, c); #else c += bp - (unsigned char *) iob->_ptr; memcpy( cp, iob->_ptr, c); @@ -373,6 +420,9 @@ m_getfld (int state, unsigned char *name, unsigned char *buf, /* the dest buffer is full */ #ifdef LINUX_STDIO iob->_IO_read_ptr += c; +#elif defined(__DragonFly__) + ((struct __FILE_public *)iob)->_r -= c; + ((struct __FILE_public *)iob)->_p += c; #else iob->_cnt -= c; iob->_ptr += c; @@ -392,6 +442,9 @@ m_getfld (int state, unsigned char *name, unsigned char *buf, iob->_IO_read_ptr = iob->_IO_read_end; c = __underflow(iob); iob->_IO_read_ptr++; /* NOT automatic! */ +#elif defined(__DragonFly__) + *cp++ =j = *(((struct __FILE_public *)iob)->_p + c); + c = __srget(iob); #else *cp++ = j = *(iob->_ptr + c); c = _filbuf(iob); @@ -401,6 +454,9 @@ m_getfld (int state, unsigned char *name, unsigned char *buf, if (c != EOF) { #ifdef LINUX_STDIO --iob->_IO_read_ptr; +#elif defined(__DragonFly__) + --((struct __FILE_public *)iob)->_p; + ++((struct __FILE_public *)iob)->_r; #else --iob->_ptr; ++iob->_cnt; @@ -424,6 +480,9 @@ m_getfld (int state, unsigned char *name, unsigned char *buf, #ifdef LINUX_STDIO bp = (unsigned char *) --iob->_IO_read_ptr; cnt = (long) iob->_IO_read_end - (long) iob->_IO_read_ptr; +#elif defined(__DragonFly__) + bp = (unsigned char *) --((struct __FILE_public *)iob)->_p; + cnt = ++((struct __FILE_public *)iob)->_r; #else bp = (unsigned char *) --iob->_ptr; cnt = ++iob->_cnt; @@ -461,22 +520,35 @@ m_getfld (int state, unsigned char *name, unsigned char *buf, 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); @@ -486,6 +558,9 @@ m_getfld (int state, unsigned char *name, unsigned char *buf, memcpy( buf, bp, c ); #ifdef LINUX_STDIO iob->_IO_read_ptr += c; +#elif defined(__DragonFly__) + ((struct __FILE_public *)iob)->_r -= c; + ((struct __FILE_public *)iob)->_p += c; #else iob->_cnt -= c; iob->_ptr += c; @@ -558,7 +633,7 @@ m_unknown(FILE *iob) msg_style = MS_MMDF; } c = strlen (delimstr); - fdelim = (unsigned char *) malloc((size_t) (c + 3)); + fdelim = (unsigned char *) mh_xmalloc((size_t) (c + 3)); *fdelim++ = '\0'; *fdelim = '\n'; msg_delim = (char *)fdelim+1; @@ -591,7 +666,7 @@ m_unknown(FILE *iob) void -m_eomsbr (int (*action)()) +m_eomsbr (int (*action)(int)) { if ((eom_action = action)) { msg_style = MS_MSH; @@ -695,10 +770,10 @@ get_returnpath (char *rp, int rplen, char *dd, int ddlen) if (cp) { /* return path for UUCP style addressing */ dp = strchr (++cp, '\n'); - snprintf (rp, rplen, "%.*s!%.*s\n", dp - cp, cp, bp - ap, ap); + 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", bp - ap, ap); + snprintf (rp, rplen, "%.*s\n", (int)(bp - ap), ap); } /*