Rearranged whitespace (and comments) in all the code!
[mmh] / sbr / m_getfld.c
index 6c15886..97b2466 100644 (file)
@@ -1,9 +1,6 @@
-
 /*
  * m_getfld.c -- read/parse a message
  *
 /*
  * 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.
  * 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.
@@ -21,7 +18,7 @@
    caused the old version of m_getfld() to declare eom prematurely.  The
    fix was a lot slower than
 
    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
 
    but it worked, and to increase generality, MBOX style maildrops could
    be parsed as well.  Unfortunately the speed issue finally caught up with
    This worked fine, until one day: a message with no body portion arrived.
    Then the
 
    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.
 
 
    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
    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
    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.
    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
    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
@@ -144,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);
 
 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;
 
 
 static unsigned char **pat_map;
 
@@ -176,7 +176,7 @@ 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.
  */
  * 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 *fdelim;
 static unsigned char *delimend;
 static int fdelimlen;
@@ -186,9 +186,9 @@ static int edelimlen;
 static int (*eom_action)(int) = NULL;
 
 #ifdef _FSTDIO
 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
 
 # define DEFINED__FILBUF_TO_SOMETHING_SPECIFIC
 #endif
 
@@ -207,308 +207,380 @@ extern int  _filbuf(FILE*);
 
 int
 m_getfld (int state, unsigned char *name, unsigned char *buf,
 
 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))
                        /* flush null messages */
                        while ((c = Getc(iob)) >= 0 && eom (c, iob))
-                           ;
+                               ;
                        if (c >= 0)
                        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
 #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
 #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
 #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
 #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
 #else
-                   if (_filbuf(iob) == EOF) {
+                                       if (_filbuf(iob) == EOF) {
 #endif
 #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
 #ifdef LINUX_STDIO
-               iob->_IO_read_ptr++; /* NOT automatic in __underflow()! */
+                                       iob->_IO_read_ptr++; /* NOT automatic in __underflow()! */
 #endif
 #endif
-               } else {
+                               } else {
 #ifdef LINUX_STDIO
 #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
 #else
-                   iob->_ptr = bp + 1;
-                   iob->_cnt = cnt - 1;
+                                       iob->_ptr = bp + 1;
+                                       iob->_cnt = cnt - 1;
 #endif
 #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
 #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
 #else
-               cnt = iob->_cnt++;
-               bp = (unsigned char *) --iob->_ptr;
+                               cnt = iob->_cnt++;
+                               bp = (unsigned char *) --iob->_ptr;
 #endif
 #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
 #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
 #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
 #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
 #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
 #else
-               c += bp - (unsigned char *) iob->_ptr;
-               memcpy( cp, iob->_ptr, c);
+                               c += bp - (unsigned char *) iob->_ptr;
+                               memcpy( cp, iob->_ptr, c);
 #endif
 #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
 #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
 #else
-                   iob->_cnt -= c;
-                   iob->_ptr += c;
+                                       iob->_cnt -= c;
+                                       iob->_ptr += c;
 #endif
 #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
 #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
 #else
-               *cp++ = j = *(iob->_ptr + c);
-               c = _filbuf(iob);
+                               *cp++ = j = *(iob->_ptr + c);
+                               c = _filbuf(iob);
 #endif
 #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
 #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
 #else
-                       --iob->_ptr;
-                       ++iob->_cnt;
+                                               --iob->_ptr;
+                                               ++iob->_cnt;
 #endif
 #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
 #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
 #else
-           bp = (unsigned char *) --iob->_ptr;
-           cnt = ++iob->_cnt;
+                       bp = (unsigned char *) --iob->_ptr;
+                       cnt = ++iob->_cnt;
 #endif
 #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
 #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
 #else
-           iob->_cnt -= c;
-           iob->_ptr += c;
+                       iob->_cnt -= c;
+                       iob->_ptr += c;
 #endif
 #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:
 finish:
-    *cp = 0;
-    msg_count = cp - buf;
-    return (state);
+       *cp = 0;
+       msg_count = cp - buf;
+       return (state);
 }
 
 
 }
 
 
@@ -519,11 +591,11 @@ static char unixbuf[BUFSIZ] = "";
 void
 m_unknown(FILE *iob)
 {
 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
 
 /*
  * Figure out what the message delimitter string is for this
@@ -538,77 +610,60 @@ m_unknown(FILE *iob)
  * specified when nmh was built (or from the mts.conf file).
  */
 
  * 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 */
 #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 */
 #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 *) 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);
-    }
-}
-
-
-void
-m_eomsbr (int (*action)(int))
-{
-    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);
+       }
 }
 
 
 }
 
 
@@ -619,45 +674,45 @@ m_eomsbr (int (*action)(int))
 static int
 m_Eom (int c, FILE *iob)
 {
 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
 #ifdef RPATHS
-    register char *cp;
+       register char *cp;
 #endif /* RPATHS */
 
 #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
 
 #if 0
-       fseek (iob, pos, SEEK_SET);
+               fseek (iob, pos, SEEK_SET);
 #endif
 
 #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
 #ifndef RPATHS
-       while ((c = getc (iob)) != '\n')
-           if (c < 0)
-               break;
+               while ((c = getc (iob)) != '\n')
+                       if (c < 0)
+                               break;
 #else /* RPATHS */
 #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 */
 #endif /* RPATHS */
-    }
+       }
 
 
-    return 1;
+       return 1;
 }
 
 
 }
 
 
@@ -676,48 +731,48 @@ m_Eom (int c, FILE *iob)
 int
 get_returnpath (char *rp, int rplen, char *dd, int ddlen)
 {
 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 */
 
 }
 #endif /* RPATHS */
 
@@ -740,7 +795,7 @@ matchc(int patln, char *pat, int strln, char *str)
                sp = str; pp = pat;
                while (pp < ep && *sp++ == *pp)
                        pp++;
                sp = str; pp = pat;
                while (pp < ep && *sp++ == *pp)
                        pp++;
-               if (pp >= ep) 
+               if (pp >= ep)
                        return ((unsigned char *)--str);
        }
 }
                        return ((unsigned char *)--str);
        }
 }
@@ -754,8 +809,9 @@ matchc(int patln, char *pat, int strln, char *str)
 static unsigned char *
 locc(int cnt, unsigned char *src, unsigned char term)
 {
 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);
 }
 
 }