From: Wietse Venema Date: Sun, 21 Dec 2003 05:00:00 +0000 (-0500) Subject: postfix-2.0.16-20031221 X-Git-Tag: v2.1-RC1-20040331~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=42f6ab4fc3120611ce3ee307690b3f3c2d2e7a4a;p=thirdparty%2Fpostfix.git postfix-2.0.16-20031221 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 04f7799dc..cccdfed8b 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -8871,13 +8871,18 @@ Apologies for any names omitted. between short queue ID and message status). File: showq/showq.c. -20031216-7 +20031216-20 Cleanup: the SMTP client now moves on to the next MX host or fallback relay when delivery fails in the middle of an - SMTP session. This includes not only broken connections - (easy) but also includes 4xx SMTP server replies (not easy). - Files: smtp/smtp.c, smtp/smtp_connect.c, smtp_trouble.c. + SMTP session. This includes both broken connections and + 4xx SMTP server replies. Files: smtp/smtp.c, smtp_rcpt.c, + smtp/smtp_connect.c, smtp_trouble.c. + + Configuration parameters: smtp_mx_address_limit (limit the + list of IP addresses from MX lookup), and smtp_mx_session_limit + (limit the number of actual SMTP sessions per delivery + attempt, ignoring unusable MX IP addresses). 20031217 @@ -8949,7 +8954,7 @@ Open problems: Low: postconf -e edits parameters that postconf won't list. - Low: while convering 8bit text to quoted-printable, perhaps + Low: while converting 8bit text to quoted-printable, perhaps use =46rom instead of >From. virtual_mailbox_path expression like forward_path, so that diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 8be73a9a4..162572466 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -22,12 +22,13 @@ snapshot release). Patches change the patchlevel and the release date. Snapshots change only the release date, unless they include the same bugfixes as a patch release. -Major changes with Postfix snapshot 2.0.16-20031217 +Major changes with Postfix snapshot 2.0.16-20031221 =================================================== The SMTP client now moves on to the next MX host (or fallback relay) when delivery fails in the middle of a session. This includes both -broken connections as well as 4XX replies to SMTP commands. +broken connections as well as 4XX replies to SMTP commands. Finally, +fallback_relay works as expected. Incompatible changes with Postfix snapshot 2.0.16-20031215 ========================================================== diff --git a/postfix/conf/sample-smtp.cf b/postfix/conf/sample-smtp.cf index 6812f14aa..5ea6fcffa 100644 --- a/postfix/conf/sample-smtp.cf +++ b/postfix/conf/sample-smtp.cf @@ -76,6 +76,23 @@ smtp_never_send_ehlo = no # smtp_defer_if_no_mx_address_found = no +# The smtp_mx_address_limit parameter limits the number of MX (mail +# exchanger) IP addresses that can result from DNS or host lookups. +# +# Specify zero to disable the limit. This is also the default. +# +smtp_mx_address_limit = 0 + +# The smtp_mx_session_limit parameter limits the number of SMTP +# sessions that the client will engage in, skipping over MX IP +# addresses that fail to complete the SMTP initial handshake. +# +# By default, Postfix SMTP client gives up after two SMTP sessions. +# +# Specify zero to disable the limit. +# +smtp_mx_session_limit = 2 + # The smtp_send_xforward_command parameter controls whether the Postfix # SMTP client will send an XFORWARD command to the SMTP server, when # the ESMTP HELO response of the remote host indicates XFORWARD support. diff --git a/postfix/html/smtp.8.html b/postfix/html/smtp.8.html index ddee21531..698d49086 100644 --- a/postfix/html/smtp.8.html +++ b/postfix/html/smtp.8.html @@ -244,29 +244,22 @@ SMTP(8) SMTP(8) smtp_mx_address_limit An upper bound on the number of MX (mail exchanger) - IP addresses that the SMTP client will try to con- - nect to, before giving up or sending the mail to a - fall-back relay host. + IP addresses that that can result from DNS or host + lookups. Specify zero to disable the limit. + Note: by default, equal preference MX addresses are + sorted into random order. + smtp_mx_session_limit An upper bound on the number of SMTP sessions that - the SMTP client will engage in before giving up or - sending the mail to a fall-back relay host. + the SMTP client will engage in per message delivery + (ignoring MX IP addresses that fail to complete the + SMTP initial handshake). Specify zero to disable the limit. - smtp_backup_on_soft_error - The types of recoverable error that qualify for - sending a recipient to a backup mail server or to a - fall-back relay host. Specify zero or more of ses- - sion (SMTP handshake failure, connection loss), - message (failure of MAIL FROM, DATA or "."), or - recipient (failure of RCPT TO). - - Recipients that do not qualify are deferred. - Timeout controls The default time unit is seconds; an explicit time unit can be specified by appending a one-letter suffix to the diff --git a/postfix/man/man8/smtp.8 b/postfix/man/man8/smtp.8 index 73af6be68..d06067d7d 100644 --- a/postfix/man/man8/smtp.8 +++ b/postfix/man/man8/smtp.8 @@ -205,24 +205,18 @@ The default limit is taken from the \fBdefault_destination_recipient_limit\fR parameter. .IP \fBsmtp_mx_address_limit\fR An upper bound on the number of MX (mail exchanger) IP addresses -that the SMTP client will try to connect to, before giving up or -sending the mail to a fall-back relay host. +that that can result from DNS or host lookups. .sp Specify zero to disable the limit. +.sp +Note: by default, equal preference MX addresses are sorted into +random order. .IP \fBsmtp_mx_session_limit\fR -An upper bound on the number of SMTP sessions that the SMTP client -will engage in before giving up or sending the mail to a fall-back -relay host. +An upper bound on the number of SMTP sessions that the SMTP +client will engage in per message delivery (ignoring MX IP +addresses that fail to complete the SMTP initial handshake). .sp Specify zero to disable the limit. -.IP \fBsmtp_backup_on_soft_error\fR -The types of recoverable error that qualify for sending a -recipient to a backup mail server or to a fall-back relay host. -Specify zero or more of \fBsession\fR (SMTP handshake failure, -connection loss), \fBmessage\fR (failure of MAIL FROM, DATA or -"."), or \fBrecipient\fR (failure of RCPT TO). -.sp -Recipients that do not qualify are deferred. .SH "Timeout controls" .ad .fi diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 7dafb2fdd..7c976429c 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -180,15 +180,6 @@ extern bool var_disable_dns; #define DEF_SMTP_HOST_LOOKUP SMTP_HOST_LOOKUP_DNS extern int var_smtp_dns_lookup; -#define SMTP_BACKUP_SESSION "session" -#define SMTP_BACKUP_MESSAGE "message" -#define SMTP_BACKUP_RECIPIENT "recipient" - -#define VAR_SMTP_BACKUP_MASK "smtp_backup_on_soft_error" -#define DEF_SMTP_BACKUP_MASK SMTP_BACKUP_SESSION \ - " " SMTP_BACKUP_MESSAGE \ - " " SMTP_BACKUP_RECIPIENT - #define VAR_SMTP_MXADDR_LIMIT "smtp_mx_address_limit" #define DEF_SMTP_MXADDR_LIMIT 0 extern int var_smtp_mxaddr_limit; diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 3b06fb7ca..6b875a530 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 "20031220" +#define MAIL_RELEASE_DATE "20031221" #define VAR_MAIL_VERSION "mail_version" #define DEF_MAIL_VERSION "2.0.16-" MAIL_RELEASE_DATE diff --git a/postfix/src/global/peer_name.c b/postfix/src/global/peer_name.c deleted file mode 100644 index 5e3affa5a..000000000 --- a/postfix/src/global/peer_name.c +++ /dev/null @@ -1,113 +0,0 @@ -/*++ -/* NAME -/* peer_name 3 -/* SUMMARY -/* produce printable peer name and address -/* SYNOPSIS -/* #include -/* -/* typedef struct { -/* .in +4 -/* int type; -/* char name; -/* char addr; -/* .in -4 -/* } PEER_NAME; -/* -/* PEER_NAME *peer_name(sock) -/* int sock; -/* DESCRIPTION -/* The \fIpeer_name\fR() routine attempts to produce a printable -/* version of the peer name and address of the specified socket. -/* The result is in static memory that will be overwritten. -/* Make a copy if the result is to be used for an appreciable -/* amount of time. -/* -/* Where information is unavailable, the name and/or address -/* are set to "unknown". -/* The \fItype\fR result field specifies how the name and address -/* should be interpreted: -/* .IP PEER_TYPE_INET -/* The socket specifies a TCP/IP endpoint. -/* The result is a hostname (from the DNS, a local hosts file or -/* other); the address a dotted quad. -/* .IP PEER_TYPE_LOCAL -/* The socket argument specifies a local transport. -/* The result name is "localhost"; the result address is "127.0.0.1". -/* .IP PEER_TYPE_UNKNOWN -/* The socket argument does not specify a socket. -/* The result name is "localhost"; the result address is "127.0.0.1". -/* LICENSE -/* .ad -/* .fi -/* The Secure Mailer license must be distributed with this software. -/* AUTHOR(S) -/* Wietse Venema -/* IBM T.J. Watson Research -/* P.O. Box 704 -/* Yorktown Heights, NY 10598, USA -/*--*/ - -/* System library. */ - -#include -#include -#include -#include -#include -#include -#include - -/* Utility library. */ - -#include -#include -#include - -/* peer_name - produce printable peer name and address */ - -PEER_NAME *peer_name(int sock) -{ - static PEER_NAME peer; - struct sockaddr_in sin; - SOCKADDR_SIZE len = sizeof(sin); - struct hostent *hp; - - if (getpeername(sock, (struct sockaddr *) & sin, &len) == 0) { - switch (sin.sin_family) { - case AF_INET: - peer.type = PEER_TYPE_INET; - hp = gethostbyaddr((char *) &(sin.sin_addr), - sizeof(sin.sin_addr), AF_INET); - peer.name = (hp && valid_hostname(hp->h_name, DO_GRIPE) ? - hp->h_name : "unknown"); - peer.addr = inet_ntoa(sin.sin_addr); - return (&peer); - case AF_UNSPEC: - case AF_UNIX: - peer.type = PEER_TYPE_LOCAL; - peer.name = "localhost"; - peer.addr = "127.0.0.1"; - return (&peer); - } - } - peer.type = PEER_TYPE_UNKNOWN; - peer.name = "localhost"; - peer.addr = "127.0.0.1"; - return (&peer); - -} - -#ifdef TEST - -#include - -int main(int unused_argc, char **unused_argv) -{ - PEER_NAME *peer; - - peer = peer_name(STDIN_FILENO); - msg_info("name %s addr %s", peer->name, peer->addr); -} - -#endif diff --git a/postfix/src/global/peer_name.h b/postfix/src/global/peer_name.h deleted file mode 100644 index f1c96374a..000000000 --- a/postfix/src/global/peer_name.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _PEER_NAME_H_INCLUDED_ -#define _PEER_NAME_H_INCLUDED_ - -/*++ -/* NAME -/* peer_name 3h -/* SUMMARY -/* produce printable peer name and address -/* SYNOPSIS -/* #include -/* DESCRIPTION - - /* - * External interface. - */ -typedef struct { - int type; /* IPC type, see below */ - char *name; /* peer official name */ - char *addr; /* peer address */ -} PEER_NAME; - -#define PEER_TYPE_UNKNOWN 0 -#define PEER_TYPE_INET 1 -#define PEER_TYPE_LOCAL 2 - -extern PEER_NAME *peer_name(int); - -/* LICENSE -/* .ad -/* .fi -/* The Secure Mailer license must be distributed with this software. -/* AUTHOR(S) -/* Wietse Venema -/* IBM T.J. Watson Research -/* P.O. Box 704 -/* Yorktown Heights, NY 10598, USA -/*--*/ - -#endif diff --git a/postfix/src/global/recipient_list.c b/postfix/src/global/recipient_list.c index 099e11887..c8fbca521 100644 --- a/postfix/src/global/recipient_list.c +++ b/postfix/src/global/recipient_list.c @@ -31,9 +31,6 @@ /* const char *orig_rcpt; /* const char *recipient; /* -/* void recipient_list_truncate(list) -/* RECIPIENT_LIST *list; -/* /* void recipient_list_free(list) /* RECIPIENT_LIST *list; /* DESCRIPTION @@ -51,9 +48,6 @@ /* recipient_list_add() adds a recipient to the specified list. /* The recipient address is copied with mystrdup(). /* -/* recipient_list_truncate() truncates the specified list to -/* the specified length. -/* /* recipient_list_free() releases memory for the specified list /* of recipient structures. /* @@ -82,7 +76,6 @@ /* System library. */ #include -#include /* Utility library. */ @@ -121,27 +114,15 @@ void recipient_list_add(RECIPIENT_LIST *list, long offset, list->len++; } -/* recipient_list_truncate - release memory for unused recipient structures */ +/* recipient_list_free - release memory for in-core recipient structure */ -void recipient_list_truncate(RECIPIENT_LIST *list, int new_len) +void recipient_list_free(RECIPIENT_LIST *list) { RECIPIENT *rcpt; - if (new_len < 0 || new_len > list->len) - msg_panic("recipient_list_truncate: bad length %d", new_len); - - for (rcpt = list->info + new_len; rcpt < list->info + list->len; rcpt++) { + for (rcpt = list->info; rcpt < list->info + list->len; rcpt++) { myfree(rcpt->orig_addr); myfree(rcpt->address); } - list->len = new_len; -} - -/* recipient_list_free - release memory for in-core recipient structure */ - -void recipient_list_free(RECIPIENT_LIST *list) -{ - if (list->len > 0) - recipient_list_truncate(list, 0); myfree((char *) list->info); } diff --git a/postfix/src/global/recipient_list.h b/postfix/src/global/recipient_list.h index b85752b18..ce40f69c8 100644 --- a/postfix/src/global/recipient_list.h +++ b/postfix/src/global/recipient_list.h @@ -32,7 +32,6 @@ typedef struct RECIPIENT_LIST { extern void recipient_list_init(RECIPIENT_LIST *); extern void recipient_list_add(RECIPIENT_LIST *, long, const char *, const char *); -extern void recipient_list_truncate(RECIPIENT_LIST *, int); extern void recipient_list_free(RECIPIENT_LIST *); /* LICENSE diff --git a/postfix/src/lmtp/Makefile.in b/postfix/src/lmtp/Makefile.in index baf5db8d4..a095dfb79 100644 --- a/postfix/src/lmtp/Makefile.in +++ b/postfix/src/lmtp/Makefile.in @@ -146,6 +146,7 @@ lmtp_proto.o: ../../include/vstream.h lmtp_proto.o: ../../include/vstring_vstream.h lmtp_proto.o: ../../include/stringops.h lmtp_proto.o: ../../include/mymalloc.h +lmtp_proto.o: ../../include/name_code.h lmtp_proto.o: ../../include/mail_params.h lmtp_proto.o: ../../include/smtp_stream.h lmtp_proto.o: ../../include/mail_queue.h diff --git a/postfix/src/smtp/Makefile.in b/postfix/src/smtp/Makefile.in index 529e8e337..771e3c0bb 100644 --- a/postfix/src/smtp/Makefile.in +++ b/postfix/src/smtp/Makefile.in @@ -1,9 +1,9 @@ SHELL = /bin/sh SRCS = smtp.c smtp_connect.c smtp_proto.c smtp_chat.c smtp_session.c \ - smtp_addr.c smtp_trouble.c smtp_state.c smtp_misc.c \ + smtp_addr.c smtp_trouble.c smtp_state.c smtp_rcpt.c \ smtp_sasl_proto.c smtp_sasl_glue.c OBJS = smtp.o smtp_connect.o smtp_proto.o smtp_chat.o smtp_session.o \ - smtp_addr.o smtp_trouble.o smtp_state.o smtp_misc.o \ + smtp_addr.o smtp_trouble.o smtp_state.o smtp_rcpt.o \ smtp_sasl_proto.o smtp_sasl_glue.o HDRS = smtp.h smtp_sasl.h TESTSRC = @@ -144,18 +144,6 @@ smtp_connect.o: ../../include/dns.h smtp_connect.o: smtp.h smtp_connect.o: ../../include/argv.h smtp_connect.o: smtp_addr.h -smtp_misc.o: smtp_misc.c -smtp_misc.o: ../../include/sys_defs.h -smtp_misc.o: ../../include/msg.h -smtp_misc.o: ../../include/deliver_request.h -smtp_misc.o: ../../include/vstring.h -smtp_misc.o: ../../include/vbuf.h -smtp_misc.o: ../../include/vstream.h -smtp_misc.o: ../../include/recipient_list.h -smtp_misc.o: ../../include/deliver_completed.h -smtp_misc.o: ../../include/sent.h -smtp_misc.o: smtp.h -smtp_misc.o: ../../include/argv.h smtp_proto.o: smtp_proto.c smtp_proto.o: ../../include/sys_defs.h smtp_proto.o: ../../include/msg.h @@ -188,6 +176,18 @@ smtp_proto.o: ../../include/header_opts.h smtp_proto.o: smtp.h smtp_proto.o: ../../include/argv.h smtp_proto.o: smtp_sasl.h +smtp_rcpt.o: smtp_rcpt.c +smtp_rcpt.o: ../../include/sys_defs.h +smtp_rcpt.o: ../../include/msg.h +smtp_rcpt.o: ../../include/deliver_request.h +smtp_rcpt.o: ../../include/vstring.h +smtp_rcpt.o: ../../include/vbuf.h +smtp_rcpt.o: ../../include/vstream.h +smtp_rcpt.o: ../../include/recipient_list.h +smtp_rcpt.o: ../../include/deliver_completed.h +smtp_rcpt.o: ../../include/sent.h +smtp_rcpt.o: smtp.h +smtp_rcpt.o: ../../include/argv.h smtp_sasl_glue.o: smtp_sasl_glue.c smtp_sasl_glue.o: ../../include/sys_defs.h smtp_sasl_glue.o: ../../include/msg.h diff --git a/postfix/src/smtp/smtp.c b/postfix/src/smtp/smtp.c index 670921fc1..87f5262f8 100644 --- a/postfix/src/smtp/smtp.c +++ b/postfix/src/smtp/smtp.c @@ -189,24 +189,18 @@ /* \fBdefault_destination_recipient_limit\fR parameter. /* .IP \fBsmtp_mx_address_limit\fR /* An upper bound on the number of MX (mail exchanger) IP addresses -/* that the SMTP client will try to connect to, before giving up or -/* sending the mail to a fall-back relay host. +/* that that can result from DNS or host lookups. /* .sp /* Specify zero to disable the limit. +/* .sp +/* Note: by default, equal preference MX addresses are sorted into +/* random order. /* .IP \fBsmtp_mx_session_limit\fR -/* An upper bound on the number of SMTP sessions that the SMTP client -/* will engage in before giving up or sending the mail to a fall-back -/* relay host. +/* An upper bound on the number of SMTP sessions that the SMTP +/* client will engage in per message delivery (ignoring MX IP +/* addresses that fail to complete the SMTP initial handshake). /* .sp /* Specify zero to disable the limit. -/* .IP \fBsmtp_backup_on_soft_error\fR -/* The types of recoverable error that qualify for sending a -/* recipient to a backup mail server or to a fall-back relay host. -/* Specify zero or more of \fBsession\fR (SMTP handshake failure, -/* connection loss), \fBmessage\fR (failure of MAIL FROM, DATA or -/* "."), or \fBrecipient\fR (failure of RCPT TO). -/* .sp -/* Recipients that do not qualify are deferred. /* .SH "Timeout controls" /* .ad /* .fi @@ -332,7 +326,6 @@ int var_smtp_pix_delay; int var_smtp_line_limit; char *var_smtp_helo_name; char *var_smtp_host_lookup; -char *var_smtp_backup_mask; bool var_smtp_quote_821_env; bool var_smtp_defer_mxaddr; bool var_smtp_send_xforward; @@ -345,7 +338,6 @@ int var_smtp_mxsess_limit; */ int smtp_errno; int smtp_host_lookup_mask; -int smtp_backup_mask; /* deliver_message - deliver message with extreme prejudice */ @@ -375,6 +367,7 @@ static int deliver_message(DELIVER_REQUEST *request) state = smtp_state_alloc(); state->request = request; state->src = request->fp; + SMTP_RCPT_INIT(state); /* * Establish an SMTP session and deliver this message to all requested @@ -420,21 +413,15 @@ static void smtp_service(VSTREAM *client_stream, char *unused_service, char **ar } } -/* post_init - post-jail initialization */ +/* pre_init - pre-jail initialization */ -static void post_init(char *unused_name, char **unused_argv) +static void pre_init(char *unused_name, char **unused_argv) { static NAME_MASK lookup_masks[] = { SMTP_HOST_LOOKUP_DNS, SMTP_MASK_DNS, SMTP_HOST_LOOKUP_NATIVE, SMTP_MASK_NATIVE, 0, }; - static NAME_MASK backup_masks[] = { - SMTP_BACKUP_SESSION, SMTP_BACKUP_SESSION_FAILURE, - SMTP_BACKUP_MESSAGE, SMTP_BACKUP_MESSAGE_FAILURE, - SMTP_BACKUP_RECIPIENT, SMTP_BACKUP_RECIPIENT_FAILURE, - 0, - }; /* * Turn on per-peer debugging. @@ -454,23 +441,6 @@ static void post_init(char *unused_name, char **unused_argv) str_name_mask(VAR_SMTP_HOST_LOOKUP, lookup_masks, smtp_host_lookup_mask)); - /* - * When to choose a backup host after a temporary failure. - */ - smtp_backup_mask = name_mask(VAR_SMTP_BACKUP_MASK, backup_masks, - var_smtp_backup_mask); - if (msg_verbose) - msg_info("when to try backup host: %s", - str_name_mask(VAR_SMTP_BACKUP_MASK, backup_masks, - smtp_backup_mask)); - -} - -/* pre_init - pre-jail initialization */ - -static void pre_init(char *unused_name, char **unused_argv) -{ - /* * SASL initialization. */ @@ -519,7 +489,6 @@ int main(int argc, char **argv) VAR_SMTP_BIND_ADDR, DEF_SMTP_BIND_ADDR, &var_smtp_bind_addr, 0, 0, VAR_SMTP_HELO_NAME, DEF_SMTP_HELO_NAME, &var_smtp_helo_name, 1, 0, VAR_SMTP_HOST_LOOKUP, DEF_SMTP_HOST_LOOKUP, &var_smtp_host_lookup, 1, 0, - VAR_SMTP_BACKUP_MASK, DEF_SMTP_BACKUP_MASK, &var_smtp_backup_mask, 0, 0, 0, }; static CONFIG_TIME_TABLE time_table[] = { @@ -564,7 +533,6 @@ int main(int argc, char **argv) MAIL_SERVER_STR_TABLE, str_table, MAIL_SERVER_BOOL_TABLE, bool_table, MAIL_SERVER_PRE_INIT, pre_init, - MAIL_SERVER_POST_INIT, post_init, MAIL_SERVER_PRE_ACCEPT, pre_accept, MAIL_SERVER_EXIT, pre_exit, 0); diff --git a/postfix/src/smtp/smtp.h b/postfix/src/smtp/smtp.h index 2d61c80f3..6dc6268b6 100644 --- a/postfix/src/smtp/smtp.h +++ b/postfix/src/smtp/smtp.h @@ -62,8 +62,9 @@ typedef struct SMTP_STATE { * session all recipients should be marked one way or the other. */ int final_server; /* final mail server */ - int drop_count; /* recipients marked as drop */ - int keep_count; /* recipients marked as keep */ + int rcpt_left; /* recipients left over */ + int rcpt_drop; /* recipients marked as drop */ + int rcpt_keep; /* recipients marked as keep */ } SMTP_STATE; /* @@ -81,47 +82,11 @@ typedef struct SMTP_STATE { #define SMTP_FEATURE_XFORWARD_PROTO (1<<9) #define SMTP_FEATURE_XFORWARD_HELO (1<<10) - /* - * Application-specific per-recipient status. At the end of each delivery - * attempt each recipient is marked as DROP (remove from recipient list) or - * KEEP (deliver to backup mail server). The ones marked DROP are deleted - * before trying to deliver the remainder to a backup server. There's a bit - * of redundcancy to ensure that all recipients are marked. - * - * The single recipient list abstraction dates from the time that the SMTP - * client would give up after one SMTP session, so that each recipient was - * either bounced, delivered or deferred. Implicitly, all recipients were - * marked as DROP. - * - * This abstraction is less convenient when an SMTP client must be able to - * deliver left-over recipients to a backup host. It might be more natural - * to have an input list with recipients to deliver, and an output list with - * the left-over recipients. - */ -#define SMTP_RCPT_KEEP 1 /* send to backup host */ -#define SMTP_RCPT_DROP 2 /* remove from request */ - -#define SMTP_RCPT_MARK_INIT(state) do { \ - (state)->drop_count = (state)->keep_count = 0; \ - } while (0) - -#define SMTP_RCPT_MARK_DROP(state, rcpt) do { \ - (rcpt)->status = SMTP_RCPT_DROP; (state)->drop_count++; \ - } while (0) - -#define SMTP_RCPT_MARK_KEEP(state, rcpt) do { \ - (rcpt)->status = SMTP_RCPT_KEEP; (state)->keep_count++; \ - } while (0) - -#define SMTP_RCPT_MARK_ISSET(rcpt) ((rcpt)->status != 0) - -extern int smtp_rcpt_mark_finish(SMTP_STATE *); - /* * smtp.c */ extern int smtp_errno; /* XXX can we get rid of this? */ - + #define SMTP_NONE 0 /* no error */ #define SMTP_FAIL 1 /* permanent error */ #define SMTP_RETRY 2 /* temporary error */ @@ -182,8 +147,29 @@ extern void smtp_chat_reset(SMTP_STATE *); extern void smtp_chat_notify(SMTP_STATE *); /* - * smtp_misc.c. + * These operations are extensively documented in smtp_rcpt.c */ +#define SMTP_RCPT_STATE_KEEP 1 /* send to backup host */ +#define SMTP_RCPT_STATE_DROP 2 /* remove from request */ + +#define SMTP_RCPT_INIT(state) do { \ + (state)->rcpt_drop = (state)->rcpt_keep = 0; \ + (state)->rcpt_left = state->request->rcpt_list.len; \ + } while (0) + +#define SMTP_RCPT_DROP(state, rcpt) do { \ + (rcpt)->status = SMTP_RCPT_STATE_DROP; (state)->rcpt_drop++; \ + } while (0) + +#define SMTP_RCPT_KEEP(state, rcpt) do { \ + (rcpt)->status = SMTP_RCPT_STATE_KEEP; (state)->rcpt_keep++; \ + } while (0) + +#define SMTP_RCPT_ISMARKED(rcpt) ((rcpt)->status != 0) + +#define SMTP_RCPT_LEFT(state) (state)->rcpt_left + +extern void smtp_rcpt_cleanup(SMTP_STATE *); extern void smtp_rcpt_done(SMTP_STATE *, const char *, RECIPIENT *); /* diff --git a/postfix/src/smtp/smtp_connect.c b/postfix/src/smtp/smtp_connect.c index 479974515..4f5a43d23 100644 --- a/postfix/src/smtp/smtp_connect.c +++ b/postfix/src/smtp/smtp_connect.c @@ -316,7 +316,7 @@ int smtp_connect(SMTP_STATE *state) * then is to build this into the pre-existing SMTP client without * getting lost in the complexity. */ - for (cpp = sites->argv; (dest = *cpp) != 0; cpp++) { + for (cpp = sites->argv; SMTP_RCPT_LEFT(state) > 0 && (dest = *cpp) != 0; cpp++) { state->final_server = (cpp[1] == 0); smtp_errno = SMTP_NONE; @@ -359,14 +359,14 @@ int smtp_connect(SMTP_STATE *state) * list. Unmark any left-over recipients and try to deliver them to a * backup mail server. */ - for (sess_count = addr_count = 0, addr = addr_list; addr; addr = next) { + sess_count = addr_count = 0; + for (addr = addr_list; SMTP_RCPT_LEFT(state) > 0 && addr; addr = next) { next = addr->next; if (++addr_count == var_smtp_mxaddr_limit) next = 0; if ((state->session = smtp_connect_addr(addr, port, why)) != 0) { if (++sess_count == var_smtp_mxsess_limit) next = 0; - SMTP_RCPT_MARK_INIT(state); state->final_server = (cpp[1] == 0 && next == 0); state->session->best = (addr->pref == addr_list->pref); debug_peer_check(state->session->host, state->session->addr); @@ -379,8 +379,7 @@ int smtp_connect(SMTP_STATE *state) /* XXX smtp_xfer() may abort in the middle of DATA. */ smtp_session_free(state->session); debug_peer_restore(); - if (smtp_rcpt_mark_finish(state) == 0) - break; + smtp_rcpt_cleanup(state); } else { msg_info("%s (port %d)", vstring_str(why), ntohs(port)); } @@ -395,7 +394,7 @@ int smtp_connect(SMTP_STATE *state) * Pay attention to what could be configuration problems, and pretend that * these are recoverable rather than bouncing the mail. */ - if (request->rcpt_list.len > 0) { + if (SMTP_RCPT_LEFT(state) > 0) { switch (smtp_errno) { default: @@ -430,6 +429,7 @@ int smtp_connect(SMTP_STATE *state) state->status = deliver_pass_all(MAIL_CLASS_PRIVATE, var_bestmx_transp, request); + SMTP_RCPT_LEFT(state) = 0; /* XXX */ break; } /* FALLTHROUGH */ @@ -440,9 +440,16 @@ int smtp_connect(SMTP_STATE *state) * We still need to bounce or defer some left-over recipients: * either mail loops or some backup mail server was unavailable. */ + state->final_server = 1; smtp_site_fail(state, smtp_errno == SMTP_RETRY ? 450 : 550, "%s", vstring_str(why)); - break; + + /* + * Sanity check. Don't silently lose recipients. + */ + smtp_rcpt_cleanup(state); + if (SMTP_RCPT_LEFT(state) > 0) + msg_panic("smtp_connect: left-over recipients"); } } diff --git a/postfix/src/smtp/smtp_misc.c b/postfix/src/smtp/smtp_misc.c deleted file mode 100644 index 509561db5..000000000 --- a/postfix/src/smtp/smtp_misc.c +++ /dev/null @@ -1,124 +0,0 @@ -/*++ -/* NAME -/* smtp_misc 3 -/* SUMMARY -/* assorted routines -/* SYNOPSIS -/* #include -/* -/* void smtp_rcpt_done(state, reply, rcpt) -/* SMTP_STATE *state; -/* const char *reply; -/* RECIPIENT *rcpt; -/* -/* int smtp_rcpt_mark_finish(SMTP_STATE *state) -/* SMTP_STATE *state; -/* DESCRIPTION -/* smtp_rcpt_done() logs that a recipient is completed and upon -/* success it marks the recipient as done in the queue file. -/* Finally, it marks the in-memory recipient as DROP. -/* -/* smtp_rcpt_mark_finish() cleans up the in-memory recipient list. -/* It deletes recipients marked DROP, and unmarks recipients marked KEEP. -/* It enforces the requirement that all recipients are marked one way -/* or the other. The result value is the number of left-over recipients. -/* DIAGNOSTICS -/* Panic: interface violation. -/* -/* When a recipient can't be logged as completed, the recipient is -/* logged as deferred instead. -/* LICENSE -/* .ad -/* .fi -/* The Secure Mailer license must be distributed with this software. -/* AUTHOR(S) -/* Wietse Venema -/* IBM T.J. Watson Research -/* P.O. Box 704 -/* Yorktown Heights, NY 10598, USA -/*--*/ - -/* System library. */ - -#include -#include /* smtp_rcpt_mark_finish */ - -/* Utility library. */ - -#include - -/* Global library. */ - -#include /* smtp_rcpt_done */ -#include /* smtp_rcpt_done */ -#include /* smtp_rcpt_done */ - -/* Application-specific. */ - -#include - -/* smtp_rcpt_done - mark recipient as done or else */ - -void smtp_rcpt_done(SMTP_STATE *state, const char *reply, RECIPIENT *rcpt) -{ - DELIVER_REQUEST *request = state->request; - SMTP_SESSION *session = state->session; - int status; - - /* - * Report success and delete the recipient from the delivery request. - * Defer if the success can't be reported. - */ - status = sent(DEL_REQ_TRACE_FLAGS(request->flags), - request->queue_id, rcpt->orig_addr, - rcpt->address, rcpt->offset, - session->namaddr, - request->arrival_time, - "%s", reply); - if (status == 0) - if (request->flags & DEL_REQ_FLAG_SUCCESS) - deliver_completed(state->src, rcpt->offset); - SMTP_RCPT_MARK_DROP(state, rcpt); - state->status |= status; -} - -/* smtp_rcpt_mark_finish_callback - qsort callback */ - -static int smtp_rcpt_mark_finish_callback(const void *a, const void *b) -{ - return (((RECIPIENT *) a)->status - ((RECIPIENT *) b)->status); -} - -/* smtp_rcpt_mark_finish - purge completed recipients from request */ - -int smtp_rcpt_mark_finish(SMTP_STATE *state) -{ - RECIPIENT_LIST *rcpt_list = &state->request->rcpt_list; - RECIPIENT *rcpt; - - /* - * Sanity checks. - */ - if (state->drop_count + state->keep_count != rcpt_list->len) - msg_panic("smtp_rcpt_mark_finish: recipient count mismatch: %d+%d!=%d", - state->drop_count, state->keep_count, rcpt_list->len); - - /* - * Recipients marked KEEP sort before recipients marked DROP. Skip the - * sorting in the common case that all recipients are marked the same. - */ - if (state->drop_count > 0 && state->keep_count > 0) - qsort((void *) rcpt_list->info, rcpt_list->len, - sizeof(rcpt_list->info), smtp_rcpt_mark_finish_callback); - - /* - * Truncate the recipient list and unmark the left-over recipients so - * that the result looks like a brand-new recipient list. - */ - if (state->keep_count < rcpt_list->len) - recipient_list_truncate(rcpt_list, state->keep_count); - for (rcpt = rcpt_list->info; rcpt < rcpt_list->info + rcpt_list->len; rcpt++) - rcpt->status = 0; - - return (rcpt_list->len); -} diff --git a/postfix/src/smtp/smtp_proto.c b/postfix/src/smtp/smtp_proto.c index 1d139b240..1b391caf8 100644 --- a/postfix/src/smtp/smtp_proto.c +++ b/postfix/src/smtp/smtp_proto.c @@ -434,10 +434,10 @@ int smtp_xfer(SMTP_STATE *state) /* * Sanity check. Recipients should be unmarked at this point. */ - if (request->rcpt_list.len <= 0) + if (SMTP_RCPT_LEFT(state) <= 0) msg_panic("smtp_xfer: bad recipient count: %d", - request->rcpt_list.len); - if (SMTP_RCPT_MARK_ISSET(request->rcpt_list.info)) + SMTP_RCPT_LEFT(state)); + if (SMTP_RCPT_ISMARKED(request->rcpt_list.info)) msg_panic("smtp_xfer: bad recipient status: %d", request->rcpt_list.info->status); @@ -616,7 +616,7 @@ int smtp_xfer(SMTP_STATE *state) QUOTE_ADDRESS(state->scratch, rcpt->address); vstring_sprintf(next_command, "RCPT TO:<%s>", vstring_str(state->scratch)); - if ((next_rcpt = send_rcpt + 1) == request->rcpt_list.len) + if ((next_rcpt = send_rcpt + 1) == SMTP_RCPT_LEFT(state)) next_state = DEL_REQ_TRACE_ONLY(request->flags) ? SMTP_STATE_ABORT : SMTP_STATE_DATA; break; @@ -779,7 +779,7 @@ int smtp_xfer(SMTP_STATE *state) } } /* If trace-only, send RSET instead of DATA. */ - if (++recv_rcpt == request->rcpt_list.len) + if (++recv_rcpt == SMTP_RCPT_LEFT(state)) recv_state = DEL_REQ_TRACE_ONLY(request->flags) ? SMTP_STATE_ABORT : SMTP_STATE_DATA; break; @@ -822,7 +822,7 @@ int smtp_xfer(SMTP_STATE *state) } else { for (nrcpt = 0; nrcpt < recv_rcpt; nrcpt++) { rcpt = request->rcpt_list.info + nrcpt; - if (!SMTP_RCPT_MARK_ISSET(rcpt)) + if (!SMTP_RCPT_ISMARKED(rcpt)) smtp_rcpt_done(state, resp->str, rcpt); } } diff --git a/postfix/src/smtp/smtp_rcpt.c b/postfix/src/smtp/smtp_rcpt.c new file mode 100644 index 000000000..8aa732edc --- /dev/null +++ b/postfix/src/smtp/smtp_rcpt.c @@ -0,0 +1,182 @@ +/*++ +/* NAME +/* smtp_rcpt 3 +/* SUMMARY +/* application-specific recipient list operations +/* SYNOPSIS +/* #include +/* +/* SMTP_RCPT_INIT(state) +/* SMTP_STATE *state; +/* +/* SMTP_RCPT_DROP(state, rcpt) +/* SMTP_STATE *state; +/* RECIPIENT *rcpt; +/* +/* SMTP_RCPT_KEEP(state, rcpt) +/* SMTP_STATE *state; +/* RECIPIENT *rcpt; +/* +/* SMTP_RCPT_ISMARKED(rcpt) +/* RECIPIENT *rcpt; +/* +/* void smtp_rcpt_cleanup(SMTP_STATE *state) +/* SMTP_STATE *state; +/* +/* int SMTP_RCPT_LEFT(state) +/* SMTP_STATE *state; +/* +/* void smtp_rcpt_done(state, reply, rcpt) +/* SMTP_STATE *state; +/* const char *reply; +/* RECIPIENT *rcpt; +/* DESCRIPTION +/* This module implements application-specific mark and sweep +/* operations on recipient lists. Operation is as follows: +/* .IP \(bu +/* In the course of a delivery attempt each recipient is +/* marked either as DROP (remove from recipient list) or KEEP +/* (deliver to backup mail server). +/* .IP \(bu +/* After a delivery attempt any recipients marked DROP are deleted +/* from the request, and the left-over recipients are unmarked. +/* .PP +/* Operations with upper case names are implemented by macros +/* whose arguments may be evaluated more than once. +/* +/* SMTP_RCPT_INIT() initializes application-specific recipient +/* information and must be called before the first delivery attempt. +/* +/* SMTP_RCPT_DROP() marks the specified recipient as DROP (remove +/* from recipient list). It is an error to mark an already marked +/* recipient. +/* +/* SMTP_RCPT_KEEP() marks the specified recipient as KEEP (deliver +/* to alternate mail server). It is an error to mark an already +/* marked recipient. +/* +/* SMTP_RCPT_ISMARKED() returns non-zero when the specified +/* recipient is marked. +/* +/* SMTP_RCPT_LEFT() returns the number of left_over recipients +/* (the total number of marked and non-marked recipients). +/* +/* smtp_rcpt_cleanup() cleans up the in-memory recipient list. +/* It removes the recipients marked DROP from the left-over +/* recipients, unmarks the left-over recipients, and enforces +/* the requirement that all recipients are marked upon entry. +/* +/* smtp_rcpt_done() logs that a recipient is completed and upon +/* success it marks the recipient as done in the queue file. +/* Finally, it marks the in-memory recipient as DROP. +/* +/* Note: smtp_rcpt_done() may change the order of the recipient +/* list. +/* DIAGNOSTICS +/* Panic: interface violation. +/* +/* When a recipient can't be logged as completed, the recipient is +/* logged as deferred instead. +/* BUGS +/* The single recipient list abstraction dates from the time +/* that the SMTP client would give up after one SMTP session, +/* so that each recipient was either bounced, delivered or +/* deferred. Implicitly, all recipients were marked as DROP. +/* +/* This abstraction is less convenient when an SMTP client +/* must be able to deliver left-over recipients to a backup +/* host. It might be more natural to have an input list with +/* recipients to deliver, and an output list with left-over +/* recipients. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +/* System library. */ + +#include +#include /* smtp_rcpt_cleanup */ + +/* Utility library. */ + +#include + +/* Global library. */ + +#include /* smtp_rcpt_done */ +#include /* smtp_rcpt_done */ +#include /* smtp_rcpt_done */ + +/* Application-specific. */ + +#include + +/* smtp_rcpt_done - mark recipient as done or else */ + +void smtp_rcpt_done(SMTP_STATE *state, const char *reply, RECIPIENT *rcpt) +{ + DELIVER_REQUEST *request = state->request; + SMTP_SESSION *session = state->session; + int status; + + /* + * Report success and delete the recipient from the delivery request. + * Defer if the success can't be reported. + */ + status = sent(DEL_REQ_TRACE_FLAGS(request->flags), + request->queue_id, rcpt->orig_addr, + rcpt->address, rcpt->offset, + session->namaddr, + request->arrival_time, + "%s", reply); + if (status == 0) + if (request->flags & DEL_REQ_FLAG_SUCCESS) + deliver_completed(state->src, rcpt->offset); + SMTP_RCPT_DROP(state, rcpt); + state->status |= status; +} + +/* smtp_rcpt_cleanup_callback - qsort callback */ + +static int smtp_rcpt_cleanup_callback(const void *a, const void *b) +{ + return (((RECIPIENT *) a)->status - ((RECIPIENT *) b)->status); +} + +/* smtp_rcpt_cleanup - purge completed recipients from request */ + +void smtp_rcpt_cleanup(SMTP_STATE *state) +{ + RECIPIENT_LIST *rcpt_list = &state->request->rcpt_list; + RECIPIENT *rcpt; + + /* + * Sanity checks. + */ + if (state->rcpt_drop + state->rcpt_keep != state->rcpt_left) + msg_panic("smtp_rcpt_cleanup: recipient count mismatch: %d+%d!=%d", + state->rcpt_drop, state->rcpt_keep, state->rcpt_left); + + /* + * Recipients marked KEEP sort before recipients marked DROP. Skip the + * sorting in the common case that all recipients are marked the same. + */ + if (state->rcpt_drop > 0 && state->rcpt_keep > 0) + qsort((void *) rcpt_list->info, state->rcpt_left, + sizeof(rcpt_list->info), smtp_rcpt_cleanup_callback); + + /* + * Truncate the recipient list and unmark the left-over recipients. + */ + state->rcpt_left = state->rcpt_keep; + for (rcpt = rcpt_list->info; rcpt < rcpt_list->info + state->rcpt_left; rcpt++) + rcpt->status = 0; + state->rcpt_drop = state->rcpt_keep = 0; +} diff --git a/postfix/src/smtp/smtp_trouble.c b/postfix/src/smtp/smtp_trouble.c index c7d3e8559..ea98fb54f 100644 --- a/postfix/src/smtp/smtp_trouble.c +++ b/postfix/src/smtp/smtp_trouble.c @@ -34,7 +34,7 @@ /* of all messages to the same domain is deferred, or one or more /* recipients are given up as non-deliverable and a bounce log is /* updated. In any case, the recipient is marked as either KEEP -/* (try again with a backup host) or DROP (delete recipient from +/* (try again with a backup host) or DROP (delete recipient from /* delivery request). /* /* In addition, when an unexpected response code is seen such @@ -47,7 +47,7 @@ /* /* In case of a soft error, action depends on whether the error /* qualifies for trying the request with other mail servers (log -/* an informational record only and try the a backup server) or +/* an informational record only and try a backup server) or /* whether this is the final server (log recipient delivery status /* records and delete the recipient from the request). /* @@ -59,7 +59,7 @@ /* The policy is: soft error, non-final server: log an informational /* record why the host is being skipped; soft error, final server: /* defer delivery of all remaining recipients and mark the destination -/* a problematic; hard error: bounce all remaining recipients. +/* as problematic; hard error: bounce all remaining recipients. /* The result is non-zero. /* /* smtp_mesg_fail() handles the case where the smtp server @@ -180,14 +180,13 @@ int smtp_site_fail(SMTP_STATE *state, int code, char *format,...) * delivery to a backup server. Just log something informative to show * why we're skipping this host. */ - if (soft_error && state->final_server == 0 - && (smtp_backup_mask & SMTP_BACKUP_SESSION_FAILURE)) { + if (soft_error && state->final_server == 0) { msg_info("%s: %s", request->queue_id, vstring_str(why)); - for (nrcpt = 0; nrcpt < request->rcpt_list.len; nrcpt++) { + for (nrcpt = 0; nrcpt < SMTP_RCPT_LEFT(state); nrcpt++) { rcpt = request->rcpt_list.info + nrcpt; - if (SMTP_RCPT_MARK_ISSET(rcpt)) + if (SMTP_RCPT_ISMARKED(rcpt)) continue; - SMTP_RCPT_MARK_KEEP(state, rcpt); + SMTP_RCPT_KEEP(state, rcpt); } } @@ -197,9 +196,9 @@ int smtp_site_fail(SMTP_STATE *state, int code, char *format,...) * the recipient for delivery to a backup server. */ else { - for (nrcpt = 0; nrcpt < request->rcpt_list.len; nrcpt++) { + for (nrcpt = 0; nrcpt < SMTP_RCPT_LEFT(state); nrcpt++) { rcpt = request->rcpt_list.info + nrcpt; - if (SMTP_RCPT_MARK_ISSET(rcpt)) + if (SMTP_RCPT_ISMARKED(rcpt)) continue; status = (soft_error ? defer_append : bounce_append) (DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, @@ -208,7 +207,7 @@ int smtp_site_fail(SMTP_STATE *state, int code, char *format,...) request->arrival_time, "%s", vstring_str(why)); if (status == 0) deliver_completed(state->src, rcpt->offset); - SMTP_RCPT_MARK_DROP(state, rcpt); + SMTP_RCPT_DROP(state, rcpt); state->status |= status; } /* XXX This assumes no fall-back relay. */ @@ -249,14 +248,13 @@ int smtp_mesg_fail(SMTP_STATE *state, int code, char *format,...) * delivery to a backup server. Just log something informative to show * why we're skipping this host. */ - if (soft_error && state->final_server == 0 - && (smtp_backup_mask & SMTP_BACKUP_MESSAGE_FAILURE)) { + if (soft_error && state->final_server == 0) { msg_info("%s: %s", request->queue_id, vstring_str(why)); - for (nrcpt = 0; nrcpt < request->rcpt_list.len; nrcpt++) { + for (nrcpt = 0; nrcpt < SMTP_RCPT_LEFT(state); nrcpt++) { rcpt = request->rcpt_list.info + nrcpt; - if (SMTP_RCPT_MARK_ISSET(rcpt)) + if (SMTP_RCPT_ISMARKED(rcpt)) continue; - SMTP_RCPT_MARK_KEEP(state, rcpt); + SMTP_RCPT_KEEP(state, rcpt); } } @@ -266,9 +264,9 @@ int smtp_mesg_fail(SMTP_STATE *state, int code, char *format,...) * the recipient for delivery to a backup server. */ else { - for (nrcpt = 0; nrcpt < request->rcpt_list.len; nrcpt++) { + for (nrcpt = 0; nrcpt < SMTP_RCPT_LEFT(state); nrcpt++) { rcpt = request->rcpt_list.info + nrcpt; - if (SMTP_RCPT_MARK_ISSET(rcpt)) + if (SMTP_RCPT_ISMARKED(rcpt)) continue; status = (soft_error ? defer_append : bounce_append) (DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, @@ -277,7 +275,7 @@ int smtp_mesg_fail(SMTP_STATE *state, int code, char *format,...) "%s", vstring_str(why)); if (status == 0) deliver_completed(state->src, rcpt->offset); - SMTP_RCPT_MARK_DROP(state, rcpt); + SMTP_RCPT_DROP(state, rcpt); state->status |= status; } } @@ -304,7 +302,7 @@ void smtp_rcpt_fail(SMTP_STATE *state, int code, RECIPIENT *rcpt, /* * Sanity check. */ - if (SMTP_RCPT_MARK_ISSET(rcpt)) + if (SMTP_RCPT_ISMARKED(rcpt)) msg_panic("smtp_rcpt_fail: recipient <%s> is marked", rcpt->address); /* @@ -312,15 +310,14 @@ void smtp_rcpt_fail(SMTP_STATE *state, int code, RECIPIENT *rcpt, * for trying other mail servers. Just log something informative to show * why we're skipping this recipient now. */ - if (soft_error && state->final_server == 0 - && (smtp_backup_mask & SMTP_BACKUP_RECIPIENT_FAILURE)) { + if (soft_error && state->final_server == 0) { VSTRING *buf = vstring_alloc(100); va_start(ap, format); vstring_vsprintf(buf, format, ap); va_end(ap); msg_info("%s: %s", request->queue_id, vstring_str(buf)); - SMTP_RCPT_MARK_KEEP(state, rcpt); + SMTP_RCPT_KEEP(state, rcpt); vstring_free(buf); } @@ -341,7 +338,7 @@ void smtp_rcpt_fail(SMTP_STATE *state, int code, RECIPIENT *rcpt, va_end(ap); if (status == 0) deliver_completed(state->src, rcpt->offset); - SMTP_RCPT_MARK_DROP(state, rcpt); + SMTP_RCPT_DROP(state, rcpt); state->status |= status; } smtp_check_code(state, code); @@ -378,14 +375,13 @@ int smtp_stream_except(SMTP_STATE *state, int code, char *description) * delivery to a backup server. Just log something informative to show * why we're skipping this host. */ - if (state->final_server == 0 - && (smtp_backup_mask & SMTP_BACKUP_SESSION_FAILURE)) { + if (state->final_server == 0) { msg_info("%s: %s", request->queue_id, vstring_str(why)); - for (nrcpt = 0; nrcpt < request->rcpt_list.len; nrcpt++) { + for (nrcpt = 0; nrcpt < SMTP_RCPT_LEFT(state); nrcpt++) { rcpt = request->rcpt_list.info + nrcpt; - if (SMTP_RCPT_MARK_ISSET(rcpt)) + if (SMTP_RCPT_ISMARKED(rcpt)) continue; - SMTP_RCPT_MARK_KEEP(state, rcpt); + SMTP_RCPT_KEEP(state, rcpt); } } @@ -394,9 +390,9 @@ int smtp_stream_except(SMTP_STATE *state, int code, char *description) * request. */ else { - for (nrcpt = 0; nrcpt < request->rcpt_list.len; nrcpt++) { + for (nrcpt = 0; nrcpt < SMTP_RCPT_LEFT(state); nrcpt++) { rcpt = request->rcpt_list.info + nrcpt; - if (SMTP_RCPT_MARK_ISSET(rcpt)) + if (SMTP_RCPT_ISMARKED(rcpt)) continue; state->status |= defer_append(DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id, @@ -404,7 +400,7 @@ int smtp_stream_except(SMTP_STATE *state, int code, char *description) rcpt->offset, session->namaddr, request->arrival_time, "%s", vstring_str(why)); - SMTP_RCPT_MARK_DROP(state, rcpt); + SMTP_RCPT_DROP(state, rcpt); } } diff --git a/postfix/src/smtpd/smtpd_xclient.c b/postfix/src/smtpd/smtpd_xclient.c deleted file mode 100644 index f8688111c..000000000 --- a/postfix/src/smtpd/smtpd_xclient.c +++ /dev/null @@ -1,94 +0,0 @@ -/*++ -/* NAME -/* smtpd_xclient 3 -/* SUMMARY -/* maintain XCLIENT information -/* SYNOPSIS -/* #include "smtpd.h" -/* -/* void smtpd_xclient_init(state) -/* SMTPD_STATE *state; -/* -/* void smtpd_xclient_reset(state) -/* SMTPD_STATE *state; -/* DESCRIPTION -/* smtpd_xclient_init() zeroes the attributes for storage of XCLIENT -/* FORWARD command parameters. -/* -/* smtpd_xclient_preset() takes the result from smtpd_xclient_init() -/* and sets all fields to the same "unknown" value that regular -/* client attributes would have. -/* -/* smtpd_xclient_reset() restores the state from smtpd_xclient_init(). -/* LICENSE -/* .ad -/* .fi -/* The Secure Mailer license must be distributed with this software. -/* AUTHOR(S) -/* Wietse Venema -/* IBM T.J. Watson Research -/* P.O. Box 704 -/* Yorktown Heights, NY 10598, USA -/*--*/ - -/* System library. */ - -#include - -/* Utility library. */ - -#include -#include - -/* Global library. */ - -#include - -/* Application-specific. */ - -#include - -/* smtpd_xclient_init - initialize XCLIENT attributes */ - -void smtpd_xclient_init(SMTPD_STATE *state) -{ - state->xclient.used = 0; - state->xclient.name = 0; - state->xclient.addr = 0; - state->xclient.namaddr = 0; - state->xclient.peer_code = 0; - state->xclient.protocol = 0; - state->xclient.helo_name = 0; -} - -/* smtpd_xclient_preset - set xclient attributes to "unknown" */ - -void smtpd_xclient_preset(SMTPD_STATE *state) -{ - - /* - * This is a temporary solution. Unknown forwarded attributes get the - * same values as unknown normal attributes, so that we don't break - * assumptions in pre-existing code. - */ - state->xclient.used = 1; - state->xclient.name = mystrdup(CLIENT_NAME_UNKNOWN); - state->xclient.addr = mystrdup(CLIENT_ADDR_UNKNOWN); - state->xclient.namaddr = mystrdup(CLIENT_NAMADDR_UNKNOWN); - state->xclient.protocol = mystrdup(CLIENT_PROTO_UNKNOWN); -} - -/* smtpd_xclient_reset - reset XCLIENT attributes */ - -void smtpd_xclient_reset(SMTPD_STATE *state) -{ -#define FREE_AND_WIPE(s) { if (s) myfree(s); s = 0; } - - state->xclient.used = 0; - FREE_AND_WIPE(state->xclient.name); - FREE_AND_WIPE(state->xclient.addr); - FREE_AND_WIPE(state->xclient.namaddr); - state->xclient.peer_code = 0; - FREE_AND_WIPE(state->xclient.protocol); - FREE_AND_WIPE(state->xclient.helo_name); -} diff --git a/postfix/src/util/intv.c b/postfix/src/util/intv.c deleted file mode 100644 index 774e12d10..000000000 --- a/postfix/src/util/intv.c +++ /dev/null @@ -1,117 +0,0 @@ -/*++ -/* NAME -/* intv 3 -/* SUMMARY -/* integer array utilities -/* SYNOPSIS -/* #include -/* -/* INTV *intv_alloc(len) -/* int len; -/* -/* INTV *intv_free(intvp) -/* INTV *intvp; -/* -/* void intv_add(intvp, count, arg, ...) -/* INTV *intvp; -/* int count; -/* int *arg; -/* DESCRIPTION -/* The functions in this module manipulate arrays of integers. -/* An INTV structure contains the following members: -/* .IP len -/* The actual length of the \fIintv\fR array. -/* .IP intc -/* The number of \fIintv\fR elements used. -/* .IP intv -/* An array of integer values. -/* .PP -/* intv_alloc() returns an empty integer array of the requested -/* length. The result is ready for use by intv_add(). -/* -/* intv_add() copies zero or more integers and adds them to the -/* specified integer array. -/* -/* intv_free() releases storage for an integer array, and conveniently -/* returns a null pointer. -/* SEE ALSO -/* msg(3) diagnostics interface -/* DIAGNOSTICS -/* Fatal errors: memory allocation problem. -/* LICENSE -/* .ad -/* .fi -/* The Secure Mailer license must be distributed with this software. -/* AUTHOR(S) -/* Wietse Venema -/* IBM T.J. Watson Research -/* P.O. Box 704 -/* Yorktown Heights, NY 10598, USA -/*--*/ - -/* System libraries. */ - -#include -#include /* 44BSD stdarg.h uses abort() */ -#include - -/* Application-specific. */ - -#include "mymalloc.h" -#include "msg.h" -#include "intv.h" - -/* intv_free - destroy integer array */ - -INTV *intv_free(INTV *intvp) -{ - myfree((char *) intvp->intv); - myfree((char *) intvp); - return (0); -} - -/* intv_alloc - initialize integer array */ - -INTV *intv_alloc(int len) -{ - INTV *intvp; - - /* - * Sanity check. - */ - if (len < 1) - msg_panic("intv_alloc: bad array length %d", len); - - /* - * Initialize. - */ - intvp = (INTV *) mymalloc(sizeof(*intvp)); - intvp->len = 0; - intvp->intv = (int *) mymalloc(len * sizeof(intvp->intv[0])); - intvp->len = len; - intvp->intc = 0; - return (intvp); -} - -/* intv_add - add integer to vector */ - -void intv_add(INTV *intvp, int count,...) -{ - va_list ap; - int new_len; - - /* - * Make sure that always intvp->intc < intvp->len. - */ - va_start(ap, count); - while (count-- > 0) { - if (intvp->intc >= intvp->len) { - new_len = intvp->len * 2; - intvp->intv = (int *) myrealloc((char *) intvp->intv, - new_len * sizeof(int)); - intvp->len = new_len; - } - intvp->intv[intvp->intc++] = va_arg(ap, int); - } - va_end(ap); -} diff --git a/postfix/src/util/intv.h b/postfix/src/util/intv.h deleted file mode 100644 index d84c5b4b1..000000000 --- a/postfix/src/util/intv.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef _INTV_H_INCLUDED_ -#define _INTV_H_INCLUDED_ - -/*++ -/* NAME -/* intv 3h -/* SUMMARY -/* string array utilities -/* SYNOPSIS -/* #include "intv.h" - DESCRIPTION - .nf - - /* - * External interface. - */ -typedef struct INTV { - int len; /* number of array elements */ - int intc; /* array elements in use */ - int *intv; /* integer array */ -} INTV; - -extern INTV *intv_alloc(int); -extern void intv_add(INTV *, int,...); -extern INTV *intv_free(INTV *); - -/* LICENSE -/* .ad -/* .fi -/* The Secure Mailer license must be distributed with this software. -/* AUTHOR(S) -/* Wietse Venema -/* IBM T.J. Watson Research -/* P.O. Box 704 -/* Yorktown Heights, NY 10598, USA -/*--*/ - -#endif