diff options
author | Fabian Groffen <grobian@gentoo.org> | 2013-10-27 20:56:26 +0000 |
---|---|---|
committer | Fabian Groffen <grobian@gentoo.org> | 2013-10-27 20:56:26 +0000 |
commit | 8668b7058b29eb11576015808a15e81b3f2a2cff (patch) | |
tree | eb53b9bc8c4efff5d81113b09c62c43cdb597a3a /mail-mta | |
parent | Remove old. (diff) | |
download | historical-8668b7058b29eb11576015808a15e81b3f2a2cff.tar.gz historical-8668b7058b29eb11576015808a15e81b3f2a2cff.tar.bz2 historical-8668b7058b29eb11576015808a15e81b3f2a2cff.zip |
Add dsn patch that applies, but needs testing, bug #489242
Package-Manager: portage-2.2.7-prefix/cvs/Darwin i386
Manifest-Sign-Key: 0x5F75F607C5C74E89
Diffstat (limited to 'mail-mta')
-rw-r--r-- | mail-mta/exim/ChangeLog | 6 | ||||
-rw-r--r-- | mail-mta/exim/Manifest | 13 | ||||
-rw-r--r-- | mail-mta/exim/exim-4.82_rc5.ebuild | 10 | ||||
-rw-r--r-- | mail-mta/exim/files/exim_482_dsn_1_3.patch | 1212 |
4 files changed, 1228 insertions, 13 deletions
diff --git a/mail-mta/exim/ChangeLog b/mail-mta/exim/ChangeLog index e218a2562932..2404964f7899 100644 --- a/mail-mta/exim/ChangeLog +++ b/mail-mta/exim/ChangeLog @@ -1,6 +1,10 @@ # ChangeLog for mail-mta/exim # Copyright 1999-2013 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/mail-mta/exim/ChangeLog,v 1.265 2013/10/24 07:03:04 grobian Exp $ +# $Header: /var/cvsroot/gentoo-x86/mail-mta/exim/ChangeLog,v 1.266 2013/10/27 20:56:22 grobian Exp $ + + 27 Oct 2013; Fabian Groffen <grobian@gentoo.org> + +files/exim_482_dsn_1_3.patch, exim-4.82_rc5.ebuild: + Add dsn patch that applies, but needs testing, bug #489242 *exim-4.82_rc5 (24 Oct 2013) diff --git a/mail-mta/exim/Manifest b/mail-mta/exim/Manifest index 52117a458d19..92bfdd7acd66 100644 --- a/mail-mta/exim/Manifest +++ b/mail-mta/exim/Manifest @@ -21,6 +21,7 @@ AUX exim.rc7 765 SHA256 9f98b698bc74e69f1b1595a108c49500dfc58d15b193bd59f3ec36bb AUX exim.rc8 755 SHA256 8ebeb8d406690918c6d4e9b87fd2fd44053055130091671e49ce7d77608e0390 SHA512 4fe4d04cc330a7445cb0f00c163148bda51b9ae6d7fece640efab1a3dec60ae4eb8ea2dbc24502a27c48e8bc03f8892d1cb6c78316d8e9262897e21e67bdc02e WHIRLPOOL e9d00cad884804f8d6b1ecd5adcc8df8be92fb305b37eaeb39194dc2d41a2ea3785d27cb34df31e29847b734318ef5ee9b42c9474203629262f32c9dc78b56e1 AUX exim.service 229 SHA256 6e5372338d93b75d96bf571d892b167ac812378bcf978dcd3f3324d7e612463a SHA512 a071e9fb74b5fc2fdf0c73ad64ddfbc3954d8f7095d6a363dacf8c75d72a479fbf6821822ec5c8f3846d7687342e1bd447b97f91ca7b0582e5c98008aac30cca WHIRLPOOL 5f2ccd6898c95599f8e801aa111c53dbb50b7ec9f6ba6552fe195ad07d41efdcbff765cba1d696df6acb564bca29830d0bf61bcda9a244a3b48354318914bbd5 AUX exim.socket 139 SHA256 3e3d8b6be2741d2587a496196c08b3f2ffa05b5803b2bf9fb49359cef3a98d26 SHA512 db621116907ceb573e6f34581f47c91f751bff593054d7ddc32397b34c7f2405bec184bdb0589d2ac457fa3a61bcba072761e3a6293a99c9c764d2d9fd6069ae WHIRLPOOL 6ddceaa1bf31d995afa2dc49ab4d8e1068321ab12b158e075f6ea3f2cc4dff35c2052da2a85fe998813354755e574670086880ef7e42e2a02877d4f766706d3c +AUX exim_482_dsn_1_3.patch 41505 SHA256 4e00069a4b2e2deb414f05ea33f29b3f007d9ebff17cfc16998800b21b8e0ef5 SHA512 5f184d903300851dba46f4c3d46e70269111ff335fc71e9d14b04f40462c163411521f6fd60e1d703dfab3a173911225a209133369bb3c26d83455499261e777 WHIRLPOOL 842040f5009ad43b40ceff4935510b06a0f7496bfb7e7a13db8f3eeb6fec63d7c7b38e4ed31b2d8de543ddaf7e8af8becef334c88d1365910e783c8c0ad5a7ff AUX exim_at.service 140 SHA256 faad96dadbb2750faa5652d830f10d5a14be487a42e8db1cec797164acf14b73 SHA512 11c8133ee15b3e5193c9b1c59aed66c81b6e045dd23310bede9fcde6c88905db5ef08afdb798b53b75a7465915ea1247e980edf95db07a7f9b7bb58ce95fbb5a WHIRLPOOL 78f0c825526ae890458c4e71df2bd724d77d508081c6d6c2e3493732f11576ffeed755968dd2f3bcfb1cc6e0b0d61ea9fc175cd71340d908646f1a9ccbc7406e DIST exim-4.80.1.tar.bz2 1650082 SHA256 9565b10f06be224fd03adafae2e07e6fdbb479f8873e3894ddb13f98eeebe78f SHA512 ed73dd34dc02ab91896c3cdcedb0618ca3be116904c8eeb1303fc3534f8ab9430083f654fa5af994b0e01049e7fdd22d268fed9a3318b64a56c3a61d7f2174f5 WHIRLPOOL d556b7515f081f39a7bb7cb16804f0e13b37a3295a5f19faf28f9fed0966411f13b521dd7e5a8f42a7a851fa46e15ef8478caff734903080f31e910fb1530eab DIST exim-4.82_RC5.tar.bz2 1723209 SHA256 242fb17bd69b828b0bb5d3b907def6b4447750ceb92e5360d93dd83c4779e7ec SHA512 71298d76f715a4a9109728e398a3f1902d1a2e632a60c8a0a045d5fc893bed54fa87833c07d4a83bad2923d6f2ec2f05ebfd1caa0ed28b0c23cdfa65e5916399 WHIRLPOOL 64f72ccad94b47a8073167a9cad404079b4be4a623a18bd458653f9bdc642b09fe24fa493ce3828270e73a65c1b2a8209de0e5cd0eb7bef2e074238600cbd79d @@ -31,13 +32,13 @@ DIST system_filter.exim.gz 3075 SHA256 3a3471b486a09e0a0153f7b520e1eaf26d21b97d7 EBUILD exim-4.80.1-r2.ebuild 12083 SHA256 5ba65d2507f561a1adbc15091562209979f18bc90e2323580c935386101298a1 SHA512 b79d8688bf37316f9e94ad7870ca53b48cf56c7061bcfafd6741478da17a30d406e512293ac8bc47c5774a6cc5114a4ea7f372f61772dc9a26a8ebec9697e22c WHIRLPOOL 05ba7fd9947c8b35a9b1304d6ad474b03dd45c6fdf273cea8e8e839b8b73a407115d97e924bc36d112417d1eb180e9e18f998f3f7a3f23a42fdd3a92ef6287bd EBUILD exim-4.80.1-r3.ebuild 12094 SHA256 c505f9e7c21d1bbc663e21a5423ece90162e34dd2d26fe6c13f72b0ea0a68872 SHA512 6df242718bc1eb8ed62a5f07e3479422a1cc5d41ee61e4d2293ec5a7cf06c5e30b20b799656fb57157c555a0f985f0433cce75e970f357093a30274a2b40fde3 WHIRLPOOL d9ad58df38b60cf2d5194adacd1b75534c866c7efa6f739f39ea9329ef144848a1821fed7743662a0e349aeb83ae9b7a71f6d37b29db93596f4c7308c3ed8d4a EBUILD exim-4.80.1.ebuild 11556 SHA256 8630f221f92ddd17cf05891d308d5e1347b550f2c6df596916e289dc2129149f SHA512 1d96761c1a2705be3e21e675ac5ecbbb11a97b140f483fd1067552c5ce07f6e3f0266bfd1139525e43c4fbc7a2ecf5b6e444912c2c6d6bbe3618d7f08c31dd2e WHIRLPOOL 2c994828d448d3266f33f514c595c21b61517ceb4ac13a7c2de519945cd853f100f16a8f3d17a956412b8be4a2a80197a316947d81f1db512d33b09c9b3ecca5 -EBUILD exim-4.82_rc5.ebuild 12521 SHA256 5b59b580692af73ab76cda0f0cf52c258173eb44891720a7edb8d39d06c9bfcd SHA512 98b9c717f1b7ab12ed4ccf26719e3a6b69d03fb4857bdf65ba76b85cd2265e9863538df57c58169468f1d18e4acdabf825008e9e614633d4de3f376cfebcce51 WHIRLPOOL 386f4487cd1839c333cd2152fe0113479acae2c3403a3f0a3441b806b60ad9e45d456ac462e2110e6182a214ee5cd6f28109f3c1a449ddb3e0a091b6938e865c -MISC ChangeLog 51137 SHA256 d968ed2c4f299ae5a97f4ae6e1586a769de942a8765b4aded51affdc0a15ea74 SHA512 8e30743cc0b3415de2e799b5bbb967f16819f6f3b2250918c230f267b5eb5699a3bbe730ae127fa9f46c8d7f5589cd1f756ec941238a72ef1c8569e121e5c0f6 WHIRLPOOL 801e2b0bd8549204545f819024c6463a3fa974dbe25d644cfb257e208e48b9ba376401914008c15f1d54b3aa99f625b86cdf7521be5a7c6e9bb575232855bb1d +EBUILD exim-4.82_rc5.ebuild 12458 SHA256 a8f0399ce63996d1592a31a532e57b4e1aff0dce9ea72da92e6ccbf12783ffcd SHA512 2950d52e62de2b350ff49209521dc6100e6bf4e1a2032bfe88f173aab12e29cfc8abd3c10c36369bf2bc41c822337ba98152a39157ebf3067701ea3b94ca6fdc WHIRLPOOL 85bc51c48d1ae677da0ceb41d56fd4838587e5beecc22aebb894e768e4a63148bfa040df452fab8280df93739ccd437f47c366d4dba995995548b900526857cc +MISC ChangeLog 51305 SHA256 7bfe741598e869bb90b498fac5e739cc3e3f029ac738083e275b49664df57df5 SHA512 dacbc1f9d6f555ebca9784da5d3c270e027be91e985cbc6fb0f1949c2fc4e4df596d40a799ad2fc85aa6b3ab22fb0515c0604026896151041efce11b6e509be9 WHIRLPOOL 8823bae232abdd9dbbfe1466458dc91e96316883f8e1fd6d798ea9b46aa2c456a0c244a8726cd37051dcaada7e338da2645831b0244094cbd41061f532d2e25b MISC metadata.xml 1893 SHA256 4590b65d91a30a7bf959d0cdf26beec4b226e55d575f56891f78e6e4432f63e4 SHA512 d959cc25e476efc68eb2e2ea4698926ab57e9dd601195ff2742825e58468df091986590e0fb36b6a862164a923c09baed18862c14726ef94e9b56b8f836ded6f WHIRLPOOL 0e66fa63b808f97af0b1f764296935efcc91f34a89f326457601d6a44ab3f11469dd1eb9df0c4916cea7721eaaabc7644fb42f07f2561c0055479c54c5d63a7e -----BEGIN PGP SIGNATURE----- -Version: GnuPG v2.0.22 (SunOS) +Version: GnuPG v2.0.22 (Darwin) -iEYEAREIAAYFAlJoxikACgkQX3X2B8XHTokVVQCfWFURjLGwPS1effDJk/cbO2fG -bxAAn07VGJWACFwWWzsI8xhqSYK05TlH -=hpxY +iEYEAREIAAYFAlJtffcACgkQX3X2B8XHTokKdQCfUAYq4psf1qegSf/kA6OnvxEK +S40AnAqXoLK5V9wX8V1AAqWjOZPut91C +=46D+ -----END PGP SIGNATURE----- diff --git a/mail-mta/exim/exim-4.82_rc5.ebuild b/mail-mta/exim/exim-4.82_rc5.ebuild index e39957879805..abf5cf308922 100644 --- a/mail-mta/exim/exim-4.82_rc5.ebuild +++ b/mail-mta/exim/exim-4.82_rc5.ebuild @@ -1,6 +1,6 @@ # Copyright 1999-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/mail-mta/exim/exim-4.82_rc5.ebuild,v 1.1 2013/10/24 07:03:04 grobian Exp $ +# $Header: /var/cvsroot/gentoo-x86/mail-mta/exim/exim-4.82_rc5.ebuild,v 1.2 2013/10/27 20:56:22 grobian Exp $ EAPI="4" @@ -9,15 +9,15 @@ inherit eutils toolchain-funcs multilib pam systemd IUSE="tcpd ssl postgres mysql ldap pam exiscan-acl lmtp ipv6 sasl dnsdb perl mbx X nis selinux syslog spf srs gnutls sqlite doc dovecot-sasl radius maildir +dkim dcc dsn dlfunc dmarc" REQUIRED_USE="spf? ( exiscan-acl ) srs? ( exiscan-acl ) dmarc? ( spf dkim )" -DSN_EXIM_V=469 +DSN_EXIM_V=482 # local version patched by us DSN_V=1_3 COMM_URI="ftp://ftp.exim.org/pub/exim/exim4$([[ ${PV} == *_rc* ]] && echo /test)" DESCRIPTION="A highly configurable, drop-in replacement for sendmail" SRC_URI="${COMM_URI}/${P//rc/RC}.tar.bz2 mirror://gentoo/system_filter.exim.gz - dsn? ( mirror://sourceforge/eximdsn/eximdsn-patch-1.3/exim_${DSN_EXIM_V}_dsn_${DSN_V}.patch ) doc? ( ${COMM_URI}/${PN}-html-${PV//rc/RC}.tar.bz2 )" + #dsn? ( mirror://sourceforge/eximdsn/eximdsn-patch-1.3/exim_${DSN_EXIM_V}_dsn_${DSN_V}.patch ) HOMEPAGE="http://www.exim.org/" SLOT="0" @@ -92,9 +92,7 @@ src_prepare() { fi if use dsn ; then - cp "${DISTDIR}"/exim_${DSN_EXIM_V}_dsn_${DSN_V}.patch . || die - epatch "${FILESDIR}"/${PN}-4.76-dsn.patch - epatch exim_${DSN_EXIM_V}_dsn_${DSN_V}.patch + epatch "${FILESDIR}"/exim_${DSN_EXIM_V}_dsn_${DSN_V}.patch fi if use ipv6 ; then diff --git a/mail-mta/exim/files/exim_482_dsn_1_3.patch b/mail-mta/exim/files/exim_482_dsn_1_3.patch new file mode 100644 index 000000000000..c30069967309 --- /dev/null +++ b/mail-mta/exim/files/exim_482_dsn_1_3.patch @@ -0,0 +1,1212 @@ +Modified for 4.82 by Gentoo -- not the official patch from +http://sourceforge.net/projects/eximdsn/ + +diff -Naur exim-4.82_RC5.orig/README.DSN exim-4.82_RC5/README.DSN +--- exim-4.82_RC5.orig/README.DSN 1970-01-01 01:00:00.000000000 +0100 ++++ exim-4.82_RC5/README.DSN 2013-10-27 21:47:32.000000000 +0100 +@@ -0,0 +1,118 @@ ++Exim DSN Patch (4.76) ++--------------------- ++ ++This patch is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 2 of the License, or ++(at your option) any later version. ++ ++This patch is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this patch; if not, write to the Free Software ++Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. ++ ++Install ++------- ++cd into the source tree for a vanilla exim ++ ++patch -p1 </path/to/patch/file.patch ++ ++Example :- ++[root@linuxbuild exim-4.72-test]# patch -p1 <../exim.dsn.patch-472 ++ ++Expected Output :- ++patching file README.DSN ++patching file src/config.h.defaults ++patching file src/deliver.c ++patching file src/exim.c ++patching file src/exim.h ++patching file src/globals.c ++patching file src/globals.h ++patching file src/local_scan.h ++patching file src/macros.h ++patching file src/readconf.c ++patching file src/route.c ++patching file src/smtp_in.c ++patching file src/spool_in.c ++patching file src/spool_out.c ++patching file src/structs.h ++patching file src/transport.c ++patching file src/transports/smtp.c ++ ++ ++This patch can be included / excluded from the compilation by use of the #define SUPPORT_DSN ++which gets added into src/config.h.defaults & src/EDITME by the patch. ++ ++Use ++--- ++ ++The facility (once compiled in) can be turned on for a particular router via the ++dsn_process directive Eg :- ++ ++dest_delivery_int: ++ driver = manualroute ++ domains = +relay_to_domains ++ condition = ${if eq {${lc:$sender_address_domain}}\ ++ {domain.com}\ ++ {yes}{no}\ ++ } ++ dsn_process ++ hide route_data = ${lc:${extract{mailHost}{$address_data}{$value}{}}} ++ transport = remote_smtp ++ ++Exim will produce 1 of 2 DSN's back to the originator, or pass on the DSN request. ++The 2 DSN's will either contain (relayed via non "Remote SMTP" router) or ++(relayed to non-DSN-aware mailer) depending on if the delivery was VIA an SMTP ++transport or not. ++ ++ ++Credits ++------- ++ ++The original work for the patch was done by Philip Hazel in Exim 3 ++ ++The extract was taken and re-applied to Exim 4 by the following :- ++Phil Bingham (phil.bingham@cwipapps.net) ++Steve Falla (steve.falla@cwipapps.net) ++Ray Edah (ray.edah@cwipapps.net) ++Andrew Johnson (andrew.johnson@cwippaps.net) ++Adrian Hungate (adrian.hungate@cwipapps.net) ++ ++Now Primarily maintained by :- ++Andrew Johnson (andrew.johnson@cwippaps.net) ++ ++Contributions ++------------- ++Andrey J. Melnikoff (TEMHOTA) (temnota@kmv.ru) ++ ++ ++ChangeLog ++--------- ++ ++14-Apr-2006 : Changed subject to "Delivery Status Notification" ++ ++17-May-2006 : debug_printf in spool-in.c were not wrapped with #ifndef COMPILE_UTILITY ++ thanks to Andrey J. Melnikoff for this information ++ ++12-Sep-2006 : Now supports Exim 4.63 ++ ++12-Sep-2006 : src/EDITME did not include the #define SUPPORT_DSN as stated ++ in the documentation, this has now been corrected ++ thanks to Robert Kehl for this information ++ ++28-Jul-2008 : New version for exim 4.69 released. ++ ++02-Jul-2010 : New version for exim 4.72 released. ++ ++20-May-2011 : New version for exim 4.76 released. ++ ++ ++Support for this patch (limited though it is) will only be provided through the SourceForge ++project page (http://sourceforge.net/projects/eximdsn/) ++ ++-- ++Andrew Johnson Cable & Wireless +diff -Naur exim-4.82_RC5.orig/src/config.h.defaults exim-4.82_RC5/src/config.h.defaults +--- exim-4.82_RC5.orig/src/config.h.defaults 2013-10-27 21:46:25.000000000 +0100 ++++ exim-4.82_RC5/src/config.h.defaults 2013-10-27 21:47:32.000000000 +0100 +@@ -136,6 +136,7 @@ + #define SUPPORT_MOVE_FROZEN_MESSAGES + #define SUPPORT_PAM + #define SUPPORT_TLS ++#define SUPPORT_DSN + #define SUPPORT_TRANSLATE_IP_ADDRESS + + #define SYSLOG_LOG_PID +diff -Naur exim-4.82_RC5.orig/src/deliver.c exim-4.82_RC5/src/deliver.c +--- exim-4.82_RC5.orig/src/deliver.c 2013-10-27 21:46:25.000000000 +0100 ++++ exim-4.82_RC5/src/deliver.c 2013-10-27 21:47:32.000000000 +0100 +@@ -63,6 +63,9 @@ + static address_item *addr_remote = NULL; + static address_item *addr_route = NULL; + static address_item *addr_succeed = NULL; ++#ifdef SUPPORT_DSN ++static address_item *addr_dsntmp = NULL; ++#endif + + static FILE *message_log = NULL; + static BOOL update_spool; +@@ -2966,6 +2969,15 @@ + addr->flags |= af_prdr_used; break; + #endif + ++ #ifdef SUPPORT_DSN ++ case 'D': ++ if (addr == NULL) break; ++ addr->dsn_aware = (*ptr)? string_copy(ptr) : string_copy(" "); ++ while (*ptr++); ++ DEBUG(D_deliver) debug_printf("DSN read: addr->dsn_aware = %s\n", addr->dsn_aware); ++ break; ++ #endif ++ + case 'A': + if (addr == NULL) + { +@@ -4074,6 +4086,15 @@ + if (addr->flags & af_prdr_used) rmt_dlv_checked_write(fd, "P", 1); + #endif + ++ #ifdef SUPPORT_DSN ++ if (addr->dsn_aware == NULL) ++ addr->dsn_aware = string_copy(" "); ++ DEBUG(D_deliver) debug_printf("DSN write: addr->dsn_aware = %s\n", addr->dsn_aware); ++ sprintf(big_buffer, "D%s", addr->dsn_aware); ++ DEBUG(D_deliver) debug_printf("DSN write: big_buffer = %s (%d)\n", big_buffer, strlen(big_buffer)+1); ++ write(fd, big_buffer, strlen(big_buffer)+1); ++ #endif ++ + /* Retry information: for most success cases this will be null. */ + + for (r = addr->retries; r != NULL; r = r->next) +@@ -5219,6 +5240,14 @@ + if (r->pno >= 0) + new->onetime_parent = recipients_list[r->pno].address; + ++ #ifdef SUPPORT_DSN ++ /* If DSN support is enabled, set the dsn flags and the original receipt ++ to be passed on to other DSN enabled MTAs */ ++ new->dsn_flags = r->dsn_flags & rf_dsnflags; ++ new->dsn_orcpt = r->orcpt; ++ debug_printf("DSN (deliver): orcpt: %s flags: %d\n", new->dsn_orcpt, new->dsn_flags); ++ #endif ++ + switch (process_recipients) + { + /* RECIP_DEFER is set when a system filter freezes a message. */ +@@ -6163,6 +6192,12 @@ + regex_must_compile(US"\\n250[\\s\\-]PRDR(\\s|\\n|$)", FALSE, TRUE); + #endif + ++ #ifdef SUPPORT_DSN ++ /* Set the regex to check for DSN support on remote MTA */ ++ if (regex_DSN == NULL) regex_DSN = ++ regex_must_compile(US"\\n250[\\s\\-]DSN(\\s|\\n|$)", FALSE, TRUE); ++ #endif ++ + /* Now sort the addresses if required, and do the deliveries. The yield of + do_remote_deliveries is FALSE when mua_wrapper is set and all addresses + cannot be delivered in one transaction. */ +@@ -6267,6 +6302,179 @@ + + else if (!dont_deliver) retry_update(&addr_defer, &addr_failed, &addr_succeed); + ++#ifdef SUPPORT_DSN ++/* ********** philb - Send DSN for successful messages */ ++ ++addr_dsntmp = addr_succeed; ++ ++while(addr_dsntmp != NULL) ++{ ++ BOOL dsn_sendmessage = FALSE; ++ uschar dsnmsgbuf[4096]; ++ ++ DEBUG(D_deliver) ++ debug_printf("DSN: processing router : %s\n", addr_dsntmp->router->name); ++ ++ DEBUG(D_deliver) ++ debug_printf("DSN: processing successful delivery address: %s\n", addr_dsntmp->address); ++ ++ if (testflag(addr_dsntmp, af_ignore_error)) ++ { ++ DEBUG(D_deliver) ++ debug_printf("DSN: Ignore error for: %s\n", addr_dsntmp->address); ++ } ++ else ++ { ++ DEBUG(D_deliver) debug_printf("DSN: Checking Flag\n"); ++ if (addr_dsntmp->dsn_aware == NULL) { ++ DEBUG(D_deliver) debug_printf("DSN: dsn_aware was NULL, setting to space at %s %d\n", __FILE__, __LINE__); ++ addr_dsntmp->dsn_aware = string_copy(" "); ++ } ++ DEBUG(D_deliver) debug_printf("DSN: Sender_address: %s\n", sender_address); ++ DEBUG(D_deliver) debug_printf("DSN: orcpt: %s flags: %d\n", addr_dsntmp->dsn_orcpt, addr_dsntmp->dsn_flags); ++ DEBUG(D_deliver) debug_printf("DSN: envid: %s ret: %d\n", dsn_envid, dsn_ret); ++ DEBUG(D_deliver) debug_printf("DSN: Remote SMTP server supports DSN: %s\n", addr_dsntmp->dsn_aware); ++ ++ /* Process the flags */ ++ if((addr_dsntmp->dsn_flags & rf_dsnflags) != 0) ++ { ++ /* We've got at least one flag set */ ++ ++ /* set flag so we don't send bounces */ ++ setflag(addr_dsntmp, af_ignore_error); ++ ++ if((addr_dsntmp->dsn_flags & rf_notify_never) != 0) ++ { ++ DEBUG(D_deliver) debug_printf("DSN: NEVER FLAG\n"); ++ ++ /* nothing to do here */ ++ } ++ ++ if((addr_dsntmp->dsn_flags & rf_notify_success) != 0) ++ { ++ DEBUG(D_deliver) debug_printf("DSN: SUCCESS FLAG\n"); ++ ++ dsn_sendmessage = TRUE; ++ } ++ ++ if((addr_dsntmp->dsn_flags & rf_notify_failure) != 0) ++ { ++ DEBUG(D_deliver) debug_printf("DSN: FAILURE FLAG\n"); ++ ++ /* allow bounce messages */ ++ clearflag(addr_dsntmp, af_ignore_error); ++ } ++ ++ if((addr_dsntmp->dsn_flags & rf_notify_delay) != 0) ++ { ++ DEBUG(D_deliver) debug_printf("DSN: DELAY FLAG\n"); ++ ++ /* hmm, what to do here? */ ++ } ++ } ++ ++ if ((addr_dsntmp->dsn_aware != 0) && (addr_dsntmp->dsn_aware[0] != 'Y') && (dsn_sendmessage == TRUE) && (addr_dsntmp->router->dsn_process == TRUE)) ++ { ++ pid_t pid; ++ int fd; ++ ++ /* remote MTA does not support DSN, so we need to send message */ ++ ++ /* create exim process to send message */ ++ pid = child_open_exim(&fd); ++ ++ DEBUG(D_deliver) debug_printf("DSN: child_open_exim returns: %d\n", pid); ++ ++ if (pid < 0) /* Creation of child failed */ ++ { ++ log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Process %d (parent %d) failed to " ++ "create child process to send failure message: %s", getpid(), ++ getppid(), strerror(errno)); ++ ++ DEBUG(D_deliver) debug_printf("DSN: child_open_exim failed\n"); ++ ++ } ++ else /* Creation of child succeeded */ ++ { ++ FILE *f = fdopen(fd, "wb"); ++ int topt = topt_add_return_path; ++ uschar boundaryStr[64]; ++ ++ DEBUG(D_deliver) debug_printf("sending error message to: %s\n", sender_address); ++ ++ /* build unique id for MIME boundary */ ++ snprintf(boundaryStr, 63, "%d-cwdsn-%d", pid, rand()); ++ DEBUG(D_deliver) debug_printf("DSN: MIME boundary: %s\n", boundaryStr); ++ ++ /* if the sender doesn't want the whole message returned, don't send the body */ ++ if (dsn_ret != dsn_ret_full) topt |= topt_no_body; ++ ++ if (errors_reply_to != NULL) fprintf(f,"Reply-To: %s\n", errors_reply_to); ++ ++ fprintf(f,"Auto-Submitted: auto-generated\n"); ++ fprintf(f,"From: Mail Delivery System <Mailer-Daemon@%s>\n", qualify_domain_sender); ++ fprintf(f,"To: %s\n", sender_address); ++ fprintf(f,"Subject: Delivery Status Notification\n"); ++ fprintf(f,"Content-Type: multipart/report; report-type=delivery-status; boundary=%s\n", boundaryStr); ++ fprintf(f,"MIME-Version: 1.0\n\n"); ++ ++ fprintf(f,"--%s\n", boundaryStr); ++ fprintf(f,"Content-type: text/plain; charset=us-ascii\n\n"); ++ ++ fprintf(f,"This message was created automatically by mail delivery software.\n"); ++ fprintf(f," ----- The following addresses had successful delivery notifications -----\n"); ++/* AH: added specific message for non "Remote SMTP" situations */ ++ if (addr_dsntmp->dsn_aware[0] == 'N') { ++ fprintf(f,"<%s> (relayed to non-DSN-aware mailer)\n\n", addr_dsntmp->address); ++ } else { ++ fprintf(f,"<%s> (relayed via non \"Remote SMTP\" router)\n\n", addr_dsntmp->address); ++ } ++ ++ fprintf(f,"--%s\n", boundaryStr); ++ fprintf(f,"Content-type: message/delivery-status\n\n"); ++ ++ if (dsn_envid) { /* Test for NULL added by GC */ ++ fprintf(f,"Original-Envelope-Id: %s\n", dsn_envid); ++ } ++ fprintf(f,"Reporting-MTA: dns; %s\n", qualify_domain_sender); ++ if (addr_dsntmp->dsn_orcpt) { /* Test for NULL added by GC */ ++ fprintf(f,"Original-Recipient: %s\n", addr_dsntmp->dsn_orcpt); ++ } ++ fprintf(f,"Action: delivered\n\n"); ++ ++ fprintf(f,"--%s\n", boundaryStr); ++ fprintf(f,"Content-type: message/rfc822\n\n"); ++ ++ fflush(f); ++ transport_filter_argv = NULL; /* Just in case */ ++ return_path = sender_address; /* In case not previously set */ ++ ++ /* Write the original email out */ ++ transport_write_message(NULL, fileno(f), topt, 2048, NULL, NULL, NULL, NULL, NULL, 0); ++ fflush(f); ++ ++ fprintf(f,"\n"); ++ fprintf(f,"--%s--\n", boundaryStr); ++ ++ fflush(f); ++ fclose(f); ++ rc = child_close(pid, 0); /* Waits for child to close, no timeout */ ++ } ++ } ++ else ++ { if (addr_dsntmp->router->dsn_process == TRUE) ++ DEBUG(D_deliver) debug_printf("DSN: *** NOT SENDING DSN SUCCESS Message ***\n"); ++ if (addr_dsntmp->router->dsn_process == FALSE) ++ DEBUG(D_deliver) debug_printf("DSN: *** NOT SENDING DSN SUCCESS Message (gagged) ***\n"); ++ } ++ } ++ ++ addr_dsntmp = addr_dsntmp->next; ++} ++ ++/* ********** philb - end of mod */ ++#endif ++ + /* If any addresses failed, we must send a message to somebody, unless + af_ignore_error is set, in which case no action is taken. It is possible for + several messages to get sent if there are addresses with different +diff -Naur exim-4.82_RC5.orig/src/EDITME exim-4.82_RC5/src/EDITME +--- exim-4.82_RC5.orig/src/EDITME 2013-10-27 21:46:25.000000000 +0100 ++++ exim-4.82_RC5/src/EDITME 2013-10-27 21:47:32.000000000 +0100 +@@ -192,6 +192,8 @@ + # least one type of lookup. You should consider whether you want to build + # the Exim monitor or not. + ++# Support DSN ++SUPPORT_DSN=yes + + #------------------------------------------------------------------------------ + # These settings determine which individual router drivers are included in the +diff -Naur exim-4.82_RC5.orig/src/exim.c exim-4.82_RC5/src/exim.c +--- exim-4.82_RC5.orig/src/exim.c 2013-10-27 21:46:25.000000000 +0100 ++++ exim-4.82_RC5/src/exim.c 2013-10-27 21:47:32.000000000 +0100 +@@ -831,6 +831,9 @@ + #ifdef EXPERIMENTAL_REDIS + fprintf(f, " Experimental_Redis"); + #endif ++#ifdef SUPPORT_DSN ++ fprintf(f, " C&W_DSN_1.3"); ++#endif + fprintf(f, "\n"); + + fprintf(f, "Lookups (built-in):"); +@@ -2653,6 +2656,16 @@ + break; + } + ++ #ifdef SUPPORT_DSN ++ /* -MCD: set the smtp_use_dsn flag; this indicates that the host ++ that exim is connected to supports the esmtp extension DSN */ ++ else if (strcmp(argrest, "CD") == 0) ++ { ++ smtp_use_dsn = TRUE; ++ break; ++ } ++ #endif ++ + /* -MCP: set the smtp_use_pipelining flag; this is useful only when + it preceded -MC (see above) */ + +diff -Naur exim-4.82_RC5.orig/src/globals.c exim-4.82_RC5/src/globals.c +--- exim-4.82_RC5.orig/src/globals.c 2013-10-27 21:46:25.000000000 +0100 ++++ exim-4.82_RC5/src/globals.c 2013-10-27 21:47:32.000000000 +0100 +@@ -124,6 +124,13 @@ + uschar *local_scan_path = NULL; + #endif + ++#ifdef SUPPORT_DSN ++BOOL dsn = TRUE; ++uschar *dsn_envid = NULL; ++int dsn_ret = 0; ++const pcre *regex_DSN = NULL; ++BOOL smtp_use_dsn = FALSE; ++#endif + + #ifdef SUPPORT_TLS + BOOL gnutls_compat_mode = FALSE; +@@ -341,6 +348,11 @@ + NULL, /* authenticator */ + NULL, /* auth_id */ + NULL, /* auth_sndr */ ++ #ifdef SUPPORT_DSN ++ NULL, /* dsn_orcpt */ ++ 0, /* dsn_flags */ ++ NULL, /* dsn_aware */ ++ #endif + (uid_t)(-1), /* uid */ + (gid_t)(-1), /* gid */ + 0, /* flags */ +@@ -1096,6 +1108,9 @@ + TRUE, /* verify_sender */ + FALSE, /* uid_set */ + FALSE, /* unseen */ ++#ifdef SUPPORT_DSN ++ FALSE, /* dsn_process */ ++#endif + + self_freeze, /* self_code */ + (uid_t)(-1), /* uid */ +@@ -1105,6 +1120,7 @@ + NULL, /* transport instance */ + NULL, /* pass_router */ + NULL /* redirect_router */ ++ + }; + + uschar *router_name = NULL; +diff -Naur exim-4.82_RC5.orig/src/globals.h exim-4.82_RC5/src/globals.h +--- exim-4.82_RC5.orig/src/globals.h 2013-10-27 21:46:25.000000000 +0100 ++++ exim-4.82_RC5/src/globals.h 2013-10-27 21:47:32.000000000 +0100 +@@ -130,6 +130,13 @@ + extern int (*receive_ferror)(void); + extern BOOL (*receive_smtp_buffered)(void); + ++#ifdef SUPPORT_DSN ++extern BOOL dsn; /* FALSE if DSN not to be used */ ++extern uschar *dsn_envid; /* DSN envid string */ ++extern int dsn_ret; /* DSN ret type*/ ++extern const pcre *regex_DSN; /* For recognizing DSN settings */ ++extern BOOL smtp_use_dsn; /* Global for passed connections */ ++#endif + + /* For clearing, saving, restoring address expansion variables. We have to have + the size of this vector set explicitly, because it is referenced from more than +diff -Naur exim-4.82_RC5.orig/src/local_scan.h exim-4.82_RC5/src/local_scan.h +--- exim-4.82_RC5.orig/src/local_scan.h 2013-10-27 21:46:25.000000000 +0100 ++++ exim-4.82_RC5/src/local_scan.h 2013-10-27 21:47:32.000000000 +0100 +@@ -124,9 +124,13 @@ + field is always NULL except for one_time aliases that had errors_to on the + routers that generated them. */ + ++/* Added the dsn attributes orcpt and dsn_flags for DSN support*/ ++ + typedef struct recipient_item { + uschar *address; /* the recipient address */ + int pno; /* parent number for "one_time" alias, or -1 */ ++ uschar *orcpt; /* DSN orcpt */ ++ int dsn_flags; /* DSN flags */ + uschar *errors_to; /* the errors_to address or NULL */ + #ifdef EXPERIMENTAL_BRIGHTMAIL + uschar *bmi_optin; +diff -Naur exim-4.82_RC5.orig/src/macros.h exim-4.82_RC5/src/macros.h +--- exim-4.82_RC5.orig/src/macros.h 2013-10-27 21:46:25.000000000 +0100 ++++ exim-4.82_RC5/src/macros.h 2013-10-27 21:47:32.000000000 +0100 +@@ -778,6 +778,22 @@ + #define topt_no_body 0x040 /* Omit body */ + #define topt_escape_headers 0x080 /* Apply escape check to headers */ + ++ /* Flags for recipient_block, used in DSN support */ ++ ++ #define rf_onetime 0x01 /* A one-time alias */ ++ #define rf_notify_never 0x02 /* NOTIFY= settings */ ++ #define rf_notify_success 0x04 ++ #define rf_notify_failure 0x08 ++ #define rf_notify_delay 0x10 ++ ++ #define rf_dsnflags (rf_notify_never | rf_notify_success | \ ++ rf_notify_failure | rf_notify_delay) ++ ++ /* DSN RET types */ ++ ++ #define dsn_ret_full 1 ++ #define dsn_ret_hdrs 2 ++ + /* Codes for the host_find_failed and host_all_ignored options. */ + + #define hff_freeze 0 +diff -Naur exim-4.82_RC5.orig/src/readconf.c exim-4.82_RC5/src/readconf.c +--- exim-4.82_RC5.orig/src/readconf.c 2013-10-27 21:46:25.000000000 +0100 ++++ exim-4.82_RC5/src/readconf.c 2013-10-27 21:49:15.000000000 +0100 +@@ -229,6 +229,9 @@ + /* This option is now a no-op, retained for compability */ + { "drop_cr", opt_bool, &drop_cr }, + /*********************************************************/ ++#ifdef SUPPORT_DSN ++ { "dsn", opt_bool, &dsn }, ++#endif + { "dsn_from", opt_stringptr, &dsn_from }, + { "envelope_to_remove", opt_bool, &envelope_to_remove }, + { "errors_copy", opt_stringptr, &errors_copy }, +diff -Naur exim-4.82_RC5.orig/src/receive.c exim-4.82_RC5/src/receive.c +--- exim-4.82_RC5.orig/src/receive.c 2013-10-27 21:46:25.000000000 +0100 ++++ exim-4.82_RC5/src/receive.c 2013-10-27 21:47:32.000000000 +0100 +@@ -490,6 +490,8 @@ + memcpy(recipients_list, oldlist, oldmax * sizeof(recipient_item)); + } + ++/* memset added by GC to blank dsn records, etc. */ ++memset(&recipients_list[recipients_count], 0, sizeof(recipient_item)); + recipients_list[recipients_count].address = recipient; + recipients_list[recipients_count].pno = pno; + #ifdef EXPERIMENTAL_BRIGHTMAIL +diff -Naur exim-4.82_RC5.orig/src/route.c exim-4.82_RC5/src/route.c +--- exim-4.82_RC5.orig/src/route.c 2013-10-27 21:46:25.000000000 +0100 ++++ exim-4.82_RC5/src/route.c 2013-10-27 21:47:32.000000000 +0100 +@@ -58,6 +58,10 @@ + (void *)offsetof(router_instance, domains) }, + { "driver", opt_stringptr|opt_public, + (void *)offsetof(router_instance, driver_name) }, ++ #ifdef SUPPORT_DSN ++ { "dsn_process", opt_bool|opt_public, ++ (void *)offsetof(router_instance, dsn_process) }, ++ #endif + { "errors_to", opt_stringptr|opt_public, + (void *)(offsetof(router_instance, errors_to)) }, + { "expn", opt_bool|opt_public, +@@ -270,6 +274,13 @@ + + if (r->pass_router_name != NULL) + set_router(r, r->pass_router_name, &(r->pass_router), TRUE); ++ ++ #ifdef SUPPORT_DSN ++ if (r->dsn_process == FALSE) ++ DEBUG(D_route) debug_printf("%s router skipping DSN - add dsn_process to router\n", r->name); ++ if (r->dsn_process == TRUE) ++ DEBUG(D_route) debug_printf("%s router performing DSN \n", r->name); ++ #endif + } + } + +@@ -1412,7 +1423,10 @@ + + copyflag(new, addr, af_propagate); + new->p.address_data = addr->p.address_data; +- ++#ifdef SUPPORT_DSN ++ new->dsn_flags = addr->dsn_flags; ++ new->dsn_orcpt = addr->dsn_orcpt; ++#endif + + /* As it has turned out, we haven't set headers_add or headers_remove for the + * clone. Thinking about it, it isn't entirely clear whether they should be +diff -Naur exim-4.82_RC5.orig/src/smtp_in.c exim-4.82_RC5/src/smtp_in.c +--- exim-4.82_RC5.orig/src/smtp_in.c 2013-10-27 21:46:25.000000000 +0100 ++++ exim-4.82_RC5/src/smtp_in.c 2013-10-27 21:47:32.000000000 +0100 +@@ -213,6 +213,9 @@ + #ifdef EXPERIMENTAL_PRDR + ENV_MAIL_OPT_PRDR, + #endif ++#ifdef SUPPORT_DSN ++ ENV_MAIL_OPT_RET, ENV_MAIL_OPT_ENVID, ++#endif + ENV_MAIL_OPT_NULL + }; + typedef struct { +@@ -228,6 +231,10 @@ + #ifdef EXPERIMENTAL_PRDR + { US"PRDR", ENV_MAIL_OPT_PRDR, FALSE }, + #endif ++#ifdef SUPPORT_DSN ++ { US"RET", ENV_MAIL_OPT_RET, FALSE }, ++ { US"ENVID", ENV_MAIL_OPT_ENVID, FALSE }, ++#endif + { US"NULL", ENV_MAIL_OPT_NULL, FALSE } + }; + +@@ -1073,6 +1080,13 @@ + sender_verified_list = NULL; /* No senders verified */ + memset(sender_address_cache, 0, sizeof(sender_address_cache)); + memset(sender_domain_cache, 0, sizeof(sender_domain_cache)); ++ ++#ifdef SUPPORT_DSN ++/* Reset the DSN flags */ ++dsn_ret = 0; ++dsn_envid = NULL; ++#endif ++ + authenticated_sender = NULL; + #ifdef EXPERIMENTAL_BRIGHTMAIL + bmi_run = 0; +@@ -2679,6 +2693,10 @@ + int ptr, size, rc; + int c, i; + auth_instance *au; ++#ifdef SUPPORT_DSN ++ uschar *orcpt = NULL; ++ int flags; ++#endif + + switch(smtp_read_command(TRUE)) + { +@@ -3106,6 +3124,12 @@ + s = string_cat(s, &size, &ptr, US"-8BITMIME\r\n", 11); + } + ++ #ifdef SUPPORT_DSN ++ /* Advertise DSN support if configured to do so. */ ++ if (dsn) ++ s = string_cat(s, &size, &ptr, US"250-DSN\r\n", 9); ++ #endif ++ + /* Advertise ETRN if there's an ACL checking whether a host is + permitted to issue it; a check is made when any host actually tries. */ + +@@ -3360,6 +3384,42 @@ + arg_error = TRUE; + break; + ++#ifdef SUPPORT_DSN ++ ++ /* Handle the two DSN options, but only if configured to do so ++ * (which will have caused "DSN" to be given in the EHLO ++ * response). The code itself is included only if configured in ++ * at build time. */ ++ ++ case ENV_MAIL_OPT_RET: ++ /* Check if RET has already been set */ ++ if (dsn_ret > 0) { ++ synprot_error(L_smtp_syntax_error, 501, NULL, ++ US"RET can be specified once only"); ++ goto COMMAND_LOOP; ++ } ++ dsn_ret = (strcmpic(value, US"HDRS") == 0)? dsn_ret_hdrs : ++ (strcmpic(value, US"FULL") == 0)? dsn_ret_full : 0; ++ DEBUG(D_receive) debug_printf("DSN_RET: %d\n", dsn_ret); ++ /* Check for invalid invalid value, and exit with error */ ++ if (dsn_ret == 0) { ++ synprot_error(L_smtp_syntax_error, 501, NULL, ++ US"Value for RET is invalid"); ++ goto COMMAND_LOOP; ++ } ++ break; ++ case ENV_MAIL_OPT_ENVID: ++ /* Check if the dsn envid has been already set */ ++ if (dsn_envid != NULL) { ++ synprot_error(L_smtp_syntax_error, 501, NULL, ++ US"ENVID can be specified once only"); ++ goto COMMAND_LOOP; ++ } ++ dsn_envid = string_copy(value); ++ DEBUG(D_receive) debug_printf("DSN_ENVID: %s\n", dsn_envid); ++ break; ++#endif ++ + /* Handle the AUTH extension. If the value given is not "<>" and either + the ACL says "yes" or there is no ACL but the sending host is + authenticated, we set it up as the authenticated sender. However, if the +@@ -3633,6 +3693,89 @@ + rcpt_fail_count++; + break; + } ++ ++ #ifdef SUPPORT_DSN ++ /* Set the DSN flags orcpt and dsn_flags from the session*/ ++ orcpt = NULL; ++ flags = 0; ++ ++ if (esmtp) for(;;) ++ { ++ uschar *name, *value, *end; ++ int size; ++ ++ if (!extract_option(&name, &value)) ++ { ++ break; ++ } ++ ++ if (strcmpic(name, US"ORCPT") == 0) ++ { ++ /* Check whether orcpt has been already set */ ++ if (orcpt != NULL) { ++ synprot_error(L_smtp_syntax_error, 501, NULL, ++ US"ORCPT can be specified once only"); ++ goto COMMAND_LOOP; ++ } ++ orcpt = string_copy(value); ++ DEBUG(D_receive) debug_printf("DSN orcpt: %s\n", orcpt); ++ } ++ ++ else if (strcmpic(name, US"NOTIFY") == 0) ++ { ++ /* Check if the notify flags have been already set */ ++ if (flags > 0) ++ { ++ synprot_error(L_smtp_syntax_error, 501, NULL, ++ US"NOTIFY can be specified once only"); ++ goto COMMAND_LOOP; ++ } ++ if (strcmpic(value, US"NEVER") == 0) flags |= rf_notify_never; else ++ { ++ uschar *p = value; ++ while (*p != 0) ++ { ++ uschar *pp = p; ++ while (*pp != 0 && *pp != ',') pp++; ++ if (*pp == ',') *pp++ = 0; ++ if (strcmpic(p, US"SUCCESS") == 0) { ++ DEBUG(D_receive) debug_printf("GC: Setting notify success\n"); ++ flags |= rf_notify_success; ++ } ++ else if (strcmpic(p, US"FAILURE") == 0) { ++ DEBUG(D_receive) debug_printf("GC: Setting notify failure\n"); ++ flags |= rf_notify_failure; ++ } ++ else if (strcmpic(p, US"DELAY") == 0) { ++ DEBUG(D_receive) debug_printf("GC: Setting notify delay\n"); ++ flags |= rf_notify_delay; ++ } ++ else ++ { ++ /* Catch any strange values */ ++ synprot_error(L_smtp_syntax_error, 501, NULL, ++ US"Invalid value for NOTIFY parameter"); ++ goto COMMAND_LOOP; ++ } ++ p = pp; ++ } ++ DEBUG(D_receive) debug_printf("DSN Flags: %x\n", flags); ++ } ++ } ++ ++ /* Unknown option. Stick back the terminator characters and break ++ the loop. An error for a malformed address will occur. */ ++ ++ else ++ { ++ DEBUG(D_receive) debug_printf("Invalid dsn command: %s : %s\n", name, value); ++ name[-1] = ' '; ++ value[-1] = '='; ++ break; ++ } ++ } ++ #endif ++ + + /* Apply SMTP rewriting then extract the working address. Don't allow "<>" + as a recipient address */ +@@ -3747,6 +3890,24 @@ + if (user_msg == NULL) smtp_printf("250 Accepted\r\n"); + else smtp_user_msg(US"250", user_msg); + receive_add_recipient(recipient, -1); ++ ++ #ifdef SUPPORT_DSN ++ ++ /* Set the dsn flags in the recipients_list */ ++ if (orcpt != NULL) ++ recipients_list[recipients_count-1].orcpt = orcpt; ++ else ++ recipients_list[recipients_count-1].orcpt = NULL; ++ ++ if (flags != 0) ++ recipients_list[recipients_count-1].dsn_flags = flags; ++ else ++ recipients_list[recipients_count-1].dsn_flags = 0; ++ debug_printf("DSN-AJ(smtp-in): orcpt: %s flags: %d\n", recipients_list[recipients_count-1].orcpt, recipients_list[recipients_count-1].dsn_flags); ++ ++ ++ #endif ++ + } + + /* The recipient was discarded */ +diff -Naur exim-4.82_RC5.orig/src/spool_in.c exim-4.82_RC5/src/spool_in.c +--- exim-4.82_RC5.orig/src/spool_in.c 2013-10-27 21:46:25.000000000 +0100 ++++ exim-4.82_RC5/src/spool_in.c 2013-10-27 21:47:32.000000000 +0100 +@@ -293,6 +293,13 @@ + spam_score_int = NULL; + #endif + ++#ifdef SUPPORT_DSN ++#ifndef COMPILE_UTILITY ++dsn_ret = 0; ++dsn_envid = NULL; ++#endif /* COMPILE_UTILITY */ ++#endif ++ + /* Generate the full name and open the file. If message_subdir is already + set, just look in the given directory. Otherwise, look in both the split + and unsplit directories, as for the data file above. */ +@@ -467,6 +474,19 @@ + case 'd': + if (Ustrcmp(p, "eliver_firsttime") == 0) + deliver_firsttime = TRUE; ++ #ifdef SUPPORT_DSN ++ #ifndef COMPILE_UTILITY ++ /* Check if the dsn flags have been set in the header file */ ++ else if (Ustrncmp(p, "sn_ret", 6) == 0) ++ { ++ dsn_ret= atoi(big_buffer + 8); ++ } ++ else if (Ustrncmp(p, "sn_envid", 8) == 0) ++ { ++ dsn_envid = string_copy(big_buffer + 11); ++ } ++ #endif /* COMPILE_UTILITY */ ++ #endif + break; + + case 'f': +@@ -554,7 +574,7 @@ + tls_in.sni = string_unprinting(string_copy(big_buffer + 9)); + break; + #endif +- ++ + default: /* Present because some compilers complain if all */ + break; /* possibilities are not covered. */ + } +@@ -604,6 +624,10 @@ + { + int nn; + int pno = -1; ++ #ifdef SUPPORT_DSN ++ int dsn_flags = 0; ++ uschar *orcpt = NULL; ++ #endif + uschar *errors_to = NULL; + uschar *p; + +@@ -672,10 +696,19 @@ + } + + /* Handle current format Exim 4 spool files */ ++ /* Spool file is modified if DSN is supported ++ Original was "address errors_to len(errors_to),pno ++ New for DSN support is now: ++ "address errors_to orcpt len(errors_to),len(orcpt),pno,dsn_flags */ + + else if (*p == '#') + { + int flags; ++ ++ #ifndef COMPILE_UTILITY ++ DEBUG(D_deliver) debug_printf("**** SPOOL_IN - Exim 4 standard format spoolfile\n"); ++ #endif /* COMPILE_UTILITY */ ++ + (void)sscanf(CS p+1, "%d", &flags); + + if ((flags & 0x01) != 0) /* one_time data exists */ +@@ -688,15 +721,82 @@ + { + p -= len; + errors_to = string_copy(p); ++ } ++ } ++ ++ *(--p) = 0; /* Terminate address */ ++ } ++ #ifdef SUPPORT_DSN ++ else if (*p == '!') /* Handle Exim4 + DSN spool files */ ++ { ++ int flags; ++ int temp_dsn_flags; ++ ++ #ifndef COMPILE_UTILITY ++ DEBUG(D_deliver) debug_printf("**** SPOOL_IN - C&W DSN format spoolfile\n"); ++ #endif /* COMPILE_UTILITY */ ++ ++ sscanf(CS p+1, "%d,%d", &flags, &temp_dsn_flags); ++ ++ if (((flags & 0x01) != 0) || (temp_dsn_flags > 0)) /* one_time data or dsn_flags exist */ ++ { ++ int len; ++ int len_orcpt; ++ ++ #ifndef COMPILE_UTILITY ++ DEBUG(D_deliver) debug_printf("**** spool_in dsn_flags = 0\n"); ++ #endif /* COMPILE_UTILITY */ ++ ++ dsn_flags = 0; ++ ++ while (isdigit(*(--p)) || *p == ',' || *p == '-'); ++ sscanf(CS p+1, "%d,%d,%d,%d", &len, &len_orcpt, &pno, &dsn_flags); ++ ++ *p = 0; ++ if (len_orcpt > 0) ++ { ++ p -= len_orcpt; ++ orcpt = string_copy(p); + } ++ *(--p) = 0; /* change the space to a NULL */ ++ ++ if (len > 0) ++ { ++ p -= len; ++ errors_to = string_copy(p); ++ } + } + + *(--p) = 0; /* Terminate address */ + } ++ #endif ++ #ifndef COMPILE_UTILITY ++ else ++ { ++ DEBUG(D_deliver) debug_printf("**** SPOOL_IN - No additional fields\n"); ++ } ++ #endif /* COMPILE_UTILITY */ ++ ++ #ifdef SUPPORT_DSN ++ #ifndef COMPILE_UTILITY ++ DEBUG(D_deliver) debug_printf("**** SPOOL_IN - address: |%s| errorsto: |%s| orcpt: |%s| dsn_flags: %d\n", ++ big_buffer, errors_to, orcpt, dsn_flags); ++ #endif /* COMPILE_UTILITY */ ++ #endif ++ #ifndef SUPPORT_DSN ++ #ifndef COMPILE_UTILITY ++ DEBUG(D_deliver) debug_printf("**** SPOOL_IN - address: |%s| errorsto: |%s|\n", ++ big_buffer, errors_to); ++ #endif /* COMPILE_UTILITY */ ++ #endif + + recipients_list[recipients_count].address = string_copy(big_buffer); + recipients_list[recipients_count].pno = pno; + recipients_list[recipients_count].errors_to = errors_to; ++ #ifdef SUPPORT_DSN ++ recipients_list[recipients_count].orcpt = orcpt; ++ recipients_list[recipients_count].dsn_flags = dsn_flags; ++ #endif + } + + /* The remainder of the spool header file contains the headers for the message, +diff -Naur exim-4.82_RC5.orig/src/spool_out.c exim-4.82_RC5/src/spool_out.c +--- exim-4.82_RC5.orig/src/spool_out.c 2013-10-27 21:46:25.000000000 +0100 ++++ exim-4.82_RC5/src/spool_out.c 2013-10-27 21:47:32.000000000 +0100 +@@ -234,6 +234,15 @@ + if (tls_in.sni != NULL) fprintf(f, "-tls_sni %s\n", string_printing(tls_in.sni)); + #endif + ++#ifdef SUPPORT_DSN ++/* Write the dsn flags to the spool header file */ ++DEBUG(D_deliver) debug_printf("DSN: Write SPOOL :-dsn_envid %s\n", dsn_envid); ++if (dsn_envid != NULL) fprintf(f, "-dsn_envid %s\n", dsn_envid); ++DEBUG(D_deliver) debug_printf("DSN: Write SPOOL :-dsn_ret %d\n", dsn_ret); ++if (dsn_ret != 0) fprintf(f, "-dsn_ret %d\n", dsn_ret); ++#endif ++ ++ + /* To complete the envelope, write out the tree of non-recipients, followed by + the list of recipients. These won't be disjoint the first time, when no + checking has been done. If a recipient is a "one-time" alias, it is followed by +@@ -244,14 +253,36 @@ + for (i = 0; i < recipients_count; i++) + { + recipient_item *r = recipients_list + i; +- if (r->pno < 0 && r->errors_to == NULL) ++#ifdef SUPPORT_DSN ++DEBUG(D_deliver) debug_printf("DSN: Flags :%d\n", r->dsn_flags); ++#endif ++ if (r->pno < 0 && r->errors_to == NULL ++ #ifdef SUPPORT_DSN ++ && r->dsn_flags == 0 ++ #endif ++ ) + fprintf(f, "%s\n", r->address); + else + { + uschar *errors_to = (r->errors_to == NULL)? US"" : r->errors_to; ++ #ifdef SUPPORT_DSN ++ uschar *orcpt = (r->orcpt == NULL)? US"" : r->orcpt; ++ fprintf(f, "%s %s %s %d,%d,%d,%d!1\n", r->address, errors_to, orcpt, ++ Ustrlen(errors_to), Ustrlen(orcpt), r->pno, r->dsn_flags); ++ #else + fprintf(f, "%s %s %d,%d#1\n", r->address, errors_to, + Ustrlen(errors_to), r->pno); ++ #endif + } ++ ++ #ifdef SUPPORT_DSN ++ DEBUG(D_deliver) debug_printf("DSN :**** SPOOL_OUT - address: |%s| errorsto: |%s| orcpt: |%s| dsn_flags: %d\n", ++ r->address, r->errors_to, r->orcpt, r->dsn_flags); ++ #endif ++ #ifndef SUPPORT_DSN ++ DEBUG(D_deliver) debug_printf("**** SPOOL_OUT - address: |%s| errorsto: |%s|\n", ++ r->address, r->errors_to); ++ #endif + } + + /* Put a blank line before the headers */ +diff -Naur exim-4.82_RC5.orig/src/structs.h exim-4.82_RC5/src/structs.h +--- exim-4.82_RC5.orig/src/structs.h 2013-10-27 21:46:25.000000000 +0100 ++++ exim-4.82_RC5/src/structs.h 2013-10-27 21:47:32.000000000 +0100 +@@ -282,7 +282,9 @@ + BOOL verify_sender; /* Use this router when verifying a sender */ + BOOL uid_set; /* Flag to indicate uid is set */ + BOOL unseen; /* If TRUE carry on, even after success */ +- ++#ifdef SUPPORT_DSN ++ BOOL dsn_process; /* If TRUE, activate DSN for this router */ ++#endif + int self_code; /* Encoded version of "self" */ + uid_t uid; /* Fixed uid value */ + gid_t gid; /* Fixed gid value */ +@@ -547,6 +549,12 @@ + uschar *auth_id; /* auth "login" name used by transport */ + uschar *auth_sndr; /* AUTH arg to SMTP MAIL, used by transport */ + ++ #ifdef SUPPORT_DSN ++ uschar *dsn_orcpt; /* DSN orcpt value */ ++ int dsn_flags; /* DSN flags */ ++ uschar *dsn_aware; /* DSN aware flag */ ++ #endif ++ + uid_t uid; /* uid for transporting */ + gid_t gid; /* gid for transporting */ + +diff -Naur exim-4.82_RC5.orig/src/transport.c exim-4.82_RC5/src/transport.c +--- exim-4.82_RC5.orig/src/transport.c 2013-10-27 21:46:25.000000000 +0100 ++++ exim-4.82_RC5/src/transport.c 2013-10-27 21:47:32.000000000 +0100 +@@ -1802,6 +1802,11 @@ + + argv = child_exec_exim(CEE_RETURN_ARGV, TRUE, &i, FALSE, 0); + ++ #ifdef SUPPORT_DSN ++ /* Call with the dsn flag */ ++ if (smtp_use_dsn) argv[i++] = US"-MCD"; ++ #endif ++ + if (smtp_authenticated) argv[i++] = US"-MCA"; + + #ifdef SUPPORT_TLS +diff -Naur exim-4.82_RC5.orig/src/transports/smtp.c exim-4.82_RC5/src/transports/smtp.c +--- exim-4.82_RC5.orig/src/transports/smtp.c 2013-10-27 21:46:25.000000000 +0100 ++++ exim-4.82_RC5/src/transports/smtp.c 2013-10-27 21:47:32.000000000 +0100 +@@ -242,6 +242,16 @@ + #endif + }; + ++#ifdef SUPPORT_DSN ++/* some DSN flags for use later */ ++ ++static int rf_list[] = {rf_notify_never, rf_notify_success, ++ rf_notify_failure, rf_notify_delay }; ++ ++static uschar *rf_names[] = { "NEVER", "SUCCESS", "FAILURE", "DELAY" }; ++#endif ++ ++ + + /* Local statics */ + +@@ -1079,6 +1089,27 @@ + else if (new[0] != 0) local_authenticated_sender = new; + } + ++#ifdef SUPPORT_DSN ++/* Add any DSN flags to the mail command */ ++ ++if (smtp_use_dsn) ++ { ++ uschar *p = buffer; ++ if (dsn_ret == dsn_ret_hdrs) ++ { ++ strcpy(p, " RET=HDRS"); ++ while (*p) p++; ++ } ++ else if (dsn_ret == dsn_ret_full) ++ { ++ strcpy(p, " RET=FULL"); ++ while (*p) p++; ++ } ++ if (dsn_envid != NULL) ++ string_format(p, sizeof(buffer) - (p-buffer), " ENVID=%s", dsn_envid); ++ } ++#endif ++ + /* Add the authenticated sender address if present */ + + if ((smtp_authenticated || ob->authenticated_sender_force) && +@@ -1587,6 +1618,14 @@ + {DEBUG(D_transport) debug_printf("PRDR usable\n");} + #endif + ++ #ifdef SUPPORT_DSN ++ /* Note if the server supports DSN */ ++ smtp_use_dsn = dsn && ++ esmtp && pcre_exec(regex_DSN, NULL, CS buffer, (int)Ustrlen(CS buffer), 0, ++ PCRE_EOPT, NULL, 0) >= 0; ++ DEBUG(D_transport) debug_printf("use_dsn=%d\n", smtp_use_dsn); ++ #endif ++ + /* Note if the response to EHLO specifies support for the AUTH extension. + If it has, check that this host is one we want to authenticate to, and do + the business. The host name and address must be available when the +@@ -1746,18 +1785,66 @@ + int count; + BOOL no_flush; + ++ #ifdef SUPPORT_DSN ++ /* philb - set dsn_aware flag for this recipient */ ++ if(smtp_use_dsn) ++ addr->dsn_aware = string_copy("Y"); ++ else ++ addr->dsn_aware = string_copy("N"); ++ #endif ++ + if (addr->transport_return != PENDING_DEFER) continue; + + address_count++; + no_flush = smtp_use_pipelining && (!mua_wrapper || addr->next != NULL); + ++ #ifdef SUPPORT_DSN ++ /* Add any DSN flags to the rcpt command and add to the sent string */ ++ ++ p = buffer; ++ *p = 0; ++ ++ if (smtp_use_dsn) ++ { ++ if ((addr->dsn_flags & rf_dsnflags) != 0) ++ { ++ int i; ++ BOOL first = TRUE; ++ strcpy(p, " NOTIFY="); ++ while (*p) p++; ++ for (i = 0; i < 4; i++) ++ { ++ if ((addr->dsn_flags & rf_list[i]) != 0) ++ { ++ if (!first) *p++ = ','; ++ first = FALSE; ++ strcpy(p, rf_names[i]); ++ while (*p) p++; ++ } ++ } ++ } ++ ++ if (addr->dsn_orcpt != NULL) ++ string_format(p, sizeof(buffer) - (p-buffer), " ORCPT=%s", ++ addr->dsn_orcpt); ++ } ++ ++ #endif ++ ++ + /* Now send the RCPT command, and process outstanding responses when + necessary. After a timeout on RCPT, we just end the function, leaving the + yield as OK, because this error can often mean that there is a problem with + just one address, so we don't want to delay the host. */ + ++ #ifdef SUPPORT_DSN ++ count = smtp_write_command(&outblock, no_flush, "RCPT TO:<%s>%s%s\r\n", ++ transport_rcpt_address(addr, tblock->rcpt_include_affixes), igquotstr, buffer); ++ #else + count = smtp_write_command(&outblock, no_flush, "RCPT TO:<%s>%s\r\n", + transport_rcpt_address(addr, tblock->rcpt_include_affixes), igquotstr); ++ #endif ++ + if (count < 0) goto SEND_FAILED; + if (count > 0) + { |