#!/bin/sh
src=`pwd`
tmp=$src/tests-tmp
rm -rf $tmp
mkdir -p $tmp
PATH="$src:/bin:/usr/bin:/usr/local/bin"
tests_failed=0
tests_count=0
_UID=`id -u`
_GID=`id -g`
sfecho() { $src/mailfront smtp echo "$@" 2>/dev/null | tail -n +2; }
pfauth() { $src/pop3front-auth "$@" echo Yes. 2>/dev/null | tail -n +2; }
ifauth() { $src/imapfront-auth sh -c 'echo Yes: $IMAPLOGINTAG' 2>/dev/null | tail -n +2; }
pfmaildir() { $src/pop3front-maildir "$@" 2>/dev/null | tail -n +2; }
maildir=$tmp/Maildir
maildir() {
  rm -rf $maildir
  mkdir -p $maildir/cur
  mkdir -p $maildir/new
  mkdir -p $maildir/tmp
}
tstmsg() {
  fn=$1
  {
    echo "Header: foo"
    echo
    echo "body"
  } >$maildir/$fn
}

PROTO=TEST
TESTLOCALIP=1.2.3.4
TESTREMOTEIP=5.6.7.8
TESTLOCALHOST=local.host
TESTREMOTEHOST=remote.host
CVM_PWFILE_PATH=$tmp/pwfile
MODULE_PATH=$src
PLUGINS=accept

export PROTO TESTLOCALIP TESTREMOTEIP TESTLOCALHOST TESTREMOTEHOST
export CVM_PWFILE_PATH MAILRULES DATABYTES MAXHOPS PATTERNS MAXNOTIMPL
export PLUGINS MODULE_PATH

echo testuser:testpass:$_UID:$_GID:Test User:$tmp:/bin/false >$CVM_PWFILE_PATH
ln -s `which cvm-pwfile` $tmp/cvm

run_compare_test() {
  local name=$1
  shift
  sed -e "s:@SOURCE@:$src:g"   	-e "s:@TMPDIR@:$tmp:g"   	-e "s:@UID@:$_UID:" 	-e "s:@GID@:$_GID:" 	>$tmp/expected
  ( runtest "$@" 2>&1 ) 2>&1 >$tmp/actual-raw
  cat -v $tmp/actual-raw >$tmp/actual
  if ! cmp $tmp/expected $tmp/actual >/dev/null 2>&1
  then
    echo "Test $name $@ failed:"
	( cd $tmp; diff -U 9999 expected actual | tail -n +3; echo; )
	tests_failed=$(($tests_failed+1))
  fi
  rm -f $tmp/expected $tmp/actual
  tests_count=$(($tests_count+1))
}

##### Test tests/rules-header-add #####

runtest() {
PLUGINS=mailrules:accept

cat >$tmp/rules <<EOF
ka@example.com:b@example.com:K1:::HEADER_ADD="X-Header: testing!!!"
EOF

MAILRULES=$tmp/rules

sfecho <<EOF
MAIL FROM:<a@example.com>
RCPT TO:<b@example.com>
DATA
.
EOF

sfecho <<EOF
MAIL FROM:<a@example.com>
RCPT TO:<c@example.com>
DATA
.
EOF

rm -f $tmp/rules
}
run_compare_test tests/rules-header-add  <<END_OF_TEST_RESULTS
250 Sender='a@example.com'.^M
250 K1^M
354 End your message with a period on a line by itself.^M
250 Received 0 bytes.^M
250 Sender='a@example.com'.^M
250 Recipient='c@example.com'.^M
354 End your message with a period on a line by itself.^M
250 Received 0 bytes.^M
END_OF_TEST_RESULTS


##### Test tests/rules-empty #####

runtest() {
PLUGINS=mailrules:accept

cat >$tmp/rules <<EOF
k:*:K1
k*:*:K2
EOF

MAILRULES=$tmp/rules

sfecho <<EOF
MAIL FROM:<>
MAIL FROM:<foo@example.com>
EOF

rm -f $tmp/rules
}
run_compare_test tests/rules-empty  <<END_OF_TEST_RESULTS
250 K1^M
250 K2^M
END_OF_TEST_RESULTS


##### Test tests/rules-recip #####

runtest() {
PLUGINS=mailrules:accept

cat >$tmp/rules <<EOF
k*:one@one.example.com:KK
d*:two@two.example.com:DD
z*:three@three.example.com:ZZ
zx@y:four@four.example.com:ZZZ
p*:five@five.example.com:PP
EOF

MAILRULES=$tmp/rules

sfecho <<EOF
MAIL FROM:<nobody@example.net>
RCPT TO:<one@one.example.com>
RCPT TO:<two@two.example.com>
RCPT TO:<three@three.example.com>
RCPT TO:<four@four.example.com>
RCPT TO:<five@five.example.com>
EOF

rm -f $tmp/rules
}
run_compare_test tests/rules-recip  <<END_OF_TEST_RESULTS
250 Sender='nobody@example.net'.^M
250 KK^M
553 DD^M
451 ZZ^M
250 Recipient='four@four.example.com'.^M
250 Recipient='five@five.example.com'.^M
END_OF_TEST_RESULTS


##### Test tests/pop3front-maildir-last #####

runtest() {
pflast() { echo LAST | pfmaildir $maildir; }
maildir
tstmsg new/1
tstmsg new/2
pflast
mv $maildir/new/1 $maildir/cur/1
pflast
mv $maildir/cur/1 $maildir/cur/1:2,S
pflast
mv $maildir/new/2 $maildir/cur/2:2,S
pflast
mv $maildir/cur/1:2,S $maildir/new/1
pflast
}
run_compare_test tests/pop3front-maildir-last  <<END_OF_TEST_RESULTS
+OK 0^M
+OK 0^M
+OK 1^M
+OK 2^M
+OK 2^M
END_OF_TEST_RESULTS


##### Test tests/pop3front-maildir-sort #####

runtest() {
maildir
tstmsg new/99
tstmsg cur/100
tstmsg new/101
tstmsg cur/98

echo UIDL | pfmaildir $maildir
}
run_compare_test tests/pop3front-maildir-sort  <<END_OF_TEST_RESULTS
+OK ^M
1 98^M
2 99^M
3 100^M
4 101^M
.^M
END_OF_TEST_RESULTS


##### Test tests/rules-negate #####

runtest() {
PLUGINS=mailrules:accept

cat >$tmp/rules <<EOF
k!a@example.com:*:A
k!!a@example.com:*:B
EOF

MAILRULES=$tmp/rules

sfecho <<EOF
MAIL FROM:<a@example.com>
MAIL FROM:<b@example.net>
EOF

rm -f $tmp/rules
}
run_compare_test tests/rules-negate  <<END_OF_TEST_RESULTS
250 B^M
250 A^M
END_OF_TEST_RESULTS


##### Test tests/plugin-reject #####

runtest() {
local msg="$1"
PLUGINS=reject:accept

env SMTPREJECT="$msg" $src/mailfront smtp echo 2>/dev/null <<EOF
HELO nobody
EHLO somebody
MAIL FROM:<somewhere>
RCPT TO:<elsewhere>
EOF
}
run_compare_test tests/plugin-reject 'rej' <<END_OF_TEST_RESULTS
220 local.host mailfront ESMTP^M
250 local.host^M
250-local.host^M
250-SIZE 0^M
250-8BITMIME^M
250-ENHANCEDSTATUSCODES^M
250 PIPELINING^M
451 rej^M
503 5.5.1 You must send MAIL FROM: first^M
END_OF_TEST_RESULTS

