The mmh website is located at <http://marmaro.de/prog/mmh/>.
Feel free to write to mmh's mailing list at <mmh@marmaro.de>
or contact Markus Schnalke <meillo@marmaro.de> directly.
+You can also join our IRC-Channel #mmh on freenode.
(The nmh website is located at <http://nmh.nongnu.org/>.)
--- /dev/null
+/* charstring.h -- dynamically-sized char array that can report size
+ * in both characters and bytes
+ *
+ * This code is Copyright (c) 2017, by the authors of nmh. See the
+ * COPYRIGHT file in the root directory of the nmh distribution for
+ * complete copyright information. */
+
+/*
+ * char array that keeps track of size in both bytes and characters
+ * Usage note:
+ * Don't store return value of charstring_buffer() and use later
+ * after intervening push_back's; use charstring_buffer_copy()
+ * instead.
+ */
+
+typedef struct charstring *charstring_t;
+
+charstring_t charstring_create(size_t);
+charstring_t charstring_copy(const charstring_t) NONNULL(1);
+void charstring_free(charstring_t);
+/* Append a single-byte character: */
+void charstring_push_back(charstring_t, const char) NONNULL(1);
+/* Append possibly multi-byte character(s): */
+void charstring_push_back_chars(charstring_t, const char [], size_t) NONNULL(1);
+void charstring_append(charstring_t, const charstring_t) NONNULL(2);
+void charstring_append_cstring(charstring_t, const char []) NONNULL(2);
+void charstring_clear(charstring_t) NONNULL(1);
+/* Don't store return value of charstring_buffer() and use later after
+ intervening push_back's; use charstring_buffer_copy() instead. */
+const char *charstring_buffer(const charstring_t) NONNULL(1);
+/* User is responsible for free'ing result of buffer copy. */
+char *charstring_buffer_copy(const charstring_t) NONNULL(1);
+size_t charstring_bytes(const charstring_t) NONNULL(1) PURE;
+size_t charstring_chars(const charstring_t) NONNULL(1) PURE;
*/
#if __GNUC__ > 2
# define NORETURN __attribute__((__noreturn__))
+# define CONST __attribute__((const))
+# define MALLOC __attribute__((malloc))
+# define NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
+# define PURE __attribute__((pure))
+# define ENDNULL __attribute__((sentinel))
#else
# define NORETURN
+# define CONST
+# define MALLOC
+# define NONNULL(...)
+# define PURE
+# define ENDNULL
+#endif
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+# define ALLOC_SIZE(...) __attribute__((alloc_size(__VA_ARGS__)))
+# define CHECK_PRINTF(fmt, arg) __attribute__((format(printf, fmt, arg)))
+#else
+# define ALLOC_SIZE(...)
+# define CHECK_PRINTF(fmt, arg)
#endif
/*
** terminating NULL.
*/
+#define MAXTEXTPERLN 78
+
/* m_getfld2() returned data */
struct field {
char name[NAMESZ];
extern char *lib_version;
extern char *whatnowproc;
+#include <h/charstring.h>
#include <h/prototypes.h>
int uprf(char *, char *);
int vfgets(FILE *, char **);
char *write_charset_8bit(void);
+void fold(charstring_t, size_t, const char *restrict);
context_find.c context_read.c \
context_replace.c context_save.c \
cpydata.c crawl_folders.c \
+ charstring.c \
dtime.c dtimep.c \
- error.c execprog.c ext_hook.c folder_addmsg.c folder_delmsgs.c \
+ error.c execprog.c ext_hook.c fold.c \
+ folder_addmsg.c folder_delmsgs.c \
folder_free.c folder_read.c \
folder_realloc.c gans.c getans.c getanswer.c \
getarguments.c \
--- /dev/null
+/* charstring.c -- dynamically-sized char array that can report size
+ * in both characters and bytes
+ *
+ * This code is Copyright (c) 2014, by the authors of nmh. See the
+ * COPYRIGHT file in the root directory of the nmh distribution for
+ * complete copyright information.
+ */
+
+#include <h/mh.h>
+#include <h/utils.h>
+
+#define CHARSTRING_DEFAULT_SIZE 64
+
+struct charstring {
+ char *buffer; /* the char array, not always null-terminated */
+ size_t max; /* current size of the char array, in bytes */
+ char *cur; /* size in bytes = cur - buffer, without trailing null */
+};
+
+
+static void
+charstring_reserve(charstring_t s, size_t need)
+{
+ const size_t cur = s->cur - s->buffer;
+
+ while (need >= s->max - cur) {
+ /* Insufficient capacity, so double it. */
+ s->buffer = mh_xrealloc(s->buffer, s->max *= 2);
+ s->cur = s->buffer + cur;
+ }
+}
+
+/*
+ * max is in characters
+ */
+charstring_t
+charstring_create(size_t max)
+{
+ charstring_t s = mh_xcalloc(1, sizeof(*s));
+
+ s->max = max ? max : CHARSTRING_DEFAULT_SIZE;
+ s->cur = s->buffer = mh_xcalloc(s->max, 1);
+
+ return s;
+}
+
+charstring_t
+charstring_copy(const charstring_t src)
+{
+ const size_t num = src->cur - src->buffer;
+ charstring_t s = mh_xcalloc(1, sizeof(*s));
+
+ s->max = src->max;
+ s->buffer = mh_xcalloc(s->max, 1);
+ memcpy(s->buffer, src->buffer, num);
+ s->cur = s->buffer + num;
+
+ return s;
+}
+
+/*
+ * OK to call charstring_free with a NULL argument.
+ */
+void
+charstring_free(charstring_t s)
+{
+ if (s) {
+ free(s->buffer);
+ free(s);
+ }
+}
+
+void
+charstring_push_back(charstring_t s, const char c)
+{
+ charstring_reserve(s, s->cur - s->buffer + 1);
+ *s->cur++ = c;
+}
+
+/*
+ * num is the number of bytes in c
+ */
+void
+charstring_push_back_chars(charstring_t s, const char c[], size_t num)
+{
+ charstring_reserve(s, s->cur - s->buffer + num);
+ memcpy(s->cur, c, num);
+ s->cur += num;
+}
+
+void
+charstring_append(charstring_t dest, const charstring_t src)
+{
+ const size_t num = src->cur - src->buffer;
+
+ if (num > 0) {
+ charstring_reserve(dest, dest->cur - dest->buffer + num);
+ memcpy(dest->cur, src->buffer, num);
+ dest->cur += num;
+ }
+}
+
+void
+charstring_append_cstring(charstring_t dest, const char src[])
+{
+ const size_t num = strlen(src);
+
+ if (num > 0) {
+ charstring_reserve(dest, dest->cur - dest->buffer + num);
+ memcpy(dest->cur, src, num); /* Exclude src's trailing NUL. */
+ dest->cur += num;
+ }
+}
+
+void
+charstring_clear(charstring_t s)
+{
+ s->cur = s->buffer;
+}
+
+/*
+ * Don't store return value of charstring_buffer() and use later after
+ * intervening push_back's; use charstring_buffer_copy() instead.
+ */
+const char *
+charstring_buffer(const charstring_t s)
+{
+ charstring_reserve(s, s->cur - s->buffer + 1);
+
+ /* This is the only place that we null-terminate the buffer. */
+ *s->cur = '\0';
+ /* Don't increment cur so that more can be appended later, and so
+ that charstring_bytes() behaves as strlen() by not counting the
+ null. */
+
+ return s->buffer;
+}
+
+char *
+charstring_buffer_copy(const charstring_t s)
+{
+ char *copy = mh_xcalloc(s->cur - s->buffer + 1, 1);
+
+ /* Use charstring_buffer() to null terminate the buffer. */
+ memcpy(copy, charstring_buffer(s), s->cur - s->buffer + 1);
+
+ return copy;
+}
+
+size_t
+charstring_bytes(const charstring_t s)
+{
+ return s->cur - s->buffer;
+}
--- /dev/null
+/* fold.c -- fold a mail header field
+ *
+ * This code is Copyright (c), by the authors of nmh. See the
+ * COPYRIGHT file in the root directory of the nmh distribution for
+ * complete copyright information. */
+
+#include <h/mh.h>
+#include <stdio.h>
+
+void
+fold(charstring_t dst, size_t namelen, const char *restrict body)
+{
+ const char *restrict body_next;
+ const char *restrict wsp;
+ const char *restrict wsp_next;
+ const int crlf = strchr(body, '\r') != NULL;
+ charstring_clear(dst);
+ namelen++;
+
+ while (*body) {
+ body_next = strchr(body, '\n');
+ if ((unsigned long) (body_next - body) <= MAXTEXTPERLN - namelen) {
+ charstring_push_back_chars(dst, body, body_next - body + 1);
+ namelen = 0;
+ body = body_next + 1;
+ continue;
+ }
+ wsp = body;
+ while (namelen == 0 && (*wsp == ' ' || *wsp == '\t')) {
+ wsp++;
+ }
+ wsp = wsp_next = strpbrk(wsp, " \t");
+
+ /* if now whitespace is in the current line just print the curret line as is */
+ if (!wsp_next || wsp_next > body_next) {
+ charstring_push_back_chars(dst, body, body_next - body + 1);
+ namelen = 0;
+ body = body_next + 1;
+ continue;
+ }
+
+ while ((unsigned long)(wsp_next - body) <= MAXTEXTPERLN - namelen) {
+ wsp = wsp_next;
+ wsp_next = strpbrk(wsp+1, " \t");
+ if (!wsp_next) {
+ break;
+ }
+ if (wsp_next > body_next) {
+ break;
+ }
+ }
+
+ charstring_push_back_chars(dst, body, wsp - body);
+ if (crlf) {
+ charstring_push_back(dst, '\r');
+ }
+ charstring_push_back(dst, '\n');
+ namelen = 0;
+ body = wsp;
+ }
+}
}
start = strchr(threadfrom, '<');
+ if (!start) {
+ return NULL;
+ }
end = strchr(start, '>');
- if (!(*start) || !(*end)) {
+ if (!end) {
return NULL;
}
*end = '\0';
--- /dev/null
+# test mhbuild linebreak for quoted-printable
+
+. "$MH_TEST_COMMON"
+
+
+draft="$MH_TEST_DIR/mhbuild-$$.draft"
+
+cat >"$draft" <<!
+From: meillo
+To: meillo
+Date: Thursday, 28 Sep 2006 00:02:00
+Subject: mhbuild header folding
+References: <aaaaaaaaaaaaaaaaaaaaaaaaaaa@example.com> <aaaaaaaaaaaaaaaaaaaaaaaaaab@example.com> <c@example.com>
+----------------
+Das ist ein test
+!
+
+
+
+runandcheck 'mhbuild "$draft"' <<!
+!
+
+runandcheck 'sed "/^Content-ID:/s/:.*/: <TESTID>/" "$draft"' <<!
+From: meillo
+To: meillo
+Date: Thursday, 28 Sep 2006 00:02:00
+Subject: mhbuild header folding
+References: <aaaaaaaaaaaaaaaaaaaaaaaaaaa@example.com>
+ <aaaaaaaaaaaaaaaaaaaaaaaaaab@example.com> <c@example.com>
+MIME-Version: 1.0
+Content-Type: text/plain; charset="us-ascii"
+Content-ID: <TESTID>
+
+Das ist ein test
+!
# check it
cat > $expected <<-EOF
-mhl: format error in message 13
+Date: Sun, 15 Jul 2018 12:26:59 +0200
+From: foo@example.edu
+To: bar@example.edu
+Subject: 999 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+
part text/plain 4
foo
EOF
# check it
cat > $expected <<-EOF
-mhl: format error in message 15
+Date: Sun, 15 Jul 2018 12:26:59 +0200
+From: foo@example.edu
+To: bar@example.edu
+Subject: 999 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+
part text/plain 4
foo
EOF
** Directory to place tmp files. This must
** be set before these routines are called.
*/
-char *tmp;
+extern char *tmp;
pid_t xpid = 0;
*/
for (compnum = 1, state = FLD2;;) {
switch (state = m_getfld2(state, &f, in)) {
+ case LENERR2:
+ state = FLD2;
case FLD2:
compnum++;
adios(EX_CONFIG, NULL, "draft has empty body -- no directives!");
/* NOTREACHED */
- case LENERR2:
case FMTERR2:
case IOERR2:
adios(EX_CONFIG, NULL, "message format error in component #%d",
for (state = FLD2; !eflag; ) {
switch (state = m_getfld2(state, &f, fp)) {
+ case LENERR2:
+ state = FLD2;
case FLD2:
for (ip = ignores; *ip; ip++)
if (simplematch(*ip, f.name)) {
}
return;
- case LENERR2:
case FMTERR2:
case IOERR2:
advise(NULL, "format error in message %s", mname);
output_headers(CT ct, FILE *out)
{
HF hp;
+ charstring_t body = charstring_create(0);
hp = ct->c_first_hf;
while (hp) {
- fprintf(out, "%s:%s", hp->name, hp->value);
+ fold(body, strlen(hp->name), hp->value);
+ fprintf(out, "%s:%s", hp->name, charstring_buffer(body));
hp = hp->next;
}
+ charstring_free(body);
}
static char body_file_name[MAXPATHLEN + 1];
/* name of mhbuild composition temporary file */
static char composition_file_name[MAXPATHLEN + 1];
-static int field_size; /* size of header field buffer */
-static char *field; /* header field buffer */
static FILE *draft_file; /* draft file pointer */
static FILE *body_file; /* body file pointer */
static FILE *composition_file; /* composition file pointer */
static int attach(char *);
static int signandenc(char *);
static void clean_up_temporary_files(void);
-static int get_line(void);
static void make_mime_composition_file_entry(char *);
static char* strexit(int status);
static int
attach(char *draft_file_name)
{
+ enum state state;
+ struct field f = {{0}};
+ int compnum;
+ int finished_header = 0;
char buf[MAXPATHLEN + 6];
- int c;
- int length = strlen(attach_hdr);
+ size_t length = strlen(attach_hdr);
char *p;
if(distfile) {
adios(EX_IOERR, NULL, "can't open draft file `%s'.", draft_file_name);
}
- /* We'll grow the buffer as needed. */
- field = mh_xcalloc(field_size = 256, sizeof(char));
-
/*
** MIMEify
*/
/* Copy non-attachment header fields to the temp composition file. */
rewind(draft_file);
- while (get_line() != EOF && *field && *field != '-') {
- if (strncasecmp(field, VRSN_FIELD, strlen(VRSN_FIELD))==0 &&
- field[strlen(VRSN_FIELD)] == ':') {
- /*
- ** The draft is already in MIME format, thus
- ** back out and use the original draft file.
- */
- clean_up_temporary_files();
- return DONE;
- }
-
- if (strncasecmp(field, attach_hdr, length) != 0 ||
- field[length] != ':') {
- fprintf(composition_file, "%s\n", field);
+ for (compnum = 1, state = FLD2; state == FLD2 || state == BODY2;) {
+ switch (state = m_getfld2(state, &f, draft_file)) {
+ case LENERR2:
+ state = FLD2;
+ case FLD2:
+ compnum++;
+ if (strncasecmp(f.name, VRSN_FIELD, sizeof(VRSN_FIELD) - 1)==0) {
+ /*
+ ** The draft is already in MIME format, thus
+ ** back out and use the original draft file.
+ */
+ clean_up_temporary_files();
+ return DONE;
+ }
+ if (strncasecmp(f.name, attach_hdr, length) != 0 ||
+ f.namelen != length) {
+ fprintf(composition_file, "%s:%s", f.name, f.value);
+ }
+ break;
+ case BODY2:
+ if (!finished_header) {
+ fputs("--------\n", composition_file);
+ finished_header++;
+ }
+ fputs(f.value, body_file);
+ break;
+ case FILEEOF2:
+ break;
+ case FMTERR2:
+ adios(EX_DATAERR, NULL, "message format error in component #%d", compnum);
+ case IOERR2:
+ adios(EX_IOERR, NULL, "error reading draft file: %s", draft_file_name);
+ default:
+ adios(EX_SOFTWARE, NULL, "getfld() returned %d", state);
}
}
- fputs("--------\n", composition_file);
-
- /* Copy the message body to the temporary file. */
- while ((c = getc(draft_file)) != EOF) {
- putc(c, body_file);
- }
fclose(body_file);
/* Add a mhbuild MIME composition file line for the body */
** composition file for each.
*/
rewind(draft_file);
- while (get_line() != EOF && *field && *field != '-') {
- if (strncasecmp(field, attach_hdr, length) == 0 &&
- field[length] == ':') {
- p = trim(field+length+1);
- if (*p == '+') {
- /* forwarded message */
- fprintf(composition_file, "#forw [forwarded message(s)] %s\n", p);
- } else {
- /* regular attachment */
- make_mime_composition_file_entry(p);
+ for (compnum = 1, state = FLD2; state == FLD2;) {
+ switch (state = m_getfld2(state, &f, draft_file)) {
+ case LENERR2:
+ state = FLD2;
+ case FLD2:
+ compnum++;
+ if (strncasecmp(f.name, attach_hdr, length) == 0 &&
+ f.namelen == length) {
+ p = trim(f.value);
+ if (*p == '+') {
+ /* forwarded message */
+ fprintf(composition_file, "#forw [forwarded message(s)] %s\n", p);
+ } else {
+ /* regular attachment */
+ make_mime_composition_file_entry(p);
+ }
}
+ break;
+ case BODY2:
+ case FILEEOF2:
+ break;
+ case FMTERR2:
+ adios(EX_DATAERR, NULL, "message format error in component #%d", compnum);
+ case IOERR2:
+ adios(EX_IOERR, NULL, "error reading draft file: %s", draft_file_name);
+ default:
+ adios(EX_SOFTWARE, NULL, "getfld() returned %d", state);
}
}
fclose(composition_file);
static int
signandenc(char *draft_file_name)
{
+ enum state state;
+ int compnum;
+ struct field f = {{0}};
char buf[BUFSIZ];
int dosign = 0;
int doenc = 0;
adios(EX_IOERR, NULL, "can't open draft file `%s'.", draft_file_name);
}
- /* We'll grow the buffer as needed. */
- field = mh_xcalloc(field_size = 256, sizeof(char));
-
/* Scan the draft file for an attachment header field name. */
- while (get_line() != EOF && *field != '\0' && *field != '-') {
- if (strncasecmp(field, sign_hdr, strlen(sign_hdr))==0 &&
- field[strlen(sign_hdr)] == ':') {
- dosign = 1;
- }
- if (strncasecmp(field, enc_hdr, strlen(enc_hdr))==0 &&
- field[strlen(enc_hdr)] == ':') {
- doenc = 1;
+ for (compnum = 1, state = FLD2; state == FLD2;) {
+ switch (state = m_getfld2(state, &f, draft_file)) {
+ case LENERR2:
+ state = FLD2;
+ case FLD2:
+ compnum++;
+ if (strcasecmp(f.name, sign_hdr)==0) {
+ dosign = 1;
+ }
+ if (strcasecmp(f.name, enc_hdr)==0) {
+ doenc = 1;
+ }
+ break;
+ case BODY2:
+ case FILEEOF2:
+ break;
+ case FMTERR2:
+ adios(EX_DATAERR, NULL, "message format error in component #%d", compnum);
+ case IOERR2:
+ adios(EX_IOERR, NULL, "error reading draft file: %s", draft_file_name);
+ default:
+ adios(EX_SOFTWARE, NULL, "getfld() returned %d", state);
}
}
+
if (!dosign && !doenc) {
return DONE;
}
return;
}
-static int
-get_line(void)
-{
- int c; /* current character */
- int n; /* number of bytes in buffer */
- char *p;
-
- /*
- ** Get a line from the input file, growing the field buffer as
- ** needed. We do this so that we can fit an entire line in the
- ** buffer making it easy to do a string comparison on both the
- ** field name and the field body which might be a long path name.
- */
- for (n = 0, p = field; (c = getc(draft_file)) != EOF; *p++ = c) {
- if (c == '\n' && (c = getc(draft_file)) != ' ' && c != '\t') {
- ungetc(c, draft_file);
- c = '\n';
- break;
- }
- if (++n >= field_size - 1) {
- field = mh_xrealloc(field, field_size += 256);
- p = field + n - 1;
- }
- }
- *p = '\0';
-
- return (c);
-}
-
static void
make_mime_composition_file_entry(char *file_name)
{
if (hdr->flags & HTRY) {
addr_end->m_next = recipients;
recipients = addr_start.m_next;
- recipientsc += i;
+ recipientsc += addrc;
}
}