mhbuild implement header folding
authorPhilipp Takacs <philipp@bureaucracy.de>
Fri, 25 Aug 2023 18:28:55 +0000 (20:28 +0200)
committerPhilipp Takacs <philipp@bureaucracy.de>
Sun, 24 Sep 2023 22:03:28 +0000 (00:03 +0200)
h/mh.h
h/prototypes.h
sbr/Makefile.in
sbr/fold.c [new file with mode: 0644]
test/tests/mhbuild/test-folding [new file with mode: 0644]
uip/mhoutsbr.c

diff --git a/h/mh.h b/h/mh.h
index 3326185..280249e 100644 (file)
--- a/h/mh.h
+++ b/h/mh.h
@@ -221,6 +221,8 @@ struct msgs {
                            ** terminating NULL.
                            */
 
+#define MAXTEXTPERLN 78
+
 /* m_getfld2() returned data */
 struct field {
        char name[NAMESZ];
index fad1af4..182cf1c 100644 (file)
@@ -114,6 +114,7 @@ void unquote_string(const char *input, char *output);
 int uprf(char *, char *);
 int vfgets(FILE *, char **);
 char *write_charset_8bit(void);
+void fold(charstring_t, size_t, const char *restrict);
 
 
 
index cee1c45..ca8b20d 100644 (file)
@@ -54,7 +54,8 @@ SRCS = addrsbr.c ambigsw.c brkstring.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 \
diff --git a/sbr/fold.c b/sbr/fold.c
new file mode 100644 (file)
index 0000000..0189382
--- /dev/null
@@ -0,0 +1,61 @@
+/* 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;
+       }
+}
diff --git a/test/tests/mhbuild/test-folding b/test/tests/mhbuild/test-folding
new file mode 100644 (file)
index 0000000..366f82b
--- /dev/null
@@ -0,0 +1,35 @@
+# 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
+!
index 87e7943..2915afe 100644 (file)
@@ -161,12 +161,15 @@ static void
 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);
 }