run_compare_test tests/plugin-reject '-rej' <<END_OF_TEST_RESULTS
220 local.host mailfront ESMTP^M
250 local.host^M
250-local.host^M
250-SIZE 0^M
250-8BITMIME^M
250-ENHANCEDSTATUSCODES^M
250 PIPELINING^M
553 rej^M
503 5.5.1 You must send MAIL FROM: first^M
END_OF_TEST_RESULTS


##### Test tests/rules-cdb #####

runtest() {
PLUGINS=mailrules:accept

cat >$tmp/rules <<EOF
k[[$tmp/list.cdb]]:*:LIST
k[[@$tmp/atlist.cdb]]:*:ATLIST
d*:*:DD
EOF

cat <<EOF | cdbmake $tmp/list.cdb $tmp/list.tmp
+13,0:a@example.net->
+12,0:@example.com->

EOF

cat <<EOF | cdbmake $tmp/atlist.cdb $tmp/atlist.tmp
+11,0:example.org->

EOF

MAILRULES=$tmp/rules

sfecho <<EOF
MAIL FROM:<a@example.net>
MAIL FROM:<b@example.net>
MAIL FROM:<a@example.org>
MAIL FROM:<b@Example.ORG>
MAIL FROM:<c@example.com>
MAIL FROM:<c@Example.COM>
MAIL FROM:<d@example.biz>
EOF

rm -f $tmp/rules $tmp/list.cdb $tmp/atlist.cdb
}
run_compare_test tests/rules-cdb  <<END_OF_TEST_RESULTS
250 LIST^M
553 DD^M
250 ATLIST^M
250 ATLIST^M
250 LIST^M
250 LIST^M
553 DD^M
END_OF_TEST_RESULTS


##### Test tests/rules-sender #####

runtest() {
PLUGINS=mailrules:accept

cat >$tmp/rules <<EOF
kone@one.example.com:*:KK
dtwo@two.example.com:*:DD
zthree@three.example.com:*:ZZ
zfour@four.example.com:one@one.example.com:ZZ
pfive@five.example.com:*:PP
EOF

MAILRULES=$tmp/rules

sfecho <<EOF
MAIL FROM:<one@one.example.com>
MAIL FROM:<two@two.example.com>
MAIL FROM:<three@three.example.com>
MAIL FROM:<four@four.example.com>
MAIL FROM:<five@five.example.com>
EOF

rm -f $tmp/rules
}
run_compare_test tests/rules-sender  <<END_OF_TEST_RESULTS
250 KK^M
553 DD^M
451 ZZ^M
250 Sender='four@four.example.com'.^M
250 Sender='five@five.example.com'.^M
END_OF_TEST_RESULTS


##### Test tests/qmqpfront-echo #####

runtest() {
printf '42:5:test\n,13:a@example.com,13:b@example.com,,' \
| $src/mailfront qmqp echo 2>/dev/null
echo
}
run_compare_test tests/qmqpfront-echo  <<END_OF_TEST_RESULTS
18:KReceived 5 bytes.,
END_OF_TEST_RESULTS


##### Test tests/imapfront-auth #####

runtest() {
CVM_SASL_PLAIN=$tmp/cvm
export CVM_SASL_PLAIN

ifauth <<EOF
1 LOGIN
2 LOGIN A
3 LOGIN A B C
4 LoGiN A B
5 LOGIN testuser testpass
EOF

ifauth <<EOF
6 login "testuser" "testpass"
EOF

ifauth <<EOF
7 login {8}
testuser{8}
testpass
EOF

unset CVM_SASL_PLAIN
}
run_compare_test tests/imapfront-auth  <<END_OF_TEST_RESULTS
1 BAD Syntax error: command requires arguments^M
2 BAD LOGIN command requires exactly two arguments^M
3 BAD LOGIN command requires exactly two arguments^M
4 NO LOGIN failed^M
Yes: 5
Yes: 6
+ OK^M
+ OK^M
Yes: 7
END_OF_TEST_RESULTS


##### Test tests/plugins-prepend #####

runtest() {
env \
PLUGINS=accept:+reject \
REJECT=reject \
$src/mailfront smtp echo 2>/dev/null <<EOF
MAIL FROM:<somewhere>
RCPT TO:<elsewhere>
EOF
}
run_compare_test tests/plugins-prepend  <<END_OF_TEST_RESULTS
220 local.host mailfront ESMTP^M
451 reject^M
503 5.5.1 You must send MAIL FROM: first^M
END_OF_TEST_RESULTS


##### Test tests/smtpfront-maxnotimpl #####

runtest() {
MAXNOTIMPL=1

sfecho <<EOF
a
b
c
d
EOF

MAXNOTIMPL=0

sfecho <<EOF
a
b
c
d
EOF
}
run_compare_test tests/smtpfront-maxnotimpl  <<END_OF_TEST_RESULTS
500 5.5.1 Not implemented.^M
503-5.5.0 Too many unimplemented commands.^M
503 5.5.0 Closing connection.^M
500 5.5.1 Not implemented.^M
500 5.5.1 Not implemented.^M
500 5.5.1 Not implemented.^M
500 5.5.1 Not implemented.^M
END_OF_TEST_RESULTS


##### Test tests/patterns-header #####

runtest() {
PLUGINS=patterns:accept

cat >$tmp/patterns <<EOF
:header2:*field*
EOF

PATTERNS=$tmp/patterns

sfecho <<EOF
MAIL FROM:<>
RCPT TO:<nobody@example.com>
DATA
header1: data
header2: another field

not

also
.
EOF

echo

cat >$tmp/patterns <<EOF
:not
:also
EOF

sfecho <<EOF
MAIL FROM:<>
RCPT TO:<nobody@example.com>
DATA
header

not

also
.
EOF

rm -f $tmp/patterns
}
run_compare_test tests/patterns-header  <<END_OF_TEST_RESULTS
250 Sender=''.^M
250 Recipient='nobody@example.com'.^M
354 End your message with a period on a line by itself.^M
554 This message contains prohibited content^M

250 Sender=''.^M
250 Recipient='nobody@example.com'.^M
354 End your message with a period on a line by itself.^M
250 Received 18 bytes.^M
END_OF_TEST_RESULTS


##### Test tests/rules-both #####

runtest() {
PLUGINS=mailrules:accept

cat >$tmp/rules <<EOF
ka@example.net:a@example.com:K1
ka@example.net:b@example.com:K2
kb@example.net:a@example.com:K3
kb@example.net:b@example.com:K4
EOF

MAILRULES=$tmp/rules

sfecho <<EOF
MAIL FROM:<a@example.net>
RCPT TO:<a@example.com>
RCPT TO:<b@example.com>
MAIL FROM:<b@example.net>
RCPT TO:<a@example.com>
RCPT TO:<b@example.com>
EOF

rm -f $tmp/rules
}
run_compare_test tests/rules-both  <<END_OF_TEST_RESULTS
250 Sender='a@example.net'.^M
250 K1^M
250 K2^M
250 Sender='b@example.net'.^M
250 K3^M
250 K4^M
END_OF_TEST_RESULTS


##### Test tests/rules-list #####

