2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 13:48:06 +00:00

postfix-2.3-20050627

This commit is contained in:
Wietse Venema
2005-06-27 00:00:00 -05:00
committed by Viktor Dukhovni
parent df5802491a
commit 6122cc449d
25 changed files with 320 additions and 86 deletions

View File

@@ -10931,8 +10931,34 @@ Apologies for any names omitted.
util/attr_print0.c, global/dsb_scan.c, global/dsn_print.c,
global/rcpt_buf,c global/rcpt_print.c, global/deliver_pass.c.
Added delegated attribute scan/print function support to
the base64 and plain attribute I/O encodings. Files:
util/attr_scan_plain.c util/attr_print_plain.c.
20040624
Added "." to the list commands that smtp-sink can "break"
(by disconnecting, or by responding with a 4XX or 5XX reply
code). File: smtpstone/smtp-sink.c.
20040625
Safety: allow only 4.x.x and 5.x.x enhanced status codes
in header/body_checks REJECT actions. File:
cleanup/cleanup_message.c.
20050627
Code cleanup: generalized the smtp-sink code that simulates
server errors. File: smtpstone/smtp-sink.c.
Open problems:
Look for systems with XPG basename() declared in <libgen.h>,
and prepare for phasing out the Postfix-supplied one.
Beware, however, that XPG basename() takes (char *), and
not (const char *) because it may change its argument.
Laptop friendliness: make the qmgr remember when the next
deferred queue scan needs to be done, and have the pickup
server stat() the maildrop directory before searching it.

View File

@@ -281,11 +281,16 @@ LMTP(8) LMTP(8)
P.O. Box 704
Yorktown Heights, NY 10598, USA
Alterations for LMTP by:
Modifications for LMTP by:
Philip A. Prindeville
Mirapoint, Inc.
USA.
SASL support originally by:
Till Franke
SuSE Rhein/Main AG
65760 Eschborn, Germany
Additional work on LMTP by:
Amos Gouaux
University of Texas at Dallas

View File

@@ -6206,7 +6206,7 @@ The default time unit is s (seconds).
<p>
The maximal number of MX (mail exchanger) IP addresses that can
result from mail exchanger lookups, or zero (no limit). Prior to
Postfix 2.3, this limit was disabled.
Postfix 2.3, this limit was disabled by default.
</p>
<p>

View File

