diff --git a/postfix/HISTORY b/postfix/HISTORY index 0900176af..3991a45cd 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -8603,15 +8603,23 @@ Apologies for any names omitted. it appears to be because the restrictions can't be used for whitelisting. File: smtpd/smtpd_check.c. +20030920 + + Bugfix: LDAP client update by by Victor Duchovni, Morgan + Stanley. Files: README_FILES/LDAP_README, util/dict_ldap.c. + + Bugfix: after returning too old mail, the bounce daemon + now deletes recipients from the original queue file, to + avoid repeated bounce notifications when the queue manager + is restarted. Files: bounce/*.[hc], global/bounce_log.[hc], + global/{bounce,defer}.[hc] and everything that invokes + these routines including queue manager and delivery agents. + Open problems: High: when virtual aliasing is turned off after content filtering, local submissions may escape virtual aliasing. - Med: qmgr should not exit while an asynchronous bounce - request is in progress; this can result in multiple - non-delivery notifications. - Low: qmgr_move should not reset time stamps on queue files without shared lock (i.e. not open by a delivery agent). diff --git a/postfix/README_FILES/LDAP_README b/postfix/README_FILES/LDAP_README index 98d176188..9aec01209 100644 --- a/postfix/README_FILES/LDAP_README +++ b/postfix/README_FILES/LDAP_README @@ -77,11 +77,11 @@ parameters. Defaults are given in parentheses: server_host (localhost) The name of the host running the LDAP server, e.g. server_host = ldap.your.com - It should be possible with all the libraries mentioned above to - specify multiple servers separated by spaces, with the libraries - trying them in order should the first one fail. It should also - be possible to give each server in the list a different port, by - naming them like "ldap.your.com:1444". + It should be possible with all the libraries mentioned above + to specify multiple servers, with the libraries trying them in + order should the first one fail. It should also be possible to + give each server in the list a different port, by naming them + like "ldap.your.com:1444". With OpenLDAP, LDAP URLs can be used to request connection over UNIX domain sockets (ldapi://%2Fsome%2Fpath) or LDAP SSL diff --git a/postfix/html/bounce.8.html b/postfix/html/bounce.8.html index 8ff624661..8ae698b05 100644 --- a/postfix/html/bounce.8.html +++ b/postfix/html/bounce.8.html @@ -1,4 +1,4 @@ -
+BOUNCE(8) BOUNCE(8) NAME @@ -48,40 +48,40 @@ BOUNCE(8) BOUNCE(8) will have to change in order to easily support standard delivery status notifications. -CONFIGURATION PARAMETERS +CONFIGURATION PARAMETERS The following main.cf parameters are especially relevant to this program. See the Postfix main.cf file for syntax - details and for default values. Use the postfix reload + details and for default values. Use the postfix reload command after a configuration change. - bounce_notice_recipient + bounce_notice_recipient The recipient of single bounce postmaster notices. - 2bounce_notice_recipient + 2bounce_notice_recipient The recipient of double bounce postmaster notices. - delay_notice_recipient + delay_notice_recipient The recipient of "delayed mail" postmaster notices. - bounce_size_limit + bounce_size_limit Limit the amount of original message context that is sent in a non-delivery notification. - backwards_bounce_logfile_compatibility + backwards_bounce_logfile_compatibility Controls whether the logfile will be readable by old Postfix versions that used the ad-hoc logfile - format of <address>: text. + format of <address>: text. - mail_name + mail_name Use this mail system name in the introductory text at the start of a bounce message. - notify_classes + notify_classes Notify the postmaster of bounced mail when this parameter includes the bounce class. For privacy reasons, the message body is not included. -SEE ALSO +SEE ALSO master(8) process manager qmgr(8) queue manager syslogd(8) system logging diff --git a/postfix/html/error.8.html b/postfix/html/error.8.html index d7563c434..f8b37bc24 100644 --- a/postfix/html/error.8.html +++ b/postfix/html/error.8.html @@ -1,4 +1,4 @@ -+ERROR(8) ERROR(8) NAME @@ -35,27 +35,27 @@ ERROR(8) ERROR(8) DIAGNOSTICS Problems and transactions are logged to syslogd(8). - Depending on the setting of the notify_classes parameter, + Depending on the setting of the notify_classes parameter, the postmaster is notified of bounces and of other trou- ble. BUGS -CONFIGURATION PARAMETERS +CONFIGURATION PARAMETERS The following main.cf parameters are especially relevant to this program. See the Postfix main.cf file for syntax - details and for default values. Use the postfix reload + details and for default values. Use the postfix reload command after a configuration change. Miscellaneous - bounce_notice_recipient + bounce_notice_recipient Postmaster for bounce error notices. - notify_classes + notify_classes When this parameter includes the bounce class, send mail to the postmaster with the headers of the bounced mail. -SEE ALSO +SEE ALSO bounce(8) non-delivery status reports master(8) process manager qmgr(8) queue manager diff --git a/postfix/html/pipe.8.html b/postfix/html/pipe.8.html index 7ca8f1288..535931905 100644 --- a/postfix/html/pipe.8.html +++ b/postfix/html/pipe.8.html @@ -1,4 +1,4 @@ -+PIPE(8) PIPE(8) NAME diff --git a/postfix/html/postkick.1.html b/postfix/html/postkick.1.html index e4890bd6f..9e0663f78 100644 --- a/postfix/html/postkick.1.html +++ b/postfix/html/postkick.1.html @@ -1,12 +1,11 @@ -- +POSTKICK(1) POSTKICK(1) NAME postkick - kick a Postfix service SYNOPSIS - postkick [-c config_dir] [-v] class service request + postkick [-c config_dir] [-v] class service request DESCRIPTION The postkick command sends request to the specified ser- @@ -16,7 +15,7 @@ POSTKICK(1) POSTKICK(1) Options: - -c config_dir + -c config_dir Read the main.cf configuration file in the named directory instead of the default configuration directory. @@ -44,22 +43,22 @@ POSTKICK(1) POSTKICK(1) stream. ENVIRONMENT - MAIL_CONFIG + MAIL_CONFIG Directory with Postfix configuration files. - MAIL_VERBOSE + MAIL_VERBOSE Enable verbose logging for debugging purposes. -CONFIGURATION PARAMETERS +CONFIGURATION PARAMETERS The following main.cf parameters are especially relevant to this program. See the Postfix main.cf file for syntax details and for default values. - queue_directory + queue_directory Location of the Postfix queue, and of the local IPC communication endpoints. -SEE ALSO +SEE ALSO qmgr(8) queue manager trigger protocol pickup(8) local pickup daemon @@ -73,6 +72,5 @@ POSTKICK(1) POSTKICK(1) P.O. Box 704 Yorktown Heights, NY 10598, USA - 1 - + POSTKICK(1)diff --git a/postfix/src/bounce/Makefile.in b/postfix/src/bounce/Makefile.in index 232875a8f..533eb0a73 100644 --- a/postfix/src/bounce/Makefile.in +++ b/postfix/src/bounce/Makefile.in @@ -121,6 +121,9 @@ bounce_notify_service.o: ../../include/post_mail.h bounce_notify_service.o: ../../include/cleanup_user.h bounce_notify_service.o: ../../include/mail_addr.h bounce_notify_service.o: ../../include/mail_error.h +bounce_notify_service.o: ../../include/bounce.h +bounce_notify_service.o: ../../include/deliver_request.h +bounce_notify_service.o: ../../include/recipient_list.h bounce_notify_service.o: bounce_service.h bounce_notify_service.o: ../../include/bounce_log.h bounce_notify_util.o: bounce_notify_util.c @@ -152,6 +155,7 @@ bounce_notify_util.o: ../../include/mail_proto.h bounce_notify_util.o: ../../include/iostuff.h bounce_notify_util.o: ../../include/attr.h bounce_notify_util.o: ../../include/lex_822.h +bounce_notify_util.o: ../../include/deliver_completed.h bounce_notify_util.o: bounce_service.h bounce_notify_verp.o: bounce_notify_verp.c bounce_notify_verp.o: ../../include/sys_defs.h @@ -167,6 +171,9 @@ bounce_notify_verp.o: ../../include/cleanup_user.h bounce_notify_verp.o: ../../include/mail_addr.h bounce_notify_verp.o: ../../include/mail_error.h bounce_notify_verp.o: ../../include/verp_sender.h +bounce_notify_verp.o: ../../include/bounce.h +bounce_notify_verp.o: ../../include/deliver_request.h +bounce_notify_verp.o: ../../include/recipient_list.h bounce_notify_verp.o: bounce_service.h bounce_notify_verp.o: ../../include/bounce_log.h bounce_one_service.o: bounce_one_service.c @@ -180,8 +187,11 @@ bounce_one_service.o: ../../include/post_mail.h bounce_one_service.o: ../../include/cleanup_user.h bounce_one_service.o: ../../include/mail_addr.h bounce_one_service.o: ../../include/mail_error.h -bounce_one_service.o: bounce_service.h +bounce_one_service.o: ../../include/bounce.h +bounce_one_service.o: ../../include/deliver_request.h bounce_one_service.o: ../../include/vstring.h +bounce_one_service.o: ../../include/recipient_list.h +bounce_one_service.o: bounce_service.h bounce_one_service.o: ../../include/bounce_log.h bounce_trace_service.o: bounce_trace_service.c bounce_trace_service.o: ../../include/sys_defs.h diff --git a/postfix/src/bounce/bounce.c b/postfix/src/bounce/bounce.c index 816a3fd38..0f75f28aa 100644 --- a/postfix/src/bounce/bounce.c +++ b/postfix/src/bounce/bounce.c @@ -145,7 +145,9 @@ static VSTRING *why; static int bounce_append_proto(char *service_name, VSTREAM *client) { + char *myname = "bounce_append_proto"; int flags; + long offset; /* * Read the and validate the client request. @@ -155,10 +157,11 @@ static int bounce_append_proto(char *service_name, VSTREAM *client) ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id, ATTR_TYPE_STR, MAIL_ATTR_ORCPT, orig_rcpt, ATTR_TYPE_STR, MAIL_ATTR_RECIP, recipient, + ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, &offset, ATTR_TYPE_STR, MAIL_ATTR_STATUS, dsn_status, ATTR_TYPE_STR, MAIL_ATTR_ACTION, dsn_action, ATTR_TYPE_STR, MAIL_ATTR_WHY, why, - ATTR_TYPE_END) != 7) { + ATTR_TYPE_END) != 8) { msg_warn("malformed request"); return (-1); } @@ -167,9 +170,9 @@ static int bounce_append_proto(char *service_name, VSTREAM *client) return (-1); } if (msg_verbose) - msg_info("bounce_append_proto: service=%s id=%s org_to=%s to=%s stat=%s act=%s why=%s", - service_name, STR(queue_id), STR(orig_rcpt), - STR(recipient), STR(dsn_status), + msg_info("%s: flags=0x%x service=%s id=%s org_to=%s to=%s off=%ld stat=%s act=%s why=%s", + myname, flags, service_name, STR(queue_id), STR(orig_rcpt), + STR(recipient), offset, STR(dsn_status), STR(dsn_action), STR(why)); /* @@ -182,8 +185,8 @@ static int bounce_append_proto(char *service_name, VSTREAM *client) /* * Execute the request. */ - return (bounce_append_service(service_name, STR(queue_id), - STR(orig_rcpt), STR(recipient), + return (bounce_append_service(flags, service_name, STR(queue_id), + STR(orig_rcpt), STR(recipient), offset, STR(dsn_status), STR(dsn_action), STR(why))); } @@ -191,8 +194,9 @@ static int bounce_append_proto(char *service_name, VSTREAM *client) /* bounce_notify_proto - bounce_notify server protocol */ static int bounce_notify_proto(char *service_name, VSTREAM *client, - int (*service) (char *, char *, char *, char *, char *)) + int (*service) (int, char *, char *, char *, char *, char *)) { + char *myname = "bounce_notify_proto"; int flags; /* @@ -217,8 +221,8 @@ static int bounce_notify_proto(char *service_name, VSTREAM *client, return (-1); } if (msg_verbose) - msg_info("bounce_notify_proto: service=%s queue=%s id=%s encoding=%s sender=%s", - service_name, STR(queue_name), STR(queue_id), + msg_info("%s: flags=0x%x service=%s queue=%s id=%s encoding=%s sender=%s", + myname, flags, service_name, STR(queue_name), STR(queue_id), STR(encoding), STR(sender)); /* @@ -231,7 +235,7 @@ static int bounce_notify_proto(char *service_name, VSTREAM *client, /* * Execute the request. */ - return (service(service_name, STR(queue_name), + return (service(flags, service_name, STR(queue_name), STR(queue_id), STR(encoding), STR(sender))); } @@ -271,8 +275,8 @@ static int bounce_verp_proto(char *service_name, VSTREAM *client) return (-1); } if (msg_verbose) - msg_info("%s: service=%s queue=%s id=%s encoding=%s sender=%s delim=%s", - myname, service_name, STR(queue_name), STR(queue_id), + msg_info("%s: flags=0x%x service=%s queue=%s id=%s encoding=%s sender=%s delim=%s", + myname, flags, service_name, STR(queue_name), STR(queue_id), STR(encoding), STR(sender), STR(verp_delims)); /* @@ -288,11 +292,11 @@ static int bounce_verp_proto(char *service_name, VSTREAM *client) */ if (!*STR(sender) || !strcasecmp(STR(sender), mail_addr_double_bounce())) { msg_warn("request to send VERP-style notification of bounced mail"); - return (bounce_notify_service(service_name, STR(queue_name), + return (bounce_notify_service(flags, service_name, STR(queue_name), STR(queue_id), STR(encoding), STR(sender))); } else - return (bounce_notify_verp(service_name, STR(queue_name), + return (bounce_notify_verp(flags, service_name, STR(queue_name), STR(queue_id), STR(encoding), STR(sender), STR(verp_delims))); } @@ -301,23 +305,26 @@ static int bounce_verp_proto(char *service_name, VSTREAM *client) static int bounce_one_proto(char *service_name, VSTREAM *client) { - int unused_flags; + char *myname = "bounce_one_proto"; + int flags; + long offset; /* * Read and validate the client request. */ if (mail_command_server(client, - ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &unused_flags, + ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &flags, ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue_name, ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id, ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding, ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender, ATTR_TYPE_STR, MAIL_ATTR_ORCPT, orig_rcpt, ATTR_TYPE_STR, MAIL_ATTR_RECIP, recipient, + ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, &offset, ATTR_TYPE_STR, MAIL_ATTR_STATUS, dsn_status, ATTR_TYPE_STR, MAIL_ATTR_ACTION, dsn_action, ATTR_TYPE_STR, MAIL_ATTR_WHY, why, - ATTR_TYPE_END) != 10) { + ATTR_TYPE_END) != 11) { msg_warn("malformed request"); return (-1); } @@ -335,17 +342,18 @@ static int bounce_one_proto(char *service_name, VSTREAM *client) return (-1); } if (msg_verbose) - msg_info("bounce_one_proto: queue=%s id=%s encoding=%s sender=%s orig_to=%s to=%s stat=%s act=%s why=%s", - STR(queue_name), STR(queue_id), STR(encoding), - STR(sender), STR(orig_rcpt), STR(recipient), + msg_info("%s: flags=0x%x queue=%s id=%s encoding=%s sender=%s orig_to=%s to=%s off=%ld stat=%s act=%s why=%s", + myname, flags, STR(queue_name), STR(queue_id), STR(encoding), + STR(sender), STR(orig_rcpt), STR(recipient), offset, STR(dsn_status), STR(dsn_action), STR(why)); /* * Execute the request. */ - return (bounce_one_service(STR(queue_name), STR(queue_id), STR(encoding), - STR(sender), STR(orig_rcpt), STR(recipient), - STR(dsn_status), STR(dsn_action), STR(why))); + return (bounce_one_service(flags, STR(queue_name), STR(queue_id), + STR(encoding), STR(sender), STR(orig_rcpt), + STR(recipient), offset, STR(dsn_status), + STR(dsn_action), STR(why))); } /* bounce_service - parse bounce command type and delegate */ @@ -368,9 +376,6 @@ static void bounce_service(VSTREAM *client, char *service_name, char **argv) * Read and validate the first parameter of the client request. Let the * request-specific protocol routines take care of the remainder. */ -#define REALLY_BOUNCE 1 -#define JUST_WARN 0 - if (attr_scan(client, ATTR_FLAG_STRICT | ATTR_FLAG_MORE, ATTR_TYPE_NUM, MAIL_ATTR_NREQ, &command, 0) != 1) { msg_warn("malformed request"); diff --git a/postfix/src/bounce/bounce_append_service.c b/postfix/src/bounce/bounce_append_service.c index 4dcf3ba48..a72b92c95 100644 --- a/postfix/src/bounce/bounce_append_service.c +++ b/postfix/src/bounce/bounce_append_service.c @@ -6,8 +6,9 @@ /* SYNOPSIS /* #include "bounce_service.h" /* -/* int bounce_append_service(queue_id, orig_rcpt, recipient, +/* int bounce_append_service(flags, queue_id, orig_rcpt, recipient, /* status, action, why) +/* int flags; /* char *queue_id; /* char *orig_rcpt; /* char *recipient; @@ -68,9 +69,9 @@ /* bounce_append_service - append bounce log */ -int bounce_append_service(char *service, char *queue_id, +int bounce_append_service(int unused_flags, char *service, char *queue_id, char *orig_rcpt, char *recipient, - char *status, char *action, + long offset, char *status, char *action, char *why) { VSTRING *in_buf = vstring_alloc(100); @@ -129,6 +130,8 @@ int bounce_append_service(char *service, char *queue_id, if (*orig_rcpt && strcasecmp(recipient, orig_rcpt) != 0) vstream_fprintf(log, "%s=%s\n", MAIL_ATTR_ORCPT, printable(vstring_str(quote_822_local(in_buf, orig_rcpt)), '?')); + if (offset > 0) + vstream_fprintf(log, "%s=%ld\n", MAIL_ATTR_OFFSET, offset); vstream_fprintf(log, "%s=%s\n", MAIL_ATTR_STATUS, printable(status, '?')); vstream_fprintf(log, "%s=%s\n", MAIL_ATTR_ACTION, printable(action, '?')); vstream_fprintf(log, "%s=%s\n", MAIL_ATTR_WHY, printable(why, '?')); diff --git a/postfix/src/bounce/bounce_notify_service.c b/postfix/src/bounce/bounce_notify_service.c index 14d67ccd4..3e20cf97b 100644 --- a/postfix/src/bounce/bounce_notify_service.c +++ b/postfix/src/bounce/bounce_notify_service.c @@ -6,8 +6,9 @@ /* SYNOPSIS /* #include "bounce_service.h" /* -/* int bounce_notify_service(queue_name, queue_id, encoding, +/* int bounce_notify_service(flags, queue_name, queue_id, encoding, /* sender) +/* int flags; /* char *queue_name; /* char *queue_id; /* char *encoding; @@ -70,6 +71,7 @@ #include#include #include +#include /* Application-specific. */ @@ -79,7 +81,7 @@ /* bounce_notify_service - send a bounce */ -int bounce_notify_service(char *service, char *queue_name, +int bounce_notify_service(int flags, char *service, char *queue_name, char *queue_id, char *encoding, char *recipient) { @@ -218,6 +220,12 @@ int bounce_notify_service(char *service, char *queue_name, } } + /* + * Optionally, delete the recipients from the queue file. + */ + if (bounce_status == 0 && (flags & BOUNCE_FLAG_DELRCPT)) + bounce_delrcpt(bounce_info); + /* * Examine the completion status. Delete the bounce log file only when * the bounce was posted successfully, and only if we are bouncing for diff --git a/postfix/src/bounce/bounce_notify_util.c b/postfix/src/bounce/bounce_notify_util.c index e04a71b41..29f06bc20 100644 --- a/postfix/src/bounce/bounce_notify_util.c +++ b/postfix/src/bounce/bounce_notify_util.c @@ -68,6 +68,12 @@ /* VSTREAM *fp; /* BOUNCE_INFO *bounce_info; /* int headers_only; +/* +/* void bounce_delrcpt(bounce_info) +/* BOUNCE_INFO *bounce_info; +/* +/* void bounce_delrcpt_one(bounce_info) +/* BOUNCE_INFO *bounce_info; /* DESCRIPTION /* This module implements the grunt work of sending a non-delivery /* notification. A bounce is sent in a form that satisfies RFC 1894 @@ -116,6 +122,12 @@ /* bounce_original() starts a message/rfc822 or headers/rfc822 /* message segment and sends the original message, either full or /* message headers only. +/* +/* bounce_delrcpt() deletes recipients in the logfile from the original +/* queue file. +/* +/* bounce_delrcpt_one() deletes one recipient from the original +/* queue file. /* DIAGNOSTICS /* Fatal error: error opening existing file. Warnings: corrupt /* message file. A corrupt message is saved to the "corrupt" @@ -173,6 +185,7 @@ #include #include #include +#include /* Application-specific. */ @@ -267,7 +280,7 @@ static BOUNCE_INFO *bounce_mail_alloc(const char *service, /* XXX Future: sender+recipient after message content. */ if (VSTRING_LEN(bounce_info->sender) == 0) msg_warn("%s: no sender before message content record", - bounce_info->queue_id); + bounce_info->queue_id); bounce_info->orig_offs = vstream_ftell(bounce_info->orig_fp); break; } @@ -310,6 +323,7 @@ BOUNCE_INFO *bounce_mail_one_init(const char *queue_name, const char *encoding, const char *orig_recipient, const char *recipient, + long offset, const char *dsn_status, const char *dsn_action, const char *why) @@ -323,7 +337,7 @@ BOUNCE_INFO *bounce_mail_one_init(const char *queue_name, */ #define REALLY_BOUNCE 1 - log_handle = bounce_log_forge(orig_recipient, recipient, dsn_status, + log_handle = bounce_log_forge(orig_recipient, recipient, offset, dsn_status, dsn_action, why); bounce_info = bounce_mail_alloc("none", queue_name, queue_id, encoding, REALLY_BOUNCE, log_handle); @@ -689,3 +703,27 @@ int bounce_original(VSTREAM *bounce, BOUNCE_INFO *bounce_info, return (status); } + +/* bounce_delrcpt - delete recipients from original queue file */ + +int bounce_delrcpt(BOUNCE_INFO *bounce_info) +{ + if (bounce_info->orig_fp != 0 + && bounce_info->log_handle != 0 + && bounce_log_rewind(bounce_info->log_handle) == 0) + while (bounce_log_read(bounce_info->log_handle) != 0) + if (bounce_info->log_handle->rcpt_offset > 0) + deliver_completed(bounce_info->orig_fp, + bounce_info->log_handle->rcpt_offset); +} + +/* bounce_delrcpt_one - delete one recipient from original queue file */ + +int bounce_delrcpt_one(BOUNCE_INFO *bounce_info) +{ + if (bounce_info->orig_fp != 0 + && bounce_info->log_handle != 0 + && bounce_info->log_handle->rcpt_offset > 0) + deliver_completed(bounce_info->orig_fp, + bounce_info->log_handle->rcpt_offset); +} diff --git a/postfix/src/bounce/bounce_notify_verp.c b/postfix/src/bounce/bounce_notify_verp.c index 3ff372f3a..d12f2c278 100644 --- a/postfix/src/bounce/bounce_notify_verp.c +++ b/postfix/src/bounce/bounce_notify_verp.c @@ -6,8 +6,9 @@ /* SYNOPSIS /* #include "bounce_service.h" /* -/* int bounce_notify_verp(service, queue_name, queue_id, sender, +/* int bounce_notify_verp(flags, service, queue_name, queue_id, sender, /* verp_delims) +/* int flags; /* char *queue_name; /* char *queue_id; /* char *sender; @@ -70,6 +71,7 @@ #include #include #include +#include /* Application-specific. */ @@ -79,10 +81,9 @@ /* bounce_notify_verp - send a bounce */ -int bounce_notify_verp(char *service, char *queue_name, +int bounce_notify_verp(int flags, char *service, char *queue_name, char *queue_id, char *encoding, - char *recipient, - char *verp_delims) + char *recipient, char *verp_delims) { char *myname = "bounce_notify_verp"; BOUNCE_INFO *bounce_info; @@ -152,9 +153,10 @@ int bounce_notify_verp(char *service, char *queue_name, break; /* - * Mark this recipient as done. + * Optionally, mark this recipient as done. */ - bounce_log_delrcpt(bounce_info->log_handle); + if (flags & BOUNCE_FLAG_DELRCPT) + bounce_delrcpt_one(bounce_info); /* * Optionally, send a postmaster notice. diff --git a/postfix/src/bounce/bounce_one_service.c b/postfix/src/bounce/bounce_one_service.c index 4cab4c82f..817b4580a 100644 --- a/postfix/src/bounce/bounce_one_service.c +++ b/postfix/src/bounce/bounce_one_service.c @@ -6,9 +6,10 @@ /* SYNOPSIS /* #include "bounce_service.h" /* -/* int bounce_one_service(queue_name, queue_id, encoding, +/* int bounce_one_service(flags, queue_name, queue_id, encoding, /* orig_sender, orig_recipient, /* status, why) +/* int flags; /* char *queue_name; /* char *queue_id; /* char *encoding; @@ -71,6 +72,7 @@ #include #include #include +#include /* Application-specific. */ @@ -80,10 +82,11 @@ /* bounce_one_service - send a bounce for one recipient */ -int bounce_one_service(char *queue_name, char *queue_id, char *encoding, - char *orig_sender, char *orig_recipient, - char *recipient, char *dsn_status, - char *dsn_action, char *why) +int bounce_one_service(int flags, char *queue_name, char *queue_id, + char *encoding, char *orig_sender, + char *orig_recipient, char *recipient, + long offset, char *dsn_status, + char *dsn_action, char *why) { BOUNCE_INFO *bounce_info; int bounce_status = 1; @@ -97,7 +100,7 @@ int bounce_one_service(char *queue_name, char *queue_id, char *encoding, */ bounce_info = bounce_mail_one_init(queue_name, queue_id, encoding, orig_recipient, - recipient, dsn_status, + recipient, offset, dsn_status, dsn_action, why); #define NULL_SENDER MAIL_ADDR_EMPTY /* special address */ @@ -220,6 +223,12 @@ int bounce_one_service(char *queue_name, char *queue_id, char *encoding, } } + /* + * Optionally, delete the recipient from the queue file. + */ + if (bounce_status == 0 && (flags & BOUNCE_FLAG_DELRCPT)) + bounce_delrcpt_one(bounce_info); + /* * Cleanup. */ diff --git a/postfix/src/bounce/bounce_service.h b/postfix/src/bounce/bounce_service.h index c3c56af82..8850a0a82 100644 --- a/postfix/src/bounce/bounce_service.h +++ b/postfix/src/bounce/bounce_service.h @@ -21,32 +21,32 @@ /* * bounce_append_service.c */ -extern int bounce_append_service(char *, char *, char *, char *, char *, char *, char *); +extern int bounce_append_service(int, char *, char *, char *, char *, long, char *, char *, char *); /* * bounce_notify_service.c */ -extern int bounce_notify_service(char *, char *, char *, char *, char *); +extern int bounce_notify_service(int, char *, char *, char *, char *, char *); /* * bounce_warn_service.c */ -extern int bounce_warn_service(char *, char *, char *, char *, char *); +extern int bounce_warn_service(int, char *, char *, char *, char *, char *); /* * bounce_trace_service.c */ -extern int bounce_trace_service(char *, char *, char *, char *, char *); +extern int bounce_trace_service(int, char *, char *, char *, char *, char *); /* * bounce_notify_verp.c */ -extern int bounce_notify_verp(char *, char *, char *, char *, char *, char *); +extern int bounce_notify_verp(int, char *, char *, char *, char *, char *, char *); /* * bounce_one_service.c */ -extern int bounce_one_service(char *, char *, char *, char *, char *, char *, char *, char *, char *); +extern int bounce_one_service(int, char *, char *, char *, char *, char *, char *, long, char *, char *, char *); /* * bounce_cleanup.c @@ -78,7 +78,7 @@ typedef struct { } BOUNCE_INFO; extern BOUNCE_INFO *bounce_mail_init(const char *, const char *, const char *, const char *, int); -extern BOUNCE_INFO *bounce_mail_one_init(const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *); +extern BOUNCE_INFO *bounce_mail_one_init(const char *, const char *, const char *, const char *, const char *, long, const char *, const char *, const char *); extern void bounce_mail_free(BOUNCE_INFO *); extern int bounce_header(VSTREAM *, BOUNCE_INFO *, const char *); extern int bounce_boilerplate(VSTREAM *, BOUNCE_INFO *); @@ -88,6 +88,8 @@ extern int bounce_header_dsn(VSTREAM *, BOUNCE_INFO *); extern int bounce_recipient_dsn(VSTREAM *, BOUNCE_INFO *); extern int bounce_diagnostic_dsn(VSTREAM *, BOUNCE_INFO *); extern int bounce_original(VSTREAM *, BOUNCE_INFO *, int); +extern int bounce_delrcpt(BOUNCE_INFO *); +extern int bounce_delrcpt_one(BOUNCE_INFO *); #define BOUNCE_MSG_FAIL 0 #define BOUNCE_MSG_WARN 1 diff --git a/postfix/src/bounce/bounce_trace_service.c b/postfix/src/bounce/bounce_trace_service.c index 40a8b5c7e..66df408a1 100644 --- a/postfix/src/bounce/bounce_trace_service.c +++ b/postfix/src/bounce/bounce_trace_service.c @@ -6,7 +6,8 @@ /* SYNOPSIS /* #include "bounce_service.h" /* -/* int bounce_trace_service(queue_name, queue_id, encoding, sender) +/* int bounce_trace_service(flags, queue_name, queue_id, encoding, sender) +/* int flags; /* char *queue_name; /* char *queue_id; /* char *encoding; @@ -73,7 +74,7 @@ /* bounce_trace_service - send a delivery status notice */ -int bounce_trace_service(char *service, char *queue_name, +int bounce_trace_service(int unused_flags, char *service, char *queue_name, char *queue_id, char *encoding, char *recipient) { diff --git a/postfix/src/bounce/bounce_warn_service.c b/postfix/src/bounce/bounce_warn_service.c index 170498a5d..fe425d831 100644 --- a/postfix/src/bounce/bounce_warn_service.c +++ b/postfix/src/bounce/bounce_warn_service.c @@ -6,7 +6,8 @@ /* SYNOPSIS /* #include "bounce_service.h" /* -/* int bounce_warn_service(queue_name, queue_id, encoding, sender) +/* int bounce_warn_service(flags, queue_name, queue_id, encoding, sender) +/* int flags; /* char *queue_name; /* char *queue_id; /* char *encoding; @@ -77,7 +78,7 @@ /* bounce_warn_service - send a delayed mail notice */ -int bounce_warn_service(char *service, char *queue_name, +int bounce_warn_service(int unused_flags, char *service, char *queue_name, char *queue_id, char *encoding, char *recipient) { diff --git a/postfix/src/cleanup/cleanup_api.c b/postfix/src/cleanup/cleanup_api.c index d361f1a77..f398281d6 100644 --- a/postfix/src/cleanup/cleanup_api.c +++ b/postfix/src/cleanup/cleanup_api.c @@ -259,7 +259,7 @@ int cleanup_flush(CLEANUP_STATE *state) if (bounce_append(BOUNCE_FLAG_CLEAN, state->queue_id, state->recip ? state->recip : "unknown", state->recip ? state->recip : "unknown", - "cleanup", state->time, + (long) 0, "cleanup", state->time, "%s", state->reason ? state->reason : cleanup_strerror(state->errs)) == 0 && bounce_flush(BOUNCE_FLAG_CLEAN, state->queue_name, diff --git a/postfix/src/error/error.c b/postfix/src/error/error.c index 72a7f4a10..001e8697e 100644 --- a/postfix/src/error/error.c +++ b/postfix/src/error/error.c @@ -131,8 +131,8 @@ static int deliver_message(DELIVER_REQUEST *request) rcpt = request->rcpt_list.info + nrcpt; if (rcpt->offset >= 0) { status = bounce_append(BOUNCE_FLAGS(request), request->queue_id, - rcpt->orig_addr, rcpt->address, "none", - request->arrival_time, + rcpt->orig_addr, rcpt->address, + rcpt->offset, "none", request->arrival_time, "%s", request->nexthop); if (status == 0) deliver_completed(src, rcpt->offset); diff --git a/postfix/src/global/bounce.c b/postfix/src/global/bounce.c index e05c4e88c..2df58b6dc 100644 --- a/postfix/src/global/bounce.c +++ b/postfix/src/global/bounce.c @@ -6,22 +6,24 @@ /* SYNOPSIS /* #include /* -/* int bounce_append(flags, id, orig_rcpt, recipient, relay, +/* int bounce_append(flags, id, orig_rcpt, recipient, offset, relay, /* entry, format, ...) /* int flags; /* const char *id; /* const char *orig_rcpt; /* const char *recipient; +/* long offset; /* const char *relay; /* time_t entry; /* const char *format; /* -/* int vbounce_append(flags, id, orig_rcpt, recipient, relay, +/* int vbounce_append(flags, id, orig_rcpt, recipient, offset, relay, /* entry, format, ap) /* int flags; /* const char *id; /* const char *orig_rcpt; /* const char *recipient; +/* long offset; /* const char *relay; /* time_t entry; /* const char *format; @@ -35,19 +37,7 @@ /* const char *sender; /* /* int bounce_one(flags, queue, id, encoding, sender, orig_rcpt, -/* recipient, relay, entry, format, ...) -/* int flags; -/* const char *queue; -/* const char *id; -/* const char *encoding; -/* const char *sender; -/* const char *recipient; -/* const char *relay; -/* time_t entry; -/* const char *format; -/* -/* int vbounce_one(flags, queue, id, encoding, sender, orig_rcpt, -/* recipient, relay, entry, format, ap) +/* recipient, offset, relay, entry, format, ...) /* int flags; /* const char *queue; /* const char *id; @@ -55,6 +45,21 @@ /* const char *sender; /* const char *orig_rcpt; /* const char *recipient; +/* long offset; +/* const char *relay; +/* time_t entry; +/* const char *format; +/* +/* int vbounce_one(flags, queue, id, encoding, sender, orig_rcpt, +/* recipient, offset, relay, entry, format, ap) +/* int flags; +/* const char *queue; +/* const char *id; +/* const char *encoding; +/* const char *sender; +/* const char *orig_rcpt; +/* const char *recipient; +/* long offset; /* const char *relay; /* time_t entry; /* const char *format; @@ -123,6 +128,8 @@ /* .IP recipient /* Recipient address that the message could not be delivered to. /* This information is used for syslogging only. +/* .IP offset +/* Queue file offset of recipient record. /* .IP format /* The reason for non-delivery. /* .IP ap @@ -175,7 +182,7 @@ /* bounce_append - append reason to per-message bounce log */ int bounce_append(int flags, const char *id, const char *orig_rcpt, - const char *recipient, const char *relay, + const char *recipient, long offset, const char *relay, time_t entry, const char *fmt,...) { va_list ap; @@ -183,7 +190,7 @@ int bounce_append(int flags, const char *id, const char *orig_rcpt, va_start(ap, fmt); status = vbounce_append(flags, id, orig_rcpt, recipient, - relay, entry, fmt, ap); + offset, relay, entry, fmt, ap); va_end(ap); return (status); } @@ -191,7 +198,7 @@ int bounce_append(int flags, const char *id, const char *orig_rcpt, /* vbounce_append - append bounce reason to per-message log */ int vbounce_append(int flags, const char *id, const char *orig_rcpt, - const char *recipient, const char *relay, + const char *recipient, long offset, const char *relay, time_t entry, const char *fmt, va_list ap) { int status; @@ -244,6 +251,7 @@ int vbounce_append(int flags, const char *id, const char *orig_rcpt, ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id, ATTR_TYPE_STR, MAIL_ATTR_ORCPT, orig_rcpt, ATTR_TYPE_STR, MAIL_ATTR_RECIP, recipient, + ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, offset, ATTR_TYPE_STR, MAIL_ATTR_STATUS, dsn_code, ATTR_TYPE_STR, MAIL_ATTR_ACTION, dsn_action, ATTR_TYPE_STR, MAIL_ATTR_WHY, vstring_str(why), @@ -255,8 +263,8 @@ int vbounce_append(int flags, const char *id, const char *orig_rcpt, entry, log_status, fmt, ap); status = (var_soft_bounce ? -1 : 0); } else if ((flags & BOUNCE_FLAG_CLEAN) == 0) { - status = defer_append(flags, id, orig_rcpt, recipient, relay, - entry, "%s or %s service failure", + status = defer_append(flags, id, orig_rcpt, recipient, offset, + relay, entry, "%s or %s service failure", var_bounce_service, var_trace_service); } else { status = -1; @@ -300,7 +308,7 @@ int bounce_flush(int flags, const char *queue, const char *id, int bounce_one(int flags, const char *queue, const char *id, const char *encoding, const char *sender, const char *orig_rcpt, const char *recipient, - const char *relay, time_t entry, + long offset, const char *relay, time_t entry, const char *fmt,...) { va_list ap; @@ -308,7 +316,7 @@ int bounce_one(int flags, const char *queue, const char *id, va_start(ap, fmt); status = vbounce_one(flags, queue, id, encoding, sender, orig_rcpt, - recipient, relay, entry, fmt, ap); + recipient, offset, relay, entry, fmt, ap); va_end(ap); return (status); } @@ -318,7 +326,7 @@ int bounce_one(int flags, const char *queue, const char *id, int vbounce_one(int flags, const char *queue, const char *id, const char *encoding, const char *sender, const char *orig_rcpt, const char *recipient, - const char *relay, time_t entry, + long offset, const char *relay, time_t entry, const char *fmt, va_list ap) { int status; @@ -349,7 +357,7 @@ int vbounce_one(int flags, const char *queue, const char *id, */ else if (var_soft_bounce) { return (vbounce_append(flags, id, orig_rcpt, recipient, - relay, entry, fmt, ap)); + offset, relay, entry, fmt, ap)); } /* @@ -370,6 +378,7 @@ int vbounce_one(int flags, const char *queue, const char *id, ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender, ATTR_TYPE_STR, MAIL_ATTR_ORCPT, orig_rcpt, ATTR_TYPE_STR, MAIL_ATTR_RECIP, recipient, + ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, offset, ATTR_TYPE_STR, MAIL_ATTR_STATUS, "5.0.0", ATTR_TYPE_STR, MAIL_ATTR_ACTION, "failed", ATTR_TYPE_STR, MAIL_ATTR_WHY, vstring_str(why), @@ -381,8 +390,8 @@ int vbounce_one(int flags, const char *queue, const char *id, entry, "bounced", fmt, ap); status = 0; } else if ((flags & BOUNCE_FLAG_CLEAN) == 0) { - status = defer_append(flags, id, orig_rcpt, recipient, relay, - entry, "%s or %s service failure", + status = defer_append(flags, id, orig_rcpt, recipient, offset, + relay, entry, "%s or %s service failure", var_bounce_service, var_trace_service); } else { status = -1; diff --git a/postfix/src/global/bounce.h b/postfix/src/global/bounce.h index b8bb11757..6f1a6a552 100644 --- a/postfix/src/global/bounce.h +++ b/postfix/src/global/bounce.h @@ -25,20 +25,20 @@ /* * Client interface. */ -extern int PRINTFLIKE(7, 8) bounce_append(int, const char *, +extern int PRINTFLIKE(8, 9) bounce_append(int, const char *, const char *, const char *, - const char *, time_t, + long, const char *, time_t, const char *,...); -extern int vbounce_append(int, const char *, const char *, const char *, +extern int vbounce_append(int, const char *, const char *, const char *, long, const char *, time_t, const char *, va_list); extern int bounce_flush(int, const char *, const char *, const char *, const char *); -extern int PRINTFLIKE(10, 11) bounce_one(int, const char *, const char *, +extern int PRINTFLIKE(11, 12) bounce_one(int, const char *, const char *, const char *, const char *, const char *, const char *, - const char *, time_t, + long, const char *, time_t, const char *,...); extern int vbounce_one(int, const char *, const char *, const char *, - const char *, const char *, const char *, + const char *, const char *, const char *, long, const char *, time_t, const char *, va_list); /* @@ -56,6 +56,7 @@ extern int vbounce_one(int, const char *, const char *, const char *, */ #define BOUNCE_FLAG_NONE 0 /* no flags up */ #define BOUNCE_FLAG_CLEAN (1<<0) /* remove log on error */ +#define BOUNCE_FLAG_DELRCPT (1<<1) /* delete recipient from queue file */ /* * Backwards compatibility. diff --git a/postfix/src/global/bounce_log.c b/postfix/src/global/bounce_log.c index 40cbe45e3..6127668f4 100644 --- a/postfix/src/global/bounce_log.c +++ b/postfix/src/global/bounce_log.c @@ -11,6 +11,7 @@ /* /* public members... */ /* const char *recipient; /* const char *orig_rcpt; +/* long rcpt_offset; /* const char *dsn_status; /* const char *dsn_action; /* const char *text; @@ -26,16 +27,14 @@ /* BOUNCE_LOG *bounce_log_read(bp) /* BOUNCE_LOG *bp; /* -/* BOUNCE_LOG *bounce_log_delrcpt(bp) -/* BOUNCE_LOG *bp; -/* /* void bounce_log_rewind(bp) /* BOUNCE_LOG *bp; /* -/* BOUNCE_LOG *bounce_log_forge(orig_rcpt, recipient, dsn_status, -/* dsn_action, why) +/* BOUNCE_LOG *bounce_log_forge(orig_rcpt, recipient, rcpt_offset, +/* dsn_status, dsn_action, why) /* const char *orig_rcpt; /* const char *recipient; +/* long rcpt_offset; /* const char *dsn_status; /* const char *dsn_action; /* const char *why; @@ -59,9 +58,6 @@ /* bounce_log_read() returns a null pointer when no recipient was read, /* otherwise it returns its argument. /* -/* bounce_log_delrcpt() marks the last accessed recipient record as -/* "deleted". This requires that the logfile is opened for update. -/* /* bounce_log_rewind() is a helper that seeks to the first recipient /* in an open bounce or defer logfile (skipping over recipients that /* are marked as done). The result is 0 in case of success, -1 in case @@ -94,6 +90,8 @@ /* .IP orig_rcpt /* Null pointer or the original recipient address in RFC 822 /* external form. +/* .IP rcpt_offset +/* Queue file offset of recipient record. /* .IP text /* The text that explains why the recipient was undeliverable. /* .IP dsn_status @@ -119,6 +117,7 @@ #include #include #include +#include /* Utility library. */ @@ -146,12 +145,12 @@ static BOUNCE_LOG *bounce_log_init(VSTREAM *fp, VSTRING *buf, VSTRING *orcp_buf, VSTRING *rcpt_buf, + long rcpt_offset, VSTRING *status_buf, const char *compat_status, VSTRING *action_buf, const char *compat_action, - VSTRING *text_buf, - long offset) + VSTRING *text_buf) { BOUNCE_LOG *bp; @@ -165,12 +164,12 @@ static BOUNCE_LOG *bounce_log_init(VSTREAM *fp, bp->buf = buf; SET_BUFFER(bp, orcp_buf, orig_rcpt); SET_BUFFER(bp, rcpt_buf, recipient); + bp->rcpt_offset = rcpt_offset; SET_BUFFER(bp, status_buf, dsn_status); bp->compat_status = compat_status; SET_BUFFER(bp, action_buf, dsn_action); bp->compat_action = compat_action; SET_BUFFER(bp, text_buf, text); - bp->offset = offset; return (bp); } @@ -199,14 +198,14 @@ BOUNCE_LOG *bounce_log_open(const char *queue_name, const char *queue_id, vstring_alloc(100), /* buffer */ vstring_alloc(10), /* orig_rcpt */ vstring_alloc(10), /* recipient */ + (long) 0, /* offset */ vstring_alloc(10), /* dsn_status */ STREQ(queue_name, MAIL_QUEUE_DEFER) ? "4.0.0" : "5.0.0", /* compatibility */ vstring_alloc(10), /* dsn_action */ STREQ(queue_name, MAIL_QUEUE_DEFER) ? "delayed" : "failed", /* compatibility */ - vstring_alloc(10), /* text */ - 0)); /* offset */ + vstring_alloc(10))); /* text */ } } @@ -218,14 +217,12 @@ BOUNCE_LOG *bounce_log_read(BOUNCE_LOG *bp) char *text; char *cp; int state; - long offset; /* * Our trivial logfile parser state machine. */ #define START 0 /* still searching */ #define FOUND 1 /* in logfile entry */ -#define SKIP 2 /* in deleted entry */ /* * Initialize. @@ -233,6 +230,7 @@ BOUNCE_LOG *bounce_log_read(BOUNCE_LOG *bp) state = START; bp->recipient = "(unavailable)"; bp->orig_rcpt = 0; + bp->rcpt_offset = 0; bp->dsn_status = "(unavailable)"; bp->dsn_action = "(unavailable)"; bp->text = "(unavailable)"; @@ -243,8 +241,7 @@ BOUNCE_LOG *bounce_log_read(BOUNCE_LOG *bp) * With backwards compatibility, we even have old format followed by new * format within the same logfile entry! */ - while ((offset = vstream_ftell(bp->fp)), - (vstring_get_nonl(bp->buf, bp->fp) != VSTREAM_EOF)) { + while ((vstring_get_nonl(bp->buf, bp->fp) != VSTREAM_EOF)) { /* * Logfile entries are separated by blank lines. Even the old ad-hoc @@ -259,34 +256,14 @@ BOUNCE_LOG *bounce_log_read(BOUNCE_LOG *bp) continue; } - /* - * Skip over deleted logfile entries. - */ - if (state == SKIP) - continue; - /* * Sanitize. XXX This needs to be done more carefully with new-style * logfile entries. */ cp = printable(STR(bp->buf), '?'); - /* - * Skip over deleted recipients. - */ - if (*cp == BOUNCE_LOG_STAT_DELETED) { - state = SKIP; - continue; - } - - /* - * Save the first record offset of this logfile entry so that it can - * be marked as deleted. - */ - if (state == START) { + if (state == START) state = FOUND; - bp->offset = offset; - } /* * New style logfile entries are in "name = value" format. @@ -313,6 +290,8 @@ BOUNCE_LOG *bounce_log_read(BOUNCE_LOG *bp) } else if (STREQ(name, MAIL_ATTR_ORCPT)) { bp->orig_rcpt = STR(vstring_strcpy(bp->orcp_buf, *value ? value : "(MAILER-DAEMON)")); + } else if (STREQ(name, MAIL_ATTR_OFFSET)) { + bp->rcpt_offset = atol(value); } else if (STREQ(name, MAIL_ATTR_STATUS)) { bp->dsn_status = STR(vstring_strcpy(bp->status_buf, value)); } else if (STREQ(name, MAIL_ATTR_ACTION)) { @@ -364,37 +343,22 @@ BOUNCE_LOG *bounce_log_read(BOUNCE_LOG *bp) return (0); } -/* bounce_log_delrcpt - mark recipient record as deleted */ - -BOUNCE_LOG *bounce_log_delrcpt(BOUNCE_LOG *bp) -{ - long current_offset; - - current_offset = vstream_ftell(bp->fp); - if (vstream_fseek(bp->fp, bp->offset, SEEK_SET) < 0) - msg_fatal("bounce logfile %s seek error: %m", VSTREAM_PATH(bp->fp)); - VSTREAM_PUTC(BOUNCE_LOG_STAT_DELETED, bp->fp); - if (vstream_fseek(bp->fp, current_offset, SEEK_SET) < 0) - msg_fatal("bounce logfile %s seek error: %m", VSTREAM_PATH(bp->fp)); - return (bp); -} - /* bounce_log_forge - forge one recipient status record */ BOUNCE_LOG *bounce_log_forge(const char *orig_rcpt, const char *recipient, - const char *dsn_status, const char *dsn_action, - const char *text) + long rcpt_offset, const char *dsn_status, + const char *dsn_action, const char *text) { return (bounce_log_init((VSTREAM *) 0, (VSTRING *) 0, SAVE_TO_VSTRING(orig_rcpt), SAVE_TO_VSTRING(recipient), + rcpt_offset, SAVE_TO_VSTRING(dsn_status), "(unavailable)", SAVE_TO_VSTRING(dsn_action), "(unavailable)", - SAVE_TO_VSTRING(text), - 0)); + SAVE_TO_VSTRING(text))); } /* bounce_log_close - close bounce reader stream */ diff --git a/postfix/src/global/bounce_log.h b/postfix/src/global/bounce_log.h index e09da9bac..916298207 100644 --- a/postfix/src/global/bounce_log.h +++ b/postfix/src/global/bounce_log.h @@ -34,22 +34,20 @@ typedef struct { /* Public. */ const char *recipient; /* final recipient */ const char *orig_rcpt; /* original recipient */ + long rcpt_offset; /* queue file offset */ const char *dsn_status; /* dsn code */ const char *dsn_action; /* dsn action */ const char *text; /* descriptive text */ - long offset; /* start of current record */ } BOUNCE_LOG; extern BOUNCE_LOG *bounce_log_open(const char *, const char *, int, int); extern BOUNCE_LOG *bounce_log_read(BOUNCE_LOG *); extern BOUNCE_LOG *bounce_log_delrcpt(BOUNCE_LOG *); -extern BOUNCE_LOG *bounce_log_forge(const char *, const char *, const char *, const char *, const char *); +extern BOUNCE_LOG *bounce_log_forge(const char *, const char *, long, const char *, const char *, const char *); extern int bounce_log_close(BOUNCE_LOG *); #define bounce_log_rewind(bp) vstream_fseek((bp)->fp, 0L, SEEK_SET) -#define BOUNCE_LOG_STAT_DELETED 'D' /* deleted record */ - /* LICENSE /* .ad /* .fi diff --git a/postfix/src/global/defer.c b/postfix/src/global/defer.c index 974eaaadf..619a1d441 100644 --- a/postfix/src/global/defer.c +++ b/postfix/src/global/defer.c @@ -6,22 +6,24 @@ /* SYNOPSIS /* #include /* -/* int defer_append(flags, id, orig_rcpt, recipient, relay, +/* int defer_append(flags, id, orig_rcpt, recipient, offset, relay, /* entry, format, ...) /* int flags; /* const char *id; /* const char *orig_rcpt; /* const char *recipient; +/* long offset; /* const char *relay; /* time_t entry; /* const char *format; /* -/* int vdefer_append(flags, id, orig_rcpt, recipient, relay, +/* int vdefer_append(flags, id, orig_rcpt, recipient, offset, relay, /* entry, format, ap) /* int flags; /* const char *id; /* const char *orig_rcpt; /* const char *recipient; +/* long offset; /* const char *relay; /* time_t entry; /* const char *format; @@ -90,6 +92,8 @@ /* .IP recipient /* A recipient address that is being deferred. The domain part /* of the address is marked dead (for a limited amount of time). +/* .IP offset +/* Queue file offset of recipient record. /* .IP encoding /* The body content encoding: MAIL_ATTR_ENC_{7BIT,8BIT,NONE}. /* .IP sender @@ -154,7 +158,7 @@ /* defer_append - defer message delivery */ int defer_append(int flags, const char *id, const char *orig_rcpt, - const char *recipient, const char *relay, + const char *recipient, long offset, const char *relay, time_t entry, const char *fmt,...) { va_list ap; @@ -162,7 +166,7 @@ int defer_append(int flags, const char *id, const char *orig_rcpt, va_start(ap, fmt); status = vdefer_append(flags, id, orig_rcpt, recipient, - relay, entry, fmt, ap); + offset, relay, entry, fmt, ap); va_end(ap); return (status); } @@ -170,7 +174,7 @@ int defer_append(int flags, const char *id, const char *orig_rcpt, /* vdefer_append - defer delivery of queue file */ int vdefer_append(int flags, const char *id, const char *orig_rcpt, - const char *recipient, const char *relay, + const char *recipient, long offset, const char *relay, time_t entry, const char *fmt, va_list ap) { const char *rcpt_domain; @@ -212,6 +216,7 @@ int vdefer_append(int flags, const char *id, const char *orig_rcpt, ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id, ATTR_TYPE_STR, MAIL_ATTR_ORCPT, orig_rcpt, ATTR_TYPE_STR, MAIL_ATTR_RECIP, recipient, + ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, offset, ATTR_TYPE_STR, MAIL_ATTR_STATUS, "4.0.0", ATTR_TYPE_STR, MAIL_ATTR_ACTION, "delayed", ATTR_TYPE_STR, MAIL_ATTR_WHY, vstring_str(why), @@ -250,6 +255,8 @@ int vdefer_append(int flags, const char *id, const char *orig_rcpt, int defer_flush(int flags, const char *queue, const char *id, const char *encoding, const char *sender) { + flags |= BOUNCE_FLAG_DELRCPT; + if (mail_command_client(MAIL_CLASS_PRIVATE, var_defer_service, ATTR_TYPE_NUM, MAIL_ATTR_NREQ, BOUNCE_CMD_FLUSH, ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags, diff --git a/postfix/src/global/defer.h b/postfix/src/global/defer.h index 3bb8827f6..9e39ce2f4 100644 --- a/postfix/src/global/defer.h +++ b/postfix/src/global/defer.h @@ -26,10 +26,11 @@ /* * External interface. */ -extern int PRINTFLIKE(7, 8) defer_append(int, const char *, const char *, - const char *, const char *, time_t, +extern int PRINTFLIKE(8, 9) defer_append(int, const char *, + const char *, const char *, + long, const char *, time_t, const char *,...); -extern int vdefer_append(int, const char *, const char *, const char *, +extern int vdefer_append(int, const char *, const char *, const char *, long, const char *, time_t, const char *, va_list); extern int defer_flush(int, const char *, const char *, const char *, const char *); diff --git a/postfix/src/global/mail_params.c b/postfix/src/global/mail_params.c index 2662b1ade..aa81791d0 100644 --- a/postfix/src/global/mail_params.c +++ b/postfix/src/global/mail_params.c @@ -31,6 +31,7 @@ /* char *var_queue_dir; /* int var_use_limit; /* int var_idle_limit; +/* int var_event_drain; /* int var_bundle_rcpt; /* char *var_procname; /* int var_pid; @@ -189,6 +190,7 @@ char *var_daemon_dir; char *var_command_dir; char *var_queue_dir; int var_use_limit; +int var_event_drain; int var_idle_limit; int var_bundle_rcpt; char *var_procname; @@ -504,6 +506,7 @@ void mail_params_init() 0, }; static CONFIG_TIME_TABLE time_defaults[] = { + VAR_EVENT_DRAIN, DEF_EVENT_DRAIN, &var_event_drain, 1, 0, VAR_MAX_IDLE, DEF_MAX_IDLE, &var_idle_limit, 1, 0, VAR_IPC_TIMEOUT, DEF_IPC_TIMEOUT, &var_ipc_timeout, 1, 0, VAR_IPC_IDLE, DEF_IPC_IDLE, &var_ipc_idle_limit, 1, 0, diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index b35f5617b..3a035f14e 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -676,6 +676,14 @@ extern int var_use_limit; #define DEF_MAX_IDLE "100s" extern int var_idle_limit; + /* + * Any subsystem: default amount of time a mail subsystem waits for + * application events to drain. + */ +#define VAR_EVENT_DRAIN "application_event_drain_time" +#define DEF_EVENT_DRAIN "100s" +extern int var_event_drain; + /* * Any subsystem: default amount of time a mail subsystem keeps an internal * IPC connection before closing it because it is idle for too much time. diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index fa8a60f18..fb846d6fb 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change the patchlevel and the release date. Snapshots change the * release date only, unless they include the same bugfix as a patch release. */ -#define MAIL_RELEASE_DATE "20030919" +#define MAIL_RELEASE_DATE "20030920" #define VAR_MAIL_VERSION "mail_version" #define DEF_MAIL_VERSION "2.0.16-" MAIL_RELEASE_DATE diff --git a/postfix/src/global/sent.c b/postfix/src/global/sent.c index b2db87b85..15695ede2 100644 --- a/postfix/src/global/sent.c +++ b/postfix/src/global/sent.c @@ -6,22 +6,24 @@ /* SYNOPSIS /* #include /* -/* int sent(flags, queue_id, orig_rcpt, recipient, relay, +/* int sent(flags, queue_id, orig_rcpt, recipient, offset, relay, /* entry, format, ...) /* int flags; /* const char *queue_id; /* const char *orig_rcpt; /* const char *recipient; +/* long offset; /* const char *relay; /* time_t entry; /* const char *format; /* -/* int vsent(flags, queue_id, orig_rcpt, recipient, relay, +/* int vsent(flags, queue_id, orig_rcpt, recipient, offset, relay, /* entry, format, ap) /* int flags; /* const char *queue_id; /* const char *orig_rcpt; /* const char *recipient; +/* long offset; /* const char *relay; /* time_t entry; /* const char *format; @@ -57,6 +59,8 @@ /* specify a null string or a null pointer. /* .IP recipient /* The recipient address. +/* .IP offset +/* Queue file offset of the recipient record. /* .IP relay /* Name of the host we're talking to. /* .IP entry @@ -112,14 +116,15 @@ /* sent - log that a message was sent */ int sent(int flags, const char *id, const char *orig_rcpt, - const char *recipient, const char *relay, + const char *recipient, long offset, const char *relay, time_t entry, const char *fmt,...) { va_list ap; int status; va_start(ap, fmt); - status = vsent(flags, id, orig_rcpt, recipient, relay, entry, fmt, ap); + status = vsent(flags, id, orig_rcpt, recipient, + offset, relay, entry, fmt, ap); va_end(ap); return (status); } @@ -127,7 +132,7 @@ int sent(int flags, const char *id, const char *orig_rcpt, /* vsent - log that a message was sent */ int vsent(int flags, const char *id, const char *orig_rcpt, - const char *recipient, const char *relay, + const char *recipient, long offset, const char *relay, time_t entry, const char *fmt, va_list ap) { int status; @@ -163,7 +168,7 @@ int vsent(int flags, const char *id, const char *orig_rcpt, entry, "sent", fmt, ap); status = 0; } else { - status = defer_append(flags, id, orig_rcpt, recipient, + status = defer_append(flags, id, orig_rcpt, recipient, offset, relay, entry, "%s: %s service failed", id, var_trace_service); } diff --git a/postfix/src/global/sent.h b/postfix/src/global/sent.h index ce7d55950..d303449e6 100644 --- a/postfix/src/global/sent.h +++ b/postfix/src/global/sent.h @@ -27,10 +27,10 @@ */ #define SENT_FLAG_NONE (0) -extern int PRINTFLIKE(7, 8) sent(int, const char *, const char *, const char *, - const char *, time_t, const char *,...); -extern int vsent(int, const char *, const char *, const char *, const char *, - time_t, const char *, va_list); +extern int PRINTFLIKE(8, 9) sent(int, const char *, const char *, const char *, + long, const char *, time_t, const char *,...); +extern int vsent(int, const char *, const char *, const char *, long, + const char *, time_t, const char *, va_list); /* LICENSE /* .ad diff --git a/postfix/src/lmtp/lmtp_proto.c b/postfix/src/lmtp/lmtp_proto.c index e89de87f9..97b53690d 100644 --- a/postfix/src/lmtp/lmtp_proto.c +++ b/postfix/src/lmtp/lmtp_proto.c @@ -545,8 +545,9 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state) if (DEL_REQ_TRACE_ONLY(request->flags) && sent(DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, rcpt->orig_addr, - rcpt->address, session->namaddr, - request->arrival_time, "%s", + rcpt->address, rcpt->offset, + session->namaddr, request->arrival_time, + "%s", translit(resp->str, "\n", " ")) == 0) { if (request->flags & DEL_REQ_FLAG_SUCCESS) deliver_completed(state->src, rcpt->offset); @@ -601,7 +602,8 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state) if (rcpt->offset) { if (sent(DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, rcpt->orig_addr, - rcpt->address, session->namaddr, + rcpt->address, rcpt->offset, + session->namaddr, request->arrival_time, "%s", resp->str) == 0) { if (request->flags & DEL_REQ_FLAG_SUCCESS) diff --git a/postfix/src/lmtp/lmtp_trouble.c b/postfix/src/lmtp/lmtp_trouble.c index 4c2916e3d..84ce001e1 100644 --- a/postfix/src/lmtp/lmtp_trouble.c +++ b/postfix/src/lmtp/lmtp_trouble.c @@ -178,7 +178,7 @@ int lmtp_site_fail(LMTP_STATE *state, int code, char *format,...) continue; status = (soft_error ? defer_append : bounce_append) (DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, - rcpt->orig_addr, rcpt->address, + rcpt->orig_addr, rcpt->address, rcpt->offset, session ? session->namaddr : "none", request->arrival_time, "%s", vstring_str(why)); if (status == 0) { @@ -226,7 +226,7 @@ int lmtp_mesg_fail(LMTP_STATE *state, int code, char *format,...) continue; status = (LMTP_SOFT(code) ? defer_append : bounce_append) (DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, - rcpt->orig_addr, rcpt->address, + rcpt->orig_addr, rcpt->address, rcpt->offset, session->namaddr, request->arrival_time, "%s", vstring_str(why)); if (status == 0) { @@ -261,7 +261,7 @@ void lmtp_rcpt_fail(LMTP_STATE *state, int code, RECIPIENT *rcpt, va_start(ap, format); status = (LMTP_SOFT(code) ? vdefer_append : vbounce_append) (DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, - rcpt->orig_addr, rcpt->address, + rcpt->orig_addr, rcpt->address, rcpt->offset, session->namaddr, request->arrival_time, format, ap); va_end(ap); if (status == 0) { @@ -309,7 +309,7 @@ int lmtp_stream_except(LMTP_STATE *state, int code, char *description) state->status |= defer_append(DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, rcpt->orig_addr, rcpt->address, - session->namaddr, + rcpt->offset, session->namaddr, request->arrival_time, "%s", vstring_str(why)); } diff --git a/postfix/src/local/local.c b/postfix/src/local/local.c index d0f7cec23..6c8ac2460 100644 --- a/postfix/src/local/local.c +++ b/postfix/src/local/local.c @@ -573,6 +573,7 @@ static int local_deliver(DELIVER_REQUEST *rqst, char *service) forward_init(); state.msg_attr.orig_rcpt = rcpt->orig_addr; state.msg_attr.recipient = rcpt->address; + state.msg_attr.rcpt_offset = rcpt->offset; rcpt_stat = deliver_recipient(state, usr_attr); rcpt_stat |= forward_finish(rqst, state.msg_attr, rcpt_stat); if (rcpt_stat == 0 && (rqst->flags & DEL_REQ_FLAG_SUCCESS)) diff --git a/postfix/src/local/local.h b/postfix/src/local/local.h index 32ad86d02..a06a037ee 100644 --- a/postfix/src/local/local.h +++ b/postfix/src/local/local.h @@ -72,6 +72,7 @@ typedef struct DELIVER_ATTR { char *sender; /* taken from envelope */ char *orig_rcpt; /* from submission */ char *recipient; /* taken from resolver */ + long rcpt_offset; /* taken from resolver */ char *domain; /* recipient domain */ char *local; /* recipient full localpart */ char *user; /* recipient localpart, base name */ @@ -124,13 +125,15 @@ typedef struct LOCAL_STATE { #define BOUNCE_FLAGS(request) DEL_REQ_TRACE_FLAGS((request)->flags) #define BOUNCE_ATTR(attr) attr.queue_id, attr.orig_rcpt, attr.recipient, \ - attr.relay, attr.arrival_time + attr.rcpt_offset, attr.relay, \ + attr.arrival_time #define BOUNCE_ONE_ATTR(attr) attr.queue_name, attr.queue_id, attr.encoding, \ attr.sender, attr.orig_rcpt, \ - attr.recipient, attr.relay, \ - attr.arrival_time -#define SENT_ATTR(attr) attr.queue_id, attr.orig_rcpt, attr.recipient, \ + attr.recipient, attr.rcpt_offset, \ attr.relay, attr.arrival_time +#define SENT_ATTR(attr) attr.queue_id, attr.orig_rcpt, attr.recipient, \ + attr.rcpt_offset, attr.relay, \ + attr.arrival_time #define OPENED_ATTR(attr) attr.queue_id, attr.sender #define COPY_ATTR(attr) attr.sender, attr.orig_rcpt, attr.delivered, \ attr.fp diff --git a/postfix/src/nqmgr/qmgr_bounce.c b/postfix/src/nqmgr/qmgr_bounce.c index 8e12bf176..92196bdaa 100644 --- a/postfix/src/nqmgr/qmgr_bounce.c +++ b/postfix/src/nqmgr/qmgr_bounce.c @@ -68,8 +68,9 @@ void qmgr_bounce_recipient(QMGR_MESSAGE *message, QMGR_RCPT *recipient, va_start(ap, format); status = vbounce_append(message->tflags, message->queue_id, - recipient->orig_rcpt, recipient->address, "none", - message->arrival_time, format, ap); + recipient->orig_rcpt, recipient->address, + recipient->offset, "none", message->arrival_time, + format, ap); va_end(ap); if (status == 0) diff --git a/postfix/src/nqmgr/qmgr_defer.c b/postfix/src/nqmgr/qmgr_defer.c index c286ef3a2..0a70df54c 100644 --- a/postfix/src/nqmgr/qmgr_defer.c +++ b/postfix/src/nqmgr/qmgr_defer.c @@ -160,5 +160,6 @@ void qmgr_defer_recipient(QMGR_MESSAGE *message, QMGR_RCPT *recipient, */ message->flags |= defer_append(message->tflags, message->queue_id, recipient->orig_rcpt, recipient->address, - "none", message->arrival_time, "%s", reason); + recipient->offset, "none", + message->arrival_time, "%s", reason); } diff --git a/postfix/src/nqmgr/qmgr_message.c b/postfix/src/nqmgr/qmgr_message.c index 74b5ab639..b2951133c 100644 --- a/postfix/src/nqmgr/qmgr_message.c +++ b/postfix/src/nqmgr/qmgr_message.c @@ -863,8 +863,9 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message) if (strncasecmp(STR(reply.recipient), var_double_bounce_sender, len) == 0 && !var_double_bounce_sender[len]) { - status = sent(message->tflags, message->queue_id, recipient->orig_rcpt, - recipient->address, "none", message->arrival_time, + status = sent(message->tflags, message->queue_id, + recipient->orig_rcpt, recipient->address, + recipient->offset, "none", message->arrival_time, "undeliverable postmaster notification discarded"); if (status == 0) { deliver_completed(message->fp, recipient->offset); diff --git a/postfix/src/pipe/pipe.c b/postfix/src/pipe/pipe.c index e9840e8f0..92bf1e3b9 100644 --- a/postfix/src/pipe/pipe.c +++ b/postfix/src/pipe/pipe.c @@ -740,7 +740,7 @@ static int eval_command_status(int command_status, char *service, rcpt = request->rcpt_list.info + n; status = sent(DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, rcpt->orig_addr, - rcpt->address, service, + rcpt->address, rcpt->offset, service, request->arrival_time, "%s", request->nexthop); if (status == 0 && (request->flags & DEL_REQ_FLAG_SUCCESS)) deliver_completed(src, rcpt->offset); @@ -752,7 +752,7 @@ static int eval_command_status(int command_status, char *service, rcpt = request->rcpt_list.info + n; status = bounce_append(DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, rcpt->orig_addr, - rcpt->address, service, + rcpt->address, rcpt->offset, service, request->arrival_time, "%s", why); if (status == 0) deliver_completed(src, rcpt->offset); @@ -764,7 +764,7 @@ static int eval_command_status(int command_status, char *service, rcpt = request->rcpt_list.info + n; result |= defer_append(DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, rcpt->orig_addr, - rcpt->address, service, + rcpt->address, rcpt->offset, service, request->arrival_time, "%s", why); } break; @@ -885,7 +885,7 @@ static int deliver_message(DELIVER_REQUEST *request, char *service, char **argv) rcpt = request->rcpt_list.info + n; status = sent(DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, rcpt->orig_addr, - rcpt->address, service, + rcpt->address, rcpt->offset, service, request->arrival_time, "delivers to command: %s", attr.command[0]); if (status == 0 && (request->flags & DEL_REQ_FLAG_SUCCESS)) diff --git a/postfix/src/postkick/postkick.c b/postfix/src/postkick/postkick.c index a4066a96a..e63256883 100644 --- a/postfix/src/postkick/postkick.c +++ b/postfix/src/postkick/postkick.c @@ -165,7 +165,7 @@ int main(int argc, char **argv) class, service); exit(1); } else { - event_drain(); + event_drain(var_event_drain); exit(0); } } diff --git a/postfix/src/qmgr/qmgr_bounce.c b/postfix/src/qmgr/qmgr_bounce.c index 15d59e07c..284342d6d 100644 --- a/postfix/src/qmgr/qmgr_bounce.c +++ b/postfix/src/qmgr/qmgr_bounce.c @@ -63,8 +63,9 @@ void qmgr_bounce_recipient(QMGR_MESSAGE *message, QMGR_RCPT *recipient, va_start(ap, format); status = vbounce_append(message->tflags, message->queue_id, - recipient->orig_rcpt, recipient->address, "none", - message->arrival_time, format, ap); + recipient->orig_rcpt, recipient->address, + recipient->offset, "none", message->arrival_time, + format, ap); va_end(ap); if (status == 0) diff --git a/postfix/src/qmgr/qmgr_defer.c b/postfix/src/qmgr/qmgr_defer.c index 60fccd8dc..405a7f476 100644 --- a/postfix/src/qmgr/qmgr_defer.c +++ b/postfix/src/qmgr/qmgr_defer.c @@ -155,5 +155,6 @@ void qmgr_defer_recipient(QMGR_MESSAGE *message, QMGR_RCPT *recipient, */ message->flags |= defer_append(message->tflags, message->queue_id, recipient->orig_rcpt, recipient->address, - "none", message->arrival_time, "%s", reason); + recipient->offset, "none", + message->arrival_time, "%s", reason); } diff --git a/postfix/src/qmgr/qmgr_message.c b/postfix/src/qmgr/qmgr_message.c index 6ed6e62a0..a860e384c 100644 --- a/postfix/src/qmgr/qmgr_message.c +++ b/postfix/src/qmgr/qmgr_message.c @@ -819,8 +819,9 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message) if (strncasecmp(STR(reply.recipient), var_double_bounce_sender, len) == 0 && !var_double_bounce_sender[len]) { - status = sent(message->tflags, message->queue_id, recipient->orig_rcpt, - recipient->address, "none", message->arrival_time, + status = sent(message->tflags, message->queue_id, + recipient->orig_rcpt, recipient->address, + recipient->offset, "none", message->arrival_time, "undeliverable postmaster notification discarded"); if (status == 0) { deliver_completed(message->fp, recipient->offset); diff --git a/postfix/src/smtp/smtp_proto.c b/postfix/src/smtp/smtp_proto.c index 58811a350..53fcd9e44 100644 --- a/postfix/src/smtp/smtp_proto.c +++ b/postfix/src/smtp/smtp_proto.c @@ -657,8 +657,9 @@ int smtp_xfer(SMTP_STATE *state) if (DEL_REQ_TRACE_ONLY(request->flags) && sent(DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, rcpt->orig_addr, - rcpt->address, session->namaddr, - request->arrival_time, "%s", + rcpt->address, rcpt->offset, + session->namaddr, request->arrival_time, + "%s", translit(resp->str, "\n", " ")) == 0) { if (request->flags & DEL_REQ_FLAG_SUCCESS) deliver_completed(state->src, rcpt->offset); @@ -720,7 +721,7 @@ int smtp_xfer(SMTP_STATE *state) if (rcpt->offset) { if (sent(DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, rcpt->orig_addr, - rcpt->address, + rcpt->address, rcpt->offset, session->namaddr, request->arrival_time, "%s", resp->str) == 0) { diff --git a/postfix/src/smtp/smtp_trouble.c b/postfix/src/smtp/smtp_trouble.c index 6269c7c4f..e945fddc4 100644 --- a/postfix/src/smtp/smtp_trouble.c +++ b/postfix/src/smtp/smtp_trouble.c @@ -167,7 +167,7 @@ int smtp_site_fail(SMTP_STATE *state, int code, char *format,...) continue; status = (soft_error ? defer_append : bounce_append) (DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, - rcpt->orig_addr, rcpt->address, + rcpt->orig_addr, rcpt->address, rcpt->offset, session ? session->namaddr : "none", request->arrival_time, "%s", vstring_str(why)); if (status == 0) { @@ -215,7 +215,7 @@ int smtp_mesg_fail(SMTP_STATE *state, int code, char *format,...) continue; status = (SMTP_SOFT(code) ? defer_append : bounce_append) (DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, - rcpt->orig_addr, rcpt->address, + rcpt->orig_addr, rcpt->address, rcpt->offset, session->namaddr, request->arrival_time, "%s", vstring_str(why)); if (status == 0) { @@ -250,7 +250,7 @@ void smtp_rcpt_fail(SMTP_STATE *state, int code, RECIPIENT *rcpt, va_start(ap, format); status = (SMTP_SOFT(code) ? vdefer_append : vbounce_append) (DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, - rcpt->orig_addr, rcpt->address, + rcpt->orig_addr, rcpt->address, rcpt->offset, session->namaddr, request->arrival_time, format, ap); va_end(ap); if (status == 0) { @@ -298,7 +298,7 @@ int smtp_stream_except(SMTP_STATE *state, int code, char *description) state->status |= defer_append(DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, rcpt->orig_addr, rcpt->address, - session->namaddr, + rcpt->offset, session->namaddr, request->arrival_time, "%s", vstring_str(why)); } diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c index fca8a3178..1de124730 100644 --- a/postfix/src/smtpd/smtpd_check.c +++ b/postfix/src/smtpd/smtpd_check.c @@ -2239,7 +2239,7 @@ static int check_server_access(SMTPD_STATE *state, const char *table, } if (dns_status != DNS_OK) { msg_warn("Unable to look up %s host for %s", dns_strtype(type), - domain && domain[1] ? domain : reply_name); + domain && domain[1] ? domain : name); return (SMTPD_CHECK_DUNNO); } diff --git a/postfix/src/util/dict_ldap.c b/postfix/src/util/dict_ldap.c index e1c4bca74..ad77b9c9f 100644 --- a/postfix/src/util/dict_ldap.c +++ b/postfix/src/util/dict_ldap.c @@ -34,7 +34,7 @@ /* .PP /* Configuration parameters: /* .IP server_host -/* Blank-separated list of hosts at which all LDAP queries are directed. +/* List of hosts at which all LDAP queries are directed. /* The host names can also be LDAP URLs if the LDAP client library used /* is OpenLDAP. /* .IP server_port @@ -670,7 +670,11 @@ static void dict_ldap_conn_find(DICT_LDAP *dict_ldap) VSTRING *keybuf = vstring_alloc(10); char *key; int len; + +#ifdef LDAP_API_FEATURE_X_OPENLDAP int sslon = dict_ldap->start_tls || dict_ldap->ldap_ssl; + +#endif LDAP_CONN *conn; #define ADDSTR(vp, s) vstring_memcat((vp), (s), strlen((s))+1) @@ -1252,13 +1256,9 @@ DICT *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags) { char *myname = "dict_ldap_open"; DICT_LDAP *dict_ldap; - -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(LDAP_OPT_NETWORK_TIMEOUT) VSTRING *url_list; - char *s, - *h; - -#endif + char *s; + char *h; char *server_host; CFG_PARSER parser; char *domainlist; @@ -1326,15 +1326,18 @@ DICT *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags) dict_ldap->version = LDAP_VERSION2; } -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(LDAP_OPT_NETWORK_TIMEOUT) +#if defined(LDAP_API_FEATURE_X_OPENLDAP) + dict_ldap->ldap_ssl = 0; +#endif - /* - * Convert (host, port) pairs to LDAP URLs - */ url_list = vstring_alloc(32); s = server_host; - dict_ldap->ldap_ssl = 0; - while ((h = mystrtok(&s, " \t")) != NULL) { + while ((h = mystrtok(&s, " \t\n\r,")) != NULL) { +#if defined(LDAP_API_FEATURE_X_OPENLDAP) + + /* + * Convert (host, port) pairs to LDAP URLs + */ if (ldap_is_ldap_url(h)) { LDAPURLDesc *url_desc; int rc; @@ -1361,21 +1364,24 @@ DICT *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags) vstring_sprintf_append(url_list, " ldap://%s:%d", h, dict_ldap->server_port); } +#else + vstring_sprintf_append(url_list, " %s", h); +#endif } dict_ldap->server_host = mystrdup(vstring_str(url_list) + 1); +#if defined(LDAP_API_FEATURE_X_OPENLDAP) + /* * With URL scheme, clear port to normalize connection cache key */ - dict_ldap->server_port = 0; + dict_ldap->server_port = LDAP_PORT; if (msg_verbose) msg_info("%s: %s server_host URL is %s", myname, ldapsource, dict_ldap->server_host); +#endif myfree(server_host); vstring_free(url_list); -#else - dict_ldap->server_host = server_host; -#endif /* * Scope handling thanks to Carsten Hoeger of SuSE. diff --git a/postfix/src/util/events.c b/postfix/src/util/events.c index 99e126956..25af73f47 100644 --- a/postfix/src/util/events.c +++ b/postfix/src/util/events.c @@ -33,7 +33,8 @@ /* void event_disable_readwrite(fd) /* int fd; /* -/* void event_drain() +/* void event_drain(time_limit) +/* int time_limit; /* DESCRIPTION /* This module delivers I/O and timer events. /* Multiple I/O streams and timers can be monitored simultaneously. @@ -102,8 +103,9 @@ /* I/O event requests. /* /* event_drain() repeatedly calls event_loop() until no more timer -/* events or I/O events are pending. This routine must not be called -/* from an event_whatever() callback routine. +/* events or I/O events are pending or until the time limit is reached. +/* This routine must not be called from an event_whatever() callback +/* routine. /* DIAGNOSTICS /* Panics: interface violations. Fatal errors: out of memory, /* system call failure. Warnings: the number of available @@ -250,17 +252,20 @@ time_t event_time(void) /* event_drain - loop until all pending events are done */ -void event_drain(void) +void event_drain(int time_limit) { fd_set zero_mask; + time_t max_time; if (EVENT_INIT_NEEDED()) return; FD_ZERO(&zero_mask); - while (event_timer_head.pred != event_timer_head.succ - || memcmp(&zero_mask, &event_xmask, sizeof(zero_mask)) != 0) - event_loop(-1); + max_time = event_present + time_limit; + while (event_present < max_time + && (event_timer_head.pred != event_timer_head.succ + || memcmp(&zero_mask, &event_xmask, sizeof(zero_mask)) != 0)) + event_loop(1); } /* event_enable_read - enable read events */ diff --git a/postfix/src/util/events.h b/postfix/src/util/events.h index d7235093b..7837a91da 100644 --- a/postfix/src/util/events.h +++ b/postfix/src/util/events.h @@ -29,7 +29,7 @@ extern void event_disable_readwrite(int); extern time_t event_request_timer(EVENT_NOTIFY_TIME, char *, int); extern int event_cancel_timer(EVENT_NOTIFY_TIME, char *); extern void event_loop(int); -extern void event_drain(void); +extern void event_drain(int); /* * Event codes. diff --git a/postfix/src/virtual/virtual.h b/postfix/src/virtual/virtual.h index 9145d5876..83c9e14fd 100644 --- a/postfix/src/virtual/virtual.h +++ b/postfix/src/virtual/virtual.h @@ -68,6 +68,7 @@ typedef struct DELIVER_ATTR { char *sender; /* taken from envelope */ char *orig_rcpt; /* taken from sender */ char *recipient; /* taken from resolver */ + long rcpt_offset; /* taken from resolver */ char *user; /* recipient lookup handle */ char *delivered; /* for loop detection */ char *relay; /* relay host */ @@ -96,9 +97,11 @@ typedef struct LOCAL_STATE { #define BOUNCE_FLAGS(request) DEL_REQ_TRACE_FLAGS((request)->flags) #define BOUNCE_ATTR(attr) attr.queue_id, attr.orig_rcpt, attr.recipient, \ - attr.relay, attr.arrival_time + attr.rcpt_offset, attr.relay, \ + attr.arrival_time #define SENT_ATTR(attr) attr.queue_id, attr.orig_rcpt, attr.recipient, \ - attr.relay, attr.arrival_time + attr.rcpt_offset, attr.relay, \ + attr.arrival_time #define COPY_ATTR(attr) attr.sender, attr.orig_rcpt, attr.delivered, \ attr.fp