runtest() {
PLUGINS=mailrules:accept

cat >$tmp/rules <<EOF
k[[$tmp/list]]:*:LIST
k[[@$tmp/atlist]]:*:ATLIST
d*:*:DD
EOF

cat >$tmp/list <<EOF
a@example.net
@example.com
EOF

cat >$tmp/atlist <<EOF
example.biz
EOF

MAILRULES=$tmp/rules

sfecho <<EOF
MAIL FROM:<a@example.net>
MAIL FROM:<b@example.net>
MAIL FROM:<a@example.biz>
MAIL FROM:<b@Example.BIZ>
MAIL FROM:<c@example.com>
MAIL FROM:<c@Example.COM>
MAIL FROM:<d@example.org>
EOF

rm -f $tmp/rules $tmp/list $tmp/atlist
}
run_compare_test tests/rules-list  <<END_OF_TEST_RESULTS
250 LIST^M
553 DD^M
250 ATLIST^M
250 ATLIST^M
250 LIST^M
250 LIST^M
553 DD^M
END_OF_TEST_RESULTS


##### Test tests/rules-noop #####

runtest() {
PLUGINS=mailrules:relayclient:accept

cat >$tmp/rules <<EOF
n*:*:Do not see this:::RELAYCLIENT=@rc
EOF

MAILRULES=$tmp/rules

sfecho <<EOF
MAIL FROM:<a@example.com>
RCPT TO:<b@example.net>
EOF

rm -f $tmp/rules
}
run_compare_test tests/rules-noop  <<END_OF_TEST_RESULTS
250 Sender='a@example.com'.^M
250 Recipient='b@example.net@rc'.^M
END_OF_TEST_RESULTS


##### Test tests/patterns-message #####

runtest() {
PLUGINS=patterns:accept

cat >$tmp/patterns <<EOF
=response 1
=response 2
/*
=response 3
EOF

PATTERNS=$tmp/patterns

sfecho <<EOF
MAIL FROM:<>
RCPT TO:<nobody@example.com>
DATA
before

after
.
EOF

rm -f $tmp/patterns
}
run_compare_test tests/patterns-message  <<END_OF_TEST_RESULTS
250 Sender=''.^M
250 Recipient='nobody@example.com'.^M
354 End your message with a period on a line by itself.^M
554 response 2^M
END_OF_TEST_RESULTS


##### Test tests/pop3front-auth #####

runtest() {
$src/pop3front-auth false echo Yes. <<EOF 2>/dev/null
QUIT NO
QUIT
QUIT AGAIN
EOF
}
run_compare_test tests/pop3front-auth  <<END_OF_TEST_RESULTS
+OK ^M
-ERR Syntax error^M
+OK ^M
END_OF_TEST_RESULTS


##### Test tests/plugin-cvm-validate #####

runtest() {
PLUGINS=cvm-validate:accept
CVM_LOOKUP=$tmp/cvm
CVM_LOOKUP_SECRET=test
export CVM_LOOKUP CVM_LOOKUP_SECRET

sfecho <<EOF
MAIL FROM:<somewhere>
RCPT TO:<testuser@here>
RCPT TO:<testxser@here>
EOF

unset CVM_LOOKUP CVM_LOOKUP_SECRET
}
run_compare_test tests/plugin-cvm-validate  <<END_OF_TEST_RESULTS
250 Sender='somewhere'.^M
250 Recipient='testuser@here'.^M
553 5.1.1 Sorry, that recipient does not exist.^M
END_OF_TEST_RESULTS


##### Test tests/patterns-normal #####

runtest() {
PLUGINS=patterns:accept

cat >$tmp/patterns <<EOF
# comment

/before
# comment
EOF

PATTERNS=$tmp/patterns

sfecho <<EOF
MAIL FROM:<>
RCPT TO:<nobody@example.com>
DATA
before

after
.
EOF

rm -f $tmp/patterns
}
run_compare_test tests/patterns-normal  <<END_OF_TEST_RESULTS
250 Sender=''.^M
250 Recipient='nobody@example.com'.^M
354 End your message with a period on a line by itself.^M
554 This message contains prohibited content^M
END_OF_TEST_RESULTS


##### Test tests/imapfront-auth-login #####

runtest() {
export CVM_SASL_PLAIN=$tmp/cvm

ifauth false <<EOF
1 AUTHENTICATE LOGIN
dGVzdHVzZXI=
dGVzdHBhc3x=
2 AUTHENTICATE LOGIN
dGVzdHVzZXI=
dGVzdHBhc3M=
EOF

ifauth false <<EOF
3 AUTHENTICATE LOGIN dGVzdHVzZXI=
dGVzdHBhc3M=
EOF

ifauth false <<EOF
4 AUTHENTICATE LOGIN
dGVzdHVzZXI=
*
EOF

unset CVM_SASL_PLAIN
}
run_compare_test tests/imapfront-auth-login  <<END_OF_TEST_RESULTS
+ VXNlcm5hbWU6^M
+ UGFzc3dvcmQ6^M
1 NO AUTHENTICATE failed: Authentication failed.^M
+ VXNlcm5hbWU6^M
+ UGFzc3dvcmQ6^M
Yes: 2
+ UGFzc3dvcmQ6^M
Yes: 3
+ VXNlcm5hbWU6^M
+ UGFzc3dvcmQ6^M
4 NO AUTHENTICATE failed: Authentication failed.^M
END_OF_TEST_RESULTS


##### Test tests/imapfront-auth-plain #####

runtest() {
export CVM_SASL_PLAIN=$tmp/cvm

ifauth <<EOF
1 AUTHENTICATE PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3x=
2 AUTHENTICATE PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M=
EOF

ifauth <<EOF
3 AUTHENTICATE PLAIN
dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M=
EOF

ifauth <<EOF
4 AUTHENTICATE PLAIN
*
EOF

unset CVM_SASL_PLAIN
}
run_compare_test tests/imapfront-auth-plain  <<END_OF_TEST_RESULTS
1 NO AUTHENTICATE failed: Authentication failed.^M
Yes: 2
+ ^M
Yes: 3
+ ^M
4 NO AUTHENTICATE failed: Authentication failed.^M
END_OF_TEST_RESULTS


##### Test tests/pop3front-maildir-flags #####

runtest() {
pftest() {
  (
    for line in "$@"; do
      echo $line
    done
  ) | pfmaildir $maildir
  ( cd $maildir && ls -1 */* )
}

# Does it properly parse existing v2 flags
maildir
tstmsg new/1000000000.12345.here:2,FX
pftest 'RETR 1' QUIT

# Does it properly ignore non-v2 flags
maildir
tstmsg new/1000000000.12345.here:1fsd
pftest 'RETR 1' QUIT
}
run_compare_test tests/pop3front-maildir-flags  <<END_OF_TEST_RESULTS
+OK ^M
Header: foo^M
^M
body^M
^M
.^M
+OK ^M
cur/1000000000.12345.here:2,FXS
+OK ^M
Header: foo^M
^M
body^M
^M
.^M
+OK ^M
cur/1000000000.12345.here:1fsd
END_OF_TEST_RESULTS


##### Test tests/patterns-general #####

runtest() {
local subject="$1"
PLUGINS=patterns:accept

cat >$tmp/patterns <<EOF
/Subject: *word*
EOF

PATTERNS=$tmp/patterns

sfecho <<EOF
MAIL FROM:<>
RCPT TO:<nobody@example.com>
DATA
Subject: $subject
.
EOF

rm -f $tmp/patterns
}
run_compare_test tests/patterns-general 'xwordx' <<END_OF_TEST_RESULTS
250 Sender=''.^M
250 Recipient='nobody@example.com'.^M
354 End your message with a period on a line by itself.^M
554 This message contains prohibited content^M
END_OF_TEST_RESULTS

