#!/bin/sh # Test all combinations of alignment of the end-of-message delimiter # with the end of a stdio buffer set -e if test -z "${MH_OBJ_DIR}"; then srcdir=`dirname "$0"`/../.. MH_OBJ_DIR=`cd "$srcdir" && pwd`; export MH_OBJ_DIR fi . "$MH_OBJ_DIR/test/common.sh" setup_test THISDIR="$srcdir/test/inc" if [ -z "$VALGRIND_ME" ]; then VALGRIND= else require_prog valgrind # Lack of quotes here is important VALGRIND="valgrind --quiet --error-exitcode=1" echo "Running tests under valgrind: takes ages!" fi # First check that all our various pieces of text are # intact. (Since we're dealing in exact byte alignment # minor corruptions such as line ending changes could # render the tests useless.) (cd "$THISDIR" && \ for i in *.txt; do echo `output_md5 $i`' '"$i" >> "$MH_TEST_DIR/inctest.md5sums" done) check "$THISDIR/md5sums" "$MH_TEST_DIR/inctest.md5sums" 'keep first' f="$MH_TEST_DIR/mmdf-magic" printf '\1\1\1\1\n' >$f got="`output_md5 $f`" want=2636d725e650779eca70d6564c4f5982 if test "$got" != "$want"; then printf '%s: MMDF magic: %s: got %s, want %s\n' \ "$0" "$f" "$got" "$want" >&2 exit 1 fi mmdf_magic="$f" empty_line="$MH_TEST_DIR/empty-line" printf '\n' >"$empty_line" FILLER="$THISDIR/filler.txt" FROMLINE="$THISDIR/fromline.txt" HDR="$THISDIR/msgheader.txt" if grep From "$FILLER" >/dev/null; then echo "Somebody's messed with $FILLER -- it must not contain" echo "anything that might look like a message delimiter!" exit 1 fi # a sort of worst-case guess for the buffer size; # obviously a buffer boundary for this will be a boundary # for any smaller power of two size. # If you need to increase this you'll need to make filler.txt # bigger as well. STDIO_BUFSZ=16384 FROMLINESZ=`wc -c < "$FROMLINE"` MMDFDELIMLINESZ=`wc -c <"$mmdf_magic"` HDRSZ=`wc -c < "$HDR"` # makembox_A mboxname sz # Assemble a mailbox into file mboxname, with two messages, such # that the first is exactly sz bytes long (including its header # and its initial 'From' line and the newline which terminates it # but not the newline which mbox format demands after each message) # We also leave the body of message one in mboxname.body # (the body of message two is always $FILLER in its entirety) makembox_A () { MBOX="$1" SZ=$2 arith_eval $SZ - $HDRSZ - $FROMLINESZ - 1; WANTSZ=$arith_val dd if="$FILLER" of="$MBOX.body" bs="$WANTSZ" count=1 2>/dev/null echo >> "$MBOX.body" cat "$FROMLINE" "$HDR" "$MBOX.body" "$empty_line" \ "$FROMLINE" "$HDR" "$FILLER" "$empty_line" >"$MBOX" } # makemmdf_A mmdfboxname sz # The first email in $MBOX will be sz bytes long, including its MMDF # magic strings that top and tail it. makemmdf_A () { MBOX="$1" SZ=$2 arith_eval $SZ - $MMDFDELIMLINESZ - $HDRSZ - 1 - $MMDFDELIMLINESZ; WANTSZ=$arith_val dd if="$FILLER" of="$MBOX.body" bs="$WANTSZ" count=1 2>/dev/null echo >> "$MBOX.body" cat "$mmdf_magic" "$HDR" "$MBOX.body" "$mmdf_magic" \ "$mmdf_magic" "$HDR" "$FILLER" "$mmdf_magic" >"$MBOX" } # make_mbox_B mboxname sz # Test B makes a mailbox with one message of sz bytes long, # which ends in a partial mbox delimiter (ie part of the string # \n\nFrom '). To both do this and be a valid mbox this means # it has to end with two newlines (one of which is in the message # body and one of which is the mbox format mandated one) makembox_B () { MBOX="$1" SZ=$2 arith_eval $SZ - $HDRSZ - $FROMLINESZ - 1; WANTSZ=$arith_val dd if="$FILLER" of="$MBOX.body" bs="$WANTSZ" count=1 2>/dev/null echo >> "$MBOX.body" cat "$FROMLINE" "$HDR" "$MBOX.body" "$empty_line" >"$MBOX" } # makemmdf_B mmdfboxname sz # The mbox file will be sz bytes and contain a single email, topped and # tailed with MMDF's magic strings. The end of the email's body looks # the same as the magic string for three bytes. makemmdf_B () { MBOX="$1" SZ=$2 arith_eval $SZ - $MMDFDELIMLINESZ - $HDRSZ - 1 - 4 - $MMDFDELIMLINESZ; WANTSZ=$arith_val dd if="$FILLER" of="$MBOX.body" bs="$WANTSZ" count=1 2>/dev/null printf '\n\1\1\1\n' >>"$MBOX.body" cat "$mmdf_magic" "$HDR" "$MBOX.body" "$mmdf_magic" >"$MBOX" } # do_one_test_A sz mbox_type # Do a single test with message one's body of size sz. do_one_test_A () { SZ=$1 MBOX_TYPE=$2 printf '%5s %s A\r' $SZ $MBOX_TYPE make${MBOX_TYPE}_A "$MH_TEST_DIR/eom-align.mbox" $SZ $VALGRIND inc -silent -file "$MH_TEST_DIR/eom-align.mbox" # We know the messages should be 11 and 12 in inbox # Now get the bodies back out. body1="$MH_TEST_DIR/eom-align.inbox.body1" body2="$MH_TEST_DIR/eom-align.inbox.body2" sed -e '1,/^$/d' "$MH_TEST_DIR/Mail/inbox/11" > "$body1" sed -e '1,/^$/d' "$MH_TEST_DIR/Mail/inbox/12" > "$body2" check "$MH_TEST_DIR/eom-align.mbox.body" "$body1" 'keep first' check "$FILLER" "$body2" 'keep first' rm "$MH_TEST_DIR/Mail/inbox/11" "$MH_TEST_DIR/Mail/inbox/12" } # do_one_test_B sz mbox_type # Do a test type B do_one_test_B () { SZ=$1 MBOX_TYPE=$2 printf '%5s %s B\r' $SZ $MBOX_TYPE make${MBOX_TYPE}_B "$MH_TEST_DIR/eom-align.mbox" $SZ $VALGRIND inc -silent -file "$MH_TEST_DIR/eom-align.mbox" # We know the message should be 11 in the inbox body1="$MH_TEST_DIR/eom-align.inbox.body1" sed -e '1,/^$/d' "$MH_TEST_DIR/Mail/inbox/11" > "$body1" check "$MH_TEST_DIR/eom-align.mbox.body" "$body1" 'keep first' rm "$MH_TEST_DIR/Mail/inbox/11" } # Cover a decent range around the stdio buffer size to make sure we catch # any corner cases whether they relate to total message size equal to # buffer size or to body size equal to buffer size. arith_eval $STDIO_BUFSZ - 16; START=$arith_val arith_eval $STDIO_BUFSZ + $HDRSZ + $FROMLINESZ + 32; FINISH=$arith_val [ -t 1 ] && echo \ "Testing inc of files with various alignments of eom marker with buffer size..." #### Trouble spots for the particular input, with BUFSZ of 8192: for sz in 3146 3147 7241 7242 7243 11338 11339 15433 15434 15435; do do_one_test_A $sz mbox do_one_test_A $sz mmdf done # Also 155, 174, 175, but they're too small for makembox_B to handle. for sz in 684 4074 4097 4148 4610 4611 5121 5122 6654 6655 8170 \ 8193 8244 8364 12266 12289 12340 16362 16385 16436; do do_one_test_B $sz mbox do_one_test_B $sz mmdf done i="$START" while test $i -le $FINISH; do do_one_test_A $i mbox do_one_test_B $i mbox do_one_test_A $i mmdf do_one_test_B $i mmdf i=`expr $i + 1` done printf '\n' test ${failed:-0} -eq 0 && \ rm "$MH_TEST_DIR/eom-align.mbox" "$MH_TEST_DIR/eom-align.mbox.body" \ "$mmdf_magic" "$empty_line" exit $failed