]> diplodocus.org Git - nmh/blobdiff - sbr/m_getfld.c
Add -initialtls/-notls flags to msgchk.
[nmh] / sbr / m_getfld.c
index e7379dfe81bf83c147f419854df48d6a977f40cf..4da2f3eeb34c8fd93fb8e2527b7331a7f5a40d22 100644 (file)
    state to FLD.
 
    void m_unknown(FILE *iob):  Determines the message delimiter string
    state to FLD.
 
    void m_unknown(FILE *iob):  Determines the message delimiter string
-   for the maildrop.  Called by inc, scan, and msh when reading from a
+   for the maildrop.  Called by inc and scan when reading from a
    maildrop file.
 
    maildrop file.
 
-   void m_eomsbr (int (*action)(int)):  Sets the hook to check for end
-   of message in a maildrop.  Called only by msh.
-
    State variables
    ===============
    m_getfld() retains state internally between calls in the
    m_getfld_state_t variable.  These are used for detecting the end of
    each message when reading maildrops:
 
    State variables
    ===============
    m_getfld() retains state internally between calls in the
    m_getfld_state_t variable.  These are used for detecting the end of
    each message when reading maildrops:
 
-     unsigned char **pat_map
-     unsigned char *fdelim
-     unsigned char *delimend
+     char **pat_map
+     char *fdelim
+     char *delimend
      int fdelimlen
      int fdelimlen
-     unsigned char *edelim
+     char *edelim
      int edelimlen
      char *msg_delim
      int msg_style
      int edelimlen
      char *msg_delim
      int msg_style
-     int (*eom_action)(int)
 
    Usage
    =====
 
    Usage
    =====
@@ -94,7 +90,7 @@
    be parsed as well.  Unfortunately the speed issue finally caught up with
    us since this routine is at the very heart of MH.
 
    be parsed as well.  Unfortunately the speed issue finally caught up with
    us since this routine is at the very heart of MH.
 
-   To speed things up considerably, the routine Eom() was made an auxilary
+   To speed things up considerably, the routine Eom() was made an auxiliary
    function called by the macro eom().  Unless we are bursting a maildrop,
    the eom() macro returns FALSE saying we aren't at the end of the
    message.
    function called by the macro eom().  Unless we are bursting a maildrop,
    the eom() macro returns FALSE saying we aren't at the end of the
    message.
  * static prototypes
  */
 struct m_getfld_state;
  * static prototypes
  */
 struct m_getfld_state;
-static int m_Eom (m_getfld_state_t, int);
-static unsigned char *matchc(int, char *, int, char *);
+static int m_Eom (m_getfld_state_t);
+static char *matchc(int, char *, int, char *);
 
 #define eom(c,s)       (s->msg_style != MS_DEFAULT && \
 
 #define eom(c,s)       (s->msg_style != MS_DEFAULT && \
-                        (((c) == *s->msg_delim && m_Eom(s,c)) || \
-                         (s->eom_action && (*s->eom_action)(c))))
+                        ((c) == *s->msg_delim && m_Eom(s)))
 
 /* This replaces the old approach, with its direct access to stdio
  * internals.  It uses one fread() to load a buffer that we manage.
 
 /* This replaces the old approach, with its direct access to stdio
  * internals.  It uses one fread() to load a buffer that we manage.
@@ -224,13 +219,13 @@ static unsigned char *matchc(int, char *, int, char *);
  * Some of the tests in the test suite assume a MSG_INPUT_SIZE
  * of 8192.
  */
  * Some of the tests in the test suite assume a MSG_INPUT_SIZE
  * of 8192.
  */