run_compare_test tests/patterns-general 'word at the beginning' <<END_OF_TEST_RESULTS
250 Sender=''.^M
250 Recipient='nobody@example.com'.^M
354 End your message with a period on a line by itself.^M
554 This message contains prohibited content^M
END_OF_TEST_RESULTS

run_compare_test tests/patterns-general 'last word' <<END_OF_TEST_RESULTS
250 Sender=''.^M
250 Recipient='nobody@example.com'.^M
354 End your message with a period on a line by itself.^M
554 This message contains prohibited content^M
END_OF_TEST_RESULTS

run_compare_test tests/patterns-general 'middle word middle' <<END_OF_TEST_RESULTS
250 Sender=''.^M
250 Recipient='nobody@example.com'.^M
354 End your message with a period on a line by itself.^M
554 This message contains prohibited content^M
END_OF_TEST_RESULTS

run_compare_test tests/patterns-general 'word' <<END_OF_TEST_RESULTS
250 Sender=''.^M
250 Recipient='nobody@example.com'.^M
354 End your message with a period on a line by itself.^M
554 This message contains prohibited content^M
END_OF_TEST_RESULTS

run_compare_test tests/patterns-general 'xord' <<END_OF_TEST_RESULTS
250 Sender=''.^M
250 Recipient='nobody@example.com'.^M
354 End your message with a period on a line by itself.^M
250 Received 14 bytes.^M
END_OF_TEST_RESULTS


##### Test tests/smtpfront-maxrcpts #####

runtest() {
PLUGINS=counters:accept

MAXRCPTS=2
export MAXRCPTS

sfecho <<EOF
MAIL FROM:<notbounce@example.com>
RCPT TO:<addr1@example.net>
RCPT TO:<addr2@example.net>
RCPT TO:<addr3@example.net>
RCPT TO:<addr4@example.net>
EOF

unset MAXRCPTS
}
run_compare_test tests/smtpfront-maxrcpts  <<END_OF_TEST_RESULTS
250 Sender='notbounce@example.com'.^M
250 Recipient='addr1@example.net'.^M
250 Recipient='addr2@example.net'.^M
550 5.5.3 Too many recipients^M
550 5.5.3 Too many recipients^M
END_OF_TEST_RESULTS


##### Test tests/smtpfront-looping-received #####

runtest() {
PLUGINS=counters:accept

MAXHOPS=1

sfecho <<EOF
MAIL FROM:<somebody@example.com>
RCPT TO:<nobody@example.org>
DATA
Received: foo
.
EOF

echo

sfecho <<EOF
MAIL FROM:<somebody@example.com>
RCPT TO:<nobody@example.org>
DATA
Received: foo
Received: foo
.
EOF
}
run_compare_test tests/smtpfront-looping-received  <<END_OF_TEST_RESULTS
250 Sender='somebody@example.com'.^M
250 Recipient='nobody@example.org'.^M
354 End your message with a period on a line by itself.^M
250 Received 14 bytes.^M

250 Sender='somebody@example.com'.^M
250 Recipient='nobody@example.org'.^M
354 End your message with a period on a line by itself.^M
554 5.6.0 This message is looping, too many hops.^M
END_OF_TEST_RESULTS


##### Test tests/pop3front-maildir-state #####

runtest() {
local quit="$1"
local command="$2"
maildir
tstmsg new/1
tstmsg new/this.is.a.very.long.filename.that.should.get.truncated.after.the.X...XBUGBUGBUGBUG
(
  echo $command
  if $quit; then echo QUIT; fi
) | pfmaildir $maildir
( cd $maildir && find new cur -type f )
}
run_compare_test tests/pop3front-maildir-state 'false' 'UIDL' <<END_OF_TEST_RESULTS
+OK ^M
1 1^M
2 this.is.a.very.long.filename.that.should.get.truncated.after.the.X...X^M
.^M
new/1
new/this.is.a.very.long.filename.that.should.get.truncated.after.the.X...XBUGBUGBUGBUG
END_OF_TEST_RESULTS

run_compare_test tests/pop3front-maildir-state 'false' 'TOP 1 0' <<END_OF_TEST_RESULTS
+OK ^M
Header: foo^M
^M
^M
.^M
new/1
new/this.is.a.very.long.filename.that.should.get.truncated.after.the.X...XBUGBUGBUGBUG
END_OF_TEST_RESULTS

run_compare_test tests/pop3front-maildir-state 'false' 'RETR 1' <<END_OF_TEST_RESULTS
+OK ^M
Header: foo^M
^M
body^M
^M
.^M
new/1
new/this.is.a.very.long.filename.that.should.get.truncated.after.the.X...XBUGBUGBUGBUG
END_OF_TEST_RESULTS

run_compare_test tests/pop3front-maildir-state 'true' 'UIDL' <<END_OF_TEST_RESULTS
+OK ^M
1 1^M
2 this.is.a.very.long.filename.that.should.get.truncated.after.the.X...X^M
.^M
+OK ^M
cur/1
cur/this.is.a.very.long.filename.that.should.get.truncated.after.the.X...XBUGBUGBUGBUG
END_OF_TEST_RESULTS

run_compare_test tests/pop3front-maildir-state 'true' 'TOP 1 0' <<END_OF_TEST_RESULTS
+OK ^M
Header: foo^M
^M
^M
.^M
+OK ^M
cur/1
cur/this.is.a.very.long.filename.that.should.get.truncated.after.the.X...XBUGBUGBUGBUG
END_OF_TEST_RESULTS

run_compare_test tests/pop3front-maildir-state 'true' 'RETR 1' <<END_OF_TEST_RESULTS
+OK ^M
Header: foo^M
^M
body^M
^M
.^M
+OK ^M
cur/1:2,S
cur/this.is.a.very.long.filename.that.should.get.truncated.after.the.X...XBUGBUGBUGBUG
END_OF_TEST_RESULTS


##### Test tests/smtpfront-databytes #####

runtest() {
PLUGINS=counters:accept

unset DATABYTES
sfecho <<EOF
EHLO hostname
MAIL FROM:<a@example.com>
MAIL FROM:<a@example.com> SIZE
MAIL FROM:<a@example.com> SIZE=
MAIL FROM:<a@example.com> SIZE=100
EOF

DATABYTES=123
export DATABYTES

sfecho <<EOF
EHLO hostname
MAIL FROM:<a@example.com>
MAIL FROM:<a@example.com> SIZE
MAIL FROM:<a@example.com> SIZE=
MAIL FROM:<a@example.com> SIZE=100
MAIL FROM:<a@example.com> SIZE=123
MAIL FROM:<a@example.com> SIZE=124
RCPT TO:<nobody@nowhere>
EOF
}
run_compare_test tests/smtpfront-databytes  <<END_OF_TEST_RESULTS
250-local.host^M
250-SIZE 0^M
250-8BITMIME^M
250-ENHANCEDSTATUSCODES^M
250 PIPELINING^M
250 Sender='a@example.com'.^M
250 Sender='a@example.com'.^M
250 Sender='a@example.com'.^M
250 Sender='a@example.com'.^M
250-local.host^M
250-SIZE 123^M
250-8BITMIME^M
250-ENHANCEDSTATUSCODES^M
250 PIPELINING^M
250 Sender='a@example.com'.^M
250 Sender='a@example.com'.^M
250 Sender='a@example.com'.^M
250 Sender='a@example.com'.^M
250 Sender='a@example.com'.^M
552 5.2.3 The message would exceed the maximum message size.^M
503 5.5.1 You must send MAIL FROM: first^M
END_OF_TEST_RESULTS


