2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 21:55:20 +00:00

postfix-2.0.16-20031221

This commit is contained in:
Wietse Venema
2003-12-21 00:00:00 -05:00
committed by Viktor Dukhovni
parent 7011a3b3b6
commit 42f6ab4fc3
23 changed files with 333 additions and 737 deletions

View File

@@ -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

View File

@@ -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
==========================================================

View File

@@ -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.

View File

@@ -244,29 +244,22 @@ SMTP(8) SMTP(8)
<b>smtp_mx_address_limit</b>
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.
<b>smtp_mx_session_limit</b>
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.
<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>
The default time unit is seconds; an explicit time unit
can be specified by appending a one-letter suffix to the

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 <sys_defs.h>
#include <msg.h>
/* 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 */
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 */
void recipient_list_free(RECIPIENT_LIST *list)
{
if (list->len > 0)
recipient_list_truncate(list, 0);
RECIPIENT *rcpt;
for (rcpt = list->info; rcpt < list->info + list->len; rcpt++) {
myfree(rcpt->orig_addr);
myfree(rcpt->address);
}
myfree((char *) list->info);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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 *);
/*

View File

@@ -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");
}
}

View File

@@ -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);
}

View File

@@ -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);
}
}

View 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;
}

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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