X-Git-Url: http://git.marmaro.de/?a=blobdiff_plain;ds=sidebyside;f=sbr%2Fm_getfld2.c;h=de38435c01267e1a328721834f5d98d3c2a81321;hb=bebbba12196b01deca4e33631937fdfdf605b75c;hp=6eb0ef8c311491acd18b8e730e4523b4cff782e3;hpb=4e6362c1749f16f1b09fb04d5951a03c1d9aa9cd;p=mmh diff --git a/sbr/m_getfld2.c b/sbr/m_getfld2.c index 6eb0ef8..de38435 100644 --- a/sbr/m_getfld2.c +++ b/sbr/m_getfld2.c @@ -23,11 +23,22 @@ enum threestate { */ static enum threestate is_falted(FILE *); static size_t copyname(char *, char *); +static int is_separator(char *); /* -** For the states FLD2, BODY2 memory is allocated for f->value. -** For the states LENERR2, FMTERR2, ERR2 and FILEEOF2 no memory is allocated. +** FLD2: We read a (complete) header field +** BODY2: We read a body line +** LENERR2: Line is too long (>998, as defined by RFC 822) +** FMTERR2: Header field invalid +** IOERR2: Failure to read +** FILEEOF2: We're at the end of the file +** +** f->name is only filled in FLD2. +** +** In FLD2, f->value contains the field's (complete) value only; +** in BODY2, LENERR2 and FMTERR2 f->value contains the whole line; +** in IOERR2 and FILEEOF2 f->value is not set. */ enum state m_getfld2(enum state s, struct field *f, FILE *msg) @@ -38,27 +49,39 @@ m_getfld2(enum state s, struct field *f, FILE *msg) enum threestate falted; nchars = getline(&tmpline, &len, msg); - if (nchars == -1) { + if (nchars < 1) { if (feof(msg)) { return FILEEOF2; } else { - return ERR2; + return IOERR2; } } + *f->name = '\0'; + f->namelen = 0; + if (nchars >= NAMESZ) { - free(tmpline); + if (f->value) { + free(f->value); + } + f->value = tmpline; + f->valuelen = nchars; return LENERR2; } switch (s) { case FLD2: if (*(tmpline + nchars - 1) != '\n') { - free(tmpline); + if (f->value) { + free(f->value); + } + f->value = tmpline; + f->valuelen = nchars; + f->alloclen = len; return FMTERR2; } - if (nchars > 0 && (*tmpline == '\n' || *tmpline == '-')) { + if (is_separator(tmpline)) { /* header/body separator found */ free(tmpline); return m_getfld2(BODY2, f, msg); @@ -66,7 +89,12 @@ m_getfld2(enum state s, struct field *f, FILE *msg) f->namelen = copyname(f->name, tmpline); if (f->namelen < 1) { - free(tmpline); + if (f->value) { + free(f->value); + } + f->value = tmpline; + f->valuelen = nchars; + f->alloclen = len; return FMTERR2; } @@ -82,16 +110,25 @@ m_getfld2(enum state s, struct field *f, FILE *msg) nchars = getline(&tmpline, &len, msg); if (nchars <= 0) { free(tmpline); - return ERR2; + return IOERR2; } if (nchars >= NAMESZ) { - free(tmpline); + if (f->value) { + free(f->value); + } + f->value = tmpline; + f->valuelen = nchars; return LENERR2; } if (*(tmpline + nchars - 1) != '\n') { - free(tmpline); + if (f->value) { + free(f->value); + } + f->value = tmpline; + f->valuelen = nchars; + f->alloclen = len; return FMTERR2; } @@ -107,15 +144,13 @@ m_getfld2(enum state s, struct field *f, FILE *msg) if (falted == FAIL) { free(tmpline); - return ERR2; + return IOERR2; } free(tmpline); return FLD2; case BODY2: - *f->name = '\0'; - f->namelen = 0; if (f->value) { free(f->value); } @@ -159,11 +194,17 @@ static size_t copyname(char *dst, char *src) { size_t len; - char *sep = strchr(src, ':'); + char *cp, *sep; - if (!sep) { + if (!(sep = strchr(src, ':'))) { return 0; } + /* whitespace is forbidden in name */ + for (cp=src; cp= NAMESZ) { @@ -175,3 +216,19 @@ copyname(char *dst, char *src) return strlen(dst); } + +static int +is_separator(char *line) +{ + /* + ** In MH, lines that are consists of dashes only are + ** separators as well ... not so in RFC 822. + */ + while (*line == '-') { + line++; + } + if (strcmp("\n", line)==0) { + return 1; + } + return 0; +}