##### Test tests/qmtpfront-echo #####

runtest() {
printf '6:\ntest\n,13:a@example.com,17:13:b@example.com,,' \
| $src/mailfront qmtp echo 2>/dev/null
echo
}
run_compare_test tests/qmtpfront-echo  <<END_OF_TEST_RESULTS
18:KReceived 5 bytes.,
END_OF_TEST_RESULTS


##### Test tests/smtpgreeting #####

runtest() {
env SMTPGREETING='hostname hello' $src/mailfront smtp echo 2>/dev/null </dev/null
}
run_compare_test tests/smtpgreeting  <<END_OF_TEST_RESULTS
220 hostname hello ESMTP^M
END_OF_TEST_RESULTS


##### Test tests/plugins-remove #####

runtest() {
local remove="$1"

env \
PLUGINS="reject:-$remove:accept" \
REJECT="reject" \
$src/mailfront smtp echo 2>/dev/null <<EOF
MAIL FROM:<somewhere>
RCPT TO:<elsewhere>
EOF
}
run_compare_test tests/plugins-remove 'reject' <<END_OF_TEST_RESULTS
220 local.host mailfront ESMTP^M
250 Sender='somewhere'.^M
250 Recipient='elsewhere'.^M
END_OF_TEST_RESULTS

run_compare_test tests/plugins-remove 'other' <<END_OF_TEST_RESULTS
220 local.host mailfront ESMTP^M
451 reject^M
503 5.5.1 You must send MAIL FROM: first^M
END_OF_TEST_RESULTS

run_compare_test tests/plugins-remove '*' <<END_OF_TEST_RESULTS
220 local.host mailfront ESMTP^M
250 Sender='somewhere'.^M
250 Recipient='elsewhere'.^M
END_OF_TEST_RESULTS


##### Test tests/smtpfront-content #####

runtest() {
RELAYCLIENT= sfecho <<EOF
MAIL FROM:<user@example.net>
RCPT TO:<user@example.com>
DATA
Subject: test

foo
..
bar
.
MAIL FROM:<user@example.net>
RCPT TO:<user@example.com>
DATA
Subject: test

foo
..
bar

.
EOF
}
run_compare_test tests/smtpfront-content  <<END_OF_TEST_RESULTS
250 Sender='user@example.net'.^M
250 Recipient='user@example.com'.^M
354 End your message with a period on a line by itself.^M
250 Received 25 bytes.^M
250 Sender='user@example.net'.^M
250 Recipient='user@example.com'.^M
354 End your message with a period on a line by itself.^M
250 Received 26 bytes.^M
END_OF_TEST_RESULTS


##### Test tests/smtpfront-auth-login #####

runtest() {
PLUGINS=relayclient:qmail-validate:accept-sender

sfecho <<EOF
AUTH LOGIN
EOF

export CVM_SASL_LOGIN=$tmp/cvm

sfecho <<EOF
MAIL FROM: <user@example.com>
RCPT TO: <user@example.com>
AUTH LOGIN
dGVzdHVzZXI=
dGVzdHBhc3x=
AUTH LOGIN
dGVzdHVzZXI=
dGVzdHBhc3M=
AUTH LOGIN
MAIL FROM: <user@example.com>
RCPT TO: <user@example.com>
EOF

sfecho << EOF
AUTH LOGIN dGVzdHVzZXI=
dGVzdHBhc3M=
EOF

sfecho <<EOF
AUTH LOGIN
dGVzdHVzZXI=
*
MAIL FROM: <user@example.com>
RCPT TO: <user@example.com>
EOF

unset CVM_SASL_PLAIN
}
run_compare_test tests/smtpfront-auth-login  <<END_OF_TEST_RESULTS
504 Unrecognized authentication mechanism.^M
250 Sender='user@example.com'.^M
550 5.1.0 Mail system is not configured to accept that recipient^M
334 VXNlcm5hbWU6^M
334 UGFzc3dvcmQ6^M
501 Authentication failed.^M
334 VXNlcm5hbWU6^M
334 UGFzc3dvcmQ6^M
235 2.7.0 Authentication succeeded.^M
503 5.5.1 You are already authenticated.^M
250 Sender='user@example.com'.^M
250 Recipient='user@example.com'.^M
334 UGFzc3dvcmQ6^M
235 2.7.0 Authentication succeeded.^M
334 VXNlcm5hbWU6^M
334 UGFzc3dvcmQ6^M
501 Authentication failed.^M
250 Sender='user@example.com'.^M
550 5.1.0 Mail system is not configured to accept that recipient^M
END_OF_TEST_RESULTS


##### Test tests/rules-selector #####

runtest() {
PLUGINS=mailrules:accept

cat >$tmp/rules <<EOF
# This selector forces what would normally be a recipient rule to be
# applied only to the sender.
:sender
kone@example.com:two@example.net:A
# This selector forces what would normally be a sender rule to be
# applied only to recipients.
:recipient
ktwo@example.net:*:B
EOF

MAILRULES=$tmp/rules

sfecho <<EOF
MAIL FROM:<one@example.com>
RCPT TO:<three@example.org>
RCPT TO:<four@example.biz>
MAIL FROM:<two@example.net>
RCPT TO:<three@example.org>
RCPT TO:<four@example.biz>
EOF

rm -f $tmp/rules
}
run_compare_test tests/rules-selector  <<END_OF_TEST_RESULTS
250 A^M
250 Recipient='three@example.org'.^M
250 Recipient='four@example.biz'.^M
250 Sender='two@example.net'.^M
250 B^M
250 B^M
END_OF_TEST_RESULTS


##### Test tests/smtpfront-auth-plain #####

runtest() {
PLUGINS=relayclient:qmail-validate:accept-sender

sfecho <<EOF
AUTH PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M=
EOF

export CVM_SASL_PLAIN=$tmp/cvm

sfecho <<EOF
MAIL FROM: <user@example.com>
RCPT TO: <user@example.com>
AUTH PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3x=
AUTH PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M=
AUTH PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M=
MAIL FROM: <user@example.com>
RCPT TO: <user@example.com>
EOF

sfecho << EOF
AUTH PLAIN
dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M=
EOF

sfecho <<EOF
AUTH PLAIN
*
MAIL FROM: <user@example.com>
RCPT TO: <user@example.com>
EOF

sfecho << EOF
AUTH PLAIN XXXXdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M=
EOF

unset CVM_SASL_PLAIN
}
run_compare_test tests/smtpfront-auth-plain  <<END_OF_TEST_RESULTS
504 Unrecognized authentication mechanism.^M
250 Sender='user@example.com'.^M
550 5.1.0 Mail system is not configured to accept that recipient^M
501 Authentication failed.^M
235 2.7.0 Authentication succeeded.^M
503 5.5.1 You are already authenticated.^M
250 Sender='user@example.com'.^M
250 Recipient='user@example.com'.^M
334 ^M
235 2.7.0 Authentication succeeded.^M
334 ^M
501 Authentication failed.^M
250 Sender='user@example.com'.^M
550 5.1.0 Mail system is not configured to accept that recipient^M
235 2.7.0 Authentication succeeded.^M
END_OF_TEST_RESULTS


##### Test tests/rules-databytes #####