@@ -50,6 +50,12 @@ SMTP-SINK(1) SMTP-SINK(1)
Reject the specified commands with a hard (5xx)
error code. This option implies <b>-p</b>.
Examples of commands are HELO, EHLO, LHLO, MAIL,
RCPT, VRFY, DATA, ., RSET, NOOP, and QUIT. Separate
command names by white space or commas, and use
quotes to protect white space from the shell. Com-
mand names are case-insensitive.
<b>-F</b> Disable XFORWARD support.
<b>-h</b> <i>hostname</i>
@@ -73,21 +79,34 @@ SMTP-SINK(1) SMTP-SINK(1)
Disconnect (without replying) after receiving one
of the specified commands.
<b>-r</b> <i>command,command,...</i>
Reject the specified commands with a soft (4xx)
error code. This option implies <b>-p</b>.
<b>-s</b> <i>command,command,...</i>
Log the named commands to syslogd. Examples of
commands that can be logged are HELO, EHLO, LHLO,
MAIL, RCPT, VRFY, RSET, NOOP, and QUIT. Separate
Examples of commands are HELO, EHLO, LHLO, MAIL,
RCPT, VRFY, DATA, ., RSET, NOOP, and QUIT. Separate
command names by white space or commas, and use
quotes to protect white space from the shell. Com-
mand names are case-insensitive.
<b>-r</b> <i>command,command,...</i>
Reject the specified commands with a soft (4xx)
error code. This option implies <b>-p</b>.
Examples of commands are HELO, EHLO, LHLO, MAIL,
RCPT, VRFY, DATA, ., RSET, NOOP, and QUIT. Separate
command names by white space or commas, and use
quotes to protect white space from the shell. Com-
mand names are case-insensitive.
<b>-s</b> <i>command,command,...</i>
Log the named commands to syslogd.
Examples of commands are HELO, EHLO, LHLO, MAIL,
RCPT, VRFY, DATA, ., RSET, NOOP, and QUIT. Separate
command names by white space or commas, and use
quotes to protect white space from the shell. Com-
mand names are case-insensitive.
<b>-t</b> <i>timeout</i> (default: 100)
Limit the time for receiving a command or sending a
response. The time limit is specified in seconds.
response. The time limit is specified in seconds.
<b>-v</b> Show the SMTP conversations.
@@ -96,7 +115,7 @@ SMTP-SINK(1) SMTP-SINK(1)
mand.
[<b>inet:</b>][<i>host</i>]:<i>port</i>
Listen on network interface <i>host</i> (default: any
Listen on network interface <i>host</i> (default: any
interface) TCP port <i>port</i>. Both <i>host</i> and <i>port</i> may be
specified in numeric or symbolic form.
@@ -104,14 +123,14 @@ SMTP-SINK(1) SMTP-SINK(1)
Listen on the UNIX-domain socket at <i>pathname</i>.
<i>backlog</i>
The maximum length the queue of pending connec-
The maximum length the queue of pending connec-
tions, as defined by the <b>listen</b>(2) system call.
<b>SEE ALSO</b>
<a href="smtp-source.1.html">smtp-source(1)</a>, SMTP/LMTP message generator
<b>LICENSE</b>
The Secure Mailer license must be distributed with this
The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>

View File

@@ -523,6 +523,11 @@ SMTP(8) SMTP(8)
Coventry,
CV1 4LY, United Kingdom.
SASL support originally by:
Till Franke
SuSE Rhein/Main AG
65760 Eschborn, Germany
Connection caching in cooperation with:
Victor Duchovni
Morgan Stanley

View File

@@ -962,6 +962,11 @@ SMTPD(8) SMTPD(8)
P.O. Box 704
Yorktown Heights, NY 10598, USA
SASL support originally by:
Till Franke
SuSE Rhein/Main AG
65760 Eschborn, Germany
TLS support originally by:
Lutz Jaenicke
BTU Cottbus

View File

@@ -49,6 +49,11 @@ Do not announce ENHANCEDSTATUSCODES support.
.IP "\fB-f \fIcommand,command,...\fR"
Reject the specified commands with a hard (5xx) error code.
This option implies \fB-p\fR.
.sp
Examples of commands are HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
DATA, ., RSET, NOOP, and QUIT. Separate command names by
white space or commas, and use quotes to protect white space
from the shell. Command names are case-insensitive.
.IP \fB-F\fR
Disable XFORWARD support.
.IP "\fB-h\fI hostname\fR"
@@ -66,15 +71,26 @@ a CISCO PIX system. Implies \fB-e\fR.
.IP "\fB-q \fIcommand,command,...\fR"
Disconnect (without replying) after receiving one of the
specified commands.
.sp
Examples of commands are HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
DATA, ., RSET, NOOP, and QUIT. Separate command names by
white space or commas, and use quotes to protect white space
from the shell. Command names are case-insensitive.
.IP "\fB-r \fIcommand,command,...\fR"
Reject the specified commands with a soft (4xx) error code.
This option implies \fB-p\fR.
.sp
Examples of commands are HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
DATA, ., RSET, NOOP, and QUIT. Separate command names by
white space or commas, and use quotes to protect white space
from the shell. Command names are case-insensitive.
.IP "\fB-s \fIcommand,command,...\fR"
Log the named commands to syslogd.
Examples of commands that can be logged are HELO, EHLO, LHLO, MAIL,
RCPT, VRFY, RSET, NOOP, and QUIT. Separate command names by white
space or commas, and use quotes to protect white space from the
shell. Command names are case-insensitive.
.sp
Examples of commands are HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
DATA, ., RSET, NOOP, and QUIT. Separate command names by
white space or commas, and use quotes to protect white space
from the shell. Command names are case-insensitive.
.IP "\fB-t \fItimeout\fR (default: 100)"
Limit the time for receiving a command or sending a response.
The time limit is specified in seconds.

View File

@@ -3437,7 +3437,7 @@ The default time unit is s (seconds).
.SH smtp_mx_address_limit (default: 5)
The maximal number of MX (mail exchanger) IP addresses that can
result from mail exchanger lookups, or zero (no limit). Prior to
Postfix 2.3, this limit was disabled.
Postfix 2.3, this limit was disabled by default.
.PP
This feature is available in Postfix 2.1 and later.
.SH smtp_mx_session_limit (default: 2)

View File

@@ -259,11 +259,16 @@ IBM T.J. Watson Research
P.O. Box 704
Yorktown Heights, NY 10598, USA
Alterations for LMTP by:
Modifications for LMTP by:
Philip A. Prindeville
Mirapoint, Inc.
USA.
SASL support originally by:
Till Franke
SuSE Rhein/Main AG
65760 Eschborn, Germany
Additional work on LMTP by:
Amos Gouaux
University of Texas at Dallas

View File

@@ -429,6 +429,11 @@ Canal Basin,
Coventry,
CV1 4LY, United Kingdom.
SASL support originally by:
Till Franke
SuSE Rhein/Main AG
65760 Eschborn, Germany
Connection caching in cooperation with:
Victor Duchovni
Morgan Stanley

View File

@@ -779,6 +779,11 @@ IBM T.J. Watson Research
P.O. Box 704
Yorktown Heights, NY 10598, USA
SASL support originally by:
Till Franke
SuSE Rhein/Main AG
65760 Eschborn, Germany
TLS support originally by:
Lutz Jaenicke
BTU Cottbus

View File

@@ -3829,7 +3829,7 @@ The default time unit is s (seconds).
<p>
The maximal number of MX (mail exchanger) IP addresses that can
result from mail exchanger lookups, or zero (no limit). Prior to
Postfix 2.3, this limit was disabled.
Postfix 2.3, this limit was disabled by default.
</p>
<p>

View File

@@ -315,6 +315,11 @@ static const char *cleanup_act(CLEANUP_STATE *state, char *context,
if (state->reason == 0) {
if (*optional_text) {
state->reason = dsn_prepend("5.7.1", optional_text);
if (*state->reason != '4' && *state->reason != '5') {
msg_warn("bad DSN action in %s -- need 4.x.x or 5.x.x",
optional_text);
*state->reason = '4';
}
} else {
detail = cleanup_stat_detail(CLEANUP_STAT_CONT);
state->reason = dsn_prepend(detail->dsn, detail->text);

View File

@@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
#define MAIL_RELEASE_DATE "20050623"
#define MAIL_RELEASE_DATE "20050627"
#define MAIL_VERSION_NUMBER "2.3"
#define VAR_MAIL_VERSION "mail_version"

View File

@@ -225,11 +225,16 @@
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Alterations for LMTP by:
/* Modifications for LMTP by:
/* Philip A. Prindeville
/* Mirapoint, Inc.
/* USA.
/*
/* SASL support originally by:
/* Till Franke
/* SuSE Rhein/Main AG
/* 65760 Eschborn, Germany
/*
/* Additional work on LMTP by:
/* Amos Gouaux
/* University of Texas at Dallas

View File

@@ -389,6 +389,11 @@
/* Coventry,
/* CV1 4LY, United Kingdom.
/*
/* SASL support originally by:
/* Till Franke
/* SuSE Rhein/Main AG
/* 65760 Eschborn, Germany
/*
/* Connection caching in cooperation with:
/* Victor Duchovni
/* Morgan Stanley

View File

@@ -355,7 +355,7 @@ int smtp_session_passivate(SMTP_SESSION *session, VSTRING *dest_prop,
/*
* Append the passivated SASL attributes.
*/
#ifdef USE_SASL
#ifdef notdef
if (smtp_sasl_enable)
smtp_sasl_passivate(endp_prop, session);
#endif
@@ -460,7 +460,7 @@ SMTP_SESSION *smtp_session_activate(int fd, VSTRING *dest_prop,
/*
* Re-activate the SASL attributes.
*/
#ifdef USE_SASL
#ifdef notdef
if (smtp_sasl_enable && smtp_sasl_activate(session, endp_props) < 0) {
vstream_fdclose(session->stream);
session->stream = 0;

View File

@@ -721,6 +721,11 @@
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* SASL support originally by:
/* Till Franke
/* SuSE Rhein/Main AG
/* 65760 Eschborn, Germany
/*
/* TLS support originally by:
/* Lutz Jaenicke
/* BTU Cottbus
@@ -1435,8 +1440,12 @@ static int extract_addr(SMTPD_STATE *state, SMTPD_TOKEN *arg,
}
/*
* Report trouble. Log a warning only if we are going to sleep+reject so
* that attackers can't flood our logfiles.
* Report trouble. XXX Should log a warning only if we are going to
* sleep+reject so that attackers can't flood our logfiles.
*
* XXX Unfortunately, the sleep-before-reject feature had to be abandoned
* (at least for small error counts) because servers were DOS-ing
* themselves when flooded by backscatter traffic.
*/
if (naddr > 1
|| (strict_rfc821 && (non_addr || *STR(arg->vstrval) != '<'))) {
@@ -1503,8 +1512,7 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
* XXX 2821 pedantism: Section 4.1.2 says that SMTP servers that receive a
* command in which invalid character codes have been employed, and for
* which there are no other reasons for rejection, MUST reject that
* command with a 501 response. So much for the principle of "be liberal
* in what you accept, be strict in what you send".
* command with a 501 response. Postfix attempts to be 8-bit clean.
*/
if (var_helo_required && state->helo_name == 0) {
state->error_mask |= MAIL_ERROR_POLICY;
@@ -2448,6 +2456,7 @@ static int vrfy_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
smtpd_chat_reply(state, "501 5.1.3 Bad recipient address syntax");
return (-1);
}
/* Not: state->addr_buf */
if (SMTPD_STAND_ALONE(state) == 0
&& (err = smtpd_check_rcpt(state, argv[1].strval)) != 0) {
smtpd_chat_reply(state, "%s", err);
@@ -2555,8 +2564,11 @@ static int quit_cmd(SMTPD_STATE *state, int unused_argc, SMTPD_TOKEN *unused_arg
* When the "." and quit replies are pipelined, make sure they are
* flushed now, to avoid repeated mail deliveries in case of a crash in
* the "clean up before disconnect" code.
*
* XXX When this was added in Postfix 2.1 we used vstream_fflush(). As of
* Postfix 2.3 we use smtp_flush() for better error reporting.
*/
vstream_fflush(state->client);
smtp_flush(state->client);
return (0);
}
@@ -2945,7 +2957,7 @@ static void chat_reset(SMTPD_STATE *state, int threshold)
#ifdef USE_TLS
/* smtpd_start_tls -turn on TLS or force disconnect */
/* smtpd_start_tls - turn on TLS or force disconnect */
static void smtpd_start_tls(SMTPD_STATE *state)
{
@@ -2961,10 +2973,10 @@ static void smtpd_start_tls(SMTPD_STATE *state)
* verification unless TLS is required.
*/
state->tls_context =
tls_server_start(smtpd_tls_ctx, state->client,
var_smtpd_starttls_tmout,
state->name, state->addr, &(state->tls_info),
(var_smtpd_tls_req_ccert && state->tls_enforce_tls));
tls_server_start(smtpd_tls_ctx, state->client,
var_smtpd_starttls_tmout,
state->name, state->addr, &(state->tls_info),
(var_smtpd_tls_req_ccert && state->tls_enforce_tls));
/*
* When the TLS handshake fails, the conversation is in an unknown state.
@@ -3493,12 +3505,13 @@ static void post_jail_init(char *unused_name, char **unused_argv)
* recipient checks, address mapping, header_body_checks?.
*/
smtpd_input_transp_mask =
input_transp_mask(VAR_INPUT_TRANSP, var_input_transp);
input_transp_mask(VAR_INPUT_TRANSP, var_input_transp);
/*
* Sanity checks. The queue_minfree value should be at least as large as
* (process_limit * message_size_limit) but that is unpractical, so we
* arbitrarily pick a number and require twice the message size limit.
* arbitrarily pick a small multiple of the per-message size limit. This
* helps to avoid many unneeded (re)transmissions.
*/
if (var_queue_minfree > 0
&& var_message_limit > 0

View File

@@ -43,6 +43,11 @@
/* .IP "\fB-f \fIcommand,command,...\fR"
/* Reject the specified commands with a hard (5xx) error code.
/* This option implies \fB-p\fR.
/* .sp
/* Examples of commands are HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
/* DATA, ., RSET, NOOP, and QUIT. Separate command names by
/* white space or commas, and use quotes to protect white space
/* from the shell. Command names are case-insensitive.
/* .IP \fB-F\fR
/* Disable XFORWARD support.
/* .IP "\fB-h\fI hostname\fR"
@@ -60,15 +65,26 @@
/* .IP "\fB-q \fIcommand,command,...\fR"
/* Disconnect (without replying) after receiving one of the
/* specified commands.
/* .sp
/* Examples of commands are HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
/* DATA, ., RSET, NOOP, and QUIT. Separate command names by
/* white space or commas, and use quotes to protect white space
/* from the shell. Command names are case-insensitive.
/* .IP "\fB-r \fIcommand,command,...\fR"
/* Reject the specified commands with a soft (4xx) error code.
/* This option implies \fB-p\fR.
/* .sp
/* Examples of commands are HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
/* DATA, ., RSET, NOOP, and QUIT. Separate command names by
/* white space or commas, and use quotes to protect white space
/* from the shell. Command names are case-insensitive.
/* .IP "\fB-s \fIcommand,command,...\fR"
/* Log the named commands to syslogd.
/* Examples of commands that can be logged are HELO, EHLO, LHLO, MAIL,
/* RCPT, VRFY, RSET, NOOP, and QUIT. Separate command names by white
/* space or commas, and use quotes to protect white space from the
/* shell. Command names are case-insensitive.
/* .sp
/* Examples of commands are HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
/* DATA, ., RSET, NOOP, and QUIT. Separate command names by
/* white space or commas, and use quotes to protect white space
/* from the shell. Command names are case-insensitive.
/* .IP "\fB-t \fItimeout\fR (default: 100)"
/* Limit the time for receiving a command or sending a response.
/* The time limit is specified in seconds.
@@ -141,6 +157,7 @@ typedef struct SINK_STATE {
int data_state;
int (*read_fn) (struct SINK_STATE *);
int rcpts;
char *push_back_ptr;
} SINK_STATE;
#define ST_ANY 0
@@ -150,6 +167,10 @@ typedef struct SINK_STATE {
#define ST_CR_LF_DOT_CR 4
#define ST_CR_LF_DOT_CR_LF 5
#define PUSH_BACK_PEEK(state) (*(state)->push_back_ptr != 0)
#define PUSH_BACK_GET(state) (*(state)->push_back_ptr++)
#define PUSH_BACK_SET(state, text) ((state)->push_back_ptr = (text))
static int var_tmout = 100;
static int var_max_line_length = 2048;
static char *var_myhostname;
@@ -170,6 +191,25 @@ static int disable_xclient;
static int disable_xforward;
static int disable_enh_status;
#define SOFT_ERROR_RESP "450 4.3.0 Error: command failed"
#define HARD_ERROR_RESP "500 5.3.0 Error: command failed"
/* hard_err_resp - generic hard error response */
static void hard_err_resp(SINK_STATE *state)
{
smtp_printf(state->stream, HARD_ERROR_RESP);
smtp_flush(state->stream);
}
/* soft_err_resp - generic soft error response */
static void soft_err_resp(SINK_STATE *state)
{
smtp_printf(state->stream, SOFT_ERROR_RESP);
smtp_flush(state->stream);
}
/* ehlo_response - respond to EHLO command */
static void ehlo_response(SINK_STATE *state)
@@ -244,6 +284,32 @@ static void data_event(int unused_event, char *context)
data_response(state);
}
/* dot_resp_hard - hard error response to . command */
static void dot_resp_hard(SINK_STATE *state)
{
if (enable_lmtp) {
while (state->rcpts-- > 0) /* XXX this could block */
smtp_printf(state->stream, HARD_ERROR_RESP);
} else {
smtp_printf(state->stream, HARD_ERROR_RESP);
}
smtp_flush(state->stream);
}
/* dot_resp_soft - soft error response to . command */
static void dot_resp_soft(SINK_STATE *state)
{
if (enable_lmtp) {
while (state->rcpts-- > 0) /* XXX this could block */
smtp_printf(state->stream, SOFT_ERROR_RESP);
} else {
smtp_printf(state->stream, SOFT_ERROR_RESP);
}
smtp_flush(state->stream);
}
/* dot_response - response to . command */
static void dot_response(SINK_STATE *state)
@@ -312,9 +378,7 @@ static int data_read(SINK_STATE *state)
else
state->data_state = ST_ANY;
if (state->data_state == ST_CR_LF_DOT_CR_LF) {
if (msg_verbose)
msg_info(".");
dot_response(state);
PUSH_BACK_SET(state, ".\r\n");
state->read_fn = command_read;
state->data_state = ST_ANY;
break;
@@ -337,6 +401,8 @@ static int data_read(SINK_STATE *state)
typedef struct SINK_COMMAND {
char *name;
void (*response) (SINK_STATE *);
void (*hard_response) (SINK_STATE *);
void (*soft_response) (SINK_STATE *);
int flags;
} SINK_COMMAND;
@@ -347,19 +413,20 @@ typedef struct SINK_COMMAND {
#define FLAG_DISCONNECT (1<<4) /* disconnect */
static SINK_COMMAND command_table[] = {
"helo", helo_response, 0,
"ehlo", ehlo_response, 0,
"lhlo", ehlo_response, 0,
"xclient", ok_response, FLAG_ENABLE,
"xforward", ok_response, FLAG_ENABLE,
"auth", ok_response, FLAG_ENABLE,
"mail", mail_response, FLAG_ENABLE,
"rcpt", rcpt_response, FLAG_ENABLE,
"data", data_response, FLAG_ENABLE,
"rset", ok_response, FLAG_ENABLE,
"noop", ok_response, FLAG_ENABLE,
"vrfy", ok_response, FLAG_ENABLE,
"quit", quit_response, FLAG_ENABLE,
"helo", helo_response, hard_err_resp, soft_err_resp, 0,
"ehlo", ehlo_response, hard_err_resp, soft_err_resp, 0,
"lhlo", ehlo_response, hard_err_resp, soft_err_resp, 0,
"xclient", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
"xforward", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
"auth", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
"mail", mail_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
"rcpt", rcpt_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
"data", data_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
".", dot_response, dot_resp_hard, dot_resp_soft, FLAG_ENABLE,
"rset", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
"noop", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
"vrfy", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
"quit", quit_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
0,
};
@@ -428,8 +495,11 @@ static int command_read(SINK_STATE *state)
* A read may result in EOF, but is never supposed to time out - a time
* out means that we were trying to read when no data was available.
*/
#define NEXT_CHAR(state) \
(PUSH_BACK_PEEK(state) ? PUSH_BACK_GET(state) : VSTREAM_GETC(state->stream))
for (;;) {
if ((ch = VSTREAM_GETC(state->stream)) == VSTREAM_EOF)
if ((ch = NEXT_CHAR(state)) == VSTREAM_EOF)
return (-1);
/*
@@ -467,7 +537,7 @@ static int command_read(SINK_STATE *state)
* instead of peek_fd() (which uses ioctl FIONREAD). Workaround added
* 20020604.
*/
if (vstream_peek(state->stream) <= 0
if (PUSH_BACK_PEEK(state) == 0 && vstream_peek(state->stream) <= 0
&& readable(vstream_fileno(state->stream)) <= 0)
return (0);
}
@@ -501,21 +571,19 @@ static int command_read(SINK_STATE *state)
smtp_flush(state->stream);
return (0);
}
if (cmdp->flags & FLAG_DISCONNECT)
return (-1);
if (cmdp->flags & FLAG_HARD_ERR) {
smtp_printf(state->stream, "500 5.3.0 Error: command failed");
smtp_flush(state->stream);
return (0);
}
if (cmdp->flags & FLAG_SOFT_ERR) {
smtp_printf(state->stream, "450 4.3.0 Error: command failed");
smtp_flush(state->stream);
return (0);
}
/* We use raw syslog. Sanitize data content and length. */
if (cmdp->flags & FLAG_SYSLOG)
syslog(LOG_INFO, "%s %.100s", command, printable(ptr, '?'));
if (cmdp->flags & FLAG_DISCONNECT)
return (-1);
if (cmdp->flags & FLAG_HARD_ERR) {
cmdp->hard_response(state);
return (0);
}
if (cmdp->flags & FLAG_SOFT_ERR) {
cmdp->soft_response(state);
return (0);
}
if (cmdp->response == data_response && fixed_delay > 0) {
event_request_timer(data_event, (char *) state, fixed_delay);
} else {
@@ -582,7 +650,7 @@ static void read_event(int unused_event, char *context)
return;
}
}
} while (vstream_peek(state->stream) > 0);
} while (PUSH_BACK_PEEK(state) != 0 || vstream_peek(state->stream) > 0);
/*
* Reset the idle timer. Wait until the next input event, or until the
@@ -633,6 +701,7 @@ static void connect_event(int unused_event, char *context)
state->buffer = vstring_alloc(1024);
state->read_fn = command_read;
state->data_state = ST_ANY;
PUSH_BACK_SET(state, "");
smtp_timeout_setup(state->stream, var_tmout);
/*

View File

@@ -56,7 +56,8 @@
/* length, and an attribute value pointer.
/* .IP "ATTR_TYPE_FUNC (ATTR_PRINT_SLAVE_FN, void *)"
/* This argument is followed by a function pointer and generic data
/* pointer.
/* pointer. The caller-specified function returns whatever the
/* specified attribute printing function returns.
/* .IP "ATTR_TYPE_HASH (HTABLE *)"
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
/* The content of the table is sent as a sequence of string-valued

View File

@@ -51,6 +51,10 @@
/* .IP "ATTR_TYPE_STR (char *, char *)"
/* This argument is followed by an attribute name and a null-terminated
/* string.
/* .IP "ATTR_TYPE_FUNC (ATTR_PRINT_SLAVE_FN, void *)"
/* This argument is followed by a function pointer and generic data
/* pointer. The caller-specified function returns whatever the
/* specified attribute printing function returns.
/* .IP "ATTR_TYPE_HASH (HTABLE *)"
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
/* The content of the table is sent as a sequence of string-valued
@@ -142,6 +146,8 @@ int attr_vprint64(VSTREAM *fp, int flags, va_list ap)
HTABLE_INFO **ht_info_list;
HTABLE_INFO **ht;
int len_val;
ATTR_PRINT_SLAVE_FN print_fn;
void *print_arg;
/*
* Sanity check.
@@ -196,6 +202,11 @@ int attr_vprint64(VSTREAM *fp, int flags, va_list ap)
if (msg_verbose)
msg_info("send attr %s = [data %d bytes]", attr_name, len_val);
break;
case ATTR_TYPE_FUNC:
print_fn = va_arg(ap, ATTR_PRINT_SLAVE_FN);
print_arg = va_arg(ap, void *);
print_fn(attr_print64, fp, flags | ATTR_FLAG_MORE, print_arg);
break;
case ATTR_TYPE_HASH:
ht_info_list = htable_list(va_arg(ap, HTABLE *));
for (ht = ht_info_list; *ht; ht++) {

View File

@@ -54,6 +54,10 @@
/* .IP "ATTR_TYPE_DATA (char *, int, char *)"
/* This argument is followed by an attribute name, an attribute value
/* length, and a pointer to attribute value.
/* .IP "ATTR_TYPE_FUNC (ATTR_PRINT_SLAVE_FN, void *)"
/* This argument is followed by a function pointer and generic data
/* pointer. The caller-specified function returns whatever the
/* specified attribute printing function returns.
/* .IP "ATTR_TYPE_HASH (HTABLE *)"
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
/* The content of the table is sent as a sequence of string-valued
@@ -112,6 +116,8 @@ int attr_vprint_plain(VSTREAM *fp, int flags, va_list ap)
HTABLE_INFO **ht;
static VSTRING *base64_buf;
int len_val;
ATTR_PRINT_SLAVE_FN print_fn;
void *print_arg;
/*
* Sanity check.
@@ -157,6 +163,11 @@ int attr_vprint_plain(VSTREAM *fp, int flags, va_list ap)
if (msg_verbose)
msg_info("send attr %s = [data %d bytes]", attr_name, len_val);
break;
case ATTR_TYPE_FUNC:
print_fn = va_arg(ap, ATTR_PRINT_SLAVE_FN);
print_arg = va_arg(ap, void *);
print_fn(attr_print_plain, fp, flags | ATTR_FLAG_MORE, print_arg);
break;
case ATTR_TYPE_HASH:
ht_info_list = htable_list(va_arg(ap, HTABLE *));
for (ht = ht_info_list; *ht; ht++) {

View File

@@ -95,7 +95,8 @@
/* This argument is followed by an attribute name and a VSTRING pointer.
/* .IP "ATTR_TYPE_FUNC (ATTR_SCAN_SLAVE_FN, void *)"
/* This argument is followed by a function pointer and a generic data
/* pointer.
/* pointer. The caller-specified function returns < 0 in case of
/* error.
/* .IP "ATTR_TYPE_HASH (HTABLE *)"
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
/* All further input attributes are processed as string attributes.

View File

@@ -47,7 +47,7 @@
/* characters. The formatting rules aim to make implementations in PERL
/* and other languages easy.
/*
/* Normally, attributes must be received in the sequence as specified with
/* Normally, attributes must be received in the sequence as specified with
/* the attr_scan64() argument list. The input stream may contain additional
/* attributes at any point in the input stream, including additional
/* instances of requested attributes.
@@ -95,6 +95,10 @@
/* This argument is followed by an attribute name and a VSTRING pointer.
/* .IP "ATTR_TYPE_DATA (char *, VSTRING *)"
/* This argument is followed by an attribute name and a VSTRING pointer.
/* .IP "ATTR_TYPE_FUNC (ATTR_SCAN_SLAVE_FN, void *)"
/* This argument is followed by a function pointer and a generic data
/* pointer. The caller-specified function returns < 0 in case of
/* error.
/* .IP "ATTR_TYPE_HASH (HTABLE *)"
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
/* All further input attributes are processed as string attributes.
@@ -165,9 +169,11 @@
static int attr_scan64_string(VSTREAM *fp, VSTRING *plain_buf, const char *context)
{
static VSTRING *base64_buf = 0;
#if 0
extern int var_line_limit; /* XXX */
int limit = var_line_limit * 4;
#endif
int ch;
@@ -254,6 +260,8 @@ int attr_vscan64(VSTREAM *fp, int flags, va_list ap)
HTABLE *hash_table;
int ch;
int conversions;
ATTR_SCAN_SLAVE_FN scan_fn;
void *scan_arg;
/*
* Sanity check.
@@ -295,7 +303,7 @@ int attr_vscan64(VSTREAM *fp, int flags, va_list ap)
if (va_arg(ap, int) !=ATTR_TYPE_END)
msg_panic("%s: ATTR_TYPE_HASH not followed by ATTR_TYPE_END",
myname);
} else {
} else if (wanted_type != ATTR_TYPE_FUNC) {
wanted_name = va_arg(ap, char *);
}
}
@@ -303,7 +311,7 @@ int attr_vscan64(VSTREAM *fp, int flags, va_list ap)
/*
* Locate the next attribute of interest in the input stream.
*/
for (;;) {
while (wanted_type != ATTR_TYPE_FUNC) {
/*
* Get the name of the next attribute. Hitting EOF is always bad.
@@ -419,6 +427,12 @@ int attr_vscan64(VSTREAM *fp, int flags, va_list ap)
return (-1);
}
break;
case ATTR_TYPE_FUNC:
scan_fn = va_arg(ap, ATTR_SCAN_SLAVE_FN);
scan_arg = va_arg(ap, void *);
if (scan_fn(attr_scan64, fp, flags | ATTR_FLAG_MORE, scan_arg) < 0)
return (-1);
break;
case ATTR_TYPE_HASH:
if (ch != ':') {
msg_warn("missing value for string attribute %s from %s",

View File

@@ -45,7 +45,7 @@
/* characters. The formatting rules aim to make implementations in PERL
/* and other languages easy.
/*
/* Normally, attributes must be received in the sequence as specified
/* Normally, attributes must be received in the sequence as specified
/* with the attr_scan_plain() argument list. The input stream may
/* contain additional attributes at any point in the input stream,
/* including additional instances of requested attributes.
@@ -93,6 +93,10 @@
/* This argument is followed by an attribute name and a VSTRING pointer.
/* .IP "ATTR_TYPE_DATA (char *, VSTRING *)"
/* This argument is followed by an attribute name and a VSTRING pointer.
/* .IP "ATTR_TYPE_FUNC (ATTR_SCAN_SLAVE_FN, void *)"
/* This argument is followed by a function pointer and a generic data
/* pointer. The caller-specified function returns < 0 in case of
/* error.
/* .IP "ATTR_TYPE_HASH (HTABLE *)"
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
/* All further input attributes are processed as string attributes.
@@ -166,6 +170,7 @@ static int attr_scan_plain_string(VSTREAM *fp, VSTRING *plain_buf,
#if 0
extern int var_line_limit; /* XXX */
int limit = var_line_limit * 4;
#endif
int ch;
@@ -268,6 +273,8 @@ int attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
HTABLE *hash_table;
int ch;
int conversions;
ATTR_SCAN_SLAVE_FN scan_fn;
void *scan_arg;
/*
* Sanity check.
@@ -309,7 +316,7 @@ int attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
if (va_arg(ap, int) !=ATTR_TYPE_END)
msg_panic("%s: ATTR_TYPE_HASH not followed by ATTR_TYPE_END",
myname);
} else {
} else if (wanted_type != ATTR_TYPE_FUNC) {
wanted_name = va_arg(ap, char *);
}
}
@@ -317,7 +324,7 @@ int attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
/*
* Locate the next attribute of interest in the input stream.
*/
for (;;) {
while (wanted_type != ATTR_TYPE_FUNC) {
/*
* Get the name of the next attribute. Hitting EOF is always bad.
@@ -361,12 +368,7 @@ int attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
}
/*
* Do the requested conversion. If the target attribute is a
* non-array type, disallow sending a multi-valued attribute, and
* disallow sending no value. If the target attribute is an array
* type, allow the sender to send a zero-element array (i.e. no value
* at all). XXX Need to impose a bound on the number of array
* elements.
* Do the requested conversion.
*/
switch (wanted_type) {
case ATTR_TYPE_NUM:
@@ -413,6 +415,12 @@ int attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
"input attribute value")) < 0)
return (-1);
break;
case ATTR_TYPE_FUNC:
scan_fn = va_arg(ap, ATTR_SCAN_SLAVE_FN);
scan_arg = va_arg(ap, void *);
if (scan_fn(attr_scan_plain, fp, flags | ATTR_FLAG_MORE, scan_arg) < 0)
return (-1);
break;
case ATTR_TYPE_HASH:
if (ch != '=') {
msg_warn("missing value for string attribute %s from %s",