X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=sbr%2Fm_getfld.c;h=97b2466d3e9a800b4a9da558bfcdee435178c412;hp=475289331d31c467be76df4e228153daf197af1a;hb=a485ed478abbd599d8c9aab48934e7a26733ecb1;hpb=045b9601403a216c400642229f2b291f85f88f7d diff --git a/sbr/m_getfld.c b/sbr/m_getfld.c index 4752893..97b2466 100644 --- a/sbr/m_getfld.c +++ b/sbr/m_getfld.c @@ -1,12 +1,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 @@ -16,7 +18,7 @@ caused the old version of m_getfld() to declare eom prematurely. The fix was a lot slower than - c == '\001' && peekc (iob) == '\001' + c == '\001' && peekc (iob) == '\001' but it worked, and to increase generality, MBOX style maildrops could be parsed as well. Unfortunately the speed issue finally caught up with @@ -39,12 +41,15 @@ This worked fine, until one day: a message with no body portion arrived. Then the - while (eom (c = Getc (iob), iob)) - continue; + while (eom (c = Getc (iob), iob)) + continue; loop caused m_getfld() to return FMTERR. So, that logic was changed to check for (*eom_action) and act accordingly. + [ Note by meillo 2011-10: + as msh was removed from mmh, m_eomsbr() became irrelevant. ] + This worked fine, until one day: someone didn't use four CTRL:A's as their delimiters. So, the bullet got bit and we read mts.h and continue to struggle on. It's not that bad though, since the only time @@ -122,7 +127,7 @@ it knows that _filbuf ignores the _ptr & _cnt and simply fills the buffer. If stdio on your system doesn't work this way, you may have to make small changes in this routine. - + This routine also "knows" that an EOF indication on a stream is "sticky" (i.e., you will keep getting EOF until you reposition the stream). If your system doesn't work this way it is broken and you @@ -139,10 +144,10 @@ static int m_Eom (int, FILE *); static unsigned char *matchc(int, char *, int, char *); static unsigned char *locc(int, unsigned char *, unsigned char); -#define Getc(iob) getc(iob) -#define eom(c,iob) (msg_style != MS_DEFAULT && \ - (((c) == *msg_delim && m_Eom(c,iob)) ||\ - (eom_action && (*eom_action)(c)))) +#define Getc(iob) getc(iob) +#define eom(c,iob) (msg_style != MS_DEFAULT && \ + (((c) == *msg_delim && m_Eom(c,iob)) ||\ + (eom_action && (*eom_action)(c)))) static unsigned char **pat_map; @@ -171,19 +176,20 @@ extern int msg_style; * is used in m_Eom because the first character of the string * has been read and matched before m_Eom is called. */ -extern char *msg_delim; /* defined in sbr/m_msgdef.c = "" */ +extern char *msg_delim; /* defined in sbr/m_msgdef.c = "" */ static unsigned char *fdelim; static unsigned char *delimend; 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 */ -# define _cnt _r /* Retch */ -# define _filbuf __srget /* Puke */ +# define _ptr _p /* Gag */ +# define _cnt _r /* Retch */ +# define _filbuf __srget /* Puke */ +# define DEFINED__FILBUF_TO_SOMETHING_SPECIFIC #endif #ifdef SCO_5_STDIO @@ -191,312 +197,390 @@ static int (*eom_action)() = NULL; # define _cnt __cnt # define _base __base # define _filbuf(fp) ((fp)->__cnt = 0, __filbuf(fp)) +# define DEFINED__FILBUF_TO_SOMETHING_SPECIFIC +#endif + +#ifndef DEFINED__FILBUF_TO_SOMETHING_SPECIFIC +extern int _filbuf(FILE*); #endif int m_getfld (int state, unsigned char *name, unsigned char *buf, - int bufsz, FILE *iob) + int bufsz, FILE *iob) { - register unsigned char *bp, *cp, *ep, *sp; - register int cnt, c, i, j; - - if ((c = Getc(iob)) < 0) { - msg_count = 0; - *buf = 0; - return FILEEOF; - } - if (eom (c, iob)) { - if (! eom_action) { - /* flush null messages */ - while ((c = Getc(iob)) >= 0 && eom (c, iob)) - ; - if (c >= 0) - ungetc(c, iob); + register unsigned char *bp, *cp, *ep, *sp; + register int cnt, c, i, j; + + if ((c = Getc(iob)) < 0) { + msg_count = 0; + *buf = 0; + return FILEEOF; } - msg_count = 0; - *buf = 0; - return FILEEOF; - } - - switch (state) { - case FLDEOF: - case BODYEOF: - case FLD: - if (c == '\n' || c == '-') { - /* we hit the header/body separator */ - while (c != '\n' && (c = Getc(iob)) >= 0) - ; - - if (c < 0 || (c = Getc(iob)) < 0 || eom (c, iob)) { - if (! eom_action) { + if (eom (c, iob)) { + if (! eom_action) { /* flush null messages */ while ((c = Getc(iob)) >= 0 && eom (c, iob)) - ; + ; if (c >= 0) - ungetc(c, iob); - } - msg_count = 0; - *buf = 0; - return FILEEOF; + ungetc(c, iob); } - state = BODY; - goto body; - } - /* - * get the name of this component. take characters up - * to a ':', a newline or NAMESZ-1 characters, whichever - * comes first. - */ - cp = name; - i = NAMESZ - 1; - for (;;) { + msg_count = 0; + *buf = 0; + return FILEEOF; + } + + switch (state) { + case FLDEOF: + case BODYEOF: + case FLD: + if (c == '\n' || c == '-') { + /* we hit the header/body separator */ + while (c != '\n' && (c = Getc(iob)) >= 0) + ; + + if (c < 0 || (c = Getc(iob)) < 0 || eom (c, iob)) { + if (! eom_action) { + /* flush null messages */ + while ((c = Getc(iob)) >= 0 && eom (c, iob)) + ; + if (c >= 0) + ungetc(c, iob); + } + msg_count = 0; + *buf = 0; + return FILEEOF; + } + state = BODY; + goto body; + } + /* + * get the name of this component. take characters up + * to a ':', a newline or NAMESZ-1 characters, + * whichever comes first. + */ + cp = name; + i = NAMESZ - 1; + for (;;) { #ifdef LINUX_STDIO - 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; + 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; + bp = sp = (unsigned char *) iob->_ptr - 1; + j = (cnt = iob->_cnt+1) < i ? cnt : i; #endif - while (--j >= 0 && (c = *bp++) != ':' && c != '\n') - *cp++ = c; + while (--j >= 0 && (c = *bp++) != ':' && c != '\n') + *cp++ = c; - j = bp - sp; - if ((cnt -= j) <= 0) { + j = bp - sp; + if ((cnt -= j) <= 0) { #ifdef LINUX_STDIO - iob->_IO_read_ptr = iob->_IO_read_end; - if (__underflow(iob) == EOF) { + iob->_IO_read_ptr = iob->_IO_read_end; + if (__underflow(iob) == EOF) { +#elif defined(__DragonFly__) + if (__srget(iob) == EOF) { #else - if (_filbuf(iob) == EOF) { + if (_filbuf(iob) == EOF) { #endif - *cp = *buf = 0; - advise (NULL, "eof encountered in field \"%s\"", name); - return FMTERR; - } + *cp = *buf = 0; + advise (NULL, "eof encountered in field \"%s\"", name); + return FMTERR; + } #ifdef LINUX_STDIO - iob->_IO_read_ptr++; /* NOT automatic in __underflow()! */ + iob->_IO_read_ptr++; /* NOT automatic in __underflow()! */ #endif - } else { + } else { #ifdef LINUX_STDIO - iob->_IO_read_ptr = bp + 1; + 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; + iob->_ptr = bp + 1; + iob->_cnt = cnt - 1; #endif - } - if (c == ':') - break; - - /* - * something went wrong. possibilities are: - * . hit a newline (error) - * . got more than namesz chars. (error) - * . 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; - } - if ((i -= j) <= 0) { - *cp = *buf = 0; - advise (NULL, "field name \"%s\" exceeds %d bytes", name, NAMESZ - 1); - state = LENERR; - goto finish; - } - } + } + if (c == ':') + break; + + /* + * something went wrong. possibilities are: + * . hit a newline (error) + * . got more than namesz chars. (error) + * . hit the end of the buffer. (loop) + */ + if (c == '\n') { + /* 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 - 2); + state = LENERR; + goto finish; + } + } - while (isspace (*--cp) && cp >= name) - ; - *++cp = 0; - /* fall through */ - - case FLDPLUS: - /* - * get (more of) the text of a field. take - * characters up to the end of this field (newline - * followed by non-blank) or bufsz-1 characters. - */ - cp = buf; i = bufsz-1; - for (;;) { + while (isspace (*--cp) && cp >= name) + ; + *++cp = 0; + /* fall through */ + + case FLDPLUS: + /* + * get (more of) the text of a field. take + * characters up to the end of this field (newline + * followed by non-blank) or bufsz-1 characters. + */ + cp = buf; i = bufsz-1; + for (;;) { #ifdef LINUX_STDIO - cnt = (long) iob->_IO_read_end - (long) iob->_IO_read_ptr; - bp = (unsigned char *) --iob->_IO_read_ptr; + 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; + cnt = iob->_cnt++; + bp = (unsigned char *) --iob->_ptr; #endif - c = cnt < i ? cnt : i; - while ((ep = locc( c, bp, '\n' ))) { - /* - * if we hit the end of this field, return. - */ - if ((j = *++ep) != ' ' && j != '\t') { + c = cnt < i ? cnt : i; + while ((ep = locc( c, bp, '\n' ))) { + /* + * if we hit the end of this field, return. + */ + if ((j = *++ep) != ' ' && j != '\t') { #ifdef LINUX_STDIO - j = ep - (unsigned char *) iob->_IO_read_ptr; - memcpy (cp, iob->_IO_read_ptr, j); - iob->_IO_read_ptr = ep; + 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); - iob->_ptr = ep; - iob->_cnt -= j; + j = ep - (unsigned char *) iob->_ptr; + memcpy (cp, iob->_ptr, j); + iob->_ptr = ep; + iob->_cnt -= j; #endif - cp += j; - state = FLD; - goto finish; - } - c -= ep - bp; - bp = ep; - } - /* - * end of input or dest buffer - copy what we've found. - */ + cp += j; + state = FLD; + goto finish; + } + c -= ep - bp; + bp = ep; + } + /* + * end of input or dest buffer - copy what we've found. + */ #ifdef LINUX_STDIO - c += bp - (unsigned char *) iob->_IO_read_ptr; - memcpy( cp, iob->_IO_read_ptr, c); + 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); + c += bp - (unsigned char *) iob->_ptr; + memcpy( cp, iob->_ptr, c); #endif - i -= c; - cp += c; - if (i <= 0) { - /* the dest buffer is full */ + i -= c; + cp += c; + if (i <= 0) { + /* the dest buffer is full */ #ifdef LINUX_STDIO - iob->_IO_read_ptr += c; + 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; + iob->_cnt -= c; + iob->_ptr += c; #endif - state = FLDPLUS; - break; - } - /* - * There's one character left in the input buffer. - * Copy it & fill the buffer. If the last char - * was a newline and the next char is not whitespace, - * this is the end of the field. Otherwise loop. - */ - --i; + state = FLDPLUS; + break; + } + /* + * There's one character left in the input buffer. + * Copy it & fill the buffer. If the last char + * was a newline and the next char is not whitespace, + * this is the end of the field. Otherwise loop. + */ + --i; #ifdef LINUX_STDIO - *cp++ = j = *(iob->_IO_read_ptr + c); - iob->_IO_read_ptr = iob->_IO_read_end; - c = __underflow(iob); - iob->_IO_read_ptr++; /* NOT automatic! */ + *cp++ = j = *(iob->_IO_read_ptr + c); + 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); + *cp++ = j = *(iob->_ptr + c); + c = _filbuf(iob); #endif - if (c == EOF || (j == '\0' || j == '\n') && c != ' ' && c != '\t') { - if (c != EOF) { + if (c == EOF || + ((j == '\0' || j == '\n') && c != ' ' && c != '\t')) { + if (c != EOF) { #ifdef LINUX_STDIO - --iob->_IO_read_ptr; + --iob->_IO_read_ptr; +#elif defined(__DragonFly__) + --((struct __FILE_public *)iob)->_p; + ++((struct __FILE_public *)iob)->_r; #else - --iob->_ptr; - ++iob->_cnt; + --iob->_ptr; + ++iob->_cnt; #endif - } - state = FLD; - break; - } - } - break; - - case BODY: - body: - /* - * get the message body up to bufsz characters or the - * end of the message. Sleazy hack: if bufsz is negative - * we assume that we were called to copy directly into - * the output buffer and we don't add an eos. - */ - i = (bufsz < 0) ? -bufsz : bufsz-1; + } + state = FLD; + break; + } + } + break; + + case BODY: + body: + /* + * get the message body up to bufsz characters or the + * end of the message. Sleazy hack: if bufsz is negative + * we assume that we were called to copy directly into + * the output buffer and we don't add an eos. + */ + i = (bufsz < 0) ? -bufsz : bufsz-1; #ifdef LINUX_STDIO - bp = (unsigned char *) --iob->_IO_read_ptr; - cnt = (long) iob->_IO_read_end - (long) iob->_IO_read_ptr; + 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; + bp = (unsigned char *) --iob->_ptr; + cnt = ++iob->_cnt; #endif - c = (cnt < i ? cnt : i); - if (msg_style != MS_DEFAULT && c > 1) { - /* - * packed maildrop - only take up to the (possible) - * start of the next message. This "matchc" should - * probably be a Boyer-Moore matcher for non-vaxen, - * particularly since we have the alignment table - * all built for the end-of-buffer test (next). - * But our vax timings indicate that the "matchc" - * instruction is 50% faster than a carefully coded - * B.M. matcher for most strings. (So much for elegant - * algorithms vs. brute force.) Since I (currently) - * run MH on a vax, we use the matchc instruction. --vj - */ - if ((ep = matchc( fdelimlen, fdelim, c, bp ))) - c = ep - bp + 1; - else { - /* - * There's no delim in the buffer but there may be - * a partial one at the end. If so, we want to leave - * it so the "eom" check on the next call picks it up. - * Use a modified Boyer-Moore matcher to make this - * check relatively cheap. The first "if" figures - * out what position in the pattern matches the last - * character in the buffer. The inner "while" matches - * the pattern against the buffer, backwards starting - * at that position. Note that unless the buffer - * ends with one of the characters in the pattern - * (excluding the first and last), we do only one test. - */ - 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. - */ - c = (ep - bp) + 2; - break; + c = (cnt < i ? cnt : i); + if (msg_style != MS_DEFAULT && c > 1) { + /* + * packed maildrop - only take up to the (possible) + * start of the next message. This "matchc" should + * probably be a Boyer-Moore matcher for non-vaxen, + * particularly since we have the alignment table + * all built for the end-of-buffer test (next). + * But our vax timings indicate that the "matchc" + * instruction is 50% faster than a carefully coded + * B.M. matcher for most strings. (So much for elegant + * algorithms vs. brute force.) Since I (currently) + * run MH on a vax, we use the matchc instruction. --vj + */ + if ((ep = matchc( fdelimlen, fdelim, c, bp ))) + c = ep - bp + 1; + else { + /* + * There's no delim in the buffer but there may be + * a partial one at the end. If so, we want to leave + * it so the "eom" check on the next call picks it up. + * Use a modified Boyer-Moore matcher to make this + * check relatively cheap. The first "if" figures + * out what position in the pattern matches the last + * character in the buffer. The inner "while" matches + * the pattern against the buffer, backwards starting + * at that position. Note that unless the buffer + * ends with one of the characters in the pattern + * (excluding the first and last), we do only one test. + */ + ep = bp + c - 1; + if ((sp = pat_map[*ep])) { + do { + /* 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; + } + } + /* try matching one less char of delim string */ + ep = bp + c - 1; + } while (--sp > fdelim); + } + } } - /* try matching one less char of delim string */ - ep = bp + c - 1; - } while (--sp > fdelim); - } - } - } - memcpy( buf, bp, c ); + memcpy( buf, bp, c ); #ifdef LINUX_STDIO - iob->_IO_read_ptr += c; + 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; + iob->_cnt -= c; + iob->_ptr += c; #endif - if (bufsz < 0) { - msg_count = c; - return (state); - } - cp = buf + c; - break; - - default: - adios (NULL, "m_getfld() called with bogus state of %d", state); - } + if (bufsz < 0) { + msg_count = c; + return (state); + } + cp = buf + c; + break; + + default: + adios (NULL, "m_getfld() called with bogus state of %d", state); + } finish: - *cp = 0; - msg_count = cp - buf; - return (state); + *cp = 0; + msg_count = cp - buf; + return (state); } @@ -507,11 +591,11 @@ static char unixbuf[BUFSIZ] = ""; void m_unknown(FILE *iob) { - register int c; - register long pos; - char text[10]; - register char *cp; - register char *delimstr; + register int c; + register long pos; + char text[10]; + register char *cp; + register char *delimstr; /* * Figure out what the message delimitter string is for this @@ -526,77 +610,60 @@ m_unknown(FILE *iob) * specified when nmh was built (or from the mts.conf file). */ - msg_style = MS_UNKNOWN; + msg_style = MS_UNKNOWN; - pos = ftell (iob); - if (fread (text, sizeof(*text), 5, iob) == 5 - && strncmp (text, "From ", 5) == 0) { - msg_style = MS_MBOX; - delimstr = "\nFrom "; -#ifndef RPATHS - while ((c = getc (iob)) != '\n' && c >= 0) - ; + pos = ftell (iob); + if (fread (text, sizeof(*text), 5, iob) == 5 + && 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; + 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); - if (mmdlm2 == NULL || *mmdlm2 == 0) - mmdlm2 = "\001\001\001\001\n"; - delimstr = mmdlm2; - msg_style = MS_MMDF; - } - c = strlen (delimstr); - fdelim = (unsigned char *) malloc((size_t) (c + 3)); - *fdelim++ = '\0'; - *fdelim = '\n'; - msg_delim = (char *)fdelim+1; - edelim = (unsigned char *)msg_delim+1; - fdelimlen = c + 1; - edelimlen = c - 1; - strcpy (msg_delim, delimstr); - delimend = (unsigned char *)msg_delim + edelimlen; - if (edelimlen <= 1) - adios (NULL, "maildrop delimiter must be at least 2 bytes"); - /* - * build a Boyer-Moore end-position map for the matcher in m_getfld. - * N.B. - we don't match just the first char (since it's the newline - * separator) or the last char (since the matchc would have found it - * if it was a real delim). - */ - pat_map = (unsigned char **) calloc (256, sizeof(unsigned char *)); - - for (cp = (char *) fdelim + 1; cp < (char *) delimend; cp++ ) - pat_map[*cp] = (unsigned char *) cp; - - if (msg_style == MS_MMDF) { - /* flush extra msg hdrs */ - while ((c = Getc(iob)) >= 0 && eom (c, iob)) - ; - if (c >= 0) - ungetc(c, iob); - } -} - - -void -m_eomsbr (int (*action)()) -{ - if ((eom_action = action)) { - msg_style = MS_MSH; - *msg_delim = 0; - fdelimlen = 1; - delimend = fdelim; - } else { - msg_style = MS_MMDF; - msg_delim = (char *)fdelim + 1; - fdelimlen = strlen((char *)fdelim); - delimend = (unsigned char *)(msg_delim + edelimlen); - } + } else { + /* not a Unix style maildrop */ + fseek (iob, pos, SEEK_SET); + if (mmdlm2 == NULL || *mmdlm2 == 0) + mmdlm2 = "\001\001\001\001\n"; + delimstr = mmdlm2; + msg_style = MS_MMDF; + } + c = strlen (delimstr); + fdelim = (unsigned char *) mh_xmalloc((size_t) (c + 3)); + *fdelim++ = '\0'; + *fdelim = '\n'; + msg_delim = (char *)fdelim+1; + edelim = (unsigned char *)msg_delim+1; + fdelimlen = c + 1; + edelimlen = c - 1; + strcpy (msg_delim, delimstr); + delimend = (unsigned char *)msg_delim + edelimlen; + if (edelimlen <= 1) + adios (NULL, "maildrop delimiter must be at least 2 bytes"); + /* + * build a Boyer-Moore end-position map for the matcher in m_getfld. + * N.B. - we don't match just the first char (since it's the newline + * separator) or the last char (since the matchc would have found it + * if it was a real delim). + */ + pat_map = (unsigned char **) calloc (256, sizeof(unsigned char *)); + + for (cp = (char *) fdelim + 1; cp < (char *) delimend; cp++ ) + pat_map[(unsigned char)*cp] = (unsigned char *) cp; + + if (msg_style == MS_MMDF) { + /* flush extra msg hdrs */ + while ((c = Getc(iob)) >= 0 && eom (c, iob)) + ; + if (c >= 0) + ungetc(c, iob); + } } @@ -607,45 +674,45 @@ m_eomsbr (int (*action)()) static int m_Eom (int c, FILE *iob) { - register long pos = 0L; - register int i; - char text[10]; + register long pos = 0L; + register int i; + char text[10]; #ifdef RPATHS - register char *cp; + register char *cp; #endif /* RPATHS */ - pos = ftell (iob); - if ((i = fread (text, sizeof *text, edelimlen, iob)) != edelimlen - || strncmp (text, (char *)edelim, edelimlen)) { - if (i == 0 && msg_style == MS_MBOX) - /* the final newline in the (brain damaged) unix-format - * maildrop is part of the delimitter - delete it. - */ - return 1; + pos = ftell (iob); + if ((i = fread (text, sizeof *text, edelimlen, iob)) != edelimlen + || strncmp (text, (char *)edelim, edelimlen)) { + if (i == 0 && msg_style == MS_MBOX) + /* the final newline in the (brain damaged) unix-format + * maildrop is part of the delimitter - delete it. + */ + return 1; #if 0 - fseek (iob, pos, SEEK_SET); + fseek (iob, pos, SEEK_SET); #endif - fseek (iob, (long)(pos-1), SEEK_SET); - getc (iob); /* should be OK */ - return 0; - } + fseek (iob, (long)(pos-1), SEEK_SET); + getc (iob); /* should be OK */ + return 0; + } - if (msg_style == MS_MBOX) { + if (msg_style == MS_MBOX) { #ifndef RPATHS - while ((c = getc (iob)) != '\n') - if (c < 0) - break; + 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; + cp = unixbuf; + while ((c = getc (iob)) != '\n' && c >= 0 && cp - unixbuf < BUFSIZ - 1) + *cp++ = c; + *cp = 0; #endif /* RPATHS */ - } + } - return 1; + return 1; } @@ -664,48 +731,48 @@ m_Eom (int c, FILE *iob) 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; + 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); } - } - - /* - * 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", dp - cp, cp, bp - ap, ap); - } else { - /* return path for standard domain addressing */ - snprintf (rp, rplen, "%.*s\n", 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; + + /* + * 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 */ @@ -723,11 +790,12 @@ matchc(int patln, char *pat, int strln, char *str) while (pc != *str++) if (str > es) return 0; - + if (str > es+1) + return 0; sp = str; pp = pat; while (pp < ep && *sp++ == *pp) pp++; - if (pp >= ep) + if (pp >= ep) return ((unsigned char *)--str); } } @@ -741,8 +809,9 @@ matchc(int patln, char *pat, int strln, char *str) static unsigned char * locc(int cnt, unsigned char *src, unsigned char term) { - while (*src++ != term && --cnt > 0); + while (*src++ != term && --cnt > 0) + ; - return (cnt > 0 ? --src : (unsigned char *)0); + return (cnt > 0 ? --src : (unsigned char *)0); }