runtest() {
PLUGINS=mailrules:counters:accept

cat >$tmp/rules <<EOF
ka@example.com:*::123
EOF

MAILRULES=$tmp/rules

sfecho <<EOF
EHLO hostname
MAIL FROM:<a@example.com>
MAIL FROM:<a@example.com> SIZE
MAIL FROM:<a@example.com> SIZE=
MAIL FROM:<a@example.com> SIZE=100
MAIL FROM:<a@example.com> SIZE=123
MAIL FROM:<a@example.com> SIZE=124
RCPT TO:<nobody@example.net>
EOF

rm -f $tmp/rules
}
run_compare_test tests/rules-databytes  <<END_OF_TEST_RESULTS
250-local.host^M
250-SIZE 0^M
250-8BITMIME^M
250-ENHANCEDSTATUSCODES^M
250 PIPELINING^M
250 OK^M
250 OK^M
250 OK^M
250 OK^M
250 OK^M
552 5.2.3 The message would exceed the maximum message size.^M
503 5.5.1 You must send MAIL FROM: first^M
END_OF_TEST_RESULTS


##### Test tests/rules-databytes2 #####

runtest() {
PLUGINS=mailrules:counters:accept

cat >$tmp/rules <<EOF
k*:a@example.com::1
k*:b@example.com::9999
k*:c@example.com::
EOF

MAILRULES=$tmp/rules

sfecho <<EOF
EHLO hostname
MAIL FROM:<somebody@example.net>
RCPT TO:<a@example.com>
RCPT TO:<b@example.com>
RCPT TO:<c@example.com>
DATA
testing
.
EOF

rm -f $tmp/rules
}
run_compare_test tests/rules-databytes2  <<END_OF_TEST_RESULTS
250-local.host^M
250-SIZE 0^M
250-8BITMIME^M
250-ENHANCEDSTATUSCODES^M
250 PIPELINING^M
250 Sender='somebody@example.net'.^M
250 OK^M
250 OK^M
250 OK^M
354 End your message with a period on a line by itself.^M
552 5.2.3 Sorry, that message exceeds the maximum message length.^M
END_OF_TEST_RESULTS


##### Test tests/rules-defaultmsg #####

runtest() {
PLUGINS=mailrules:accept

cat >$tmp/rules <<EOF
dd@example.com:*
zz@example.com:*
kk@example.com:*
d*:d@example.com
z*:z@example.com
k*:k@example.com
EOF

MAILRULES=$tmp/rules

sfecho <<EOF
MAIL FROM:<d@example.com>
MAIL FROM:<z@example.com>
MAIL FROM:<k@example.com>
RCPT TO:<d@example.com>
RCPT TO:<z@example.com>
RCPT TO:<k@example.com>
EOF

rm -f $tmp/rules
}
run_compare_test tests/rules-defaultmsg  <<END_OF_TEST_RESULTS
553 Rejected^M
451 Deferred^M
250 OK^M
553 Rejected^M
451 Deferred^M
250 OK^M
END_OF_TEST_RESULTS


##### Test tests/smtpfront-require-auth #####

runtest() {
PLUGINS=require-auth:relayclient:qmail-validate:accept

export CVM_SASL_PLAIN=$tmp/cvm

sfecho <<EOF
MAIL FROM: <user@example.net>
RCPT TO: <user@example.net>
AUTH PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M=
MAIL FROM: <user@example.net>
RCPT TO: <user@example.net>
EOF

unset CVM_SASL_PLAIN
unset REQUIRE_AUTH
}
run_compare_test tests/smtpfront-require-auth  <<END_OF_TEST_RESULTS
530 5.7.1 You must authenticate first.^M
503 5.5.1 You must send MAIL FROM: first^M
235 2.7.0 Authentication succeeded.^M
250 Sender='user@example.net'.^M
250 Recipient='user@example.net'.^M
END_OF_TEST_RESULTS


##### Test tests/smtpfront-quotes #####

runtest() {
sfecho <<EOF
MAIL FROM:<"me, myself, and I"@example.net>
RCPT TO:<"you, yourself, and you"@example.com>
RCPT TO:<him\,himself@example.com>
RCPT TO:<@somewhere,@elsewhere:two@example.com>
EOF
}
run_compare_test tests/smtpfront-quotes  <<END_OF_TEST_RESULTS
250 Sender='me, myself, and I@example.net'.^M
250 Recipient='you, yourself, and you@example.com'.^M
250 Recipient='him,himself@example.com'.^M
250 Recipient='two@example.com'.^M
END_OF_TEST_RESULTS


##### Test tests/pop3front-auth-userpass #####

runtest() {
# Should fix this and the others to actually check the stderr output too.
pfauth $tmp/cvm <<EOF 2>/dev/null
USER testuser
PASS testpass
EOF
pfauth $tmp/cvm <<EOF 2>/dev/null
USER testuser
PASS testpasx
EOF
}
run_compare_test tests/pop3front-auth-userpass  <<END_OF_TEST_RESULTS
+OK ^M
Yes.
+OK ^M
-ERR Authentication failed^M
END_OF_TEST_RESULTS


##### Test tests/patterns-after #####

runtest() {
PLUGINS=patterns:accept

cat >$tmp/patterns <<EOF
\after
EOF

PATTERNS=$tmp/patterns
export PATTERNS

sfecho <<EOF
MAIL FROM:<>
RCPT TO:<nobody@example.com>
DATA
before

after
.
EOF

echo

cat >$tmp/patterns <<EOF
\before
EOF

sfecho <<EOF
MAIL FROM:<>
RCPT TO:<nobody@example.com>
DATA
before

after
.
EOF

rm -f $tmp/patterns
}
run_compare_test tests/patterns-after  <<END_OF_TEST_RESULTS
250 Sender=''.^M
250 Recipient='nobody@example.com'.^M
354 End your message with a period on a line by itself.^M
554 This message contains prohibited content^M

250 Sender=''.^M
250 Recipient='nobody@example.com'.^M
354 End your message with a period on a line by itself.^M
250 Received 14 bytes.^M
END_OF_TEST_RESULTS


##### Test tests/rules-maxhops #####

runtest() {
PLUGINS=mailrules:counters:accept

cat >$tmp/rules <<EOF
ka@example.com:b@example.com:K1:::MAXHOPS=1
EOF

MAILRULES=$tmp/rules
export MAILRULES

sfecho <<EOF
MAIL FROM:<a@example.com>
RCPT TO:<b@example.com>
DATA
Received: hop1
Received: hop2
.
EOF
MAILRULES=$tmp/rules sfecho <<EOF
MAIL FROM:<a@example.com>
RCPT TO:<c@example.com>
DATA
Received: hop1
Received: hop1
.
EOF

rm -f $tmp/rules
}
run_compare_test tests/rules-maxhops  <<END_OF_TEST_RESULTS
250 Sender='a@example.com'.^M
250 K1^M
354 End your message with a period on a line by itself.^M
554 5.6.0 This message is looping, too many hops.^M
250 Sender='a@example.com'.^M
250 Recipient='c@example.com'.^M
354 End your message with a period on a line by itself.^M
250 Received 30 bytes.^M
END_OF_TEST_RESULTS


##### Test tests/smtpfront-looping-delivered-to #####

runtest() {
PLUGINS=counters:accept

MAXHOPS=1
export MAXHOPS

sfecho <<EOF
MAIL FROM:<somebody@example.com>
RCPT TO:<nobody@example.org>
DATA
Delivered-To: foo
.
EOF

echo

sfecho <<EOF
MAIL FROM:<somebody@example.com>
RCPT TO:<nobody@example.org>
DATA
Delivered-To: foo
Delivered-To: foo
.
EOF
}
run_compare_test tests/smtpfront-looping-delivered-to  <<END_OF_TEST_RESULTS
250 Sender='somebody@example.com'.^M
250 Recipient='nobody@example.org'.^M
354 End your message with a period on a line by itself.^M
250 Received 18 bytes.^M

