2 ** m_getfld2 -- replacement for m_getfld()
3 ** read an RFC 822 message
7 #define _POSIX_C_SOURCE 200809L
25 static enum threestate is_falted(FILE *);
26 static size_t copyname(char *, char *);
27 static bool is_separator(char *);
31 ** FLD2: We read a (complete) header field
32 ** BODY2: We read a body line
33 ** LENERR2: Line is too long (>998, as defined by RFC 822)
34 ** FMTERR2: Header field invalid
35 ** IOERR2: Failure to read
36 ** FILEEOF2: We're at the end of the file
38 ** f->name is only filled in FLD2.
40 ** In FLD2, f->value contains the field's (complete) value only;
41 ** in BODY2, LENERR2 and FMTERR2 f->value contains the whole line;
42 ** in IOERR2 and FILEEOF2 f->value is not set.
45 m_getfld2(enum state s, struct field *f, FILE *msg)
50 enum threestate falted;
54 nchars = getline(&tmpline, &len, msg);
66 if (nchars >= NAMESZ) {
75 if (*(tmpline + nchars - 1) != '\n') {
85 if (is_separator(tmpline)) {
86 /* header/body separator found */
88 return m_getfld2(BODY2, f, msg);
91 f->namelen = copyname(f->name, tmpline);
102 /* copy the field's value */
103 if (f->alloclen <= nchars - f->namelen) {
104 f->value = mh_xrealloc(f->value, f->alloclen + len);
107 strcpy(f->value, tmpline + f->namelen + 1);
108 f->valuelen = nchars - f->namelen - 1;
110 while ((falted = is_falted(msg)) == B_TRUE) {
111 nchars = getline(&tmpline, &len, msg);
117 if (nchars >= NAMESZ) {
122 f->valuelen = nchars;
126 if (*(tmpline + nchars - 1) != '\n') {
131 f->valuelen = nchars;
136 if (f->alloclen - f->valuelen <= nchars) {
137 f->value = mh_xrealloc(f->value,
141 strcpy(f->value + f->valuelen, tmpline);
142 f->valuelen += nchars;
146 if (falted == FAIL) {
155 nchars = getline(&tmpline, &len, msg);
167 if (nchars >= NAMESZ) {
172 f->valuelen = nchars;
179 f->valuelen = nchars;
184 /* give error states back as received */
189 static enum threestate
195 if ((c = getc(msg)) < 0) {
208 if (ungetc(c, msg) != c) {
215 copyname(char *dst, char *src)
220 if (!(sep = strchr(src, ':'))) {
223 /* whitespace is forbidden in name */
224 for (cp=src; cp<sep; cp++) {
242 is_separator(char *line)
245 ** In MH, lines that are consists of dashes only are
246 ** separators as well ... not so in RFC 822.
248 while (*line == '-') {
251 if (strcmp("\n", line) == 0 || strcmp("\r\n", line) == 0 ) {