names are typically short (~8 char) and the loop that extracts them
might terminate on a colon, newline or max width. I considered
using a Vax "scanc" to locate the end of the field followed by a
- "bcopy" but the routine call overhead on a Vax is too large for this
+ "memmove" but the routine call overhead on a Vax is too large for this
to work on short names. If Berkeley ever makes "inline" part of the
C optimiser (so things like "scanc" turn into inline instructions) a
change here would be worthwhile.
so message bodies average at least a few hundred characters.
Assuming your system uses reasonably sized stdio buffers (1K or
more), this routine should be able to remove the body in large
- (>500 byte) chunks. The makes the cost of a call to "bcopy"
+ (>500 byte) chunks. The makes the cost of a call to "memmove"
small but there is a premium on checking for the eom in packed
maildrops. The eom pattern is always a simple string so we can
construct an efficient pattern matcher for it (e.g., a Vax "matchc"
m_getfld_state_init (m_getfld_state_t *gstate, FILE *iob) {
m_getfld_state_t s;
- s = *gstate = (m_getfld_state_t) mh_xmalloc(sizeof (struct m_getfld_state));
+ NEW(s);
+ *gstate = s;
s->readpos = s->end = s->msg_buf;
s->bytes_read = s->total_bytes_read = 0;
s->last_caller_pos = s->last_internal_pos = 0;
Peek (m_getfld_state_t s) {
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 ? (unsigned char) *s->readpos : EOF;
}
static int
Ungetc (int c, m_getfld_state_t s) {
if (s->readpos == s->msg_buf) {
return EOF;
- } else {
- --s->bytes_read;
- return *--s->readpos = (unsigned char) c;
}
+ --s->bytes_read;
+ return *--s->readpos = (unsigned char) c;
}
FILE *iob)
{
m_getfld_state_t s;
- register char *cp;
- register int max, n, c;
+ char *cp;
+ int max, n, c;
enter_getfld (gstate, iob);
s = *gstate;
memcpy (buf, name, n - 1);
buf[n - 1] = '\n';
buf[n] = '\0';
+ /* Indicate this wasn't a header field using a character
+ that can't appear in a header field. */
+ name[0] = ':';
/* The last character read was '\n'. s->bytes_read
(and n) include that, but it was not put into the
name array in the for loop above. So subtract 1. */
*bufsz = --s->bytes_read; /* == n - 1 */
leave_getfld (s);
return s->state = BODY;
- } else if (max <= n) {
+ }
+ if (max <= n) {
/* By design, the loop above discards the last character
it had read. It's in c, use it. */
*cp++ = c;
*/
char *bp;
+ name[0] = '\0';
max = *bufsz-1;
/* Back up and store the current position. */
bp = --s->readpos;
m_unknown(m_getfld_state_t *gstate, FILE *iob)
{
m_getfld_state_t s;
- register int c;
+ int c;
char text[MAX_DELIMITER_SIZE];
char from[] = "From ";
- register char *cp;
- register char *delimstr;
+ char *cp;
+ char *delimstr;
unsigned int i;
enter_getfld (gstate, iob);
static int
m_Eom (m_getfld_state_t s)
{
- register int i;
+ int i;
char text[MAX_DELIMITER_SIZE];
char *cp;
static char *
matchc(int patln, char *pat, int strln, char *str)
{
- register char *es = str + strln - patln;
- register char *sp;
- register char *pp;
- register char *ep = pat + patln;
- register char pc = *pat++;
+ char *es = str + strln - patln;
+ char *sp;
+ char *pp;
+ char *ep = pat + patln;
+ char pc = *pat++;
for(;;) {
while (pc != *str++)