250 Sender='somebody@example.com'.^M
250 Recipient='nobody@example.org'.^M
354 End your message with a period on a line by itself.^M
554 5.6.0 This message is looping, too many hops.^M
END_OF_TEST_RESULTS


##### Test tests/rules-rcptlist #####

runtest() {
PLUGINS=mailrules:accept

cat >$tmp/rules <<EOF
:r
k*:[[$tmp/list]]:LIST
k*:[[@$tmp/atlist]]:ATLIST
d*:*:DD
EOF

cat >$tmp/list <<EOF
a@example.net
@example.com
EOF

cat >$tmp/atlist <<EOF
example.org
EOF

MAILRULES=$tmp/rules $src/mailfront smtp echo <<EOF 2>/dev/null | tail -n +2
MAIL FROM:<nobody@example.com>
RCPT TO:<a@example.net>
RCPT TO:<b@example.net>
RCPT TO:<a@example.org>
RCPT TO:<b@example.org>
RCPT TO:<c@example.com>
RCPT TO:<c@Example.COM>
RCPT TO:<d@example.biz>
EOF

rm -f $tmp/rules $tmp/list $tmp/atlist
}
run_compare_test tests/rules-rcptlist  <<END_OF_TEST_RESULTS
250 Sender='nobody@example.com'.^M
250 LIST^M
553 DD^M
250 ATLIST^M
250 ATLIST^M
250 LIST^M
250 LIST^M
553 DD^M
END_OF_TEST_RESULTS


##### Test tests/pop3front-auth-login #####

runtest() {
pfauth false <<EOF
AUTH LOGIN
EOF

export CVM_SASL_LOGIN=$tmp/cvm

pfauth false <<EOF
AUTH LOGIN
dGVzdHVzZXI=
dGVzdHBhc3x=
AUTH LOGIN
dGVzdHVzZXI=
dGVzdHBhc3M=
EOF

pfauth false <<EOF
AUTH LOGIN dGVzdHVzZXI=
dGVzdHBhc3M=
EOF

pfauth false <<EOF
AUTH LOGIN
dGVzdHVzZXI=
*
EOF

unset CVM_SASL_PLAIN
}
run_compare_test tests/pop3front-auth-login  <<END_OF_TEST_RESULTS
-ERR Unrecognized authentication mechanism.^M
+ VXNlcm5hbWU6^M
+ UGFzc3dvcmQ6^M
-ERR Authentication failed.^M
+ VXNlcm5hbWU6^M
+ UGFzc3dvcmQ6^M
Yes.
+ UGFzc3dvcmQ6^M
Yes.
+ VXNlcm5hbWU6^M
+ UGFzc3dvcmQ6^M
-ERR Authentication failed.^M
END_OF_TEST_RESULTS


##### Test tests/pop3front-auth-plain #####

runtest() {
pfauth false <<EOF
AUTH PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M=
EOF

export CVM_SASL_PLAIN=$tmp/cvm

pfauth false <<EOF
AUTH PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3x=
AUTH PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M=
EOF

pfauth false <<EOF
AUTH PLAIN
dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M=
EOF

pfauth false <<EOF
AUTH PLAIN
*
EOF

unset CVM_SASL_PLAIN
}
run_compare_test tests/pop3front-auth-plain  <<END_OF_TEST_RESULTS
-ERR Unrecognized authentication mechanism.^M
-ERR Authentication failed.^M
Yes.
+ ^M
Yes.
+ ^M
-ERR Authentication failed.^M
END_OF_TEST_RESULTS


##### Test tests/pop3front-auth-split #####

runtest() {
pfauth $tmp/cvm <<EOF
USER testuser@adomain
PASS testpass
EOF
pfauth $tmp/cvm <<EOF
USER testuser@adomain
PASS testpasx
EOF
}
run_compare_test tests/pop3front-auth-split  <<END_OF_TEST_RESULTS
+OK ^M
Yes.
+OK ^M
-ERR Authentication failed^M
END_OF_TEST_RESULTS


##### Test tests/smtpfront-bad-bounce #####

runtest() {
# Note: this test no longer tests anything significant.

sfecho <<EOF
MAIL FROM:<notbounce@example.com>
RCPT TO:<addr1@example.com>
RCPT TO:<addr2@example.com>
DATA
.
EOF

sfecho <<EOF
MAIL FROM:<>
RCPT TO:<addr1@example.com>
DATA
.
EOF

sfecho <<EOF
MAIL FROM:<>
RCPT TO:<addr1@example.com>
RCPT TO:<addr2@example.com>
DATA
.
EOF
}
run_compare_test tests/smtpfront-bad-bounce  <<END_OF_TEST_RESULTS
250 Sender='notbounce@example.com'.^M
250 Recipient='addr1@example.com'.^M
250 Recipient='addr2@example.com'.^M
354 End your message with a period on a line by itself.^M
250 Received 0 bytes.^M
250 Sender=''.^M
250 Recipient='addr1@example.com'.^M
354 End your message with a period on a line by itself.^M
250 Received 0 bytes.^M
250 Sender=''.^M
250 Recipient='addr1@example.com'.^M
250 Recipient='addr2@example.com'.^M
354 End your message with a period on a line by itself.^M
250 Received 0 bytes.^M
END_OF_TEST_RESULTS


##### Test tests/received #####

runtest() {
local remotehost="$1"
local remoteip="$2"
local localhost="$3"
local localip="$4"
local helo="$5"

PLUGINS=add-received:accept
TESTLOCALHOST="$localhost"
TESTLOCALIP="$localip"
TESTREMOTEHOST="$remotehost"
TESTREMOTEIP="$remoteip"

$src/mailfront smtp echo 2>&1 >/dev/null <<EOF | \
	sed -n -e 's/^.* Received: //p'
$helo
MAIL FROM:<>
RCPT TO:<test@example.com>
DATA
.
EOF
}
run_compare_test tests/received '' '' '' '' '' <<END_OF_TEST_RESULTS
from unknown  by unknown
END_OF_TEST_RESULTS

run_compare_test tests/received '' '' '' '' 'EHLO hh' <<END_OF_TEST_RESULTS
from hh  by unknown
END_OF_TEST_RESULTS

run_compare_test tests/received '' '' '' 'li' '' <<END_OF_TEST_RESULTS
from unknown  by li ([li])
END_OF_TEST_RESULTS

run_compare_test tests/received '' '' '' 'li' 'EHLO hh' <<END_OF_TEST_RESULTS
from hh  by li ([li])
END_OF_TEST_RESULTS

run_compare_test tests/received '' '' 'lh' '' '' <<END_OF_TEST_RESULTS
from unknown  by lh
END_OF_TEST_RESULTS

run_compare_test tests/received '' '' 'lh' '' 'EHLO hh' <<END_OF_TEST_RESULTS
from hh  by lh
END_OF_TEST_RESULTS

run_compare_test tests/received '' '' 'lh' 'li' '' <<END_OF_TEST_RESULTS
from unknown  by lh ([li])
END_OF_TEST_RESULTS

run_compare_test tests/received '' '' 'lh' 'li' 'EHLO hh' <<END_OF_TEST_RESULTS
from hh  by lh ([li])
END_OF_TEST_RESULTS

run_compare_test tests/received '' 'ri' '' '' '' <<END_OF_TEST_RESULTS
from ri ([ri])  by unknown
END_OF_TEST_RESULTS

