about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--mdeliver.c19
-rwxr-xr-xt/1900-mdeliver.t69
2 files changed, 85 insertions, 3 deletions
diff --git a/mdeliver.c b/mdeliver.c
index 27c4b9c..c9e00c5 100644
--- a/mdeliver.c
+++ b/mdeliver.c
@@ -147,6 +147,8 @@ try_again:
 
 		int in_header = 1;
 		int is_old = 0;
+		int prev_line_empty = 0;
+		int this_line_empty = 0;  // only for mbox parsing
 		while (1) {
 			errno = 0;
 			ssize_t rd = getdelim(&line, &linelen, '\n', infile);
@@ -158,8 +160,12 @@ try_again:
 			char *line_start = line;
 
 			if (line[0] == '\n' && (!line[1] ||
-			                        (line[1] == '\r' && !line[2])))
+			                        (line[1] == '\r' && !line[2]))) {
+				this_line_empty = Mflag ? 1 : 0;
 				in_header = 0;
+			} else {
+				this_line_empty = 0;
+			}
 
 			if (Mflag && strncmp("From ", line, 5) == 0)
 				break;
@@ -189,8 +195,15 @@ try_again:
 				}
 			}
 
-			if (fwrite(line_start, 1, rd, outfile) != (size_t)rd)
-				goto fail;
+			// print delayed empty line
+			if (prev_line_empty)
+				if (fputc('\n', outfile) == EOF)
+					goto fail;
+			if (!this_line_empty)
+				if (fwrite(line_start, 1, rd, outfile) != (size_t)rd)
+					goto fail;
+
+			prev_line_empty = this_line_empty;
 		}
 		if (fflush(outfile) == EOF)
 			goto fail;
diff --git a/t/1900-mdeliver.t b/t/1900-mdeliver.t
new file mode 100755
index 0000000..179cbbe
--- /dev/null
+++ b/t/1900-mdeliver.t
@@ -0,0 +1,69 @@
+#!/bin/sh -e
+cd ${0%/*}
+. ./lib.sh
+plan 2
+
+rm -rf test.dir
+mkdir test.dir
+cd test.dir
+
+mmkdir inbox
+
+cat <<EOF >tmp.1
+Subject: message 1
+
+This is message 1.
+EOF
+
+cat <<EOF >tmp.2
+Subject: message 2
+
+This is message 2.  It has a trailing empty line.
+
+EOF
+
+printf >tmp.3 'Subject: message 3
+
+This is message 3.  It has a no trailing newline, oops.'
+
+cat <<EOF >tmp.4
+Subject: message 4
+
+
+
+This is message 4.  It has multiple trailing empty lines.
+
+
+EOF
+
+mexport ./tmp.1 | mdeliver -M inbox/
+check 'message 1 is delivered verbatim via mbox' 'cmp ./tmp.1 ./inbox/new/*:2,'
+rm -f ./inbox/new/*
+
+mexport ./tmp.2 | mdeliver -M inbox/
+check 'message 2 is delivered verbatim via mbox' 'cmp ./tmp.2 ./inbox/new/*:2,'
+rm -f ./inbox/new/*
+
+mexport ./tmp.3 | mdeliver -M inbox/
+check 'message 3 gets a newline via mbox' 'awk 1 ./tmp.3 | cmp - ./inbox/new/*:2,'
+rm -f ./inbox/new/*
+
+mexport ./tmp.4 | mdeliver -M inbox/
+check 'message 4 gets delivered verbatim via mbox' 'cmp ./tmp.4 ./inbox/new/*:2,'
+rm -f ./inbox/new/*
+
+mdeliver inbox/ <./tmp.1
+check 'message 1 is delivered verbatim via stdin' 'cmp ./tmp.1 ./inbox/new/*:2,'
+rm -f ./inbox/new/*
+
+mdeliver inbox/ <./tmp.2
+check 'message 2 is delivered verbatim via stdin' 'cmp ./tmp.2 ./inbox/new/*:2,'
+rm -f ./inbox/new/*
+
+mdeliver inbox/ <./tmp.3
+check 'message 3 gets a newline via stdin' 'cmp ./tmp.3 ./inbox/new/*:2,'
+rm -f ./inbox/new/*
+
+mdeliver inbox/ <./tmp.4
+check 'message 4 is delivered verbatim via stdin' 'cmp ./tmp.4 ./inbox/new/*:2,'
+rm -f ./inbox/new/*