mirror of
https://github.com/vdukhovni/postfix
synced 2025-09-01 14:45:32 +00:00
postfix-2.0.16-20031221
This commit is contained in:
committed by
Viktor Dukhovni
parent
7011a3b3b6
commit
42f6ab4fc3
@@ -8871,13 +8871,18 @@ Apologies for any names omitted.
|
|||||||
between short queue ID and message status). File:
|
between short queue ID and message status). File:
|
||||||
showq/showq.c.
|
showq/showq.c.
|
||||||
|
|
||||||
20031216-7
|
20031216-20
|
||||||
|
|
||||||
Cleanup: the SMTP client now moves on to the next MX host
|
Cleanup: the SMTP client now moves on to the next MX host
|
||||||
or fallback relay when delivery fails in the middle of an
|
or fallback relay when delivery fails in the middle of an
|
||||||
SMTP session. This includes not only broken connections
|
SMTP session. This includes both broken connections and
|
||||||
(easy) but also includes 4xx SMTP server replies (not easy).
|
4xx SMTP server replies. Files: smtp/smtp.c, smtp_rcpt.c,
|
||||||
Files: smtp/smtp.c, smtp/smtp_connect.c, smtp_trouble.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
|
20031217
|
||||||
|
|
||||||
@@ -8949,7 +8954,7 @@ Open problems:
|
|||||||
|
|
||||||
Low: postconf -e edits parameters that postconf won't list.
|
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.
|
use =46rom instead of >From.
|
||||||
|
|
||||||
virtual_mailbox_path expression like forward_path, so that
|
virtual_mailbox_path expression like forward_path, so that
|
||||||
|
@@ -22,12 +22,13 @@ snapshot release). Patches change the patchlevel and the release
|
|||||||
date. Snapshots change only the release date, unless they include
|
date. Snapshots change only the release date, unless they include
|
||||||
the same bugfixes as a patch release.
|
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)
|
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
|
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
|
Incompatible changes with Postfix snapshot 2.0.16-20031215
|
||||||
==========================================================
|
==========================================================
|
||||||
|
@@ -76,6 +76,23 @@ smtp_never_send_ehlo = no
|
|||||||
#
|
#
|
||||||
smtp_defer_if_no_mx_address_found = 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
|
# The smtp_send_xforward_command parameter controls whether the Postfix
|
||||||
# SMTP client will send an XFORWARD command to the SMTP server, when
|
# SMTP client will send an XFORWARD command to the SMTP server, when
|
||||||
# the ESMTP HELO response of the remote host indicates XFORWARD support.
|
# the ESMTP HELO response of the remote host indicates XFORWARD support.
|
||||||
|
@@ -244,29 +244,22 @@ SMTP(8) SMTP(8)
|
|||||||
|
|
||||||
<b>smtp_mx_address_limit</b>
|
<b>smtp_mx_address_limit</b>
|
||||||
An upper bound on the number of MX (mail exchanger)
|
An upper bound on the number of MX (mail exchanger)
|
||||||
IP addresses that the SMTP client will try to con-
|
IP addresses that that can result from DNS or host
|
||||||
nect to, before giving up or sending the mail to a
|
lookups.
|
||||||
fall-back relay host.
|
|
||||||
|
|
||||||
Specify zero to disable the limit.
|
Specify zero to disable the limit.
|
||||||
|
|
||||||
|
Note: by default, equal preference MX addresses are
|
||||||
|
sorted into random order.
|
||||||
|
|
||||||
<b>smtp_mx_session_limit</b>
|
<b>smtp_mx_session_limit</b>
|
||||||
An upper bound on the number of SMTP sessions that
|
An upper bound on the number of SMTP sessions that
|
||||||
the SMTP client will engage in before giving up or
|
the SMTP client will engage in per message delivery
|
||||||
sending the mail to a fall-back relay host.
|
(ignoring MX IP addresses that fail to complete the
|
||||||
|
SMTP initial handshake).
|
||||||
|
|
||||||
Specify zero to disable the limit.
|
Specify zero to disable the limit.
|
||||||
|
|
||||||
<b>smtp_backup_on_soft_error</b>
|
|
||||||
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 <b>ses-</b>
|
|
||||||
<b>sion</b> (SMTP handshake failure, connection loss),
|
|
||||||
<b>message</b> (failure of MAIL FROM, DATA or "."), or
|
|
||||||
<b>recipient</b> (failure of RCPT TO).
|
|
||||||
|
|
||||||
Recipients that do not qualify are deferred.
|
|
||||||
|
|
||||||
<b>Timeout controls</b>
|
<b>Timeout controls</b>
|
||||||
The default time unit is seconds; an explicit time unit
|
The default time unit is seconds; an explicit time unit
|
||||||
can be specified by appending a one-letter suffix to the
|
can be specified by appending a one-letter suffix to the
|
||||||
|
@@ -205,24 +205,18 @@ The default limit is taken from the
|
|||||||
\fBdefault_destination_recipient_limit\fR parameter.
|
\fBdefault_destination_recipient_limit\fR parameter.
|
||||||
.IP \fBsmtp_mx_address_limit\fR
|
.IP \fBsmtp_mx_address_limit\fR
|
||||||
An upper bound on the number of MX (mail exchanger) IP addresses
|
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
|
that that can result from DNS or host lookups.
|
||||||
sending the mail to a fall-back relay host.
|
|
||||||
.sp
|
.sp
|
||||||
Specify zero to disable the limit.
|
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
|
.IP \fBsmtp_mx_session_limit\fR
|
||||||
An upper bound on the number of SMTP sessions that the SMTP client
|
An upper bound on the number of SMTP sessions that the SMTP
|
||||||
will engage in before giving up or sending the mail to a fall-back
|
client will engage in per message delivery (ignoring MX IP
|
||||||
relay host.
|
addresses that fail to complete the SMTP initial handshake).
|
||||||
.sp
|
.sp
|
||||||
Specify zero to disable the limit.
|
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"
|
.SH "Timeout controls"
|
||||||
.ad
|
.ad
|
||||||
.fi
|
.fi
|
||||||
|
@@ -180,15 +180,6 @@ extern bool var_disable_dns;
|
|||||||
#define DEF_SMTP_HOST_LOOKUP SMTP_HOST_LOOKUP_DNS
|
#define DEF_SMTP_HOST_LOOKUP SMTP_HOST_LOOKUP_DNS
|
||||||
extern int var_smtp_dns_lookup;
|
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 VAR_SMTP_MXADDR_LIMIT "smtp_mx_address_limit"
|
||||||
#define DEF_SMTP_MXADDR_LIMIT 0
|
#define DEF_SMTP_MXADDR_LIMIT 0
|
||||||
extern int var_smtp_mxaddr_limit;
|
extern int var_smtp_mxaddr_limit;
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
* Patches change the patchlevel and the release date. Snapshots change the
|
* Patches change the patchlevel and the release date. Snapshots change the
|
||||||
* release date only, unless they include the same bugfix as a patch release.
|
* 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 VAR_MAIL_VERSION "mail_version"
|
||||||
#define DEF_MAIL_VERSION "2.0.16-" MAIL_RELEASE_DATE
|
#define DEF_MAIL_VERSION "2.0.16-" MAIL_RELEASE_DATE
|
||||||
|
@@ -1,113 +0,0 @@
|
|||||||
/*++
|
|
||||||
/* NAME
|
|
||||||
/* peer_name 3
|
|
||||||
/* SUMMARY
|
|
||||||
/* produce printable peer name and address
|
|
||||||
/* SYNOPSIS
|
|
||||||
/* #include <peer_name.h>
|
|
||||||
/*
|
|
||||||
/* 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 <sys_defs.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
|
|
||||||
/* Utility library. */
|
|
||||||
|
|
||||||
#include <msg.h>
|
|
||||||
#include <valid_hostname.h>
|
|
||||||
#include <peer_name.h>
|
|
||||||
|
|
||||||
/* 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 <unistd.h>
|
|
||||||
|
|
||||||
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
|
|
@@ -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 <peer_name.h>
|
|
||||||
/* 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
|
|
@@ -31,9 +31,6 @@
|
|||||||
/* const char *orig_rcpt;
|
/* const char *orig_rcpt;
|
||||||
/* const char *recipient;
|
/* const char *recipient;
|
||||||
/*
|
/*
|
||||||
/* void recipient_list_truncate(list)
|
|
||||||
/* RECIPIENT_LIST *list;
|
|
||||||
/*
|
|
||||||
/* void recipient_list_free(list)
|
/* void recipient_list_free(list)
|
||||||
/* RECIPIENT_LIST *list;
|
/* RECIPIENT_LIST *list;
|
||||||
/* DESCRIPTION
|
/* DESCRIPTION
|
||||||
@@ -51,9 +48,6 @@
|
|||||||
/* recipient_list_add() adds a recipient to the specified list.
|
/* recipient_list_add() adds a recipient to the specified list.
|
||||||
/* The recipient address is copied with mystrdup().
|
/* 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
|
/* recipient_list_free() releases memory for the specified list
|
||||||
/* of recipient structures.
|
/* of recipient structures.
|
||||||
/*
|
/*
|
||||||
@@ -82,7 +76,6 @@
|
|||||||
/* System library. */
|
/* System library. */
|
||||||
|
|
||||||
#include <sys_defs.h>
|
#include <sys_defs.h>
|
||||||
#include <msg.h>
|
|
||||||
|
|
||||||
/* Utility library. */
|
/* Utility library. */
|
||||||
|
|
||||||
@@ -121,27 +114,15 @@ void recipient_list_add(RECIPIENT_LIST *list, long offset,
|
|||||||
list->len++;
|
list->len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* recipient_list_truncate - release memory for unused recipient structures */
|
|
||||||
|
|
||||||
void recipient_list_truncate(RECIPIENT_LIST *list, int new_len)
|
|
||||||
{
|
|
||||||
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++) {
|
|
||||||
myfree(rcpt->orig_addr);
|
|
||||||
myfree(rcpt->address);
|
|
||||||
}
|
|
||||||
list->len = new_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* recipient_list_free - release memory for in-core recipient structure */
|
/* recipient_list_free - release memory for in-core recipient structure */
|
||||||
|
|
||||||
void recipient_list_free(RECIPIENT_LIST *list)
|
void recipient_list_free(RECIPIENT_LIST *list)
|
||||||
{
|
{
|
||||||
if (list->len > 0)
|
RECIPIENT *rcpt;
|
||||||
recipient_list_truncate(list, 0);
|
|
||||||
|
for (rcpt = list->info; rcpt < list->info + list->len; rcpt++) {
|
||||||
|
myfree(rcpt->orig_addr);
|
||||||
|
myfree(rcpt->address);
|
||||||
|
}
|
||||||
myfree((char *) list->info);
|
myfree((char *) list->info);
|
||||||
}
|
}
|
||||||
|
@@ -32,7 +32,6 @@ typedef struct RECIPIENT_LIST {
|
|||||||
|
|
||||||
extern void recipient_list_init(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_add(RECIPIENT_LIST *, long, const char *, const char *);
|
||||||
extern void recipient_list_truncate(RECIPIENT_LIST *, int);
|
|
||||||
extern void recipient_list_free(RECIPIENT_LIST *);
|
extern void recipient_list_free(RECIPIENT_LIST *);
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
|
@@ -146,6 +146,7 @@ lmtp_proto.o: ../../include/vstream.h
|
|||||||
lmtp_proto.o: ../../include/vstring_vstream.h
|
lmtp_proto.o: ../../include/vstring_vstream.h
|
||||||
lmtp_proto.o: ../../include/stringops.h
|
lmtp_proto.o: ../../include/stringops.h
|
||||||
lmtp_proto.o: ../../include/mymalloc.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/mail_params.h
|
||||||
lmtp_proto.o: ../../include/smtp_stream.h
|
lmtp_proto.o: ../../include/smtp_stream.h
|
||||||
lmtp_proto.o: ../../include/mail_queue.h
|
lmtp_proto.o: ../../include/mail_queue.h
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
SRCS = smtp.c smtp_connect.c smtp_proto.c smtp_chat.c smtp_session.c \
|
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
|
smtp_sasl_proto.c smtp_sasl_glue.c
|
||||||
OBJS = smtp.o smtp_connect.o smtp_proto.o smtp_chat.o smtp_session.o \
|
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
|
smtp_sasl_proto.o smtp_sasl_glue.o
|
||||||
HDRS = smtp.h smtp_sasl.h
|
HDRS = smtp.h smtp_sasl.h
|
||||||
TESTSRC =
|
TESTSRC =
|
||||||
@@ -144,18 +144,6 @@ smtp_connect.o: ../../include/dns.h
|
|||||||
smtp_connect.o: smtp.h
|
smtp_connect.o: smtp.h
|
||||||
smtp_connect.o: ../../include/argv.h
|
smtp_connect.o: ../../include/argv.h
|
||||||
smtp_connect.o: smtp_addr.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: smtp_proto.c
|
||||||
smtp_proto.o: ../../include/sys_defs.h
|
smtp_proto.o: ../../include/sys_defs.h
|
||||||
smtp_proto.o: ../../include/msg.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: smtp.h
|
||||||
smtp_proto.o: ../../include/argv.h
|
smtp_proto.o: ../../include/argv.h
|
||||||
smtp_proto.o: smtp_sasl.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: smtp_sasl_glue.c
|
||||||
smtp_sasl_glue.o: ../../include/sys_defs.h
|
smtp_sasl_glue.o: ../../include/sys_defs.h
|
||||||
smtp_sasl_glue.o: ../../include/msg.h
|
smtp_sasl_glue.o: ../../include/msg.h
|
||||||
|
@@ -189,24 +189,18 @@
|
|||||||
/* \fBdefault_destination_recipient_limit\fR parameter.
|
/* \fBdefault_destination_recipient_limit\fR parameter.
|
||||||
/* .IP \fBsmtp_mx_address_limit\fR
|
/* .IP \fBsmtp_mx_address_limit\fR
|
||||||
/* An upper bound on the number of MX (mail exchanger) IP addresses
|
/* 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
|
/* that that can result from DNS or host lookups.
|
||||||
/* sending the mail to a fall-back relay host.
|
|
||||||
/* .sp
|
/* .sp
|
||||||
/* Specify zero to disable the limit.
|
/* 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
|
/* .IP \fBsmtp_mx_session_limit\fR
|
||||||
/* An upper bound on the number of SMTP sessions that the SMTP client
|
/* An upper bound on the number of SMTP sessions that the SMTP
|
||||||
/* will engage in before giving up or sending the mail to a fall-back
|
/* client will engage in per message delivery (ignoring MX IP
|
||||||
/* relay host.
|
/* addresses that fail to complete the SMTP initial handshake).
|
||||||
/* .sp
|
/* .sp
|
||||||
/* Specify zero to disable the limit.
|
/* 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"
|
/* .SH "Timeout controls"
|
||||||
/* .ad
|
/* .ad
|
||||||
/* .fi
|
/* .fi
|
||||||
@@ -332,7 +326,6 @@ int var_smtp_pix_delay;
|
|||||||
int var_smtp_line_limit;
|
int var_smtp_line_limit;
|
||||||
char *var_smtp_helo_name;
|
char *var_smtp_helo_name;
|
||||||
char *var_smtp_host_lookup;
|
char *var_smtp_host_lookup;
|
||||||
char *var_smtp_backup_mask;
|
|
||||||
bool var_smtp_quote_821_env;
|
bool var_smtp_quote_821_env;
|
||||||
bool var_smtp_defer_mxaddr;
|
bool var_smtp_defer_mxaddr;
|
||||||
bool var_smtp_send_xforward;
|
bool var_smtp_send_xforward;
|
||||||
@@ -345,7 +338,6 @@ int var_smtp_mxsess_limit;
|
|||||||
*/
|
*/
|
||||||
int smtp_errno;
|
int smtp_errno;
|
||||||
int smtp_host_lookup_mask;
|
int smtp_host_lookup_mask;
|
||||||
int smtp_backup_mask;
|
|
||||||
|
|
||||||
/* deliver_message - deliver message with extreme prejudice */
|
/* deliver_message - deliver message with extreme prejudice */
|
||||||
|
|
||||||
@@ -375,6 +367,7 @@ static int deliver_message(DELIVER_REQUEST *request)
|
|||||||
state = smtp_state_alloc();
|
state = smtp_state_alloc();
|
||||||
state->request = request;
|
state->request = request;
|
||||||
state->src = request->fp;
|
state->src = request->fp;
|
||||||
|
SMTP_RCPT_INIT(state);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Establish an SMTP session and deliver this message to all requested
|
* 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[] = {
|
static NAME_MASK lookup_masks[] = {
|
||||||
SMTP_HOST_LOOKUP_DNS, SMTP_MASK_DNS,
|
SMTP_HOST_LOOKUP_DNS, SMTP_MASK_DNS,
|
||||||
SMTP_HOST_LOOKUP_NATIVE, SMTP_MASK_NATIVE,
|
SMTP_HOST_LOOKUP_NATIVE, SMTP_MASK_NATIVE,
|
||||||
0,
|
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.
|
* 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,
|
str_name_mask(VAR_SMTP_HOST_LOOKUP, lookup_masks,
|
||||||
smtp_host_lookup_mask));
|
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.
|
* 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_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_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_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,
|
0,
|
||||||
};
|
};
|
||||||
static CONFIG_TIME_TABLE time_table[] = {
|
static CONFIG_TIME_TABLE time_table[] = {
|
||||||
@@ -564,7 +533,6 @@ int main(int argc, char **argv)
|
|||||||
MAIL_SERVER_STR_TABLE, str_table,
|
MAIL_SERVER_STR_TABLE, str_table,
|
||||||
MAIL_SERVER_BOOL_TABLE, bool_table,
|
MAIL_SERVER_BOOL_TABLE, bool_table,
|
||||||
MAIL_SERVER_PRE_INIT, pre_init,
|
MAIL_SERVER_PRE_INIT, pre_init,
|
||||||
MAIL_SERVER_POST_INIT, post_init,
|
|
||||||
MAIL_SERVER_PRE_ACCEPT, pre_accept,
|
MAIL_SERVER_PRE_ACCEPT, pre_accept,
|
||||||
MAIL_SERVER_EXIT, pre_exit,
|
MAIL_SERVER_EXIT, pre_exit,
|
||||||
0);
|
0);
|
||||||
|
@@ -62,8 +62,9 @@ typedef struct SMTP_STATE {
|
|||||||
* session all recipients should be marked one way or the other.
|
* session all recipients should be marked one way or the other.
|
||||||
*/
|
*/
|
||||||
int final_server; /* final mail server */
|
int final_server; /* final mail server */
|
||||||
int drop_count; /* recipients marked as drop */
|
int rcpt_left; /* recipients left over */
|
||||||
int keep_count; /* recipients marked as keep */
|
int rcpt_drop; /* recipients marked as drop */
|
||||||
|
int rcpt_keep; /* recipients marked as keep */
|
||||||
} SMTP_STATE;
|
} SMTP_STATE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -81,47 +82,11 @@ typedef struct SMTP_STATE {
|
|||||||
#define SMTP_FEATURE_XFORWARD_PROTO (1<<9)
|
#define SMTP_FEATURE_XFORWARD_PROTO (1<<9)
|
||||||
#define SMTP_FEATURE_XFORWARD_HELO (1<<10)
|
#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
|
* smtp.c
|
||||||
*/
|
*/
|
||||||
extern int smtp_errno; /* XXX can we get rid of this? */
|
extern int smtp_errno; /* XXX can we get rid of this? */
|
||||||
|
|
||||||
#define SMTP_NONE 0 /* no error */
|
#define SMTP_NONE 0 /* no error */
|
||||||
#define SMTP_FAIL 1 /* permanent error */
|
#define SMTP_FAIL 1 /* permanent error */
|
||||||
#define SMTP_RETRY 2 /* temporary 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 *);
|
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 *);
|
extern void smtp_rcpt_done(SMTP_STATE *, const char *, RECIPIENT *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -316,7 +316,7 @@ int smtp_connect(SMTP_STATE *state)
|
|||||||
* then is to build this into the pre-existing SMTP client without
|
* then is to build this into the pre-existing SMTP client without
|
||||||
* getting lost in the complexity.
|
* 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);
|
state->final_server = (cpp[1] == 0);
|
||||||
smtp_errno = SMTP_NONE;
|
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
|
* list. Unmark any left-over recipients and try to deliver them to a
|
||||||
* backup mail server.
|
* 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;
|
next = addr->next;
|
||||||
if (++addr_count == var_smtp_mxaddr_limit)
|
if (++addr_count == var_smtp_mxaddr_limit)
|
||||||
next = 0;
|
next = 0;
|
||||||
if ((state->session = smtp_connect_addr(addr, port, why)) != 0) {
|
if ((state->session = smtp_connect_addr(addr, port, why)) != 0) {
|
||||||
if (++sess_count == var_smtp_mxsess_limit)
|
if (++sess_count == var_smtp_mxsess_limit)
|
||||||
next = 0;
|
next = 0;
|
||||||
SMTP_RCPT_MARK_INIT(state);
|
|
||||||
state->final_server = (cpp[1] == 0 && next == 0);
|
state->final_server = (cpp[1] == 0 && next == 0);
|
||||||
state->session->best = (addr->pref == addr_list->pref);
|
state->session->best = (addr->pref == addr_list->pref);
|
||||||
debug_peer_check(state->session->host, state->session->addr);
|
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. */
|
/* XXX smtp_xfer() may abort in the middle of DATA. */
|
||||||
smtp_session_free(state->session);
|
smtp_session_free(state->session);
|
||||||
debug_peer_restore();
|
debug_peer_restore();
|
||||||
if (smtp_rcpt_mark_finish(state) == 0)
|
smtp_rcpt_cleanup(state);
|
||||||
break;
|
|
||||||
} else {
|
} else {
|
||||||
msg_info("%s (port %d)", vstring_str(why), ntohs(port));
|
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
|
* Pay attention to what could be configuration problems, and pretend that
|
||||||
* these are recoverable rather than bouncing the mail.
|
* these are recoverable rather than bouncing the mail.
|
||||||
*/
|
*/
|
||||||
if (request->rcpt_list.len > 0) {
|
if (SMTP_RCPT_LEFT(state) > 0) {
|
||||||
switch (smtp_errno) {
|
switch (smtp_errno) {
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -430,6 +429,7 @@ int smtp_connect(SMTP_STATE *state)
|
|||||||
state->status = deliver_pass_all(MAIL_CLASS_PRIVATE,
|
state->status = deliver_pass_all(MAIL_CLASS_PRIVATE,
|
||||||
var_bestmx_transp,
|
var_bestmx_transp,
|
||||||
request);
|
request);
|
||||||
|
SMTP_RCPT_LEFT(state) = 0; /* XXX */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
@@ -440,9 +440,16 @@ int smtp_connect(SMTP_STATE *state)
|
|||||||
* We still need to bounce or defer some left-over recipients:
|
* We still need to bounce or defer some left-over recipients:
|
||||||
* either mail loops or some backup mail server was unavailable.
|
* either mail loops or some backup mail server was unavailable.
|
||||||
*/
|
*/
|
||||||
|
state->final_server = 1;
|
||||||
smtp_site_fail(state, smtp_errno == SMTP_RETRY ? 450 : 550,
|
smtp_site_fail(state, smtp_errno == SMTP_RETRY ? 450 : 550,
|
||||||
"%s", vstring_str(why));
|
"%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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,124 +0,0 @@
|
|||||||
/*++
|
|
||||||
/* NAME
|
|
||||||
/* smtp_misc 3
|
|
||||||
/* SUMMARY
|
|
||||||
/* assorted routines
|
|
||||||
/* SYNOPSIS
|
|
||||||
/* #include <smtp.h>
|
|
||||||
/*
|
|
||||||
/* 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 <sys_defs.h>
|
|
||||||
#include <stdlib.h> /* smtp_rcpt_mark_finish */
|
|
||||||
|
|
||||||
/* Utility library. */
|
|
||||||
|
|
||||||
#include <msg.h>
|
|
||||||
|
|
||||||
/* Global library. */
|
|
||||||
|
|
||||||
#include <deliver_request.h> /* smtp_rcpt_done */
|
|
||||||
#include <deliver_completed.h> /* smtp_rcpt_done */
|
|
||||||
#include <sent.h> /* smtp_rcpt_done */
|
|
||||||
|
|
||||||
/* Application-specific. */
|
|
||||||
|
|
||||||
#include <smtp.h>
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
|
@@ -434,10 +434,10 @@ int smtp_xfer(SMTP_STATE *state)
|
|||||||
/*
|
/*
|
||||||
* Sanity check. Recipients should be unmarked at this point.
|
* 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",
|
msg_panic("smtp_xfer: bad recipient count: %d",
|
||||||
request->rcpt_list.len);
|
SMTP_RCPT_LEFT(state));
|
||||||
if (SMTP_RCPT_MARK_ISSET(request->rcpt_list.info))
|
if (SMTP_RCPT_ISMARKED(request->rcpt_list.info))
|
||||||
msg_panic("smtp_xfer: bad recipient status: %d",
|
msg_panic("smtp_xfer: bad recipient status: %d",
|
||||||
request->rcpt_list.info->status);
|
request->rcpt_list.info->status);
|
||||||
|
|
||||||
@@ -616,7 +616,7 @@ int smtp_xfer(SMTP_STATE *state)
|
|||||||
QUOTE_ADDRESS(state->scratch, rcpt->address);
|
QUOTE_ADDRESS(state->scratch, rcpt->address);
|
||||||
vstring_sprintf(next_command, "RCPT TO:<%s>",
|
vstring_sprintf(next_command, "RCPT TO:<%s>",
|
||||||
vstring_str(state->scratch));
|
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) ?
|
next_state = DEL_REQ_TRACE_ONLY(request->flags) ?
|
||||||
SMTP_STATE_ABORT : SMTP_STATE_DATA;
|
SMTP_STATE_ABORT : SMTP_STATE_DATA;
|
||||||
break;
|
break;
|
||||||
@@ -779,7 +779,7 @@ int smtp_xfer(SMTP_STATE *state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* If trace-only, send RSET instead of DATA. */
|
/* 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) ?
|
recv_state = DEL_REQ_TRACE_ONLY(request->flags) ?
|
||||||
SMTP_STATE_ABORT : SMTP_STATE_DATA;
|
SMTP_STATE_ABORT : SMTP_STATE_DATA;
|
||||||
break;
|
break;
|
||||||
@@ -822,7 +822,7 @@ int smtp_xfer(SMTP_STATE *state)
|
|||||||
} else {
|
} else {
|
||||||
for (nrcpt = 0; nrcpt < recv_rcpt; nrcpt++) {
|
for (nrcpt = 0; nrcpt < recv_rcpt; nrcpt++) {
|
||||||
rcpt = request->rcpt_list.info + 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);
|
smtp_rcpt_done(state, resp->str, rcpt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
182
postfix/src/smtp/smtp_rcpt.c
Normal file
182
postfix/src/smtp/smtp_rcpt.c
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
/*++
|
||||||
|
/* NAME
|
||||||
|
/* smtp_rcpt 3
|
||||||
|
/* SUMMARY
|
||||||
|
/* application-specific recipient list operations
|
||||||
|
/* SYNOPSIS
|
||||||
|
/* #include <smtp.h>
|
||||||
|
/*
|
||||||
|
/* 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 <sys_defs.h>
|
||||||
|
#include <stdlib.h> /* smtp_rcpt_cleanup */
|
||||||
|
|
||||||
|
/* Utility library. */
|
||||||
|
|
||||||
|
#include <msg.h>
|
||||||
|
|
||||||
|
/* Global library. */
|
||||||
|
|
||||||
|
#include <deliver_request.h> /* smtp_rcpt_done */
|
||||||
|
#include <deliver_completed.h> /* smtp_rcpt_done */
|
||||||
|
#include <sent.h> /* smtp_rcpt_done */
|
||||||
|
|
||||||
|
/* Application-specific. */
|
||||||
|
|
||||||
|
#include <smtp.h>
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
@@ -34,7 +34,7 @@
|
|||||||
/* of all messages to the same domain is deferred, or one or more
|
/* 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
|
/* recipients are given up as non-deliverable and a bounce log is
|
||||||
/* updated. In any case, the recipient is marked as either KEEP
|
/* 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).
|
/* delivery request).
|
||||||
/*
|
/*
|
||||||
/* In addition, when an unexpected response code is seen such
|
/* 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
|
/* In case of a soft error, action depends on whether the error
|
||||||
/* qualifies for trying the request with other mail servers (log
|
/* 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
|
/* whether this is the final server (log recipient delivery status
|
||||||
/* records and delete the recipient from the request).
|
/* records and delete the recipient from the request).
|
||||||
/*
|
/*
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
/* The policy is: soft error, non-final server: log an informational
|
/* The policy is: soft error, non-final server: log an informational
|
||||||
/* record why the host is being skipped; soft error, final server:
|
/* record why the host is being skipped; soft error, final server:
|
||||||
/* defer delivery of all remaining recipients and mark the destination
|
/* 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.
|
/* The result is non-zero.
|
||||||
/*
|
/*
|
||||||
/* smtp_mesg_fail() handles the case where the smtp server
|
/* 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
|
* delivery to a backup server. Just log something informative to show
|
||||||
* why we're skipping this host.
|
* why we're skipping this host.
|
||||||
*/
|
*/
|
||||||
if (soft_error && state->final_server == 0
|
if (soft_error && state->final_server == 0) {
|
||||||
&& (smtp_backup_mask & SMTP_BACKUP_SESSION_FAILURE)) {
|
|
||||||
msg_info("%s: %s", request->queue_id, vstring_str(why));
|
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;
|
rcpt = request->rcpt_list.info + nrcpt;
|
||||||
if (SMTP_RCPT_MARK_ISSET(rcpt))
|
if (SMTP_RCPT_ISMARKED(rcpt))
|
||||||
continue;
|
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.
|
* the recipient for delivery to a backup server.
|
||||||
*/
|
*/
|
||||||
else {
|
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;
|
rcpt = request->rcpt_list.info + nrcpt;
|
||||||
if (SMTP_RCPT_MARK_ISSET(rcpt))
|
if (SMTP_RCPT_ISMARKED(rcpt))
|
||||||
continue;
|
continue;
|
||||||
status = (soft_error ? defer_append : bounce_append)
|
status = (soft_error ? defer_append : bounce_append)
|
||||||
(DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id,
|
(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));
|
request->arrival_time, "%s", vstring_str(why));
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
deliver_completed(state->src, rcpt->offset);
|
deliver_completed(state->src, rcpt->offset);
|
||||||
SMTP_RCPT_MARK_DROP(state, rcpt);
|
SMTP_RCPT_DROP(state, rcpt);
|
||||||
state->status |= status;
|
state->status |= status;
|
||||||
}
|
}
|
||||||
/* XXX This assumes no fall-back relay. */
|
/* 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
|
* delivery to a backup server. Just log something informative to show
|
||||||
* why we're skipping this host.
|
* why we're skipping this host.
|
||||||
*/
|
*/
|
||||||
if (soft_error && state->final_server == 0
|
if (soft_error && state->final_server == 0) {
|
||||||
&& (smtp_backup_mask & SMTP_BACKUP_MESSAGE_FAILURE)) {
|
|
||||||
msg_info("%s: %s", request->queue_id, vstring_str(why));
|
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;
|
rcpt = request->rcpt_list.info + nrcpt;
|
||||||
if (SMTP_RCPT_MARK_ISSET(rcpt))
|
if (SMTP_RCPT_ISMARKED(rcpt))
|
||||||
continue;
|
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.
|
* the recipient for delivery to a backup server.
|
||||||
*/
|
*/
|
||||||
else {
|
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;
|
rcpt = request->rcpt_list.info + nrcpt;
|
||||||
if (SMTP_RCPT_MARK_ISSET(rcpt))
|
if (SMTP_RCPT_ISMARKED(rcpt))
|
||||||
continue;
|
continue;
|
||||||
status = (soft_error ? defer_append : bounce_append)
|
status = (soft_error ? defer_append : bounce_append)
|
||||||
(DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id,
|
(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));
|
"%s", vstring_str(why));
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
deliver_completed(state->src, rcpt->offset);
|
deliver_completed(state->src, rcpt->offset);
|
||||||
SMTP_RCPT_MARK_DROP(state, rcpt);
|
SMTP_RCPT_DROP(state, rcpt);
|
||||||
state->status |= status;
|
state->status |= status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,7 +302,7 @@ void smtp_rcpt_fail(SMTP_STATE *state, int code, RECIPIENT *rcpt,
|
|||||||
/*
|
/*
|
||||||
* Sanity check.
|
* Sanity check.
|
||||||
*/
|
*/
|
||||||
if (SMTP_RCPT_MARK_ISSET(rcpt))
|
if (SMTP_RCPT_ISMARKED(rcpt))
|
||||||
msg_panic("smtp_rcpt_fail: recipient <%s> is marked", rcpt->address);
|
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
|
* for trying other mail servers. Just log something informative to show
|
||||||
* why we're skipping this recipient now.
|
* why we're skipping this recipient now.
|
||||||
*/
|
*/
|
||||||
if (soft_error && state->final_server == 0
|
if (soft_error && state->final_server == 0) {
|
||||||
&& (smtp_backup_mask & SMTP_BACKUP_RECIPIENT_FAILURE)) {
|
|
||||||
VSTRING *buf = vstring_alloc(100);
|
VSTRING *buf = vstring_alloc(100);
|
||||||
|
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
vstring_vsprintf(buf, format, ap);
|
vstring_vsprintf(buf, format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
msg_info("%s: %s", request->queue_id, vstring_str(buf));
|
msg_info("%s: %s", request->queue_id, vstring_str(buf));
|
||||||
SMTP_RCPT_MARK_KEEP(state, rcpt);
|
SMTP_RCPT_KEEP(state, rcpt);
|
||||||
vstring_free(buf);
|
vstring_free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,7 +338,7 @@ void smtp_rcpt_fail(SMTP_STATE *state, int code, RECIPIENT *rcpt,
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
deliver_completed(state->src, rcpt->offset);
|
deliver_completed(state->src, rcpt->offset);
|
||||||
SMTP_RCPT_MARK_DROP(state, rcpt);
|
SMTP_RCPT_DROP(state, rcpt);
|
||||||
state->status |= status;
|
state->status |= status;
|
||||||
}
|
}
|
||||||
smtp_check_code(state, code);
|
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
|
* delivery to a backup server. Just log something informative to show
|
||||||
* why we're skipping this host.
|
* why we're skipping this host.
|
||||||
*/
|
*/
|
||||||
if (state->final_server == 0
|
if (state->final_server == 0) {
|
||||||
&& (smtp_backup_mask & SMTP_BACKUP_SESSION_FAILURE)) {
|
|
||||||
msg_info("%s: %s", request->queue_id, vstring_str(why));
|
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;
|
rcpt = request->rcpt_list.info + nrcpt;
|
||||||
if (SMTP_RCPT_MARK_ISSET(rcpt))
|
if (SMTP_RCPT_ISMARKED(rcpt))
|
||||||
continue;
|
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.
|
* request.
|
||||||
*/
|
*/
|
||||||
else {
|
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;
|
rcpt = request->rcpt_list.info + nrcpt;
|
||||||
if (SMTP_RCPT_MARK_ISSET(rcpt))
|
if (SMTP_RCPT_ISMARKED(rcpt))
|
||||||
continue;
|
continue;
|
||||||
state->status |= defer_append(DEL_REQ_TRACE_FLAGS(request->flags),
|
state->status |= defer_append(DEL_REQ_TRACE_FLAGS(request->flags),
|
||||||
request->queue_id,
|
request->queue_id,
|
||||||
@@ -404,7 +400,7 @@ int smtp_stream_except(SMTP_STATE *state, int code, char *description)
|
|||||||
rcpt->offset, session->namaddr,
|
rcpt->offset, session->namaddr,
|
||||||
request->arrival_time,
|
request->arrival_time,
|
||||||
"%s", vstring_str(why));
|
"%s", vstring_str(why));
|
||||||
SMTP_RCPT_MARK_DROP(state, rcpt);
|
SMTP_RCPT_DROP(state, rcpt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 <sys_defs.h>
|
|
||||||
|
|
||||||
/* Utility library. */
|
|
||||||
|
|
||||||
#include <mymalloc.h>
|
|
||||||
#include <msg.h>
|
|
||||||
|
|
||||||
/* Global library. */
|
|
||||||
|
|
||||||
#include <mail_proto.h>
|
|
||||||
|
|
||||||
/* Application-specific. */
|
|
||||||
|
|
||||||
#include <smtpd.h>
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
|
@@ -1,117 +0,0 @@
|
|||||||
/*++
|
|
||||||
/* NAME
|
|
||||||
/* intv 3
|
|
||||||
/* SUMMARY
|
|
||||||
/* integer array utilities
|
|
||||||
/* SYNOPSIS
|
|
||||||
/* #include <intv.h>
|
|
||||||
/*
|
|
||||||
/* 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 <sys_defs.h>
|
|
||||||
#include <stdlib.h> /* 44BSD stdarg.h uses abort() */
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
|
@@ -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
|
|
Reference in New Issue
Block a user