run_compare_test tests/received '' 'ri' '' '' 'EHLO hh' <<END_OF_TEST_RESULTS
from hh ([ri])  by unknown
END_OF_TEST_RESULTS

run_compare_test tests/received '' 'ri' '' 'li' '' <<END_OF_TEST_RESULTS
from ri ([ri])  by li ([li])
END_OF_TEST_RESULTS

run_compare_test tests/received '' 'ri' '' 'li' 'EHLO hh' <<END_OF_TEST_RESULTS
from hh ([ri])  by li ([li])
END_OF_TEST_RESULTS

run_compare_test tests/received '' 'ri' 'lh' '' '' <<END_OF_TEST_RESULTS
from ri ([ri])  by lh
END_OF_TEST_RESULTS

run_compare_test tests/received '' 'ri' 'lh' '' 'EHLO hh' <<END_OF_TEST_RESULTS
from hh ([ri])  by lh
END_OF_TEST_RESULTS

run_compare_test tests/received '' 'ri' 'lh' 'li' '' <<END_OF_TEST_RESULTS
from ri ([ri])  by lh ([li])
END_OF_TEST_RESULTS

run_compare_test tests/received '' 'ri' 'lh' 'li' 'EHLO hh' <<END_OF_TEST_RESULTS
from hh ([ri])  by lh ([li])
END_OF_TEST_RESULTS

run_compare_test tests/received '' '' '' '' '' <<END_OF_TEST_RESULTS
from unknown  by unknown
END_OF_TEST_RESULTS

run_compare_test tests/received '' '' '' '' 'EHLO hh' <<END_OF_TEST_RESULTS
from hh  by unknown
END_OF_TEST_RESULTS

run_compare_test tests/received '' '' '' 'li' '' <<END_OF_TEST_RESULTS
from unknown  by li ([li])
END_OF_TEST_RESULTS

run_compare_test tests/received '' '' '' 'li' 'EHLO hh' <<END_OF_TEST_RESULTS
from hh  by li ([li])
END_OF_TEST_RESULTS

run_compare_test tests/received '' '' 'lh' '' '' <<END_OF_TEST_RESULTS
from unknown  by lh
END_OF_TEST_RESULTS

run_compare_test tests/received '' '' 'lh' '' 'EHLO hh' <<END_OF_TEST_RESULTS
from hh  by lh
END_OF_TEST_RESULTS

run_compare_test tests/received '' '' 'lh' 'li' '' <<END_OF_TEST_RESULTS
from unknown  by lh ([li])
END_OF_TEST_RESULTS

run_compare_test tests/received '' '' 'lh' 'li' 'EHLO hh' <<END_OF_TEST_RESULTS
from hh  by lh ([li])
END_OF_TEST_RESULTS

run_compare_test tests/received '' 'ri' '' '' '' <<END_OF_TEST_RESULTS
from ri ([ri])  by unknown
END_OF_TEST_RESULTS

run_compare_test tests/received '' 'ri' '' '' 'EHLO hh' <<END_OF_TEST_RESULTS
from hh ([ri])  by unknown
END_OF_TEST_RESULTS

run_compare_test tests/received '' 'ri' '' 'li' '' <<END_OF_TEST_RESULTS
from ri ([ri])  by li ([li])
END_OF_TEST_RESULTS

run_compare_test tests/received '' 'ri' '' 'li' 'EHLO hh' <<END_OF_TEST_RESULTS
from hh ([ri])  by li ([li])
END_OF_TEST_RESULTS

run_compare_test tests/received '' 'ri' 'lh' '' '' <<END_OF_TEST_RESULTS
from ri ([ri])  by lh
END_OF_TEST_RESULTS

run_compare_test tests/received '' 'ri' 'lh' '' 'EHLO hh' <<END_OF_TEST_RESULTS
from hh ([ri])  by lh
END_OF_TEST_RESULTS

run_compare_test tests/received '' 'ri' 'lh' 'li' '' <<END_OF_TEST_RESULTS
from ri ([ri])  by lh ([li])
END_OF_TEST_RESULTS

run_compare_test tests/received '' 'ri' 'lh' 'li' 'EHLO hh' <<END_OF_TEST_RESULTS
from hh ([ri])  by lh ([li])
END_OF_TEST_RESULTS


##### Test tests/rules-multiline #####

runtest() {
PLUGINS=mailrules:accept

cat >$tmp/rules <<EOF
ka@example.com:*:ONE\nTWO
ka@example.net:*:ONE\:TWO
ka@example.org:*:ONE\\\\TWO:
EOF

MAILRULES=$tmp/rules
export MAILRULES

sfecho <<EOF
MAIL FROM:<a@example.com>
MAIL FROM:<a@example.net>
MAIL FROM:<a@example.org>
EOF

rm -f $tmp/rules
}
run_compare_test tests/rules-multiline  <<END_OF_TEST_RESULTS
250-ONE^M
250 TWO^M
250 ONE:TWO^M
250 ONE\TWO^M
END_OF_TEST_RESULTS


##### Test tests/plugin-force-file #####

runtest() {
local tmpdir="$1"
local plugins="$2"

PLUGINS=${plugins}:add-received:accept
TMPDIR=$tmpdir 
export TMPDIR

sfecho <<EOF
MAIL FROM:<>
RCPT TO:<test@example.com>
DATA
.
EOF

unset TMPDIR
}
run_compare_test tests/plugin-force-file '/tmp' '' <<END_OF_TEST_RESULTS
250 Sender=''.^M
250 Recipient='test@example.com'.^M
354 End your message with a period on a line by itself.^M
250 Received 128 bytes.^M
END_OF_TEST_RESULTS

run_compare_test tests/plugin-force-file '/tmp' 'force-file' <<END_OF_TEST_RESULTS
250 Sender=''.^M
250 Recipient='test@example.com'.^M
354 End your message with a period on a line by itself.^M
250 Received 128 bytes.^M
END_OF_TEST_RESULTS

run_compare_test tests/plugin-force-file '/@notmp@' '' <<END_OF_TEST_RESULTS
250 Sender=''.^M
250 Recipient='test@example.com'.^M
354 End your message with a period on a line by itself.^M
250 Received 128 bytes.^M
END_OF_TEST_RESULTS

run_compare_test tests/plugin-force-file '/@notmp@' 'force-file' <<END_OF_TEST_RESULTS
250 Sender=''.^M
250 Recipient='test@example.com'.^M
451 4.3.0 Internal error.^M
500 5.5.1 Not implemented.^M
END_OF_TEST_RESULTS


##### Test tests/rules-asterisk #####

runtest() {
PLUGINS=mailrules:accept

cat >$tmp/rules <<EOF
ka@example.com:*:K1
k*@example.com:*:K2
kc@*:*:K3
k*:*:K4
EOF

MAILRULES=$tmp/rules
export MAILRULES

sfecho <<EOF
MAIL FROM:<a@example.com>
MAIL FROM:<b@example.com>
MAIL FROM:<c@example.net>
MAIL FROM:<d@example.org>
MAIL FROM:<>
MAIL FROM:<1@2@example.com@example.com>
EOF

rm -f $tmp/rules
}
run_compare_test tests/rules-asterisk  <<END_OF_TEST_RESULTS
250 K1^M
250 K2^M
250 K3^M
250 K4^M
250 K4^M
250 K2^M
END_OF_TEST_RESULTS


rm -rf $tmp
echo $tests_count tests executed, $tests_failed failures
if [ $tests_failed != 0 ]; then exit 1; fi


syntax highlighted by Code2HTML, v. 0.9.1