-#define MSG_INPUT_SIZE (BUFSIZ >= 1024 ? BUFSIZ : 1024)
+#define MSG_INPUT_SIZE NMH_BUFSIZ
 #define MAX_DELIMITER_SIZE 5
 
 struct m_getfld_state {
 #define MAX_DELIMITER_SIZE 5
 
 struct m_getfld_state {
-    unsigned char msg_buf[2 * MSG_INPUT_SIZE + MAX_DELIMITER_SIZE];
-    unsigned char *readpos;
-    unsigned char *end;  /* One past the last character read in. */
+    char msg_buf[2 * MSG_INPUT_SIZE + MAX_DELIMITER_SIZE];
+    char *readpos;
+    char *end;  /* One past the last character read in. */
     /* The following support tracking of the read position in the
        input file stream so that callers can interleave m_getfld()
        calls with ftell() and fseek().  ytes_read replaces the old
     /* The following support tracking of the read position in the
        input file stream so that callers can interleave m_getfld()
        calls with ftell() and fseek().  ytes_read replaces the old
@@ -244,7 +239,7 @@ struct m_getfld_state {
     off_t last_internal_pos;
     FILE *iob;
 
     off_t last_internal_pos;
     FILE *iob;
 
-    unsigned char **pat_map;
+    char **pat_map;
     int msg_style;
     /*
      * The "full" delimiter string for a packed maildrop consists
     int msg_style;
     /*
      * The "full" delimiter string for a packed maildrop consists
@@ -259,12 +254,11 @@ struct m_getfld_state {
      * has been read and matched before m_Eom is called.
      */
     char *msg_delim;
      * has been read and matched before m_Eom is called.
      */
     char *msg_delim;
-    unsigned char *fdelim;
-    unsigned char *delimend;
+    char *fdelim;
+    char *delimend;
     int fdelimlen;
     int fdelimlen;
-    unsigned char *edelim;
+    char *edelim;
     int edelimlen;
     int edelimlen;
-    int (*eom_action)(int);
     int state;
     int track_filepos;
 };
     int state;
     int track_filepos;
 };
@@ -284,7 +278,6 @@ m_getfld_state_init (m_getfld_state_t *gstate, FILE *iob) {
     s->msg_delim = "";
     s->fdelim = s->delimend = s->edelim = NULL;
     s->fdelimlen = s->edelimlen = 0;
     s->msg_delim = "";
     s->fdelim = s->delimend = s->edelim = NULL;
     s->fdelimlen = s->edelimlen = 0;
-    s->eom_action = NULL;
     s->state = FLD;
     s->track_filepos = 0;
 }
     s->state = FLD;
     s->track_filepos = 0;
 }
@@ -313,7 +306,10 @@ void m_getfld_state_destroy (m_getfld_state_t *gstate) {
     m_getfld_state_t s = *gstate;
 
     if (s) {
     m_getfld_state_t s = *gstate;
 
     if (s) {
-       if (s->fdelim) free (s->fdelim-1);
+       if (s->fdelim) {
+           free (s->fdelim-1);
+           free (s->pat_map);
+       }
        free (s);
        *gstate = 0;
     }
        free (s);
        *gstate = 0;
     }
@@ -431,7 +427,7 @@ read_more (m_getfld_state_t s) {
     size_t num_read;
 
     if (retain < s->end - s->readpos) retain = s->end - s->readpos;
     size_t num_read;
 
     if (retain < s->end - s->readpos) retain = s->end - s->readpos;
-    /* assert (retain <= s->readpos - s->msg_buf <= sizeof msg_buf); */
+    assert (retain <= s->readpos - s->msg_buf);
 
     /* Move what we want to retain at end of the buffer to the beginning. */
     memmove (s->msg_buf, s->readpos - retain, retain);
 
     /* Move what we want to retain at end of the buffer to the beginning. */
     memmove (s->msg_buf, s->readpos - retain, retain);
@@ -443,31 +439,26 @@ read_more (m_getfld_state_t s) {
     return num_read;
 }
 
     return num_read;
 }
 
+/* The return values of the following functions are a bit
+   subtle.  They can return 0x00 - 0xff as a valid character,
+   but EOF is typically 0xffffffff. */
 static int
 Getc (m_getfld_state_t s) {
 static int
 Getc (m_getfld_state_t s) {
-    if (s->end - s->readpos < 1) {
-       if (read_more (s) == 0) {
-           /* Pretend that we read a character.  That's what stdio does. */
-           ++s->readpos;
-           return EOF;
-       }
+    if (s->end - s->readpos < 1  &&  read_more (s) == 0) {
+        return EOF;
+    } else {
+        ++s->bytes_read;
+        return s->readpos < s->end  ?  (unsigned char) *s->readpos++  :  EOF;
     }
     }
-
-    ++s->bytes_read;
-    return s->readpos < s->end  ?  *s->readpos++  :  EOF;
 }
 
 static int
 Peek (m_getfld_state_t s) {
 }
 
 static int
 Peek (m_getfld_state_t s) {
-    if (s->end - s->readpos < 1) {
-       if (read_more (s) == 0) {
-           /* Pretend that we read a character.  That's what stdio does. */
-           ++s->readpos;
-           return EOF;
-       }
+    if (s->end - s->readpos < 1  &&  read_more (s) == 0) {
+        return EOF;
+    } else {
+        return s->readpos < s->end  ?  (unsigned char) *s->readpos  :  EOF;
     }
     }
-
-    return s->readpos < s->end  ?  *s->readpos  :  EOF;
 }
 
 static int
 }
 
 static int
@@ -476,17 +467,17 @@ Ungetc (int c, m_getfld_state_t s) {
        return EOF;
     } else {
        --s->bytes_read;
        return EOF;
     } else {
        --s->bytes_read;
-       return *--s->readpos = c;
+       return *--s->readpos = (unsigned char) c;
     }
 }
 
 
 int
     }
 }
 
 
 int
-m_getfld (m_getfld_state_t *gstate, unsigned char name[NAMESZ],
-          unsigned char *buf, int *bufsz, FILE *iob)
+m_getfld (m_getfld_state_t *gstate, char name[NAMESZ], char *buf, int *bufsz,
+          FILE *iob)
 {
     m_getfld_state_t s;
 {
     m_getfld_state_t s;
-    register unsigned char *cp;
+    register char *cp;
     register int max, n, c;
 
     enter_getfld (gstate, iob);
     register int max, n, c;
 
     enter_getfld (gstate, iob);
@@ -498,14 +489,12 @@ m_getfld (m_getfld_state_t *gstate, unsigned char name[NAMESZ],
        return s->state = FILEEOF;
     }
     if (eom (c, s)) {
        return s->state = FILEEOF;
     }
     if (eom (c, s)) {
-       if (! s->eom_action) {
-           /* flush null messages */
-           while ((c = Getc(s)) >= 0 && eom (c, s))
-               ;
+       /* flush null messages */
+       while ((c = Getc(s)) >= 0 && eom (c, s))
+           ;
 
 
-           if (c >= 0)
-               Ungetc(c, s);
-       }
+       if (c >= 0)
+           Ungetc(c, s);
        *bufsz = *buf = 0;
        leave_getfld (s);
        return s->state = FILEEOF;
        *bufsz = *buf = 0;
        leave_getfld (s);
        return s->state = FILEEOF;
@@ -518,13 +507,11 @@ m_getfld (m_getfld_state_t *gstate, unsigned char name[NAMESZ],
                while (c != '\n' && (c = Getc(s)) >= 0) continue;
 
                if (c < 0 || (c = Getc(s)) < 0 || eom (c, s)) {
                while (c != '\n' && (c = Getc(s)) >= 0) continue;
 
                if (c < 0 || (c = Getc(s)) < 0 || eom (c, s)) {
-                   if (! s->eom_action) {
-                       /* flush null messages */
-                       while ((c = Getc(s)) >= 0 && eom (c, s))
-                           ;
-                       if (c >= 0)
-                           Ungetc(c, s);
-                   }
+                   /* flush null messages */
+                   while ((c = Getc(s)) >= 0 && eom (c, s))
+                       ;
+                   if (c >= 0)
+                       Ungetc(c, s);
                    *bufsz = *buf = 0;
                    leave_getfld (s);
                    return s->state = FILEEOF;
                    *bufsz = *buf = 0;
                    leave_getfld (s);
                    return s->state = FILEEOF;
@@ -606,7 +593,7 @@ m_getfld (m_getfld_state_t *gstate, unsigned char name[NAMESZ],
            }
 
            /* Trim any trailing spaces from the end of name. */
            }
 
            /* Trim any trailing spaces from the end of name. */
-           while (isspace (*--cp) && cp >= name) continue;
+           while (isspace ((unsigned char) *--cp) && cp >= name) continue;
            *++cp = 0;
            /* readpos points to the first character of the field body. */
            /* fall through */
            *++cp = 0;
            /* readpos points to the first character of the field body. */
            /* fall through */
@@ -624,12 +611,21 @@ m_getfld (m_getfld_state_t *gstate, unsigned char name[NAMESZ],
            n = 0;
            for (finished = 0; ! finished; ) {
                while (c != '\n'  &&  c != EOF  &&  n++ < max) {
            n = 0;
            for (finished = 0; ! finished; ) {
                while (c != '\n'  &&  c != EOF  &&  n++ < max) {
-                   *cp++ = c = Getc (s);
+                   if ((c = Getc (s)) != EOF) { *cp++ = c; }
                }
 
                if (c != EOF) c = Peek (s);
                if (max < n) {
                }
 
                if (c != EOF) c = Peek (s);
                if (max < n) {
-                   /* the dest buffer is full */
+                   /* The dest buffer is full.  Need to back the read
+                      pointer up by one because when m_getfld() is
+                      reentered, it will read a character.  Then
+                      we'll jump right to the FLDPLUS handling code,
+                      which will not store that character, but
+                      instead move on to the next one. */
+                   if (s->readpos > s->msg_buf) {
+                       --s->readpos;
+                       --s->bytes_read;
+                   }
                    s->state = FLDPLUS;
                    finished = 1;
                } else if (c != ' '  &&  c != '\t') {
                    s->state = FLDPLUS;
                    finished = 1;
                } else if (c != ' '  &&  c != '\t') {
@@ -653,7 +649,7 @@ m_getfld (m_getfld_state_t *gstate, unsigned char name[NAMESZ],
             * get the message body up to bufsz characters or the
             * end of the message.
             */
             * get the message body up to bufsz characters or the
             * end of the message.
             */
-           unsigned char *bp;
+           char *bp;
 
            max = *bufsz-1;
            /* Back up and store the current position. */
 
            max = *bufsz-1;
            /* Back up and store the current position. */
@@ -672,7 +668,7 @@ m_getfld (m_getfld_state_t *gstate, unsigned char name[NAMESZ],
                 * algorithms vs. brute force.)  Since I (currently)
                 * run MH on a vax, we use the matchc instruction. --vj
                 */
                 * algorithms vs. brute force.)  Since I (currently)
                 * run MH on a vax, we use the matchc instruction. --vj
                 */
-               unsigned char *ep;
+               char *ep;
 
                if ((ep = matchc( s->fdelimlen, s->fdelim, c, bp )))
                    c = ep - bp + 1;
 
                if ((ep = matchc( s->fdelimlen, s->fdelim, c, bp )))
                    c = ep - bp + 1;
@@ -690,10 +686,10 @@ m_getfld (m_getfld_state_t *gstate, unsigned char name[NAMESZ],
                     * ends with one of the characters in the pattern
                     * (excluding the first and last), we do only one test.
                     */
                     * ends with one of the characters in the pattern
                     * (excluding the first and last), we do only one test.
                     */
-                   unsigned char *sp;
+                   char *sp;
 
                    ep = bp + c - 1;
 
                    ep = bp + c - 1;
-                   if ((sp = s->pat_map[*ep])) {
+                   if ((sp = s->pat_map[(unsigned char) *ep])) {
                        do {
                            /* This if() is true unless (a) the buffer is too
                             * small to contain this delimiter prefix, or
                        do {
                            /* This if() is true unless (a) the buffer is too
                             * small to contain this delimiter prefix, or
@@ -784,8 +780,11 @@ m_unknown(m_getfld_state_t *gstate, FILE *iob)
     s->msg_style = MS_UNKNOWN;
 
     for (i = 0, cp = text; i < sizeof text; ++i, ++cp) {
     s->msg_style = MS_UNKNOWN;
 
     for (i = 0, cp = text; i < sizeof text; ++i, ++cp) {
-       if ((*cp = Getc (s)) == EOF) {
+       if ((c = Getc (s)) == EOF) {
+           *cp = '\0';
            break;
            break;
+       } else {
+           *cp = c;
        }
     }
 
        }
     }
 
@@ -796,19 +795,20 @@ m_unknown(m_getfld_state_t *gstate, FILE *iob)
     } else {
        /* not a Unix style maildrop */
        s->readpos -= s->bytes_read;
     } else {
        /* not a Unix style maildrop */
        s->readpos -= s->bytes_read;
+       s->bytes_read = 0;
        delimstr = mmdlm2;
        s->msg_style = MS_MMDF;
     }
     c = strlen (delimstr);
        delimstr = mmdlm2;
        s->msg_style = MS_MMDF;
     }
     c = strlen (delimstr);
-    s->fdelim = (unsigned char *) mh_xmalloc((size_t) (c + 3));
+    s->fdelim = mh_xmalloc (c + 3);
     *s->fdelim++ = '\0';
     *s->fdelim = '\n';
     *s->fdelim++ = '\0';
     *s->fdelim = '\n';
-    s->msg_delim = (char *)s->fdelim+1;
-    s->edelim = (unsigned char *)s->msg_delim+1;
+    s->msg_delim = s->fdelim+1;
+    s->edelim = s->msg_delim+1;
     s->fdelimlen = c + 1;
     s->edelimlen = c - 1; /* == strlen (delimstr) */
     strcpy (s->msg_delim, delimstr);
     s->fdelimlen = c + 1;
     s->edelimlen = c - 1; /* == strlen (delimstr) */
     strcpy (s->msg_delim, delimstr);
-    s->delimend = (unsigned char *)s->msg_delim + s->edelimlen;
+    s->delimend = s->msg_delim + s->edelimlen;
     if (s->edelimlen <= 1)
        adios (NULL, "maildrop delimiter must be at least 2 bytes");
     /*
     if (s->edelimlen <= 1)
        adios (NULL, "maildrop delimiter must be at least 2 bytes");
     /*
@@ -817,10 +817,10 @@ m_unknown(m_getfld_state_t *gstate, FILE *iob)
      * separator) or the last char (since the matchc would have found it
      * if it was a real delim).
      */
      * separator) or the last char (since the matchc would have found it
      * if it was a real delim).
      */
-    s->pat_map = (unsigned char **) calloc (256, sizeof(unsigned char *));
+    s->pat_map = (char **) mh_xcalloc (256, sizeof(char *));
 
 
-    for (cp = (char *) s->fdelim + 1; cp < (char *) s->delimend; cp++ )
-       s->pat_map[(unsigned char)*cp] = (unsigned char *) cp;
+    for (cp = s->fdelim + 1; cp < s->delimend; cp++ )
+       s->pat_map[(unsigned char)*cp] = cp;
 
     if (s->msg_style == MS_MMDF) {
        /* flush extra msg hdrs */
 
     if (s->msg_style == MS_MMDF) {
        /* flush extra msg hdrs */
@@ -834,37 +834,25 @@ m_unknown(m_getfld_state_t *gstate, FILE *iob)
 }
 
 
 }
 
 
-void
-m_eomsbr (m_getfld_state_t s, int (*action)(int))
-{
-    if ((s->eom_action = action)) {
-       s->msg_style = MS_MSH;
-       *s->msg_delim = 0;
-       s->fdelimlen = 1;
-       s->delimend = s->fdelim;
-    } else {
-       s->msg_style = MS_MMDF;
-       s->msg_delim = (char *)s->fdelim + 1;
-       s->fdelimlen = strlen((char *)s->fdelim);
-       s->delimend = (unsigned char *)(s->msg_delim + s->edelimlen);
-    }
-}
-
-
 /*
  * test for msg delimiter string
  */
 
 static int
 /*
  * test for msg delimiter string
  */
 
 static int
-m_Eom (m_getfld_state_t s, int c)
+m_Eom (m_getfld_state_t s)
 {
     register int i;
     char text[MAX_DELIMITER_SIZE];
     char *cp;
 
     for (i = 0, cp = text; i < s->edelimlen; ++i, ++cp) {
 {
     register int i;
     char text[MAX_DELIMITER_SIZE];
     char *cp;
 
     for (i = 0, cp = text; i < s->edelimlen; ++i, ++cp) {
-       if ((*cp = Getc (s)) == EOF) {
+       int c2;
+
+       if ((c2 = Getc (s)) == EOF) {
+           *cp = '\0';
            break;
            break;
+       } else {
+           *cp = c2;
        }
     }
 
        }
     }
 
@@ -880,10 +868,12 @@ m_Eom (m_getfld_state_t s, int c)
           Note that on input, a character had already been read
           with Getc().  It will be unget by m_getfld () on return. */
        s->readpos -= s->bytes_read - 1;
           Note that on input, a character had already been read
           with Getc().  It will be unget by m_getfld () on return. */
        s->readpos -= s->bytes_read - 1;
+       s->bytes_read = 1;
        return 0;
     }
 
     if (s->msg_style == MS_MBOX) {
        return 0;
     }
 
     if (s->msg_style == MS_MBOX) {
+       int c;
        while ((c = Getc (s)) != '\n')
            if (c < 0)
                break;
        while ((c = Getc (s)) != '\n')
            if (c < 0)
                break;
@@ -893,7 +883,7 @@ m_Eom (m_getfld_state_t s, int c)
 }
 
 
 }
 
 
-static unsigned char *
+static char *
 matchc(int patln, char *pat, int strln, char *str)
 {
        register char *es = str + strln - patln;
 matchc(int patln, char *pat, int strln, char *str)
 {
        register char *es = str + strln - patln;
@@ -912,6 +902,6 @@ matchc(int patln, char *pat, int strln, char *str)
                while (pp < ep && *sp++ == *pp)
                        pp++;
                if (pp >= ep)
                while (pp < ep && *sp++ == *pp)
                        pp++;
                if (pp >= ep)
-                       return ((unsigned char *)--str);
+                       return --str;
        }
 }
        }
 }